参考这个
https://mp.weixin.qq.com/s/tg96p50alrqAtRih8a3AhA
总算是弄懂了view初始化一些细节问题。
先说结论:
当前线程只能更新该线程维护的View。
流水账:
1.关键点在 ViewRootImpl的checkThread方法;
这个方法是用 mThread == Thread.currentThread() 判断
这个mThread是什么就是关键了。
-
ViewRootImpl的构造函数里对 mThread进行赋值,赋值不是 mainThread!!!
而是 Thread.currentThread()!!!! 所以这就很玄妙!!! -
用Dialog.show来举例!
Dialog.show()
会调用Dialog的构造函数
构造器内 Window = new PhoneWindow
WindowManager 是获取的系统服务Window_service
这个window进行了 setWindowManager
5.很玄妙
image.png
new了一个WindowManagerImpl
6.回到 Dialog的show方法
最终是把view添加到decor
image.png
7.这个mWindowManager就是第5的,也就是
8.WindowManagerImpl维护 一个mGlobal
它的add方法,完成了ViewRootImpl的初始化。
image.png
9.mGlobal是单例,没有问题,
只要调用方 这个Dialog 创建时(真正的是Window)是在哪个线程
它的ViewRootImpl创建的mThread是哪个线程。
假设说
Thread-4 创建了dialog,show
那么以后dialog里的ui操作,都应该是Thread-4来操作,不然会checkThread失败。
Activity的操作
Activity.attach()时,
image.png image.png
window创建,接下来的WindowManagerImpl创建。
因为Activity.attach是main线程,所以接下来就都是main线程了。
假如能开子线程 startActivity,接下来的操作应该就是用那个线程去维护界面更新了。
所以,不能单纯的说,不能在子线程更新UI。
比较准确的说,
当前线程只能更新该线程维护的View。
网友评论