Activity的显示

Activity的显示

Android小彩虹2021-07-11 14:59:22170A+A-

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);
    }
    .......
    .......
    .......
}

点击这里复制本文地址 以上内容由权冠洲的博客整理呈现,请务必在转载分享时注明本文地址!如对内容有疑问,请联系我们,谢谢!

支持Ctrl+Enter提交

联系我们| 本站介绍| 留言建议 | 交换友链 | 域名展示
本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除

权冠洲的博客 © All Rights Reserved.  Copyright quanguanzhou.top All Rights Reserved
苏公网安备 32030302000848号   苏ICP备20033101号-1

联系我们