浅谈Android无效分析

  

<强> 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。无效的源码分析

  

先看一张图:

  

浅谈Android无效分析

  

无效的流程

  

于是自己尝试走走源码:

     //视图中   公共空间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无效分析