问题笔记-子线程操作UI,catch异常带来的影响

194 阅读1分钟

背景:大家都知道子线程不能更新UI,正常情况下,操作UI都会切到主线程处理,否则就会抛出异常,如果对异常做catch处理,会发生什么???

问题案例:catch住异常后,addview,但是发现view宽高为0(并没有measure)

源码分析:

image.png

1.

子view调用requestlayout,会沿着view树,递归调用父view的requestlayout,并且将mPrivateFlags变量添加PFLAG_FORCE_LAYOUT标记,最终递归调用到android.view.ViewRootImpl的requestLayout方法

image.png

如果此时线程是子线程,checkThread抛出异常并且catch后,mLayoutRequested没有设置成true,会导致下一次Vsync信号到来时,不会触发measure和layout,layout不执行,导致view树上view的mPrivateFlags没有清除PFLAG_FORCE_LAYOUT,此时,View树上的View状态是异常的;

2.

此时,页面中addview,由于父view的mPrivateFlags状态异常,不会向上递归调用requestlayout

image.png

Vsync信号到来时,由于mLayoutRequested状态错误,view树没有执行测量和布局,导致新添加的view宽高一直为0

结论

更新UI一定要切换到主线程,不能简单的catch处理,否则会造成更严重的影响