1

私はAndroid用のopenglゲームに取り組んでいます。ユーザーがゲームを失うとメインメニューに戻る必要がありますが、この呼び出しはOpenGl ESスレッドからUIスレッドに行われるため、いくつかの問題があります。私はこの投稿を見つけ、queueEvent()を使用してレンダラーと別のクラスの間で変数を渡し、次のコードでHandlerクラスを追加しようとしました。

public class GameActivity extends Activity {

    private GLSurfaceView gameView;
    private int menuViewID;

    private Handler gameOverHandler;

    public GameActivity () {
        super();
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        gameOverHandler = new Handler() {

            public void handleMessage (Message msg){
                handleGameOver();
            }
        };
        gameView = new GameView(this, gameOverHandler);
        menuViewID = R.layout.main;

        setContentView(menuViewID);
    }

    /** Called when the user selects the Send button */
    public void startGame(View view) {
        setContentView(gameView);
        gameView.setVisibility(View.VISIBLE);
    }

    private void handleGameOver() {
        /**
         * TODO: switch back to main menu
         */

//      setContentView(menuViewID);         // after this gameView freezes
//      gameView.setVisibility(View.GONE);  // after this application throw an error: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.


    }
}

その後、OpenGLESコードで

gameOverHandler.dispatchMessage(Message.obtain(gameOverHandler));

しかし、まだフリーズまたはランタイム例外が発生しています(上記のコードのコメント行を参照してください)。私がここで見逃していること、または間違っていることは何ですか?

ちなみに、XMLで定義されたViewインスタンスの参照を取得する方法(menuViewID上記のコードを参照)、またはfindViewByIdメソッドが返す理由はNULL何ですか?

4

2 に答える 2

2

dispatchMessage(msg)このメソッドは使用しません。これは、ハンドラーを直接呼び出すのと明らかに同じです。(ドキュメントは貧弱です。システムでの使用を目的としているようです)。

ここで同様の質問を参照してください:

Handler.dispatchMessage(msg)とHandler.sendMessage(msg)の違い

代わりに、これを使用できます。

gameOverHandler.obtainMessage(MY_MSG_INT_ID).sendToTarget();
于 2012-09-10T22:07:41.627 に答える
0

UIスレッドで処理する必要がありますか?このコードを使用して、ゲームクラスから問題なく処理できます。

    Intent myIntent = new Intent(myContext, EndGameActivity.class);
    ((Activity)getContext()).startActivityForResult(myIntent, 0);

UIスレッドアクティビティからアクティビティにコンテキストをキャストし、そこから結果を得るために新しいアクティビティを開始します。結果を送り返し、UIスレッドでのアクティビティで、次のように結果をキャッチします。

    @Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) { 

    super.onActivityResult(requestCode, resultCode, data); 
    if (resultCode == 1) { 
       this.finish(); 
    }

} 
于 2012-09-10T22:00:51.940 に答える