Android View相关总结

  1. viewrootimpl,windowmanager等的关系。


    image
  2. view绘制流程


    image
  3. 子线程为什么不能更新ui?

ViewRootImpl.java
@Override
public void requestLayout() {
   if (!mHandlingLayoutInLayoutRequest) {
       checkThread();
       mLayoutRequested = true;
       scheduleTraversals();
   }
}
   
void checkThread() {
       if (mThread != Thread.currentThread()) {
           throw new CalledFromWrongThreadException(
                   "Only the original thread that created a view hierarchy can touch its views.");
       }
   }

//在主线程触发,ActiviyThread.handleResumeActivity()-->wm.addView(decor, l);
public ViewRootImpl(Context context, Display display) {
   mThread = Thread.currentThread();
}

  1. 什么时候获取宽高?为什么?

//1. ViewTreeObserver.dispatchOnGlobalLayout

ViewRootImpl.java
private void performTraversals() {
   //host代表view DecorView
   host.dispatchAttachedToWindow(mAttachInfo, 0);
   //触发dispatchOnWindowAttachedChange回掉
   mAttachInfo.mTreeObserver.dispatchOnWindowAttachedChange(true);
   //host代表view DecorView
    host.dispatchWindowVisibilityChanged(viewVisibility);
   //测量确定window大小
   measureHierarchy()
   //调整window大小
   relayoutWindow()
   //测量
   performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
   //摆放
   performLayout(lp, mWidth, mHeight);
   //触发回掉
   mAttachInfo.mTreeObserver.dispatchOnGlobalLayout();
   //绘制
   performDraw();
}


//2. post
View.java
public boolean post(Runnable action) {
  
   final AttachInfo attachInfo = mAttachInfo;
    //attachInfo 在ViewRootImpl.performTraversals()里面 dispatchAttachedToWindow的时候设置
   if (attachInfo != null) {
       return attachInfo.mHandler.post(action);
   }

   // Postpone the runnable until we know on which thread it needs to run.
   // Assume that the runnable will be successfully placed after attach.
   getRunQueue().post(action);
   return true;
}

void dispatchAttachedToWindow(AttachInfo info, int visibility) {
    mAttachInfo = info;
    // Transfer all pending runnables.
   if (mRunQueue != null) {
       //加入到ViewRootImpl的handler 
       //final ViewRootHandler mHandler = new ViewRootHandler();
       //正常这个handle是主线程的handler,所以在执行performTraversals之后将会执行这个,不如第一种方式的时机更快
       mRunQueue.executeActions(info.mHandler);
       mRunQueue = null;
   }
}


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。