public class MainActivity extends Activity { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TextView show = (TextView)findViewById(R.id.show);
new Thread()
{
@Override
public void run()
{
show.setText("子线程更新UI");
}
}.start();
}不是说在新建的线程中不能更新UI吗?为什么我在UI线程中新建了一个线程还能够更新成功?
有劳各位了!
解决方案 »
- android仿酷狗界面设计问题,求解答。。。
- Android 嵌入式
- 新手求指导,关于一个监听器实现多个监听
- android 源码下载 问题,求大神
- 哪个系统下使用用eclipse开发android好点?
- android中用jave转换amr到mp3,报没有权限,IO异常
- WCF service 如何通过TCP协议 与Android交互
- 如何将底层C++库包装成Java类供上层APP调用?(就像使用Android SDK一样)
- 安卓分享音乐文件后点击可自动播放的问题
- UltimateRecyclerView 如何监听拖拽已经结束
- 求指点。SQLite数据存储出错
- android的页面四个按钮实现跳转
例如从子线程对Textview.setText,
通过报错的log能看出, 抛出异常的位置是在android.view.ViewRoot.checkThread()(),从字面的意思看,这个方法就是用来检查修改view的Thread()是否主线程。
这个检查方法在view的requestLayout()里面被调用,但是requestLayout()有些情况下不会被调用:
if(mParent != null){
if (!mParent.isLayoutRequested()) {
mParent.requestLayout();
}
}
唯一的解释就是以上2个if中的一个不符合,导致后面的checkThread()()没被调用,子线程就成功地修改了界面UI。
这个可能是在activity 被创建的初期,layout或者其他动作初始化还没有完成,导致线程的检查没有发生,具体的问题就要去研究下才知道了。
你可以试一下, 你的第一种情况,在new Thread 修改textview之前让线程睡眠2秒,这时候再来修改UI就会抛出异常了。
new Thread()
{
@Override
public void run()
{
show.setText("子线程更新UI");
}
}.start();从实现上来讲子线程是可以更改布局界面的,只是在代码只做了限制,更新ui的时候会判断线程是不是主线程,如果不是就报异常,这是一种机制。
其实如果在模拟器上运行的时侯,即使将上面这段代码放入按钮的单击事件里,也会将 “子线程更新UI”显示出来,然后才报错的。