Android框架保证View更新必须在主线程的解读
16lz
2021-01-25
今天一位朋友问了我一个问题,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
更多相关文章
- Android(安卓)读取扫码枪的内容,可以读取条形码 ,二维码
- Android中的Parcelable序列化对象
- android中view事件传递
- android HorizontalScrollView实现滚动状态监听
- android 开发 View _1_ View的子类们 和 视图坐标系图
- android 左右滑动+索引图标实现方法与代码
- Android: Keyguard分析之一:开机流程篇
- Android发送邮件的方法实例详解
- Android(安卓)多个listview监听item的点击事件