背景:大家都知道子线程不能更新UI,正常情况下,操作UI都会切到主线程处理,否则就会抛出异常,如果对异常做catch处理,会发生什么???
问题案例:catch住异常后,addview,但是发现view宽高为0(并没有measure)
源码分析:
1.
子view调用requestlayout,会沿着view树,递归调用父view的requestlayout,并且将mPrivateFlags变量添加PFLAG_FORCE_LAYOUT标记,最终递归调用到android.view.ViewRootImpl的requestLayout方法
如果此时线程是子线程,checkThread抛出异常并且catch后,mLayoutRequested没有设置成true,会导致下一次Vsync信号到来时,不会触发measure和layout,layout不执行,导致view树上view的mPrivateFlags没有清除PFLAG_FORCE_LAYOUT,此时,View树上的View状态是异常的;
2.
此时,页面中addview,由于父view的mPrivateFlags状态异常,不会向上递归调用requestlayout
Vsync信号到来时,由于mLayoutRequested状态错误,view树没有执行测量和布局,导致新添加的view宽高一直为0
结论
更新UI一定要切换到主线程,不能简单的catch处理,否则会造成更严重的影响