<强> 1。无效和postInvalidate的关系强>
postInvalidate是通过处理程序切换回到主线程,然后在调用无效的,源码:
公共空间postInvalidate () { postInvalidateDelayed (0); } 公共空间postInvalidateDelayed(长delayMilliseconds) {//我们尝试> 公开课MainActivity延伸活动{ 私人TextView tvText; @Override 公共空间>//ActivityThread中 最后的空白handleResumeActivity(内部令牌, 布尔clearHide、布尔isForward布尔reallyResume int seq,字符串原因){ ActivityClientRecord r=mActivities.get(令牌); … 如果(r !=null) { 最终活动=r.activity; 如果(r。窗口==零,,一个!mFinished,,willBeVisible) { r。窗口=r.activity.getWindow (); 视图装饰=r.window.getDecorView (); decor.setVisibility (View.INVISIBLE); ViewManager wm=a.getWindowManager (); WindowManager。LayoutParams l=r.window.getAttributes (); … 如果(a.mVisibleFromClient) { 如果(! a.mWindowAdded) { 一个。mWindowAdded=true;//关键代码 wm。addView(装饰,l); 其他}{ a.onWindowAttributesChanged (l); } } … }//WindowManagerGlobal中 公共空间addView(查看视图,ViewGroup。LayoutParams参数, 显示器显示、窗口parentWindow) { … ViewRootImpl根; 视图panelParentView=零; 同步(mLock) { …//在这里创建ViewRootImpl 根=new ViewRootImpl (view.getContext(),显示); view.setLayoutParams(按钮); … } }//在ViewRootImpl中有这么段代码,所有更新UI都会走到这里 空白checkThread () { 如果(mThread !=Thread.currentThread ()) {//mThread就是主线程 把新的CalledFromWrongThreadException ( “只有原始线程创建了一个视图层次能触摸其观点。”); } } >之前所以子线程只要在ViewRootImpl创建之前更新UI就没问题!
<强> 3。无效的源码分析强>
先看一张图:
无效的流程
于是自己尝试走走源码:
//视图中 公共空间invalidate () { 无效(真正的); } 公共空白无效(布尔invalidateCache) { invalidateInternal (0, 0, mRight——mLeft mBottom——mTop,支持invalidateCache, true); } 空白invalidateInternal (r t l int, int, int, int b,布尔invalidateCache 布尔fullInvalidate) { 如果(mGhostView !=null) { mGhostView.invalidate(真正的); 返回; } 如果(skipInvalidate ()) { 返回; } 如果(mPrivateFlags,(PFLAG_DRAWN | PFLAG_HAS_BOUNDS))==(PFLAG_DRAWN | PFLAG_HAS_BOUNDS) | | (invalidateCache,,(mPrivateFlags和;PFLAG_DRAWING_CACHE_VALID)==PFLAG_DRAWING_CACHE_VALID) | | (mPrivateFlags,PFLAG_INVALIDATED) !=PFLAG_INVALIDATED | | (fullInvalidate,,isOpaque () !=mLastIsOpaque)) { 如果(fullInvalidate) { mLastIsOpaque=isOpaque (); mPrivateFlags,=~ PFLAG_DRAWN; } mPrivateFlags |=PFLAG_DIRTY; 如果(invalidateCache) { mPrivateFlags |=PFLAG_INVALIDATED; mPrivateFlags,=~ PFLAG_DRAWING_CACHE_VALID; }//传播损失矩形父视图。 最后AttachInfo ai=mAttachInfo; 最后ViewParent p=mParent; 如果(p !=零,,人工智能!=零,,l & lt;r,,t & lt;b) { 最后矩形伤害=ai.mTmpInvalRect; 损害。组(r l、t、b);//调用父类的invalidateChild方法 p。invalidateChild(伤害); }//破坏整个投影接收机,如果必要的。 如果(mBackground !=零,,mBackground.isProjected ()) { 最后视图接收机=getProjectionReceiver (); 如果(接收机!=null) { receiver.damageInParent (); } } } } >之前看到视图的最无效后是调用了p。invalidateChild(伤害);p是ViewParent的对象,具体实现是ViewGroup
//ViewGroup中 @Override 公众最终无效invalidateChild(查看孩子,最终矩形脏){ 最后AttachInfo AttachInfo=mAttachInfo; … ViewParent父母=; {做 视图视图=零; …//关键代码 父母=父母。invalidateChildInParent(位置、脏); … }(父!=null); } @Override 最后公共ViewParent invalidateChildInParent (int[]的位置,最终矩形脏){ 如果(mPrivateFlags,(PFLAG_DRAWN | PFLAG_DRAWING_CACHE_VALID) !=0) {//画或者DRAWING_CACHE_VALID 如果(mGroupFlags,(FLAG_OPTIMIZE_INVALIDATE | FLAG_ANIMATION_DONE)) !=FLAG_OPTIMIZE_INVALIDATE) { 脏了。抵消(位置[CHILD_LEFT_INDEX]——mScrollX 位置[CHILD_TOP_INDEX] - mScrollY); 如果(mGroupFlags,FLAG_CLIP_CHILDREN)==0) { 脏了。联盟(0,0,mRight——mLeft mBottom——mTop)支持; } 最终int=mLeft; 最后一个int顶级=mTop;支持 如果(mGroupFlags,FLAG_CLIP_CHILDREN)==FLAG_CLIP_CHILDREN) { 如果(! dirty.intersect (0, 0, mRight -左,mBottom -前)){ dirty.setEmpty (); } } 位置(CHILD_LEFT_INDEX)=左; 位置(CHILD_TOP_INDEX)=最高; 其他}{ 如果(mGroupFlags,FLAG_CLIP_CHILDREN)==FLAG_CLIP_CHILDREN) { 脏了。集(0,0,mRight——mLeft mBottom——mTop)支持; 其他}{//如果脏矩形扩展这个容器的范围之外 脏了。联盟(0,0,mRight——mLeft mBottom——mTop)支持; } 位置(CHILD_LEFT_INDEX)=mLeft; 位置[CHILD_TOP_INDEX]=mTop;支持 mPrivateFlags,=~ PFLAG_DRAWN; } mPrivateFlags,=~ PFLAG_DRAWING_CACHE_VALID; 如果(mLayerType !=LAYER_TYPE_NONE) { mPrivateFlags |=PFLAG_INVALIDATED; } 返回mParent; } 返回null; }浅谈Android无效分析