我正在使用Open GL开发一款带图形的简单游戏。我想要它,以便当某个事件发生时,玩家得到一个点,这会更新覆盖游戏活动的GLSurfaceView的文本视图。
提前致谢!
以下是我的代码的相关部分:
活动:
public class playActivity extends Activity {
private GLSurfaceView myGLView;
private Handler mGameHandler;
private TextView mScoreView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mScoreView = new TextView(this);
mScoreView.setTextColor(0xFF00FF00); // Green
string myZeroString = "0";
mScoreView.setText(myZeroString); //Starting score will always be 0
mGameHandler = new Handler(){
public void handleMessage(Message msg){
if (msg.what == MyGLRenderer.GAME_SCORE_FLAG) {
int score = msg.arg1;
mScoreView.setText(Integer.toString(score));
}
}
};
myGLView = new MyGLSurfaceView(this);
setContentView(myGLView);
addContentView(mScoreView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
}
private void updateScoreBoard(int score){
mScoreView.setText(Integer.toString(score));
}
class MyGLSurfaceView extends GLSurfaceView{
private final MyGLRenderer myRenderer;
public MyGLSurfaceView(Context context){
super(context);
// Create an OpenGL ES 2.0 context
setEGLContextClientVersion(2);
myRenderer = new MyGLRenderer(context);
myRenderer.initiateHandler(mGameHandler);
// Set the Renderer for drawing on the GLSurfaceView
setRenderer(myRenderer);
setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
}
}
}
GlSurfaceView.Renderer:
public class MyGLRenderer implements GLSurfaceView.Renderer{
public static final int GAME_SCORE_FLAG = 1;
private Handler mGameHandler = null;
private int mScore = 0;
public void initiateHandler(Handler handler){
mGameHandler = handler;
}
...
@Override
public void onDrawFrame(GL10 unused){
if (scoreCondition){
mScore += 1;
if (mGameHandler != null) {
int flag = MyGLRenderer.GAME_SCORE_FLAG;
mGameHandler.dispatchMessage(Message.obtain(mGameHandler, flag, 2));
}
}
}
}
当我运行它时,它给了我错误: " android.view.ViewRootImpl $ CalledFromWrongThreadException:只有创建视图层次结构的原始线程才能触及其视图。"
但是,在顶部的代码块中,当我替换
时int score = msg.arg1;
mScoreView.setText(Integer.toString(score));
与
final int score = 3;
runOnUiThread(new Runnable() {
@Override
public void run() {
mScoreView.setText(Integer.toString(score));
}
});
我不再收到错误而且有效。我认为在第一个构造中,当我调用setText时,它必须在UI线程上执行,但Android Studio的思维方式不同。任何人都可以向我解释这个吗?谢谢!
答案 0 :(得分:1)
变化:
mGameHandler.dispatchMessage(Message.obtain(mGameHandler, flag, 2));
为:
mGameHandler.sendMessage(Message.obtain(mGameHandler, flag, 2));
调用dispatchMessage()
将导致在当前线程(在您的情况下是GL线程)上传递消息。