从另一个线程更新UI
我知道从另一个线程更新UI是被禁止的,所以我试着看看我会从应用程序中得到什么结果。是的,更新UI组件时应用程序会崩溃,但有一种情况我不明白,应用程序运行良好。从另一个线程更新UI
1)
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
tv = (TextView)findViewById(R.id.textView1);
bt = (Button)findViewById(R.id.button1);
new Thread(){ //1
public void run() {
tv.setText("changed");
}}.start(); //1 }
}
2)
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
tv = (TextView)findViewById(R.id.textView1);
bt = (Button)findViewById(R.id.button1);
bt.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View arg0) {
new Thread(){ //1
public void run() {
tv.setText("changed");
}}.start(); //1 }
}
});
}
对不起,我以前我的问题的描述,我想大多数人误解,所以我改一下这个问题。上面有两种情况,他们应该给我崩溃的错误,因为都创建新的线程和更新UI组件,但实际上,只有第二种情况下崩溃,但fisrt方案不会崩溃。任何人都知道原因?
检查此异常
E/AndroidRuntime(7652): FATAL EXCEPTION: Thread-19449
E/AndroidRuntime(7652): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
E/AndroidRuntime(7652): at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:4357)
E/AndroidRuntime(7652): at android.view.ViewRootImpl.invalidateChild(ViewRootImpl.java:802)
E/AndroidRuntime(7652): at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:851)
E/AndroidRuntime(7652): at android.view.ViewGroup.invalidateChild(ViewGroup.java:4312)
E/AndroidRuntime(7652): at android.view.View.invalidate(View.java:8603)
E/AndroidRuntime(7652): at android.view.View.invalidate(View.java:8554)
UI线程检查仅在无效(渲染)的时间进行检查。
所以在创建时(onCreate),没有问题。
您可以在setText之前添加Thread.sleep(5000),并发生上述异常。
哦,男人,你摇滚!我想你找到了原因。你的答案最有意义。谢谢。 – 2012-04-24 03:40:19
哦,我没有足够的声望投票。你应该大拇指。 – 2012-04-24 03:44:02
哈哈,谢谢。接受我的答案或者如果你喜欢它,就投票。 – 2012-04-24 03:44:03
检查了这一点
private void startthread() {
anihandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
tv.setText("changed");
}
};
aniThread = new Thread() {
public void run() {
sleep(1000);
anihandler.sendMessage(anihandler
.obtainMessage());
}
};
aniThread.start();
}
我改变了这个问题,可能会更容易理解。 – 2012-04-24 03:41:51
runOnUiThread或在UI线程中创建处理程序(例如,将其作为字段或最终处理程序作为本地变量),然后使用handler.post。 Runnable将是这些函数的参数,里面的代码就是你想在UI线程中做什么 – 2012-04-24 02:00:09
嗨,谢谢你的回复。我还不是很清楚你的意思。该功能是否存在于adroid中,或者存在于J2SE中?通常我可以在J2SE中使用这种方式创建新线程,对吗? – 2012-04-24 02:38:28
我改变了这个问题,可能会更容易理解。 – 2012-04-24 03:37:05