android view初始化 开线程,Android框架保证View更新必须在主线程的解读

今天一位朋友问了我一个问题,android更新ui的时候,如果不在主线程更新ui,系统就会报出错误,应用崩溃

CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

基于此,简读了一下View ViewRootImpl 的源码。

总得来说android 在UI线程创建UI元素,并把线程的引用存储到UI控件中,。在更新UI之前检测下当前线程是否跟创建自己的线程是同一个线程。

每个View持有一个viewParent的引用。ViewParent 是一个接口,ViewGroup ViewRootImpl 都实现了这个接口。

protected ViewParent mParent;

public interface ViewParent{

...

public void invalidateChild(View child,Rect r);

public ViewParent invalidateChildInParent(int[]location,Rect r);

...

}

更新View invalidate的时候,会最终调用到ViewGroup的invalidateChild

最终调用ViewRootImpl的invalidateChidInParent方法

如果View在invalidate之前调用了requestLayout方法,那么这个之后,viewRootImpl的requestLayout,就会调用checkThread来检测,此方法就是检测创建自己的线程跟更新自己的线程是否是同一个线程。

如ImageView在setImageResource的时候,判断,如果新的resource 的width和height跟old都相同,就不会调用requestLayout,这个时候会在invalidate的时候进行检查。而在setScaleType的时候,只要跟原scaleType不一致,就会requestLayout,这个时候,在requestLayout的时候就会被检测到。

如TextView在setText的时候会调用checkForRelayout,方法会调用requestLayout

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值