2011-04-29 2 views
8

J'ai android surfaceview et en ce que j'essaie d'ajouter des boutons à cela. Dans le canvas surfaceview je dessine quelque chose. Et j'ai une classe de thread pour continuer à dessiner.Android: Crash: ligne de fichier XML binaire: erreur classe de gonflement (en utilisant SurfaceView)

package com.androidsurfaceview; 

import android.app.Activity; 
import android.os.Bundle; 
import android.view.View; 
import android.widget.Button; 

public class androidsurfaceview extends Activity { 
    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     Button buttonShowHide = (Button)findViewById(R.id.showhide); 
     final Button buttonDummy = (Button)findViewById(R.id.dummy); 

     buttonShowHide.setOnClickListener(
       new Button.OnClickListener(){ 

        @Override 
        public void onClick(View arg0) { 
         // TODO Auto-generated method stub 
         if(buttonDummy.getVisibility()==View.VISIBLE){ 
          buttonDummy.setVisibility(View.GONE); 
         } 
         else{ 
          buttonDummy.setVisibility(View.VISIBLE); 
         } 
        } 

       } 
     ); 

La classe fil

package com.androidsurfaceview; 

import android.graphics.Canvas; 
import android.view.SurfaceHolder; 
public class MySurfaceThread extends Thread { 
    private SurfaceHolder myThreadSurfaceHolder; 
    private com.androidsurfaceview.test.MySurfaceView myThreadSurfaceView; 
    private boolean myThreadRun = false; 

    public MySurfaceThread(SurfaceHolder surfaceHolder, com.androidsurfaceview.test.MySurfaceView surfaceView) { 
     myThreadSurfaceHolder = surfaceHolder; 
     myThreadSurfaceView = surfaceView; 
    } 

    public void setRunning(boolean b) { 
     myThreadRun = b; 
    } 

    @Override 
    public void run() { 
     // TODO Auto-generated method stub 
     while(myThreadRun){ 
      Canvas c = null; 

      try{ 
       c = myThreadSurfaceHolder.lockCanvas(null); 
       synchronized (myThreadSurfaceHolder){ 
        myThreadSurfaceView.onDraw(c); 
       } 
       sleep(100); 
      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
      finally{ 
       // do this in a finally so that if an exception is thrown 
       // during the above, we don't leave the Surface in an 
       // inconsistent state 
       if (c != null) { 
        myThreadSurfaceHolder.unlockCanvasAndPost(c); 
       } 
      } 
     } 
    } 
} 

Le surfaceview & la classe pour le dessin

package com.androidsurfaceview; 

import android.app.Activity; 
import android.content.Context; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.util.AttributeSet; 
import android.view.SurfaceHolder; 
import android.view.SurfaceView; 

public class test extends Activity{ 

     //  ...... 
     // I do a few things here... with this class test. 

    public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback{ 

     private MySurfaceThread thread; 
     private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); 
     int cx, cy, offx, offy; 

     public MySurfaceView(Context context) { 
      super(context); 
      // TODO Auto-generated constructor stub 
      init(); 
     } 

     public MySurfaceView(Context context, AttributeSet attrs) { 
      super(context, attrs); 
      // TODO Auto-generated constructor stub 
      init(); 
     } 

     public MySurfaceView(Context context, AttributeSet attrs, int defStyle) { 
      super(context, attrs, defStyle); 
      // TODO Auto-generated constructor stub 
      init(); 
     } 

     private void init(){ 
       getHolder().addCallback(this); 
       thread = new MySurfaceThread(getHolder(), this); 

       setFocusable(true); // make sure we get key events 

       paint.setStyle(Paint.Style.STROKE); 
       paint.setStrokeWidth(3); 
       paint.setColor(Color.WHITE); 

       cx = 0; 
       cy = 0; 
       offx = 10; 
       offy = 10; 

      } 

     @Override 
     public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) { 
      // TODO Auto-generated method stub 

     } 

     @Override 
     public void surfaceCreated(SurfaceHolder holder) { 
      // TODO Auto-generated method stub 
      thread.setRunning(true); 
      thread.start(); 

     } 

     @Override 
     public void surfaceDestroyed(SurfaceHolder holder) { 
      // TODO Auto-generated method stub 
      boolean retry = true; 
      thread.setRunning(false); 
      while (retry) { 
       try { 
        thread.join(); 
        retry = false; 
       } 
       catch (InterruptedException e) { 
       } 
      } 
     } 
    ////Just a simple graphic of moving circle. 
     @Override 
     protected void onDraw(Canvas canvas) { 
      // TODO Auto-generated method stub 
      canvas.drawRGB(0, 0, 0); 
      canvas.drawCircle(cx, cy, 3, paint); 
      cx += offx; 
      if (cx > getWidth() || (cx < 0)){ 
       offx *= -1; 
       cx += offx; 
      } 

      cy += offy; 
      if (cy > getHeight() || (cy < 0)){ 
       offy *= -1; 
       cy += offy; 
      } 
     } 
    } 
    } 

Voici le main.xml

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"> 
<Button 
    android:id="@+id/showhide" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="Toggle The Another Button Show/Hide" /> 
<Button 
    android:id="@+id/dummy" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="a Button" /> 
<FrameLayout 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"> 

<com.androidsurfaceview.test.MySurfaceView 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"/> 

</FrameLayout> 
</LinearLayout> 

PROBLÈME: Le code ci-dessus fonctionne SEULEMENT si je n'ai pas le "MySurfaceView" comme classe imbriquée. mais avec la classe externe "test" Je reçois l'erreur suivante. Si je supprime le "test de classe" cela fonctionne très bien.

Erreur/accident

04-29 11:43:18.977: ERROR/AndroidRuntime(21832): FATAL EXCEPTION: main 
04-29 11:43:18.977: ERROR/AndroidRuntime(21832): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.androidsurfaceview/com.androidsurfaceview.androidsurfaceview}: **android.view.InflateException: Binary XML file line #20: Error inflating class com.androidsurfaceview.test.MySurfaceView** 
04-29 11:43:18.977: ERROR/AndroidRuntime(21832):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663) 
04-29 11:43:18.977: ERROR/AndroidRuntime(21832):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679) 
04-29 11:43:18.977: ERROR/AndroidRuntime(21832):  at android.app.ActivityThread.access$2300(ActivityThread.java:125) 
04-29 11:43:18.977: ERROR/AndroidRuntime(21832):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033) 
04-29 11:43:18.977: ERROR/AndroidRuntime(21832):  at android.os.Handler.dispatchMessage(Handler.java:99) 
04-29 11:43:18.977: ERROR/AndroidRuntime(21832):  at android.os.Looper.loop(Looper.java:123) 
04-29 11:43:18.977: ERROR/AndroidRuntime(21832):  at android.app.ActivityThread.main(ActivityThread.java:4627) 
04-29 11:43:18.977: ERROR/AndroidRuntime(21832):  at java.lang.reflect.Method.invokeNative(Native Method) 
04-29 11:43:18.977: ERROR/AndroidRuntime(21832):  at java.lang.reflect.Method.invoke(Method.java:521) 
04-29 11:43:18.977: ERROR/AndroidRuntime(21832):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 
04-29 11:43:18.977: ERROR/AndroidRuntime(21832):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 
04-29 11:43:18.977: ERROR/AndroidRuntime(21832):  at dalvik.system.NativeStart.main(Native Method) 
**04-29 11:43:18.977: ERROR/AndroidRuntime(21832): Caused by: android.view.InflateException: Binary XML file line #20: Error inflating class com.androidsurfaceview.test.MySurfaceView** 
04-29 11:43:18.977: ERROR/AndroidRuntime(21832):  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:576) 
04-29 11:43:18.977: ERROR/AndroidRuntime(21832):  at android.view.LayoutInflater.rInflate(LayoutInflater.java:618) 
04-29 11:43:18.977: ERROR/AndroidRuntime(21832):  at android.view.LayoutInflater.rInflate(LayoutInflater.java:621) 
04-29 11:43:18.977: ERROR/AndroidRuntime(21832):  at android.view.LayoutInflater.inflate(LayoutInflater.java:407) 
04-29 11:43:18.977: ERROR/AndroidRuntime(21832):  at android.view.LayoutInflater.inflate(LayoutInflater.java:320) 
04-29 11:43:18.977: ERROR/AndroidRuntime(21832):  at android.view.LayoutInflater.inflate(LayoutInflater.java:276) 
04-29 11:43:18.977: ERROR/AndroidRuntime(21832):  at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:200) 
04-29 11:43:18.977: ERROR/AndroidRuntime(21832):  at android.app.Activity.setContentView(Activity.java:1647) 
04-29 11:43:18.977: ERROR/AndroidRuntime(21832):  at com.androidsurfaceview.androidsurfaceview.onCreate(androidsurfaceview.java:13) 
04-29 11:43:18.977: ERROR/AndroidRuntime(21832):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 
04-29 11:43:18.977: ERROR/AndroidRuntime(21832):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627) 

Toute aide sera grande ... Je suis coincé avec cela.

+0

Je pense qu'il n'est pas capable de trouver la classe si j'ai "MySurfaceView" comme imbriqué/classe interne. Des idées ! – m4n07

+0

avez-vous réellement cette classe dans ce paquet? parce que vous continuez à nommer vos classes après la convention de nommage des paquets, et dans votre core partagé, il n'y a aucune déclaration de paquetage! Si vous utilisez le package par défaut, essayez rekaszeru

+0

Désolé, vous avez oublié d'ajouter. Mis à jour avec les détails du package. – m4n07

Répondre

11

D'abord, vous devez déclarer votre point de vue en tant que type static, pour pouvoir être gonflé, même quand aucune instance de la classe de maintien est disponible:

public static class MySurfaceView extends SurfaceView 
    implements SurfaceHolder.Callback 

La ligne

<com.androidsurfaceview.test.MySurfaceView 

Dans votre mise en page XML suggère que la classe MySurfaceView est à l'intérieur du paquet com.androidsurfaceview.test, et tente de gonfler à partir de là, ce qui est faux.

Dans votre mise en page, vous devez suivre la forme package.class $ innerclass.

MAIS depuis le "$" est le caractère illégal, vous ne pouvez pas écrire

<com.androidsurfaceview.test$MySurfaceView 

vous devez donc préciser votre point de vue dans la mise en page XML comme suit:

<view class="com.androidsurfaceview.test$MySurfaceView" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"/> 

De cette façon, cela fonctionnera.

+0

Merci beaucoup !!! Ça a marché. J'ai aussi essayé de rendre la classe statique au départ.Mais je ne savais pas que je dois le donner avec vue classe et $. Recommandez-vous un tutoriel ou un livre où je peux apprendre. – m4n07

+1

J'ai beaucoup appris en lisant les [sujets intéressants des développeurs Android] (http://developer.android.com/guide/topics/ui/index.html), mais il y a beaucoup de tutoriels et d'exemples. Mes préférés sont les astuces de @Renaun Ericksson et les exemples de @CommonsWare. – rekaszeru

+0

Merci beaucoup !!! Je vais essayer de les traverser. – m4n07

Questions connexes