Activity的setContentView看View的绘制流程

Activity 的setContentView看View的绘制流程

1.Activity.setContentView

    public void setContentView(@LayoutRes int layoutResID) {
        //获取window = PhoneWindow对象
        getWindow().setContentView(layoutResID);
        initWindowDecorActionBar();
    }

2.进入PhoneWindow.setContentView

    @Override
    public void setContentView(int layoutResID) {
        if (mContentParent == null) {
	        // 1.初始化DecorView对象,装在各种styleable属性
	        /**
	        //2.注入一个用于存子View的mContentRoot容器,再装入DecorView中,为什么这样做?
	        //我也不太明白,我猜是为了分离DecorView的部分业务吧
			View in = mLayoutInflater.inflate(layoutResource, null);
			        decor.addView(in, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
			        mContentRoot = (ViewGroup) in;
			*/
			详见2.1
            installDecor();
        ... 省略N行 ... 
        
        详见2.2
        mContentParent.requestApplyInsets();
        final Callback cb = getCallback();
        if (cb != null && !isDestroyed()) {
            cb.onContentChanged();
        }
    }

	2.1 mContentParent = installDecor();
		mContentParent.addView(view, params);
		//mContentRoot 被添加进decorView中,而DecorView是一个FrameLayout
		View in = mLayoutInflater.inflate(layoutResource, null);
		        decor.addView(in, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
		        mContentRoot = (ViewGroup) in;
	
	2.2 mContentParent.requestApplyInsets();
		//mContentParent是View,此时进入View的requestFitSystemWindows方法,View间接又调起了ViewRootImpl的

3.进入ViewRootImpl

    @Override
    public void requestFitSystemWindows() {
    //初始化时,记录当时的线程,到执行到这里的时候获取当前线程,比较是否是主线程
        checkThread();
        mApplyInsetsRequested = true;
        //准备View绘制流程工作
        scheduleTraversals();
    }
    3.1
        void scheduleTraversals() {
        if (!mTraversalScheduled) {
            mTraversalScheduled = true;
            mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();
            //mTraversalRunnable 是一个runnbale ,run方法执行了
            mChoreographer.postCallback(
                    Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
            if (!mUnbufferedInputDispatch) {
                scheduleConsumeBatchedInput();
            }
            notifyRendererOfFramePending();
            pokeDrawLockIfNeeded();
        }
    }
    3.2 TraversalRunnable
        final class TraversalRunnable implements Runnable {
        @Override
        public void run() {
	        //开始View绘制流程
            doTraversal();
        }
    }
	

4.开始 performTraversals ,里面有7百多行代码

private void performTraversals() {
	    //1.处理LayoutParams相关
	    //2.处理mAttachInfo相关和相关attachedWindow回调分发和回调
	    //3.布置宽高
		//4. performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
		//确认是否需要再次测量,如果在测量过程中,有子View强行不和measureSpec给的有冲突,那就调整再次测量。
		//5.performLayout(lp, desiredWindowWidth, desiredWindowHeight);
		//6.performDraw()
		//7.如果中途有View改变的visibility,则调用前面的scheduleTraversals();重新走流程。
	}

伟大的7百行代码,干了很多事情,真能干。从上面的代码可以找出我们View绘制流程中常见的三个方法 performMeasure,performLayout,performDraw ,这三个方法分别各自调用自己的分发过程。在这里就不分析了,网上一大把View的绘制流程。至此,一个Activity就这样降临到你眼前的眼帘,一边看源码一边敲的,做个粗略的笔记。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值