Java 为什么布局根通过观察者?
几个小时以来,我一直在使用我的新安卓应用程序,但却遇到了一个非常奇怪的例外。 这意味着例外是明确的,但我不理解它背后的内容 我有一个名为MainActivity的活动,如下所示: 公共类MainActivity扩展了活动实现{Java 为什么布局根通过观察者?,java,android,Java,Android,几个小时以来,我一直在使用我的新安卓应用程序,但却遇到了一个非常奇怪的例外。 这意味着例外是明确的,但我不理解它背后的内容 我有一个名为MainActivity的活动,如下所示: 公共类MainActivity扩展了活动实现{ private gameState st = new gameState(); private gameEngine bc; public RelativeLayout gameLayout; @Override protected void onCreate(B
private gameState st = new gameState();
private gameEngine bc;
public RelativeLayout gameLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
st.addObserver(this);
gameLayout = (RelativeLayout) findViewById(R.id.gLayout);
startGame();
}
@Override
public void update(Observable observable, Object data) {
int gameState = ((gameState) observable).getState();
if(gameState == 1){
continueGame();
}
if(gameState == 2){
killGame();
}
}
private void killGame(){
if(!bc.BarThread.isInterrupted()){
bc.BarThread.interrupt();
}
gameLayout.removeAllViewsInLayout();
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT
);
TextView tv = new TextView(this);
gameLayout.addView(tv, params);
tv.setText("Game Over");
}
}
我的简单游戏状态类:
public class gameState extends Observable{
private int state = 0;
public gameState() {
}
public void setState(int var){
synchronized(this){
state = var;
}
setChanged();
notifyObservers();
}
public synchronized int getState(){
return state;
}
}
我的游戏引擎被实例化为bc,太长了,无法在这里发布,但我可以尝试用简单的语言解释内容
游戏引擎具有一些游戏元素,如按钮、进度条和线程,这些元素不断填充进度条。
如果用户成功,gameEngine会将gameState设置为1,MainActivity会执行类似killGame方法的操作,这非常有效
如果用户速度太慢且进度条已满,则BarThread会将游戏状态设置为2。
然后MainActivity执行killGame和抛出
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
但是我不明白为什么线程会通过观察者产生影响?我猜BarThread调用setStateint var,对吗?如果这是真的,那么在不是主线程的线程上调用该方法。这意味着setState调用的所有内容(例如NotifyObservators)都不会在主线程上调用。我猜NotifyObservators最终会调用MainActivity.updateObservable observable对象数据,这会调用killGame,这会更改视图层次结构,即添加文本视图。这意味着您的视图层次结构是从非主线程的线程修改而来的
您可能需要在MainActivity中创建一个处理程序。然后在killGame中,调用Handler.postRunnable。大概是这样的:
private Handler handler;
@Override
public void onCreate(Bundle savedInstanceState) {
handler = new Handler();
}
private void killGame() {
if(!bc.BarThread.isInterrupted()){
bc.BarThread.interrupt();
}
handler.post(new Runnable() {
@Override
public void run() {
gameLayout.removeAllViewsInLayout();
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT
);
TextView tv = new TextView(MainActivity.this);
gameLayout.addView(tv, params);
tv.setText("Game Over");
}
});
}
您的答案看起来很好,但是如何设置TextView的上下文,因为“this”现在是可运行的,而不是MainActivity?您应该能够使用MainActivity.this。另一个选项是在handler.post调用外部创建TextView。您需要将其设置为final,然后您应该能够在handler.post中简单地调用最后两行addView和setText