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.


    }
}

然后在 OpenGL ES 代码中

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

但我仍然遇到冻结或运行时异常(请参阅上面代码中的注释行)。我在这里错过了什么或做错了什么?

顺便说一句,如何获取在 XML 中定义的 View 实例的引用(参见menuViewID上面的代码),或者该findViewById方法为什么返回NULL

4

2 回答 2

2

您不想使用该dispatchMessage(msg)方法。这显然与直接调用 Handler 相同。(文档很差。它似乎是供系统使用的)。

在这里查看类似的问题:

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 回答