Activity启动流程与View绘制流程详解

文字描述如下

1 launcher 通过ServiceManager找到AMS(AMS所在进程为SystemServer)通知AMS启动对应Activity

2 AMS收到通知,通知launcher onPause,完毕后AMS准备启动Activity

3 Activity查看对应activity所在进程是否存在,不存在则通知zygote fork 进程

4 完毕后利用反射启动ActivityThread,ActivityThread启动后会将appThead attch到AMS

5 AMS然后会将appThread与先前fork的进程绑定,然后调用AppThread的bindApplication

6 AppThread会利用Hanlder发送bindApplicatoin消息

7 然后调用handleBindApplication,makeApplication 再次利用反射,创建Applicatoin类

8 至此Application启动完成

9 然后AMS会继承调用AppThread通知ActivityThread启动Activity

10 Activity收到通知,HanldeLanunActivity->performLaunchActivity->activity.attach()

11 然后会创建PhoneWindow,调用callActivityOnCreate ->setContentView->installDecorView

12 然后到HanldeResumeActivity->WindowManager.addView()->WindowManagerImpl.addView()->WindowManagerImpl.addView()

13 新建ViewRootImpl(view.getContext(), display),然后setView()->performTraversals

14 performTraversal会判断是否存在Surface,如果没有则进行relayoutWindow->此时会创建Surface用于绘制 -> 走至少一次的performMeasure(至多两次,第一次为子类希望的大小,如果不合理(父布局判断)则重新测量,父布局提供具体限制)->再次判断是否存在Surface,(此时存在)->进行onDraw()

private void performTraversals() {
        // 省略无关代码
        // Execute enqueued actions on every traversal in case a detached view enqueued an action
        getRunQueue().executeActions(mAttachInfo.mHandler);

          // 省略无关代码

            boolean hwInitialized = false;
            boolean contentInsetsChanged = false;
            boolean newSurface = false;
            /**
                hadSurface 第一次进入,mSurface.isValid 为false
                因为还没有创建Surface
                再次进入已经有Surface了,所以重新为true
            **/
            boolean hadSurface = mSurface.isValid();

                       // 省略无关代码

                // 此时创建Surface,利用WindowSession代理对象,WindowManagerService通信,调用其relayoutWindow函数
                // 会创建SurfaceContronll然后获取Surface
                relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);

                // 省略无关代码

                if (!hadSurface) {//hadSurface在第一次进入时,为false.
                    if (mSurface.isValid()) {//此时Surface已经存在,因为走过了一遍relayoutWindow
                        // If we are creating a new surface, then we need to
                        // completely redraw it.  Also, when we get to the
                        // point of drawing it we will hold off and schedule
                        // a new traversal instead.  This is so we can tell the
                        // window manager about all of the windows being displayed
                        // before actually drawing them, so it can display then
                        // all at once.
                        newSurface = true;//标记新建Surface
                        }
                    }
                } 

       
                    // Ask host how big it wants to be
                    performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);

                    if (measureAgain) {
                        performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
                    }
 
        if (didLayout) {
            performLayout(lp, mWidth, mHeight);
        }

       // 省略无关代码

        boolean cancelDraw = mAttachInfo.mTreeObserver.dispatchOnPreDraw() || !isViewVisible;

        if (!cancelDraw && !newSurface) {//第一次进来,newSurface为ture,所以走else分支。
            performDraw();
        } else {
            if (isViewVisible) {
                // Try again
                scheduleTraversals();//重新Travesals
        }
    }

如图所示


启动流程详解

另外是此图给了我灵感,表示感谢

启动流程详解

你可能感兴趣的:(Activity启动流程与View绘制流程详解)