Activity的显示

214 阅读2分钟

ActivityWindowPhoneWindowDecorView之间的关系是什么

Activity是什么? activity是Android中的四大组件之一,其负责数据模型和页面模型的交互以表达业务逻辑显示能力等 那么Window又是什么呢? Window是一个抽象类,一个Activity维护了一个Window,而window只有一个唯一的子类实现-->PhoneWindow 所以一个Activity中维护了一个PhoneWindow实例 PhoneWindow是什么,怎么创建的 ActivityThread中handleLaunchActivity-->performLaunchActivity-->创建Activity,创建Application(makeApplication),Context,接着对activity进行了attach-->里面创建了mWindow = PhoneWindow()--≥mInstrumentation#callActivityCreate()

Activity执行oncreate()-->setContentView(resId)后执行了mWindow.setContentView()

这里的mWindoW就是mPhoneWindow,mPhoneWindow里面有一个成员变量mDecorView,mPhoneWindow的作用是分装了DecorView对子view的再次包装,解耦UI的逻辑操作,创建mDecorView和mContentParent的生成 DecorView mDecorView会通过feature_no_title等配置不同的子容器 generateLayout()-->解析resId的xml把view通过addview添加到decorview上 最终会通过mInflate.inflate(resid,mContentParent)添加到mContentParent上 这个时候oncreate就执行完了

Activity怎么显示的

当执行到handleResumeActivity时,activity的onResume被调用,接着会通过r.activity.getDecorView()获取decorView对象,通过WindowManager.addview把decorView添加进去-->最终会通过WindowManagerGlobal.addView()

WindowManagerGlobal.addView接着创建了ViewRootImpl()-->setView()

ViewRoot是什么

ViewRoot是一个抽象类,它的实现类是ViewRootImpl,负责连接WMS和DecorView的交互通讯,实际上是双向绑定事件,而这个事件是binder驱动的,服务端通过IWindow向decorview派发事件,完成View的绘制都是在ViewRootImpl里

setView里执行了resquestLayout()-->scheduleTraversals()--> mChoreographer.postCallback(Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);

final class TraversalRunnable implements Runnable {
    @Override
    public void run() {
        doTraversal();
    }
}
void doTraversal() {
    if (mTraversalScheduled) {
        mTraversalScheduled = false;
        mHandler.getLooper().getQueue().removeSyncBarrier(mTraversalBarrier);

        if (mProfile) {
            Debug.startMethodTracing("ViewAncestor");
        }

        performTraversals();

        if (mProfile) {
            Debug.stopMethodTracing();
            mProfile = false;
        }
    }
}
private void performTraversals() {
    .......
    .......
    relayout   addtoDiaplay()
    .......
     int childWidthMeasureSpec = getRootMeasureSpec(mWidth, lp.width);
     int childHeightMeasureSpec = getRootMeasureSpec(mHeight, lp.height);      
     ......
     // Ask host how big it wants to be
     //Measure
     performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
     ......
     //layout
     performLayout(lp, mWidth, mHeight);
    ......
     //Draw
     performDraw();
}

relayout里有mWindowSession.addtoDiaplay(mWindow) Session负责WMS的通讯,里面有一个suface,维护suface层级,View的宽度等

//从根节点向下遍历View树,完成所有ViewGroup和View的测量工作,计算出所有ViewGroup和View显示出来需要的高度和宽度;
private void performMeasure(int childWidthMeasureSpec, int childHeightMeasureSpec) {
    if (mView == null) {
        return;
    }
    Trace.traceBegin(Trace.TRACE_TAG_VIEW, "measure");
    try {
        mView.measure(childWidthMeasureSpec, childHeightMeasureSpec);
    } finally {
        Trace.traceEnd(Trace.TRACE_TAG_VIEW);
    }
}
//从根节点向下遍历View树,完成所有ViewGroup和View的布局计算工作,根据测量出来的宽高及自身属性,计算出所有ViewGroup和View显示在屏幕上的区域;
private void performLayout(WindowManager.LayoutParams lp, int desiredWindowWidth,
            int desiredWindowHeight) {
    ......
    try {
        host.layout(0, 0, host.getMeasuredWidth(), host.getMeasuredHeight());
        ......
    }
    ......
}
//从根节点向下遍历View树,完成所有ViewGroup和View的绘制工作,根据布局过程计算出的显示区域,将所有View的当前需显示的内容画到屏幕上
private void performDraw() {
    ......
    try {
        draw(fullRedrawNeeded);
    } finally {
        mIsDrawing = false;
        Trace.traceEnd(Trace.TRACE_TAG_VIEW);
    }
    .......
    .......
    .......
}