View绘制流程的源码所得

一些问题

子线程可以更新 UI 吗

答案是可以的,在特定的情况下可以

  1. 可以先在主线程中调用requestLayout() 方法,然后紧接着在子线程中更新UI (原理:不要在子线程触发 checkThread() 方法,而checkThread() 方法的调用时机是在requestLayout() 方法中,checkThread判断规则是判断调用线程是不是我所在的线程,不出意外的话,我所在的线程是主线程)
  2. 在子线程中创建ViewRootIml ,(原理:ViewRootIml 最初创建的是哪个线程,之后就可以(必须)一直在这个线程中更新UI,默认是主线程创建)因为他所在线程是子线程,直接运行会报错,因为子线程没有looper ,需要Looper.prepare(); 之后就可以在这个子线程当中一直更新UI了(再换一个子线程也不行,主线程更新UI也会报错) Looper.loop();
  3. view 的宽高为固定宽高也可以进行更新,因为在checkForRelayout() 方法中会宽高是否是matchParent或者固定值,如果是就不需要请求重新布局,或者高不是固定值,重绘后高度不会发生改变,直接重绘就行了(关闭硬件加速就不行了)绘制是不检查线程的
  4. 使用SurfaceView 可以在子线程中更新UI

子线程吐司

报错:不能在一个没有Looper.prepare()的线程中吐司,同样的道理
Looper.prepare()
Toast.show("aaa")
Looper.loop()

也可以进行吐司

View绘制完成的宽度在哪个时刻能一定拿到?Activity的onStart?onResume?view.post { } ?

都不是,最好的是viewTree.observ

Window是个抽象类,他的实现类有哪些?

Window 只有一个实现类:PhoneWindow

布局通过setContentView传给Activity,他们是怎么结合到一起的?

Activity 调用Window 的setContentView ,PhoneWindow 会关联DecorView ,DecorView 会匹配系统内置布局文件,默认的是ActionBar+FramLayout 那个布局,FramLayout 的id 是content ,然后将我们传入的布局文件add进FramLayout

Activity在使用的过程中,从来没有new的操作,他是怎么来的?

ActivityThread创建,Activity的生命周期的调用,也是他在不同时机进行的,比如 handleLancherActivity会创建当前Activity,调用Activity的attach、onCreat

总结

子线程不是不能更新UI,而是谷歌工程师不让我们在子线程更新UI,是一种代码级别的约定,因为如果任意线程都能更新UI,那么系统工程师就需要做线程安全,每次更新UI都得执行加锁、解锁操作,浪费性能,还得考虑各种意外情况

出于成本考虑,强制让开发者在主线程更新UI,能解决掉非常大的性能问题和巨量的工作,所以说不允许在子线程更新UI

相关推荐
警醒与鞭策4 小时前
Codex桌面版与Claude桌面版使用设置
android·unity·ai·性能优化
传奇开心果7 小时前
【Compose Multiplatform跨端声明式UI实用技术】第19课:多平台部署与发布
android·kotlin
红尘伴蝶舞7 小时前
加密拦截器让抓包失效,我只能从 4KB 的 logcat 碎片里拼回 JSON
android·kotlin·ai编程
booboosui7 小时前
219 个还是 0 个:读不到微信界面时,我只加不删
android
Android打工仔7 小时前
Compose 中何时该用 padding,何时该用 offset
android·android jetpack
二流小码农7 小时前
HarmonyOS开发助手,0代码让元服务从开发到上架
android·ios·harmonyos
limit00757 小时前
三维 WebGIS 工具选型:加载、样式、分析、交付,一套界面能做完什么
android·前端·web3·安卓·webgl
骑着蜗牛撵大象3279 小时前
让 Codex 值夜班:把告警排查与巡检接成可回滚的自动化链路
android·java·运维·ai·自动化·codex·智能体
2401_885885049 小时前
芬兰语音通知接口怎样对接?语音提醒接入流程
android·前端·python·php·语音识别
程序猿老A9 小时前
轻量应用服务器怎么用phpcms搭建网站?
android