只能在子线程操作UI?

2020-04-22  本文已影响0人  普通的程序员

参考这个
https://mp.weixin.qq.com/s/tg96p50alrqAtRih8a3AhA

总算是弄懂了view初始化一些细节问题。

先说结论:
当前线程只能更新该线程维护的View。

流水账:
1.关键点在 ViewRootImpl的checkThread方法;
这个方法是用 mThread == Thread.currentThread() 判断
这个mThread是什么就是关键了。

  1. ViewRootImpl的构造函数里对 mThread进行赋值,赋值不是 mainThread!!!
    而是 Thread.currentThread()!!!! 所以这就很玄妙!!!

  2. 用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的,也就是

image.png

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。

上一篇下一篇

猜你喜欢

热点阅读