2011-04-29 2 views
8

안드로이드 표면 뷰를 사용하고 있으며 버튼을 추가하려고합니다. 표면보기 캔버스에서 나는 무언가를 그립니다. 그리고 드로잉을 유지하는 스레드 클래스가 있습니다.Android : 크래시 : 이진 XML 파일 행 : 클래스 팽창 오류 (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); 
         } 
        } 

       } 
     ); 

스레드 클래스

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); 
       } 
      } 
     } 
    } 
} 

서피스 뷰 SurfaceView & 여기

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; 
      } 
     } 
    } 
    } 

그리기위한 클래스 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> 

이다 문제 : "MySurfaceView"중첩 된 클래스로이 없으면 위의 코드는에만 작동합니다. 하지만 외부 클래스 "테스트" 나는 다음과 같은 오류가 발생합니다. "클래스 테스트" 을 제거하면 올바르게 작동합니다.

오류/충돌

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) 

어떤 도움이 큰 것입니다 ... 나는 이것에 붙어있어.

+0

내가 "MySurfaceView"를 중첩 된/내부 클래스로 사용하면 클래스를 찾을 수 없다고 생각합니다. 어떤 아이디어! – m4n07

+0

그 패키지에 실제로 해당 클래스가 있습니까? 패키지 명명 규칙 이후에 클래스의 이름을 유지하고 공유 코어에 패키지 선언이 전혀 없기 때문에! 기본 패키지를 사용한다면' rekaszeru

+0

죄송합니다. 패키지 세부 정보로 업데이트되었습니다. – m4n07

답변

11

첫째, 당신은 유지 클래스의 인스턴스를 사용할 수없는이 경우에도 팽창 할 수 있도록하는 static 형식으로보기를 선언해야합니다 :

public static class MySurfaceView extends SurfaceView 
    implements SurfaceHolder.Callback 

라인

<com.androidsurfaceview.test.MySurfaceView 

귀하의 레이아웃 xml에 따르면, MySurfaceView 클래스가 com.androidsurfaceview.test 패키지 안에 있고, 거기에서 부풀려하려고 시도했는데 잘못된 것입니다.

레이아웃에서 package.class $ innerclass 신고 양식을 따라야합니다.

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

가 작동이 방법은 다음 "$" 이후

하지만 는 다음과 같이

<com.androidsurfaceview.test$MySurfaceView 

은 그래서 당신은 레이아웃 XML에서보기를 지정해야 쓸 수 없습니다, 불법 문자입니다.

+0

고마워요 !!! 그것은 효과가 있었다. 나는 또한 처음에 클래스를 정적으로 만들려고했다.그러나 나는 내가보기 클래스 & $로 그것을 줘야한다라는 것을 모르고 있었다. 내가 배울 수있는 튜토리얼이나 책을 추천 해 주시겠습니까? – m4n07

+1

[Android 개발자의 흥미로운 주제] (http://developer.android.com/guide/topics/ui/index.html)를 읽음으로써 많은 것을 배웠습니다. 그러나 많은 자습서와 샘플이 있습니다. 내가 좋아하는 것은 @Renaun Ericksson의 트릭과 @ CommonSWare의 예다. – rekaszeru

+0

고마워요 !!! 나는 그들을 통과하려고 노력할 것이다. – m4n07