Android UI更新只能在主线程工作是个美丽的谎言?
来源:互联网 发布:php清空文件内容 编辑:程序博客网 时间:2024/05/01 06:40
最近看到某博客出现了一个关于非主线程更新view的一个案例,这个有兴趣的朋友可以搜索一下,这里借鉴使用一下demo
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textView= (TextView) findViewById(R.id.tv); new Thread(new Runnable() { @Override public void run() { textView.setText("子线程设置"); } }).start(); }
运行这个代码,竟然神奇的没有出现报错!
然而,当你替换代码
new Thread(new Runnable() { @Override public void run() { try{ Thread.sleep(100); }catch (Exception e){ e.printStackTrace(); } textView.setText("子线程设置"); } }).start();
出现如下错误:
FATAL EXCEPTION: Thread-1055 Process: com.tianyuan.viewthread, PID: 7532 android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6495) at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:904) at android.view.View.requestLayout(View.java:17534) at android.view.View.requestLayout(View.java:17534) at android.view.View.requestLayout(View.java:17534) at android.view.View.requestLayout(View.java:17534) at android.view.View.requestLayout(View.java:17534) at android.view.View.requestLayout(View.java:17534) at android.view.View.requestLayout(View.java:17534) at android.widget.TextView.checkForRelayout(TextView.java:6952) at android.widget.TextView.setText(TextView.java:4080) at android.widget.TextView.setText(TextView.java:3938) at android.widget.TextView.setText(TextView.java:3913) at com.tianyuan.viewthread.MainActivity$1.run(MainActivity.java:25)
为什么前后会出现如此的区别呢?那么我们根据报错日志看看,报错位置是在android.view.ViewRootImpl 中间有个check Thread方法,代码如下
我们仔细查看viewrootimpl方法后发现,这个方法会在一些重要位置检查Thread,viewrootimpl对于view tree进行perfrom traversals ,view tree的初始化是从viewrootimpl执行perform traversals开始的,这个过程遍历view tree节点。
通过debug,我们可以看到view在执行一些操作大体步骤为:
view.invalidate
view.invalidateinternal
Viewgroup.invalidatechild
viewgroup.invalidateChildINparent
viewrootimpl.invalidateChildinparent
viewrootimpl.checkThread
当activity初始化时,viewroot没有完整的viewtree,view的mAttachinfo还未初始化完成。我们看到很多方法是这么的
if (mAttachInfo == null) { return; }
/** * A set of information given to a view when it is attached to its parent * window. */ final static class AttachInfo { interface Callbacks { void playSoundEffect(int effectId); boolean performHapticFeedback(int effectId, boolean always); }
由此我们知道了,android更新UI之所以不能再主线程更新,是因为view这个类中viewrootimpl对于更新关键的操作进行了线程判断而导致的,在某些初始化未完成的时候,也是可以执行的,不过是特例而已。
- Android UI更新只能在主线程工作是个美丽的谎言?
- Android 更新UI 只能在主线程?
- “只能在UI主线程更新View”这件小事,android ui
- Android显示系统之View与SurfaceView更新屏幕的区别.对于View.则是在UI主线程中更新画面.SurfaceView更新屏幕,是在非UI线程(主线程)中实现SurfaceHolde
- 在主线程更新UI
- 【Android开发经验】来来来,同学,咱们讨论一下“只能在UI主线程更新View”这件小事
- 【Android开发经验】来来来,同学,咱们讨论一下“只能在UI主线程更新View”这件小事
- 【Android开发经验】来来来,同学,咱们讨论一下“只能在UI主线程更新View”这件小事
- 在Android中,非主线程不能更新UI
- Android 在子线程中更新主线程UI
- Android中在主线程与在子线程中更新UI的探索
- Android禁止在非Activity主线程中更新UI的解决办法
- 在分线程更新主线程的Ui界面方法
- Android UI主线程和工作线程的总结
- 【Android】几种子线程更新UI主线程的方法
- Android AsyncTask使用心得及错误处理-只能在主线程改变UI组件
- Android的UI主线程是ActivityThread吗?
- Android之UI主线程更新问题
- Android 提醒微技巧
- Cordova学习笔记一:plugin.xml文件之platform的讲解
- 抽象类和接口
- hdu 2024C语言合法标识符
- Fizz Buzz
- Android UI更新只能在主线程工作是个美丽的谎言?
- C++模拟双向链表的基本操作
- UVA 10491 Cows and Cars(全概率)
- auxiliary variable(辅助变量)的引入
- Delphi编程常用快捷键大全
- struts2实现文件上传进度条(前端JS+Java)(收藏)
- JavaScript中的this题2
- 图像去黑暗-————去雾算法延伸
- Linux用户和用户组操作----指令操作