我正在开发Android的opengl游戏。当用户失去游戏时应返回主菜单,但此调用是从OpenGl ES线程到UI线程进行的,并且存在一些问题。我发现了这篇文章Pass variables between renderer and another class with 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
的原因?
答案 0 :(得分:2)
您不想使用dispatchMessage(msg)
方法。这显然与直接调用Handler相同。 (文档很差。似乎它是供系统使用的。)
在此处查看类似问题:
The difference between Handler.dispatchMessage(msg) and Handler.sendMessage(msg)
相反,你可以使用它:
gameOverHandler.obtainMessage(MY_MSG_INT_ID).sendToTarget();
答案 1 :(得分: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();
}
}