-1

アプリを実行すると、MenuView は正常に表示されますが、ヘルプ画像のある場所をクリックすると、アプリが強制終了されます....

主な活動:

public class MainActivity extends Activity {

private static final String TAG = MainActivity.class.getSimpleName();

MenuView menuView;
HelpView helpView;
GameView gameView;

Handler myHandler = new Handler(){
    public void handleMessage(Message msg) {

        if(msg.what == 2){
            if(menuView != null){
                menuView = null;
            }
            MainActivity.this.setContentView(menuView);
            new Thread(){
                public void run(){
                    Looper.prepare();
                    gameView = new GameView(MainActivity.this);
                    Looper.loop();
                }
            }.start();
        }
        else if(msg.what == 3){
            initHelpView();
        }

    }
}; 

public void initHelpView(){
    helpView = new HelpView(this);
    this.setContentView(helpView);
}


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 
            WindowManager.LayoutParams.FLAG_FULLSCREEN);
    setContentView(new MenuView(this));
    Log.d(TAG, "View added");
    new Thread(){
        public void run(){
            Looper.prepare();
            menuView = new MenuView(MainActivity.this);
        }
    }.start();
}

@Override
protected void onDestroy() {
    Log.d(TAG, "Destroying...");
    super.onDestroy();
}


@Override
protected void onStop() {
    Log.d(TAG, "Stopping...");
    super.onStop();
}




    }

メニュービュー:

public class MenuView extends SurfaceView implements
  SurfaceHolder.Callback {
private static final String TAG = MenuView.class.getSimpleName();

private MenuViewThread thread;
private MainActivity activity;

public MenuView(Context context) {
    super(context);
    getHolder().addCallback(this);
    thread = new MenuViewThread(getHolder(),this);
    setFocusable(true);
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
        int height) {


}

@Override
public void surfaceCreated(SurfaceHolder holder) {
    thread.setRunning(true);
    thread.start();

}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {

    Log.d(TAG, "Surface is being destroyed");
     boolean retry = true;
     while (retry){
         try {
             thread.join();
             retry = false;
         }catch ( InterruptedException e){
             //try again shutting down the thread
         }
     }

}


protected void onDraw(Canvas canvas) {
     canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.background), 0,0,null);
     canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.opensound), 105,240,null);
     canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.help), 225,240,null);
     canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.exit), 345,240,null);
     canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.startgame), 190,150,null);

}

public boolean onTouchEvent(MotionEvent event) {
    if(event.getAction() == MotionEvent.ACTION_DOWN){


        if(event.getX()>225 && event.getX()<255 + 30
                && event.getY()>240& event.getY() <270 + 30){
            activity.myHandler.sendEmptyMessage(3);
        }else {
            Log.d(TAG, "Coords: x=" + event.getX() + ",y=" + event.getY());
        }
    }return super.onTouchEvent(event);

}

    }

メニュービュースレッド:

public class MenuViewThread extends Thread {
private static final String TAG = MenuViewThread.class.getSimpleName();

private MenuView menu;
private SurfaceHolder surfaceHolder;
private boolean running;

public void setRunning(boolean running){
    this.running = running;
}


public MenuViewThread( SurfaceHolder surfaceHolder, MenuView menu){
    super();
    this.surfaceHolder = surfaceHolder;
    this.menu = menu;
}

@Override
public void run() {
      Canvas canvas;
      while (running) {
       canvas = null;
       // try locking the canvas for exclusive pixel editing on the surface
       try {
        canvas = this.surfaceHolder.lockCanvas();
        synchronized (surfaceHolder) {
         // update game state
         // draws the canvas on the panel
         this.menu.onDraw(canvas);
        }
       } finally {
        // in case of an exception the surface is not left in
        // an inconsistent state
        if (canvas != null) {
         this.surfaceHolder.unlockCanvasAndPost(canvas);
        }
       } // end finally
      }
}

    }

このアプリにはエラーはないように見えますが、画像をクリックするとうまくいきません。何が問題なのですか?

ログキャット:

12-12 06:50:20.792: D/MainActivity(1342): View added
12-12 06:50:24.312: D/AndroidRuntime(1342): Shutting down VM
12-12 06:50:24.312: W/dalvikvm(1342): threadid=1: thread exiting with uncaught exception (group=0x4001d800)
12-12 06:50:24.312: E/AndroidRuntime(1342): FATAL EXCEPTION: main
12-12 06:50:24.312: E/AndroidRuntime(1342): java.lang.NullPointerException
12-12 06:50:24.312: E/AndroidRuntime(1342):     at com.example.demo.MenuView.onTouchEvent(MenuView.java:75)
12-12 06:50:24.312: E/AndroidRuntime(1342):     at android.view.View.dispatchTouchEvent(View.java:3766)
12-12 06:50:24.312: E/AndroidRuntime(1342):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:863)
12-12 06:50:24.312: E/AndroidRuntime(1342):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:863)
12-12 06:50:24.312: E/AndroidRuntime(1342):     at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1671)
12-12 06:50:24.312: E/AndroidRuntime(1342):     at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1107)
12-12 06:50:24.312: E/AndroidRuntime(1342):     at android.app.Activity.dispatchTouchEvent(Activity.java:2086)
12-12 06:50:24.312: E/AndroidRuntime(1342):     at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1655)
12-12 06:50:24.312: E/AndroidRuntime(1342):     at android.view.ViewRoot.handleMessage(ViewRoot.java:1785)
12-12 06:50:24.312: E/AndroidRuntime(1342):     at android.os.Handler.dispatchMessage(Handler.java:99)
12-12 06:50:24.312: E/AndroidRuntime(1342):     at android.os.Looper.loop(Looper.java:123)
12-12 06:50:24.312: E/AndroidRuntime(1342):     at android.app.ActivityThread.main(ActivityThread.java:4627)
12-12 06:50:24.312: E/AndroidRuntime(1342):     at java.lang.reflect.Method.invokeNative(Native Method)
12-12 06:50:24.312: E/AndroidRuntime(1342):     at java.lang.reflect.Method.invoke(Method.java:521)
12-12 06:50:24.312: E/AndroidRuntime(1342):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
12-12 06:50:24.312: E/AndroidRuntime(1342):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
12-12 06:50:24.312: E/AndroidRuntime(1342):     at dalvik.system.NativeStart.main(Native Method)
12-12 06:50:39.443: D/dalvikvm(1342): GC_FOR_MALLOC freed 6747 objects / 375136 bytes in 64ms

新しい logcat:

12-12 07:11:15.433: I/Process(1461): Sending signal. PID: 1461 SIG: 9
12-12 07:15:58.392: D/MainActivity(1491): View added
12-12 07:16:08.022: D/MenuView(1491): Surface is being destroyed
12-12 07:16:14.212: I/dalvikvm(1491): threadid=3: reacting to signal 3
12-12 07:16:14.222: I/dalvikvm(1491): Wrote stack traces to '/data/anr/traces.txt'
12-12 07:16:26.433: D/MainActivity(1501): View added
12-12 07:16:28.153: D/MenuView(1501): Coords: x=224.0,y=250.0
12-12 07:16:29.113: D/MenuView(1501): Surface is being destroyed
12-12 07:16:35.072: I/dalvikvm(1501): threadid=3: reacting to signal 3
12-12 07:16:35.072: I/dalvikvm(1501): Wrote stack traces to '/data/anr/traces.txt'
12-12 07:16:53.493: D/dalvikvm(1501): GC_FOR_MALLOC freed 7084 objects / 359392 bytes in 72ms
4

1 に答える 1

0
java.lang.NullPointerException
    at com.example.demo.MenuView.onTouchEvent(MenuView.java:75)

初期化するのを忘れたようactivityです。


おそらく、コンストラクターでアクティビティを渡すことができます。

public MenuView(Context context, Activity activity) {
    ...
    this.activity = activity; 
}

追加
このアプローチが機能するかどうかはわかりませんが。別のスレッドでUI要素を操作するという概念:

new Thread(){
    public void run(){
        Looper.prepare();
        gameView = new GameView(MainActivity.this);
        Looper.loop();
    }
}.start();

CalledFromWrongThreadExceptionをスローする必要があります。また、アクティビティでハンドラーを使用しようとしているため、このスレッドをLooper用に準備する必要はないようです。

于 2012-12-11T22:53:03.093 に答える