应用冷启动流程分析 - AndroidU

一:背景

    应用启动速度是用户体验的核心指标之一,无论是Google还是手机厂商还是应用开发者,都在不断地优化启动时间,为了更快一点而努力。想优化应用启动流程,就必须要对应用启动流程有充分的认识与了解。下文将会基于AndroidU的源码,结合systrace,来剖析应用冷启动的全流程。

二:Input事件处理流程

2.1 Input事件处理机制

 用户的点击事件,属于Input事件,Input是Android系统常见的事件之一。Input事件的处理核心是InputReader和InputDispatcher,InputReader和InputDispatcher是运行在SystemServer进程中的两个线程,里面各有一个死循环,负责读取和分发Input事件。

    按键、屏等驱动会把接收到的input事件存放在/dev/input节点中,InputReader从EventHub中利用Linux的epoll机制监听读取驱动上报的input事件并分发给InputDispatcher,InputDispatcher中把事件放到InboundQueue队列中,然后寻找处理Input事件的目标窗口,并讲事件放入对应目标窗口OutboundQueue队列中,等待通过SocketPair双工信道发送到目标窗口中,发送完毕后会把事件移动到WaitQueue队列中等待事件处理完成并开始计时,如果下次分发事件时,上一次事件在5s内目标窗口没有处理完,就会触发ANR。大致流程如下:

2.1.1 InputReader从EventHub中把Input事件读取出来,执行mQueuedListener.notify发送Input事件。

2.1.2 InputDispatcher接收到notify回调后,更新mInboundQueue。在本身分发事件的循环中检测到mInboundQueue队列中有事件后,对事件进行分装,然后根据KeyEntry找到displayId,把事件传递到displayId对应的窗口。

2.1.3 窗口对应的app,遍历View数,处理Input事件。

这里有几个点需要注意下:

1. InboundQueue("iq")队列中存放着InputDispatcher从InputReader拿到的input事件

2. OutboundQueue("oq")队列中存放着即将要发送给各个窗口的input事件

3. WaitQueue("wq")队列中存放着已经分发给窗口app,但是app还没有处理成功的input事件

4. PendingInputEventQueue("aq")队列中存放着app需要处理的input事件

5. deliverInputEvent 标识着App UI线程被Input事件唤醒

2.2 Systrace中input处理流程

  2.2.1 InputReader读取事件

  2.2.2 InputDispatcher接收到InputReader读取到的事件,放入InboundQueue即"iq"队列中

  2.2.3 InputDispatcher查找目标窗口,把事件放到OutboundQueue即"oq"队列中

  2.2.4 InputDispatcher把事件分发给对应窗口(也就是Launcher),把事件放入WaitQueue即"wq"队列中,等待事件处理完成

  2.2.5 Launcher接收到Input事件后,先通过enqueueInputEvent函数把事件放入到PendingInputEventQueue即"aq"队列中,并在deliverInputEvent的流程中进行Input事件的分发和处理

  2.2.6 Launcher把事件先交给应用界面Window创建时的ViewRootImpl.setView流程中创建的多个不同类型的InputStage中依次进行处理,最后交给ViewPostImeInputStage中进行处理,会从View布局树的根节点DecorView开始遍历View树中的每个子View或者viewGroup进行事件的分发、拦截、处理的逻辑

  2.2.7 Input事件在View树中处理完成后会调用finishInputEvent结束应用对Input事件处理逻辑,这里会通过jni调用到native层InputConsumer的sendFinishedSignal函数通知InputDispatcher事件处理完成,把事件从"wq"队列中移除,避免报ANR

 2.2.8 Launcher在处理一系列的ACTION_DOWN,ACTION_MOVE一直到ACTION_UP的touch事件后,判断是点击事件,触发View的onClick函数,通过binder调用AMS的startActvity触发进程启动的流程

三:应用进程的创建和启动

  3.1 Pause前一个应用

    3.1.1 Launcher通过binder调用AMS的startActivity函数后,会执行到ActivityStarter.Request.execute函数,这里会开始记录launchingActivity的systrace tag,即perfetto中看到的Android App Startups开始的地方,即perfetto上看到的进程启动开始的地方

//frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
    static class Request {
        ...
        int execute() {
            ...
                //systrace中统计进程启动开始的地方
                launchingState = mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(
                        mRequest.intent, caller, callingUid);
            ...
                res = executeRequest(mRequest);
            ...
        }
    }

    3.1.2 AMS继续执行startActivity流程,在ActivityStarter.startActivityUnchecked函数中会记录startActivityInner的systrace tag,并调用startActivityInner函数,startActivityInner是真正启动Activity的地方

//frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
    private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, ActivityOptions options, Task inTask,
            TaskFragment inTaskFragment, @BalCode int balCode,
            NeededUriGrants intentGrants, int realCallingUid) {
        ...
        try {
            ...
            try {
                Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "startActivityInner");
                result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
                        startFlags, options, inTask, inTaskFragment, balCode,
                        intentGrants, realCallingUid);
            } finally {
                Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
                startedActivityRootTask = handleStartResult(r, options, result, newTransition,
                        remoteTransition);
            }
        } finally {
            mService.continueWindowLayout();
        }
        postStartActivityProcessing(r, result, startedActivityRootTask);

        return result;
    }

3.1.3 在TaskFragment.resumeTopActivity函数中会调用startPausing来暂定Launcher进程

//frameworks/base/services/core/java/com/android/server/wm/TaskFragment.java
    final boolean resumeTopActivity(ActivityRecord prev, ActivityOptions options,
            boolean deferPause) {
        ...
        boolean pausing = !deferPause && taskDisplayArea.pauseBackTasks(next);
        if (mResumedActivity != null) {
            //开始暂停上一个Activity
            pausing |= startPausing(mTaskSupervisor.mUserLeaving, false /* uiSleeping */,
                    next, "resumeTopActivity");
        }
        ...
        if (pausing) {
            if (next.attachedToProcess()) {//要启动的Activity所属进程已存在
                ...
            } else if (!next.isProcessRunning()) {//要启动的Activity所属进程不存在
                final boolean isTop = this == taskDisplayArea.getFocusedRootTask();
                //启动进程
                mAtmService.startProcessAsync(next, false /* knownToBeDead */, isTop,
                        isTop ? HostingRecord.HOSTING_TYPE_NEXT_TOP_ACTIVITY
                                : HostingRecord.HOSTING_TYPE_NEXT_ACTIVITY);
            }
            ...
            return true;
        }
        ...
        return true;
    }

3.1.4 startPausing函数最终对通过Activity.performPause函数调用到Launcher对应Activity的onPause函数,然后调用ActivityRecord.activityPaused函数来通知taskFragment,Activity的pause已经完成,重新执行TaskFragment.resumeTopActivity函数来继续进程启动流程。

    回头看4.1.3,这时候pausing变量变成了true,会判断将要启动的Activity所属进程存不存在,如果没有在运行,则会调用mAtmService.startProcessAsync函数进行进程启动工作

//frameworks/base/services/core/java/com/android/server/wm/TaskFragment.java
    boolean startPausing(boolean userLeaving, boolean uiSleeping, ActivityRecord resuming,
            String reason) {
        ...
        if (prev.attachedToProcess()) {
            ...
            } else {
                //分发pause Activity
                schedulePauseActivity(prev, userLeaving, pauseImmediately,
                        false /* autoEnteringPip */, reason);
            }
        }
    }

    void schedulePauseActivity(ActivityRecord prev, boolean userLeaving,
            boolean pauseImmediately, boolean autoEnteringPip, String reason) {
        try {
            ...
            mAtmService.getLifecycleManager().scheduleTransaction(prev.app.getThread(),
                    prev.token, PauseActivityItem.obtain(prev.finishing, userLeaving,
                            prev.configChangeFlags, pauseImmediately, autoEnteringPip));
        }
        ...
    }

//frameworks/base/core/java/android/app/servertransaction/PauseActivityItem.java
    //先执行
    public void execute(ClientTransactionHandler client, ActivityClientRecord r,
            PendingTransactionActions pendingActions) {
        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
        client.handlePauseActivity(r, mFinished, mUserLeaving, mConfigChanges, mAutoEnteringPip,
                pendingActions, "PAUSE_ACTIVITY_ITEM");
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }

    //后执行
    public void postExecute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        ...
        ActivityClient.getInstance().activityPaused(token);
    }

//frameworks/base/core/java/android/app/Activity.java
    final void performPause() {
        ...
        dispatchActivityPrePaused();
        ...
        //调用Launcher进程对应Activity的onPause函数
        onPause();
        ...
        dispatchActivityPostPaused();
    }

//frameworks/base/services/core/java/com/android/server/wm/ActivityRecord.java
    void activityPaused(boolean timeout) {
        ...
                try {
                    //通知系统Activity已经pause完成,可以继续进程启动流程
                    taskFragment.completePause(true /* resumeNext */, null /* resumingActivity */);
                }
                ...
    }

pause Activity的流程在systrace上的体现如下:

3.2 新进程的创建

3.2.1 AMS向zygote发送创建进程的socket请求

    接着mAtmService.startProcessAsync函数来看进程创建流程。此函数会经过ATMS-AMS-ProcessList-Process,最终调用到ZygoteProcess.startViaZygote函数,通过socket通信通知zygote fork进程。

注意:ProcessList的startProcessLocked函数,有五个同名的函数,且存在相互调用的逻辑,这里需要根据函数的传参以及函数返回值确认每次具体调用的函数,实在区分不了可以打堆栈确认。

//frameworks/base/services/core/java/com/android/server/am/ProcessList.java
    boolean startProcessLocked(...) {
        ...
        try {
            ...
            //进程创建成功会返回对应的pid,并保存在ProcessStartResult中
            final Process.ProcessStartResult startResult = startProcess(hostingRecord,
                        entryPoint, app,
                        uid, gids, runtimeFlags, zygotePolicyFlags, mountExternal, seInfo,
                        requiredAbi, instructionSet, invokeWith, startUptime);
            //更新zygote创建进程成功后返回的pid到ProcessRecord
            handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
                        startSeq, false);
        }
        ...
    }

//frameworks/base/services/core/java/com/android/server/am/ProcessList.java
    private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,
            ProcessRecord app, int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags,
            int mountExternal, String seInfo, String requiredAbi, String instructionSet,
            String invokeWith, long startTime) {
        try {
            ...
            //进程启动的systrace tag
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
                    app.processName);
            ...
            //下面是三种不同类型的创建进程的方式,一般应用都是通过最后一种即Process.start的方式创建
            if (hostingRecord.usesWebviewZygote()) {
                startResult = startWebView(...);
            } else if (hostingRecord.usesAppZygote()) {
                final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app);

                // We can't isolate app data and storage data as parent zygote already did that.
                startResult = appZygote.getProcess().start(...);
            } else {
                zygotePolicyFlags = ZygoteConfigExt.updateZygotePolicyFlags(
                        mService.mContext.getContentResolver(), zygotePolicyFlags);
                regularZygote = true;
                startResult = Process.start(...);
                // By now the process group should have been created by zygote.
                app.mProcessGroupCreated = true;
            }
        }
        ...
    }

//frameworks/base/core/java/android/os/Process.java
    public static ProcessStartResult start(...) {
        return ZYGOTE_PROCESS.start(...);


//frameworks/base/core/java/android/os/ZygoteProcess.java
    private Process.ProcessStartResult startViaZygote(...)
                                                      throws ZygoteStartFailedEx {
        ...
        synchronized(mLock) {
            ...
            //把创建进程的参数通过socket发送给zygote进程,zygote进程会fork出新的进程并返回pid
            return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),
                                              zygotePolicyFlags,
                                              argsForZygote);
        }
        ...
    }

    private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
        try {
            //判断是否已经建立socket连接,如果没有则建立连接
            attemptConnectionToPrimaryZygote();

            //socket连接已建立
            if (primaryZygoteState.matches(abi)) {
                return primaryZygoteState;
            }

            ...
        }
        ...
    }

    private void attemptConnectionToPrimaryZygote() throws IOException {
        //如果没有建立连接,则建立socket连接
        if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
            primaryZygoteState =
                    ZygoteState.connect(mZygoteSocketAddress, mUsapPoolSocketAddress);
            ...
        }
    }

    private Process.ProcessStartResult attemptZygoteSendArgsAndGetResult(
            ZygoteState zygoteState, String msgStr) throws ZygoteStartFailedEx {
        try {
            final BufferedWriter zygoteWriter = zygoteState.mZygoteOutputWriter;
            final DataInputStream zygoteInputStream = zygoteState.mZygoteInputStream;

            //向zygote发送创建进程的请求
            zygoteWriter.write(msgStr);
            zygoteWriter.flush();

            Process.ProcessStartResult result = new Process.ProcessStartResult();
            //zygote创建进程成功后返回新进程的pid
            result.pid = zygoteInputStream.readInt();
            result.usingWrapper = zygoteInputStream.readBoolean();

            return result;
        }
        ...
    }

3.2.2 Zygote fork进程

    ZygoteInit在开机阶段就完成了初始化,会创建一个ZygoteServer对象,在一个单独的线程中进入死循环,等待来自AMS的socket请求。ZygoteServer接收到socket请求后,会调用ZygoteConnection.processCommand函数进行socket请求处理,接着调用Zygote.forkAndSpecialize进行进程的fork创建,创建成功后会返回对应的pid,在ZygoteConnection.handleChildProc中继续处理请求参数。

//frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
    public static void main(String[] argv) {
        ZygoteServer zygoteServer = null;
        ...
        Runnable caller;
        try {
            ...
            //做fork前的一些初始化工作,主要是enable DDMS
            RuntimeInit.preForkInit();
            ...
            if (!enableLazyPreload) {
                ...
                //提前加载框架通用类和系统资源
                preload(bootTimingsTraceLog);
                ...
            }
            ...
            //初始化gc
            gcAndFinalize();
            ...
            //创建zygote的服务端对象
            zygoteServer = new ZygoteServer(isPrimaryZygote);
            ...
            //在单独的线程中启一个死循环,用来接收AMS的socket请求
            caller = zygoteServer.runSelectLoop(abiList);
            ...
        }
        ...
        if (caller != null) {
            caller.run();
        }
    }

//frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
    Runnable runSelectLoop(String abiList) {
        ...
        while (true) {
            ...
            try {
                ...
                //获取socket连接
                ZygoteConnection connection = peers.get(pollIndex);
                //处理socket请求
                final Runnable command =
                        connection.processCommand(this, multipleForksOK);
                ...
            }
        ...
        }
    }

//frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
    Runnable processCommand(ZygoteServer zygoteServer, boolean multipleOK) {
        try (ZygoteCommandBuffer argBuffer = new ZygoteCommandBuffer(mSocket)) {
            while (true) {
                ...
                //调用Zygote的forkAndSpecialize函数进行fork process
                pid = Zygote.forkAndSpecialize(...);
                ...
                try {
                    if (pid == 0) {
                        ...
                        //pid为0,当前处于新创建的子应用进程中,处理请求参数
                        return handleChildProc(parsedArgs, childPipeFd,
                                parsedArgs.mStartChildZygote);
                    } else {
                        ...
                        handleParentProc(pid, serverPipeFd);
                        ...
                    }
                }
            }
        }
    }

//frameworks/base/core/java/com/android/internal/os/Zygote.java
    static int forkAndSpecialize(...) {
        ZygoteHooks.preFork();
        //真正fork process的地方是在native层
        int pid = nativeForkAndSpecialize(...);
        ...
    }

//frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
    private Runnable handleChildProc(ZygoteArguments parsedArgs,
            FileDescriptor pipeFd, boolean isZygote) {
        //关闭从父进程zygote继承过来的ZygoteServer服务端地址
        closeSocket();
        ...
        if (parsedArgs.mInvokeWith != null) {
            ...
        } else {
            if (!isZygote) {
                //调用ZygoteInit.zygoteInit继续子应用进程的相关初始化工作
                return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
                        parsedArgs.mDisabledCompatChanges,
                        parsedArgs.mRemainingArgs, null /* classLoader */);
            } else {
                ...
            }
        }
    }

3.3 应用进程初始化

  设置应用进程默认的java处理机制,启动进程的binder线程池,通过反射调用ActivityThread.attach函数进行Application的初始化工作,创建并启动应用主线程的Looper消息循环机制,接着调用AMS的attachApplication进行Application的初始化,到此进程创建流程就走完了。

PS:进程的binder线程池,这是要注意下,非system_server的binder线程池最大数量是16个,具体定义的位置:frameworks/native/libs/binder/ProcessState.cpp

#define DEFAULT_MAX_BINDER_THREADS 15

//frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
    public static Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,
            String[] argv, ClassLoader classLoader) {
        ...
        //开始"ZygoteInit"的systrace tag
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
        RuntimeInit.redirectLogStreams();
        //设置应用进程默认的java异常处理机制,可以实现监听、拦截应用进程所有的Java crash的逻辑
        RuntimeInit.commonInit();
        //JNI调用启动进程的binder线程池,应用进程的binder线程池资源是自己创建的并非从zygote父进程继承的
        ZygoteInit.nativeZygoteInit();
        //反射创建ActivityThread对象并调用其“main”入口方法
        return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,
                classLoader);
    }

//frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
    protected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges,
            String[] argv, ClassLoader classLoader) {
        ...
        //结束"ZygoteInit"的systrace tag
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

        // Remaining arguments are passed to the start class's static main
        return findStaticMain(args.startClass, args.startArgs, classLoader);
    }

    protected static Runnable findStaticMain(String className, String[] argv,
            ClassLoader classLoader) {
        Class<?> cl;

        try {
            //反射加载创建ActivityThread类对象
            cl = Class.forName(className, true, classLoader);
        } catch (ClassNotFoundException ex) {
            ...
        }

        Method m;
        try {
            //反射调用ActivityThread的main方法
            m = cl.getMethod("main", new Class[] { String[].class });
        } catch (NoSuchMethodException ex) {
            ...
        } catch (SecurityException ex) {
            ...
        }

        ...
        //执行ActivityThread的main方法
        return new MethodAndArgsCaller(m, argv);
    }

//frameworks/base/core/java/android/app/ActivityThread.java
    public static void main(String[] args) {
        //开始"ActivityThreadMain"的systrace tag
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");

        ...
        //创建主线程的loop消息循环
        Looper.prepareMainLooper();

        ...
        ActivityThread thread = new ActivityThread();
        //执行attach继续进行应用初始化的工作
        thread.attach(false, startSeq);

        ...
        //结束"ActivityThreadMain"的systrace tag
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        ...
        //启动主线程的loop消息循环
        Looper.loop();
    }


    private void attach(boolean system, long startSeq) {
        ...
        if (!system) {
            ...
            final IActivityManager mgr = ActivityManager.getService();
            try {
                //调用attachApplication进行Application的初始化
                mgr.attachApplication(mAppThread, startSeq);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
            ...
        }
    }

新进程的创建在systrace上体现如下:

四:Application的初始化及Activity的启动

4.1 Application的创建及初始化

在ActivityThread.handleBindApplication初始化过程中,在应用主线程中主要完成以下工作:

  • 根据AMS传入的ApplicationInfo信息创建应用APK对应的LoadedApk对象
  • 创建应用Application的Context对象
  • 调用LoadedApk的makeApplicationInner函数,创建应用的Application对象
//frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
    public final void attachApplication(IApplicationThread thread, long startSeq) {
        ...
        synchronized (this) {
            ...
            attachApplicationLocked(thread, callingPid, callingUid, startSeq);
            ...
        }
    }

    private void attachApplicationLocked(@NonNull IApplicationThread thread,
            int pid, int callingUid, long startSeq) {
        ...
        try {
            if (app.getIsolatedEntryPoint() != null) {
                ...
            } else if (instr2 != null) {
                //调用应用进程ActivityThread.ApplicationThread.bindApplication接口
                thread.bindApplication(...);
            }
            ...
            //更新LRU进程列表
            updateLruProcessLocked(app, false, null);
            ...
        }
    }

//frameworks/base/core/java/android/app/ActivityThread.java
    private class ApplicationThread extends IApplicationThread.Stub {
        public final void bindApplication(...) {
            ...
            //向应用进程主线程Handler发送BIND_APPLICATION消息
            sendMessage(H.BIND_APPLICATION, data);
        }
    }

    class H extends Handler {
        public void handleMessage(Message msg) {
            ...
            switch (msg.what) {
                ...
                case BIND_APPLICATION:
                    //开始"bindApplication"的systrace tag
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
                    ...
                    //在应用主线程执行handleBindApplication初始化动作
                    handleBindApplication(data);
                    //结束"bindApplication"的systrace tag
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
                ...
            }
        }
    }

    private void handleBindApplication(AppBindData data) {
        ...
        //创建应用的LoadedApk对象
        data.info = getPackageInfo(data.appInfo, mCompatibilityInfo, null /* baseLoader */,
                false /* securityViolation */, true /* includeCode */,
                false /* registerPackage */, isSdkSandbox);
        ...
        final IActivityManager mgr = ActivityManager.getService();
        //创建应用Application的Context,触发Art虚拟机加载应用APK的Dex文件到内存中,并加载应用APK的Resource资源
        final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
        ...
        try {
            //调用LoadedApk的makeApplicationInner函数,创建应用的Application对象
            app = data.info.makeApplicationInner(data.restrictedBackupMode, null);
            ...
            mgr.finishAttachApplication(mStartSeq);
         catch (RemoteException ex) {
            ...
        }
    }

//frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
    private void finishAttachApplicationInner(long startSeq, int uid, int pid) {
        ...
        synchronized (this) {
            ...
            if (normalMode) {
                try {
                    //继续执行启动应用Activity的流程
                    didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
                } catch (Exception e) {
                    ...
                }
            }
            if (!badApp) {
                try {
                    //继续执行启动应用Service的流程
                    didSomething |= mServices.attachApplicationLocked(app, processName);
                    ...
                } catch (Exception e) {
                    ...
                }
            }

            if (!badApp) {
                try {
                    for (BroadcastQueue queue : mBroadcastQueues) {
                        //继续执行启动应用roadcast的流程
                        didSomething |= queue.onApplicationAttachedLocked(app);
                    }
                    ...
                } catch (BroadcastDeliveryFailedException e) {
                    ...
                }
            }
            ...
        }
    }

4.1.1 创建应用APK对应的LoadedApk对象

//frameworks/base/core/java/android/app/ActivityThread.java
    private LoadedApk getPackageInfo(ApplicationInfo aInfo, CompatibilityInfo compatInfo,
            ClassLoader baseLoader, boolean securityViolation, boolean includeCode,
            boolean registerPackage, boolean isSdkSandbox) {
        ...
        packageInfo =
                    new LoadedApk(this, aInfo, compatInfo, baseLoader,
                            securityViolation, includeCode
                            && (aInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0, registerPackage);
        ...
    }

4.1.2 创建Application的Context对象

    4.1.2.1 应用dex文件的加载

    在创建Application的Context对象后,会尝试获取加载apk对应的资源文件,这里最终会触发ART加载应用的dex文件(ART加载dex文件的过程后续完善)

//frameworks/base/core/java/android/app/ContextImpl.java
    static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo,
            String opPackageName) {
        if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
        //new一个Application的Context对象
        ContextImpl context = new ContextImpl(null, mainThread, packageInfo,
            ContextParams.EMPTY, null, null, null, null, null, 0, null, opPackageName);
        //获取apk对应的资源文件
        context.setResources(packageInfo.getResources());
        context.mContextType = isSystemOrSystemUI(context) ? CONTEXT_TYPE_SYSTEM_OR_SYSTEM_UI
                : CONTEXT_TYPE_NON_UI;
        ...
        return context;
    }

//frameworks/base/core/java/android/app/LoadedApk.java
    public Resources getResources() {
        if (mResources == null) {
            ...
            //通过getClassLoader()创建类加载器ClassLoader对象并触发Art虚拟机执行OpenDexFilesFromOat动作加载应用APK的Dex文件
            mResources = ResourcesManager.getInstance().getResources(null, mResDir,
                    splitPaths, mLegacyOverlayDirs, mOverlayPaths,
                    mApplicationInfo.sharedLibraryFiles, null, null, getCompatibilityInfo(),
                    getClassLoader(), null);
        }
        return mResources;
    }

//frameworks/base/core/java/android/app/LoadedApk.java
    public ClassLoader getClassLoader() {
        synchronized (mLock) {
            if (mClassLoader == null) {
                createOrUpdateClassLoaderLocked(null /*addedPaths*/);
            }
            return mClassLoader;
        }
    }

//frameworks/base/core/java/android/app/LoadedApk.java
    private void createOrUpdateClassLoaderLocked(List<String> addedPaths) {
        ...
        //寻找apk的资源文件路径保存在zipPaths中,寻找apk的库文件路径保存在libPaths中
        makePaths(mActivityThread, isBundledApp, mApplicationInfo, zipPaths, libPaths);
        ...
        //如果应用没有包含可执行代码(即应用没有Java 类或其他需要被执行的代码)
        if (!mIncludeCode) {
            if (mDefaultClassLoader == null) {
                StrictMode.ThreadPolicy oldPolicy = allowThreadDiskReads();
                //构造默认类加载器时,传入的codePath是null
                mDefaultClassLoader = ApplicationLoaders.getDefault().getClassLoader(
                        "" /* codePath */, mApplicationInfo.targetSdkVersion, isBundledApp,
                        librarySearchPath, libraryPermittedPath, mBaseClassLoader,
                        null /* classLoaderName */);
                ...
            }

            if (mClassLoader == null) {
                mClassLoader = mAppComponentFactory.instantiateClassLoader(mDefaultClassLoader,
                        new ApplicationInfo(mApplicationInfo));
            }

            return;
        }
        ...
        if (mDefaultClassLoader == null) {
            ...
            //构造默认类加载器,触发art虚拟机加载dex文件
            mDefaultClassLoader = ApplicationLoaders.getDefault().getClassLoaderWithSharedLibraries(
                    zip, mApplicationInfo.targetSdkVersion, isBundledApp, librarySearchPath,
                    libraryPermittedPath, mBaseClassLoader,
                    mApplicationInfo.classLoaderName, sharedLibraries.first, nativeSharedLibraries,
                    sharedLibraries.second);
            ...
        }
        ...
        if (mClassLoader == null) {
            //赋值给mClassLoader对象
            mClassLoader = mAppComponentFactory.instantiateClassLoader(mDefaultClassLoader,
                    new ApplicationInfo(mApplicationInfo));
        }
    }

//frameworks/base/core/java/android/app/ApplicationLoaders.java
    ClassLoader getClassLoaderWithSharedLibraries(...) {
        return getClassLoader(...);
    }

//frameworks/base/core/java/android/app/ApplicationLoaders.java
    private ClassLoader getClassLoader(...) {
        ...
        synchronized (mLoaders) {
            ...
            //创建PathClassLoader加载应用APK的Dex类,并增加相应的systrace tag
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, zip);
            ClassLoader loader = ClassLoaderFactory.createClassLoader(
                    zip, null, parent, classLoaderName, sharedLibraries,
                    null /*sharedLibrariesLoadedAfterApp*/);
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        ...
        }
    }

//frameworks/base/core/java/com/android/internal/os/ClassLoaderFactory.java
    public static ClassLoader createClassLoader(String dexPath,
            String librarySearchPath, ClassLoader parent, String classloaderName,
            List<ClassLoader> sharedLibraries, List<ClassLoader> sharedLibrariesLoadedAfter) {
        //通过new的方式创建ClassLoader对象,最终会触发art虚拟机加载APK的dex文件
        ClassLoader[] arrayOfSharedLibraries = (sharedLibraries == null)
                ? null
                : sharedLibraries.toArray(new ClassLoader[sharedLibraries.size()]);
        ClassLoader[] arrayOfSharedLibrariesLoadedAfterApp = (sharedLibrariesLoadedAfter == null)
                ? null
                : sharedLibrariesLoadedAfter.toArray(
                        new ClassLoader[sharedLibrariesLoadedAfter.size()]);
        if (isPathClassLoaderName(classloaderName)) {
            return new PathClassLoader(dexPath, librarySearchPath, parent, arrayOfSharedLibraries,
                    arrayOfSharedLibrariesLoadedAfterApp);
        } else if (isDelegateLastClassLoaderName(classloaderName)) {
            ...
        }
    }
4.1.2.2 应用资源的加载

    在创建Resources对象过程中加载了应用的资源文件,加载资源文件最终是通过JNI调用Native层的系统system/lib/libandroidfw.so库中的相关C函数实现对APK文件压缩包的解析与加载

//frameworks/base/core/java/android/app/LoadedApk.java
    public Resources getResources() {
        if (mResources == null) {
            ...
            mResources = ResourcesManager.getInstance().getResources(null, mResDir,
                    splitPaths, mLegacyOverlayDirs, mOverlayPaths,
                    mApplicationInfo.sharedLibraryFiles, null, null, getCompatibilityInfo(),
                    getClassLoader(), null);
        }
        return mResources;
    }

//frameworks/base/core/java/android/app/ResourcesManager.java
    public Resources getResources(...) {
        try {
            //开始"ResourcesManager#getResources"的systrace tag
            Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, "ResourcesManager#getResources");
            ...
            //activityToken为getResources传入的第一个参数,此处为null,走else
            if (activityToken != null) {
                ...
            } else {
                //创建资源文件
                resources = createResources(key, classLoader, assetsSupplier);
            }
            return resources;
        } finally {
            //结束"ResourcesManager#getResources"的systrace tag
            Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
        }
    }

//frameworks/base/core/java/android/app/ResourcesManager.java
    private Resources createResources(@NonNull ResourcesKey key, @NonNull ClassLoader classLoader,
            @Nullable ApkAssetsSupplier apkSupplier) {
        synchronized (mLock) {
            ...
            //执行创建Resources资源对象
            ResourcesImpl resourcesImpl = findOrCreateResourcesImplForKeyLocked(key, apkSupplier);
            ...
            return createResourcesLocked(classLoader, resourcesImpl, key.mCompatInfo);
        }
    }

//frameworks/base/core/java/android/app/ResourcesManager.java
    private @Nullable ResourcesImpl findOrCreateResourcesImplForKeyLocked(
            @NonNull ResourcesKey key, @Nullable ApkAssetsSupplier apkSupplier) {
        ...
        if (impl == null) {
            impl = createResourcesImpl(key, apkSupplier);
            ...
        }
        return impl;
    }

//frameworks/base/core/java/android/app/ResourcesManager.java
    private @Nullable ResourcesImpl createResourcesImpl(@NonNull ResourcesKey key,
            @Nullable ApkAssetsSupplier apkSupplier) {
        //构造AssetManager对象
        final AssetManager assets = createAssetManager(key, apkSupplier);
        ...
        //构造ResourcesImpl对象
        final ResourcesImpl impl = new ResourcesImpl(assets, displayMetrics, config, daj);

        ...
        return impl;
    }

//frameworks/base/core/java/android/app/ResourcesManager.java
    private @Nullable AssetManager createAssetManager(@NonNull final ResourcesKey key,
            @Nullable ApkAssetsSupplier apkSupplier) {
        final AssetManager.Builder builder = new AssetManager.Builder();

        final ArrayList<ApkKey> apkKeys = extractApkKeys(key);
        for (int i = 0, n = apkKeys.size(); i < n; i++) {
            final ApkKey apkKey = apkKeys.get(i);
            try {
                //通过loadApkAssets加载应用的资源文件
                builder.addApkAssets(
                        (apkSupplier != null) ? apkSupplier.load(apkKey) : loadApkAssets(apkKey));
            } catch (IOException e) {
                ...
            }
        }
        ...
        return builder.build();
    }

//frameworks/base/core/java/android/app/ResourcesManager.java
    private @NonNull ApkAssets loadApkAssets(@NonNull final ApkKey key) throws IOException {
        ...
        if (key.overlay) {
            apkAssets = ApkAssets.loadOverlayFromPath(overlayPathToIdmapPath(key.path), flags);
        } else {
            //
            apkAssets = ApkAssets.loadFromPath(key.path, flags);
        }
        ...
    }

//frameworks/base/core/java/android/content/res/ApkAssets.java
    public static @NonNull ApkAssets loadFromPath(@NonNull String path, @PropertyFlags int flags,
            @Nullable AssetsProvider assets) throws IOException {
        return new ApkAssets(FORMAT_APK, path, flags, assets);
    }

//frameworks/base/core/java/android/content/res/ApkAssets.java
    private ApkAssets(@FormatType int format, @NonNull String path, @PropertyFlags int flags,
            @Nullable AssetsProvider assets) throws IOException {
        ...
        //通过JNI调用Native层的系统system/lib/libandroidfw.so库中的相关C函数实现对APK文件压缩包的解析与加载
        mNativePtr = nativeLoad(format, path, flags, assets);
        ...
    }

//frameworks/base/core/jni/android_content_res_ApkAssets.cpp
static jlong NativeLoad(JNIEnv* env, jclass /*clazz*/, const format_type_t format,
                        jstring java_path, const jint property_flags, jobject assets_provider) {
  ...
  switch (format) {
    case FORMAT_APK: {
        auto assets = MultiAssetsProvider::Create(std::move(loader_assets),
                                                  ZipAssetsProvider::Create(path.c_str(),
                                                                            property_flags));
        //加载资源文件
        apk_assets = ApkAssets::Load(std::move(assets), property_flags);
        break;
    }
    ...
  }
  ...
  return CreateGuardedApkAssets(std::move(apk_assets));
}

4.1.3 调用LoadedApk的makeApplicationInner函数,创建应用的Application对象

//frameworks/base/core/java/android/app/LoadedApk.java
    private Application makeApplicationInner(boolean forceDefaultAppClass,
            Instrumentation instrumentation, boolean allowDuplicateInstances) {
        ...
        //开始"makeApplication"的systrace tag
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "makeApplication");
        ...
        try {
            ...
            //最终通过ClassLoader.loadClass创建Application对象
            app = mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);
            ...
        } catch (Exception e) {
            ...
        }
        ...
        //结束"makeApplication"的systrace tag
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        ...
    }

Application的创建即初始化在systrace上体现如下:

4.2 Activity的启动

    由5.1可知application创建完成后,会执行AMS.finishAttachApplicationInner函数,在这里执行Activity的启动流程,依次执行Activity的生命周期函数。

4.2.1 Activity.onCreate

   在ActivityTaskSupervisor的realStartActivityLocked函数中完成Activity创建流程,主要做了以下工作:

  • 创建Activity的context对象
  • 通过反射创建Activity对象
  • 在Activity的attach的函数中创建PhoneWindow对象,并PhoneWindow设置WindowManager
  • 调用应用Activity的onCreate函数
//frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
    private void finishAttachApplicationInner(long startSeq, int uid, int pid) {
        ...
        synchronized (this) {
            ...
            if (normalMode) {
                try {
                    didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
                } catch (Exception e) {
                    ...
                }
            }
        }
        ...
    }

//frameworks/base/services/core/java/com/android/server/am/ActivityTaskManagerService.java
    final class LocalService extends ActivityTaskManagerInternal {
        public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
            synchronized (mGlobalLockWithoutBoost) {
                ...
                try {
                    return mRootWindowContainer.attachApplication(wpc);
                }
                ...
            }
        }
    }

//frameworks/base/services/core/java/com/android/server/am/RootWindowContainer.java
    boolean attachApplication(WindowProcessController app) throws RemoteException {
        try {
            return mAttachApplicationHelper.process(app);
        } finally {
            ...
        }
    }

//frameworks/base/services/core/java/com/android/server/am/RootWindowContainer.java
    private class AttachApplicationHelper implements Consumer<Task>, Predicate<ActivityRecord> {
        boolean process(WindowProcessController app) throws RemoteException {
            ...
            if (!mHasActivityStarted) {
                ensureActivitiesVisible(null /* starting */, 0 /* configChanges */,
                        false /* preserveWindows */);
            }
            return mHasActivityStarted;
        }

//frameworks/base/services/core/java/com/android/server/am/RootWindowContainer.java
    void ensureActivitiesVisible(ActivityRecord starting, int configChanges,
            boolean preserveWindows, boolean notifyClients) {
        ...
        try {
            ...
            display.ensureActivitiesVisible(starting, configChanges, preserveWindows,
                    notifyClients);
        }
        ...
    }

//frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java
    void ensureActivitiesVisible(ActivityRecord starting, int configChanges,
            boolean preserveWindows, boolean notifyClients) {
        ...
        try {
            forAllRootTasks(rootTask -> {
                rootTask.ensureActivitiesVisible(starting, configChanges, preserveWindows,
                        notifyClients);
            });
            ...
        }
        ...
    }

//frameworks/base/services/core/java/com/android/server/wm/Task.java
    void ensureActivitiesVisible(@Nullable ActivityRecord starting, int configChanges,
            boolean preserveWindows, boolean notifyClients) {
        ...
        try {
            forAllLeafTasks(task -> {
                task.updateActivityVisibilities(starting, configChanges, preserveWindows,
                        notifyClients);
            }, true /* traverseTopToBottom */);
            ...
        }
        ...
    }

//frameworks/base/services/core/java/com/android/server/wm/TaskFragment.java
    final void updateActivityVisibilities(@Nullable ActivityRecord starting, int configChanges,
            boolean preserveWindows, boolean notifyClients) {
        ...
        try {
            mEnsureActivitiesVisibleHelper.process(
                    starting, configChanges, preserveWindows, notifyClients);
        }
        ...
    }

//frameworks/base/services/core/java/com/android/server/wm/TaskFragment.java
    private class EnsureVisibleActivitiesConfigHelper implements Predicate<ActivityRecord> {
        ...
        void process(ActivityRecord start, boolean preserveWindow) {
            if (start == null || !start.isVisibleRequested()) {
                return;
            }
            reset(preserveWindow);
            forAllActivities(this, start, true /* includeBoundary */,
                    true /* traverseTopToBottom */);

            if (mUpdateConfig) {
                // Ensure the resumed state of the focus activity if we updated the configuration of
                // any activity.
                mRootWindowContainer.resumeFocusedTasksTopActivities();
            }
        }
        ...
    }

//frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
    boolean resumeFocusedTasksTopActivities(
            Task targetRootTask, ActivityRecord target, ActivityOptions targetOptions,
            boolean deferPause) {
        ...
        if (targetRootTask != null && (targetRootTask.isTopRootTaskInDisplayArea()
                || getTopDisplayFocusedRootTask() == targetRootTask)) {
            result = targetRootTask.resumeTopActivityUncheckedLocked(target, targetOptions,
                    deferPause);
        }
        ...
        for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
            ...
            display.forAllRootTasks(rootTask -> {
                final ActivityRecord topRunningActivity = rootTask.topRunningActivity();
                ...
                if (topRunningActivity.isState(RESUMED)
                        && topRunningActivity == rootTask.getDisplayArea().topRunningActivity()) {
                    ...
                } else {
                    //调用ActivityRecord的makeActiveIfNeeded来startActivity
                    resumedOnDisplay[0] |= topRunningActivity.makeActiveIfNeeded(target);
                }
            });
        }
    }

//frameworks/base/services/core/java/com/android/server/wm/Task.java
    private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options,
            boolean deferPause) {
        ...
        resumed[0] = topFragment.resumeTopActivity(prev, options, deferPause);
        ...
    }

//frameworks/base/services/core/java/com/android/server/wm/TaskFragmen.java
    final boolean resumeTopActivity(ActivityRecord prev, ActivityOptions options,
            boolean deferPause) {
        ...
        mTaskSupervisor.startSpecificActivity(next, true, true);
        ...
    }

//frameworks/base/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
    void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
        ...
        final WindowProcessController wpc =
                mService.getProcessController(r.processName, r.info.applicationInfo.uid);
        ...
        if (wpc != null && wpc.hasThread()) {
            try {
                realStartActivityLocked(r, wpc, andResume, checkConfig);
                return;
            } catch (RemoteException e) {
                ...
            }
            ...
        } else if (r.intent.isSandboxActivity(mService.mContext)) {
            ...
        }
        ...
    }

//frameworks/base/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
    boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
            boolean andResume, boolean checkConfig) throws RemoteException {
        ...
        try {
            r.startFreezingScreenLocked(proc, 0);
            ...
            clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                    ...));
            ...
            final ActivityLifecycleItem lifecycleItem;
            if (andResume) {
                lifecycleItem = ResumeActivityItem.obtain(isTransitionForward,
                        r.shouldSendCompatFakeFocus());
            } else {
                lifecycleItem = PauseActivityItem.obtain();
            }
            clientTransaction.setLifecycleStateRequest(lifecycleItem);
            // Schedule transaction.
            mService.getLifecycleManager().scheduleTransaction(clientTransaction);
            ...
        }
        ...
        proc.onStartActivity(mService.mTopProcessState, r.info);
        ...
    }

//frameworks/base/core/java/android/app/servertransaction/LaunchActivityItem.java
    public void execute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        //开始"activityStart"的systrace tag
        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
        ...
        client.handleLaunchActivity(r, pendingActions, mDeviceId, null /* customIntent */);
        //结束"activityStart"的systrace tag
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }

//frameworks/base/core/java/android/app/ActivityThread.java
    public Activity handleLaunchActivity(ActivityClientRecord r,
            PendingTransactionActions pendingActions, int deviceId, Intent customIntent) {
        ...
        final Activity a = performLaunchActivity(r, customIntent);
        ...
    }

//frameworks/base/core/java/android/app/ActivityThread.java
    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        ...
        //创建Activity的context对象
        ContextImpl appContext = createBaseContextForActivity(r);
        ...
        try {
            //通过反射创建Activity对象
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            
        }
        ...
        try {
            //创建Application对象
            Application app = r.packageInfo.makeApplicationInner(false, mInstrumentation);
            if (activity != null) {
                ...
                //初始化Activity resources
                appContext.getResources().addLoaders(
                        app.getResources().getLoaders().toArray(new ResourcesLoader[0]));
                ...
                //调用Activity的attach函数
                activity.attach(...);
                ...
                //设置主题
                activity.setTheme(theme);
                ...
                //调用Instrumentation.callActivityOnCreate函数
                mInstrumentation.callActivityOnCreate(activity, r.state);
                ...
        ...
    }

//frameworks/base/core/java/android/app/Activity.java
    final void attach(...) {
        ...
        //创建PhoneWindow对象
        mWindow = new PhoneWindow(this, window, activityConfigCallback);
        ...
        //为PhoneWindow设置WindowManager
        mWindow.setWindowManager(
                (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
                mToken, mComponent.flattenToString(),
                (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
        ...
    }

//frameworks/base/core/java/android/app/Instrumentation.java
    public void callActivityOnCreate(Activity activity, Bundle icicle) {
        ...
        activity.performCreate(icicle);
        ...
    }

//frameworks/base/core/java/android/app/Activity.java
    final void performCreate(Bundle icicle, PersistableBundle persistentState) {
        if (Trace.isTagEnabled(Trace.TRACE_TAG_WINDOW_MANAGER)) {
            //开始"performCreate:"的systrace tag
            Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "performCreate:"
                    + mComponent.getClassName());
        }
        ...
        //恢复Activity已经申请的权限
        restoreHasCurrentPermissionRequest(icicle);
        ...
        //调用应用的onCreate函数
        onCreate(icicle);
        ...
        //结束"performCreate:"的systrace tag
        Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
    }

4.2.2 Activity.onResume

这里主要做了两件事:

  • 调用应用Activity的onResume函数
  • 执行WindowManager的addView函数开始视图绘制逻辑
//frameworks/base/core/java/android/app/servertransaction/ResumeActivityItem.java
    public void execute(ClientTransactionHandler client, ActivityClientRecord r,
            PendingTransactionActions pendingActions) {
        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
        client.handleResumeActivity(r, true /* finalStateRequest */, mIsForward,
                mShouldSendCompatFakeFocus, "RESUME_ACTIVITY");
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }

//frameworks/base/core/java/android/app/ActivityThread.java
    public void handleResumeActivity(ActivityClientRecord r, boolean finalStateRequest,
            boolean isForward, boolean shouldSendCompatFakeFocus, String reason) {
        ...
        //
        if (!performResumeActivity(r, finalStateRequest, reason)) {
            return;
        }
        ...
        if (r.window == null && !a.mFinished && willBeVisible) {
            r.window = r.activity.getWindow();
            //获取DecorView
            View decor = r.window.getDecorView();
            ...
            //获取WindowManager对象
            ViewManager wm = a.getWindowManager();
            WindowManager.LayoutParams l = r.window.getAttributes();
            a.mDecor = decor;
            ...
            if (a.mVisibleFromClient) {
                if (!a.mWindowAdded) {
                    ...
                    //执行WindowManager的addView函数开始视图绘制逻辑
                    wm.addView(decor, l);
                }
                ...
            }
        }
        ...
    }

//frameworks/base/core/java/android/app/ActivityThread.java
    public boolean performResumeActivity(ActivityClientRecord r, boolean finalStateRequest,
            String reason) {
        ...
        try {
            //如果是通过startActivityForResult方式启动Activity,这里返回结果
            if (r.pendingResults != null) {
                deliverResults(r, r.pendingResults, reason);
                r.pendingResults = null;
            }
            //执行Activity的performResume函数
            r.activity.performResume(r.startsNotResumed, reason);
            ...
            //把Activity的状态设置成ON_RESUME
            r.setState(ON_RESUME);
            ...
        }
        ...
    }

//frameworks/base/core/java/android/app/Activity.java
    final void performResume(boolean followedByPause, String reason) {
        //开始"performResume:"的systrace tag
        if (Trace.isTagEnabled(Trace.TRACE_TAG_WINDOW_MANAGER)) {
            Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "performResume:"
                    + mComponent.getClassName());
        }
        ...
        //调用Instrumentation.callActivityOnResume函数
        mInstrumentation.callActivityOnResume(this);
        ...
        //结束"performResume:"的systrace tag
        Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
        ...
    }

//frameworks/base/services/core/java/android/app/Instrumentation.java
    public void callActivityOnResume(Activity activity) {
        ...
        //调用应用Activity的onResume函数
        activity.onResume();
        ...
    }

4.2.3 Activity.onStart

    众所周知Activity的启动,生命周期的执行顺序是onCreate/onStart/onReusme,看完上面两小结,大家是否有一个疑问:onStart哪儿去了?带着这个疑问继续往下看看。

    Activity的生命周期基本都是通过Transaction来执行的,传入一个开始状态的lifecycle,传入一个结束状态的lifecycle,中间状态的Transaction会在开始和结束中间依次执行。

    状态保存的地方是ActivityLifecycleItem

    @IntDef(prefix = { "UNDEFINED", "PRE_", "ON_" }, value = {
            UNDEFINED,
            PRE_ON_CREATE,
            ON_CREATE,
            ON_START,
            ON_RESUME,
            ON_PAUSE,
            ON_STOP,
            ON_DESTROY,
            ON_RESTART
    })

    public static final int UNDEFINED = -1;
    public static final int PRE_ON_CREATE = 0;
    public static final int ON_CREATE = 1;
    public static final int ON_START = 2;
    public static final int ON_RESUME = 3;
    public static final int ON_PAUSE = 4;
    public static final int ON_STOP = 5;
    public static final int ON_DESTROY = 6;
    public static final int ON_RESTART = 7;
//frameworks/base/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
    boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
            boolean andResume, boolean checkConfig) throws RemoteException {
        ...
        final ClientTransaction clientTransaction = ClientTransaction.obtain(
                proc.getThread(), r.token);
        ...
        //设置Transaction开始的Lifecycle,即ON_CREATE
        clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent), ...));
        final ActivityLifecycleItem lifecycleItem;
        if (andResume) {
            lifecycleItem = ResumeActivityItem.obtain(isTransitionForward,
                            r.shouldSendCompatFakeFocus());
        }
        clientTransaction.setLifecycleStateRequest(lifecycleItem);
        //设置Transaction结束的Lifecycle,即ON_RESUME
        mService.getLifecycleManager().scheduleTransaction(clientTransaction);
        ...
    }

//frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java
    public void execute(ClientTransaction transaction) {
        ...
        //执行回调
        executeCallbacks(transaction);

        executeLifecycleState(transaction);
        ...
    }

//frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java
    public void executeCallbacks(ClientTransaction transaction) {
        final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
        ...
        final int size = callbacks.size();
        for (int i = 0; i < size; ++i) {
            ...
            if (postExecutionState != UNDEFINED && r != null) {
                ...
                cycleToPath(r, postExecutionState, shouldExcludeLastTransition, transaction);
            }
        }
    }

//frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java
    private void cycleToPath(ActivityClientRecord r, int finish, boolean excludeLastState,
            ClientTransaction transaction) {
        //获取Lifecycle开始的状态,这是获取到的是ON_CREATE
        final int start = r.getLifecycleState();
        ...
        //获取main lifecycle states,也就是开始和结束中间的需要依次执行的transaction数组。这里传入的finish是ON_RESUME
        final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);
        //依次执行transaction数组
        performLifecycleSequence(r, path, transaction);
    }

//frameworks/base/core/java/android/app/servertransaction/TransactionExecutorHelper.java
    public IntArray getLifecyclePath(int start, int finish, boolean excludeLastState) {
        ...
        if (finish >= start) {
            if (start == ON_START && finish == ON_STOP) {
                ...
            } else {
                for (int i = start + 1; i <= finish; i++) {
                    //这里会把ON_START传入mLifecycleSequence中
                    mLifecycleSequence.add(i);
                }
            }
            ...
        }
    }

//frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java
    private void performLifecycleSequence(ActivityClientRecord r, IntArray path,
            ClientTransaction transaction) {
        final int size = path.size();
        for (int i = 0, state; i < size; i++) {
            state = path.get(i);
            ...
            switch (state) {
                ...
                case ON_START:
                    //这里会调用到ActivityThread的handleStartActivity函数
                    mTransactionHandler.handleStartActivity(r, mPendingActions,
                            null /* activityOptions */);
                    break;
                ...
            }
        ...
        }
    }

//frameworks/base/core/java/android/app/ActivityThread.java
    public void handleStartActivity(ActivityClientRecord r,
            PendingTransactionActions pendingActions, ActivityOptions activityOptions) {
        ...
        activity.performStart("handleStartActivity");
        r.setState(ON_START);
        ...
    }

//frameworks/base/core/java/android/app/Activity.java
    final void performStart(String reason) {
        ...
        mInstrumentation.callActivityOnStart(this);
        ...
    }

//frameworks/base/core/java/android/app/Instrumentation.java
    public void callActivityOnStart(Activity activity) {
        //调用应用Activity的onStart函数
        activity.onStart();
    }

Activity启动流程,在systrace上体现如下:

五:应用界面的绘制

    在继续界面绘制的流程之前,这里先说明下一些view、window的概念、相关的基本类以及相互关系,便于理解后面流程。

  • View:Android应用用户界面的基本构建块,用于构建用户界面中的各种元素,如按钮、文本框、图像等。
  • Window:用于承载应用的用户界面。一个Activity通常对应一个Window,但也可以有多个Window,如dialog等;Window包含一个DecorView,它是View的容器,用于承载应用的内容视图
  • PhoneWindow:Window的实现类,负责管理应用窗口的显示、布局、交互等方面的功能;每个Activity都会有一个PhoneWindow对象来管理其所有的Window。在Activity创建过程中的attach函数中会创建一个PhoneWindow对象(详见5.2.1章节)
  • DecorView:应用View树的根节点,继承自View,通过它可以找到View树中的任一节点
  • WindowManager:继承自ViewManager,提供了View的基本操作方法;其实现类是WindowManagerImpl,在WindowManagerImpl中有一个WindowManagerGlobal类型的变量mGlobal,用来操作View
  • WindowManagerGlobal:是一个单例。其内部有三个非常重要的数组:mViews,mRoots,mParams,分别保存View、ViewRootImpl、LayoutParams对象。对于一个View,如果想获取它对应的ViewRootImpl以及LayoutParams,只需要先在mViews数组中通过View找到对应的位置(即数组下标),然后找到mRoots和mParams对应位置的对象即可。三个数组在相同下标保存的对象是一一对应关系
  • ViewRootImpl:ViewRootImpl连接View系统和WindowManager系统,负责管理View的绘制、事件处理、布局和与WindowManagerService、InputMethodManager的交互。

相互关系如下图所示:

5.1 ViewRootImpl.setView

  由4.2.2可知,界面绘制开始的入口是WindowManager的addView函数,咱们接着来看界面绘制流程。View绘制的主要实现是在ViewRootImpl的setView中,下面说明setView的关键流程

  • 根据应用是否有surface,判断是否要开启硬件加速
  • 通过requestLayout函数,触发界面绘制(onMeasure/onLayout/onDraw)
  • 通过WindowSession的addToDisplayAsUser函数来添加窗口
  • 创建WindowInputEventReceiver对象,封装实现窗口接收Input事件的逻辑
  • 设置DecorView的parent为ViewRootImpl
//frameworks/base/core/java/android/view/WindowManagerImpl.java
    public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
        applyTokens(params);
        mGlobal.addView(view, params, mContext.getDisplayNoVerify(), mParentWindow,
                mContext.getUserId());
    }

//frameworks/base/core/java/android/view/WindowManagerGlobal.java
    public void addView(View view, ViewGroup.LayoutParams params,
            Display display, Window parentWindow, int userId) {
        ...
        //初始化wparams
        final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams) params;
        ...
        synchronized (mLock) {
            ...
            //初始化root,这里的windowlessSession是null
            if (windowlessSession == null) {
                root = new ViewRootImpl(view.getContext(), display);
            } else {
                root = new ViewRootImpl(view.getContext(), display,
                        windowlessSession, new WindowlessWindowLayout());
            }
            ...
            //更新数组
            mViews.add(view);
            mRoots.add(root);
            mParams.add(wparams);

            try {
                //调用ViewRootImpl的setView函数
                root.setView(view, wparams, panelParentView, userId);
            }
        }
        ...
    }

//frameworks/base/core/java/android/view/ViewRootImpl.java
    public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView,
            int userId) {
        synchronized (this) {
            if (mView == null) {
                ...
                //触发界面绘制(onMeasure/onLayout/onDraw)
                requestLayout();
                //初始化inputChannel
                InputChannel inputChannel = null;
                if ((mWindowAttributes.inputFeatures
                        & WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0) {
                    inputChannel = new InputChannel();
                }
                ...
                try {
                    ...
                    //添加窗口
                    res = mWindowSession.addToDisplayAsUser(mWindow, mWindowAttributes,
                            getHostVisibility(), mDisplay.getDisplayId(), userId,
                            mInsetsController.getRequestedVisibleTypes(), inputChannel, mTempInsets,
                            mTempControls, attachedFrame, compatScale);
                    ...
                }
                ...
                if (inputChannel != null) {
                    //封装实现窗口接收Input事件的逻辑
                    mInputEventReceiver = new WindowInputEventReceiver(inputChannel, 
                            Looper.myLooper());
                }
                ...
                //设置DecorView的parent为ViewRootImpl
                view.assignParent(this);
                }
            }
        }
    }

5.2 ViewRootImpl.requestLayout

    咱们接着看requestLayout,这里会先判断更新UI的是不是主线程,只有主线程才允许更新UI。然后会通过Choreographer往主线程消息队列添加CALLBACK_TRAVERSAL绘制类型的待执行消息,最终会通过DisplayEventReceiver的scheduleVsync函数申请Vsync信号。

    这里介绍下Choreographer和Vsync

  • Choreographer:主要用于协调和同步 UI 绘制相关的操作。它与系统的 VSync(垂直同步)信号进行同步,确保动画的绘制和界面更新在屏幕刷新时进行,避免出现撕裂(tearing)等视觉问题。它在 Android 渲染链路中起到一个承上启下的作用。

    承上: 负责接收和处理 App(ViewRootImpl) 的各种更新消息和回调,等到 Vsync 到来的时候统一处理。例如:集中处理Traversal(包括measure、layout、draw等操作) ,判断掉帧情况,记录 CallBack 耗时等。
    启下: 负责请求和接收 Vsync 信号。
        请求 Vsync:通过FrameDisplayEventReceiver.scheduleVsync()。
        接收 Vsync 事件回调:通过FrameDisplayEventReceiver.onVsync()。

  • Vsync:Vsync信号的全称是Vertical Synchronization(中文名垂直同步),由GPU厂商开发,其基本思路就是在屏幕刷新之前向外提供一个信号。例如屏幕刷新率如果是60Hz,那么每隔1000/60=16.6ms就会发送vsync信号。
//frameworks/base/core/java/android/view/ViewRootImpl.java
    public void requestLayout() {
        if (!mHandlingLayoutInLayoutRequest) {
            ...
            //检查是否是主线程。只有主线程才可以更新UI
            checkThread();
            //触发绘制流程
            scheduleTraversals();
        }
    }

//frameworks/base/core/java/android/view/ViewRootImpl.java
    void scheduleTraversals() {
        ...
        if (!mTraversalScheduled) {
            ...
            //注意此处会往主线程的MessageQueue消息队列中添加同步栅栏,因为系统绘制消息属于异步消息,需要更高优先级的处理
            mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();
            ...
            //通过Choreographer往主线程消息队列添加CALLBACK_TRAVERSAL绘制类型的待执行消息,用于触发后续UI线程真正实现绘制动作
            mChoreographer.postCallback(
                    Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
            ...
        }
        ...
    }

//frameworks/base/core/java/android/view/Choreographer.java
    private void postCallbackDelayedInternal(int callbackType,
            Object action, Object token, long delayMillis) {
        ...
        synchronized (mLock) {
            final long now = SystemClock.uptimeMillis();
            //这里传入的delayMillis是0
            final long dueTime = now + delayMillis;
            //把mTraversalRunnable加入到CallbackQueues中
            mCallbackQueues[callbackType].addCallbackLocked(dueTime, action, token);

            if (dueTime <= now) {
                //请求Vsync信号
                scheduleFrameLocked(now);
            }
            ...
        }
    }

//frameworks/base/core/java/android/view/Choreographer.java
    private void scheduleFrameLocked(long now) {
        if (!mFrameScheduled) {
            mFrameScheduled = true;
            if (USE_VSYNC) {
                ...
                if (isRunningOnLooperThreadLocked()) {
                    //请求Vsync信号
                    scheduleVsyncLocked();
                }
                ...
            }
            ...
        }
    }

//frameworks/base/core/java/android/view/Choreographer.java
    private void scheduleVsyncLocked() {
        try {
            Trace.traceBegin(Trace.TRACE_TAG_VIEW, "Choreographer#scheduleVsyncLocked");
            //通过DisplayEventReceiver的scheduleVsync函数请求Vsync信号
            mDisplayEventReceiver.scheduleVsync();
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_VIEW);
        }
    }

//frameworks/base/core/java/android/view/DisplayEventReceiver.java
    public void scheduleVsync() {
        ...
        //通过nativeScheduleVsync函数请求Vsync信号
        nativeScheduleVsync(mReceiverPtr);
        ...
    }

5.3 ViewRootImpl.performTraversals

    当Vsync信号到来后,会触发Choreographer的FrameDisplayEventReceiver的onVsync函数,执行完毕后,会通过run函数调用doframe函数,doframe会处理丢帧逻辑并触发callback(例如Input、animation、traversal等)。tracersal类型的callback被触发后,会调用到ViewRootImpl的performTraversals函数,这里详细说下该函数做了哪些事情。

  • 通过Binder调用WMS的relayoutWindow接口,主要完成的工作:1. 创建SurfaceControl 2. 计算窗口大小 3. 给应用端SurfaceControl赋值 4. 填充WMS计算好的数据返回给应用端
  • 从DecorView根节点出发,遍历整个View控件树,完成整个View控件树的measure操作
  • 从DecorView根节点出发,遍历整个View控件树,完成整个View控件树的layout操作
  • 从DecorView根节点出发,遍历整个View控件树,完成整个View控件树的draw操作
//frameworks/base/core/java/android/view/Choreographer.java
    private Choreographer(Looper looper, int vsyncSource, long layerHandle) {
        mLooper = looper;
        //把TRACE_TAG_VIEW systrace tag和looper绑定
        mLooper.setTraceTag(Trace.TRACE_TAG_VIEW);
        //初始化FrameHandler,绑定Looper
        mHandler = new FrameHandler(looper);
        //初始化FrameDisplayEventReceiver,与SurfaceFlinger建立通信用于接收和请求Vsync信号
        mDisplayEventReceiver = USE_VSYNC
                ? new FrameDisplayEventReceiver(looper, vsyncSource, layerHandle)
                : null;
        mLastFrameTimeNanos = Long.MIN_VALUE;

        mFrameIntervalNanos = (long)(1000000000 / getRefreshRate());
        //初始化CallbackQueue,数组长度为5
        mCallbackQueues = new CallbackQueue[CALLBACK_LAST + 1];
        for (int i = 0; i <= CALLBACK_LAST; i++) {
            mCallbackQueues[i] = new CallbackQueue();
        }
        ...
    }

//frameworks/base/core/java/android/view/Choreographer.java
    private final class FrameDisplayEventReceiver extends DisplayEventReceiver
            implements Runnable {
        public void onVsync(long timestampNanos, long physicalDisplayId, int frame,
                VsyncEventData vsyncEventData) {
            try {
                ...
                //保存绘制时间、帧数和事件数据
                mTimestampNanos = timestampNanos;
                mFrame = frame;
                mLastVsyncEventData.copyFrom(vsyncEventData);
                ...
            } finally {
                Trace.traceEnd(Trace.TRACE_TAG_VIEW);
            }
        }

        @Override
        public void run() {
            //调用主处理函数doFrame
            doFrame(mTimestampNanos, mFrame, mLastVsyncEventData);
        }
    }

//frameworks/base/core/java/android/view/Choreographer.java
    void doFrame(long frameTimeNanos, int frame,
            DisplayEventReceiver.VsyncEventData vsyncEventData) {
        ...
        try {
            ...
            synchronized (mLock) {
                ...
                //Vsync信号到来的时间距离现在超过一个帧间隔,即出现了丢帧
                if (jitterNanos >= frameIntervalNanos) {
                    ...
                    if (frameIntervalNanos == 0) {
                        ...
                    } else {
                        ...
                        //丢帧超过30帧会打印如下日志,碰到卡顿问题时可以搜到响应关键字看丢帧情况
                        if (skippedFrames >= SKIPPED_FRAME_WARNING_LIMIT) {
                            Log.i(TAG, "Skipped " + skippedFrames + " frames!  "
                                    + "The application may be doing too much work on its main "
                                    + "thread.");
                        }
                        ...
                    }
                    ...
                }
            }
            ...
            //处理Input类型的callback
            doCallbacks(Choreographer.CALLBACK_INPUT, frameIntervalNanos);
            //处理insets animation类型的callback
            doCallbacks(Choreographer.CALLBACK_INSETS_ANIMATION, frameIntervalNanos);
            //处理traversal类型的callback,这里会回调到ViewRootImpl,触发view的绘制逻辑
            doCallbacks(Choreographer.CALLBACK_TRAVERSAL, frameIntervalNanos);
            //处理commit类型的callback
            doCallbacks(Choreographer.CALLBACK_COMMIT, frameIntervalNanos);
        }
    }

//frameworks/base/core/java/android/view/ViewRootImpl.java
    final class TraversalRunnable implements Runnable {
        @Override
        public void run() {
            doTraversal();
        }
    }

//frameworks/base/core/java/android/view/ViewRootImpl.java
    void doTraversal() {
        if (mTraversalScheduled) {
            ...
            //调用removeSyncBarrier及时移除主线程MessageQueue中的Barrier同步栅栏,以避免主线程发生"假死"
            mHandler.getLooper().getQueue().removeSyncBarrier(mTraversalBarrier);
            ...
            performTraversals();
            ...
        }
    }

//frameworks/base/core/java/android/view/ViewRootImpl.java
    private void performTraversals() {
        ...
        //通过Binder调用WMS的relayoutWindow接口,主要完成的工作:1. 创建SurfaceControl 2. 计算窗口大小 3. 给应用端SurfaceControl赋值 4. 填充WMS计算好的数据返回给应用端
        relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);
        ...
        //从DecorView根节点出发,遍历整个View控件树,完成整个View控件树的measure操作
        performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
        ...
        //从DecorView根节点出发,遍历整个View控件树,完成整个View控件树的layout操作
        performLayout(lp, mWidth, mHeight);
        ...
        //WMS请求同步
        createSyncIfNeeded();
        notifyDrawStarted(isInWMSRequestedSync());
        ...
        //从DecorView根节点出发,遍历整个View控件树,完成整个View控件树的draw操作
        if (!performDraw() && mActiveSurfaceSyncGroup != null) {
            //触发绘制完成回调
            mActiveSurfaceSyncGroup.markSyncReady();
        }
        ...
    }

//frameworks/base/core/java/android/view/ViewRootImpl.java
    private void performMeasure(int childWidthMeasureSpec, int childHeightMeasureSpec) {
        //开始记录measure的systrace tag
        Trace.traceBegin(Trace.TRACE_TAG_VIEW, "measure");
        try {
            //完成以DecorView为根节点的整个View树的measure工作,View绘制三部曲的第一步measure
            mView.measure(childWidthMeasureSpec, childHeightMeasureSpec);
        } finally {
            //结束记录measure的systrace tag
            Trace.traceEnd(Trace.TRACE_TAG_VIEW);
        }
        ...
    }

//frameworks/base/core/java/android/view/ViewRootImpl.java
    private void performLayout(WindowManager.LayoutParams lp, int desiredWindowWidth,
            int desiredWindowHeight) {
        ...
        //开始记录layout的systrace tag
        Trace.traceBegin(Trace.TRACE_TAG_VIEW, "layout");
        try {
            //完成以DecorView为根节点的整个View树的layout工作,View绘制三部曲的第二步layout
            host.layout(0, 0, host.getMeasuredWidth(), host.getMeasuredHeight());
            ...
        } finally {
            //结束记录layout的systrace tag
            Trace.traceEnd(Trace.TRACE_TAG_VIEW);
        }
        ...
    }

//frameworks/base/core/java/android/view/ViewRootImpl.java
    private boolean performDraw() {
        ...
        //开始记录draw的systrace tag
        Trace.traceBegin(Trace.TRACE_TAG_VIEW, "draw");
        ...
        try {
            boolean canUseAsync = draw(fullRedrawNeeded, usingAsyncReport && mSyncBuffer);
            ...
        } finally {
            //结束记录draw的systrace tag
            Trace.traceEnd(Trace.TRACE_TAG_VIEW);
        }
        ...
    }

//frameworks/base/core/java/android/view/ViewRootImpl.java
    private boolean draw(boolean fullRedrawNeeded, boolean forceDraw) {
        ...
        //如果开启了硬绘
        if (isHardwareEnabled()) {
            ...
            //在Renderthread中做绘制动作(现在绝大部分走硬绘)
            mAttachInfo.mThreadedRenderer.draw(mView, mAttachInfo, this);
            ...
        } else {
            ...
            //走软绘流程
            if (!drawSoftware(...)) {
                ...
            }
        }
        ...
    }

以上过程其实就是view绘制三部曲,在systrace上体现如下:

六:Renderthread的绘制

    目前Android 4.X之后系统默认是开启硬件加速的,所以我们重点分析硬件加速条件下的界面渲染流程。

  • 从DecorView根节点出发,递归遍历View控件树,记录每个View节点的绘制操作命令,完成绘制操作命令树的构建
  • JNI调用同步Java层构建的绘制命令树到Native层的RenderThread渲染线程,并唤醒渲染线程利用OpenGL执行渲染任务
//frameworks/base/core/java/android/view/ThreadedRenderer.java
    void draw(View view, AttachInfo attachInfo, DrawCallbacks callbacks) {
        ...
        //从DecorView根节点出发,递归遍历View控件树,记录每个View节点的绘制操作命令,完成绘制操作命令树的构建
        updateRootDisplayList(view, callbacks);
        ...
        //JNI调用同步Java层构建的绘制命令树到Native层的RenderThread渲染线程,并唤醒渲染线程利用OpenGL执行渲染任务
        int syncResult = syncAndDrawFrame(frameInfo);
        ...
    }

6.1 绘制命令树的构建

  • 通过renderNode创建一个RecordingCanvas类型的画布
  • 利用RecordingCanvas,在每个子View控件的onDraw绘制函数中调用drawRect等绘制操作时,创建对应的DisplayListOp绘制命令,并缓存记录到其内部的DisplayList持有的DisplayListData中
  • 将包含有DisplayListOp绘制命令缓存的DisplayList对象设置填充到RenderNode中
  • 将所有DisplayListOp绘制命令填充到RootRenderNode中
//frameworks/base/core/java/android/view/ThreadedRenderer.java
    private void updateRootDisplayList(View view, DrawCallbacks callbacks) {
        //开始记录"Record View#draw()"的systrace tag
        Trace.traceBegin(Trace.TRACE_TAG_VIEW, "Record View#draw()");
        //递归子View的updateDisplayListIfDirty实现构建DisplayListOp
        updateViewTreeDisplayList(view);
        ...
        if (mRootNodeNeedsUpdate || !mRootNode.hasDisplayList()) {
            //获取根View的SkiaRecordingCanvas
            RecordingCanvas canvas = mRootNode.beginRecording(mSurfaceWidth, mSurfaceHeight);
            try {
                ...
                //利用canvas缓存DisplayListOp绘制命令
                canvas.drawRenderNode(view.updateDisplayListIfDirty());
                ...
            } finally {
                //将所有DisplayListOp绘制命令填充到RootRenderNode中
                mRootNode.endRecording();
            }
        }
        ...
        //结束记录"Record View#draw()"的systrace tag
        Trace.traceEnd(Trace.TRACE_TAG_VIEW);
    }

//frameworks/base/core/java/android/view/ThreadedRenderer.java
    private void updateViewTreeDisplayList(View view) {
        ...
        //从DecorView根节点出发,开始递归调用每个View树节点的updateDisplayListIfDirty函数
        view.updateDisplayListIfDirty();
        ...
    }

//frameworks/base/core/java/android/view/View.java
    public RenderNode updateDisplayListIfDirty() {
        final RenderNode renderNode = mRenderNode;
        ...
        if ((mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == 0
                || !renderNode.hasDisplayList()
                || (mRecreateDisplayList)) {
            //如果已经有了DisplayList且不需要重新创建DisplayList
            if (renderNode.hasDisplayList()
                    && !mRecreateDisplayList) {
                ...
                //获取view的DisplayList,DisplayList是一个存储了view绘制所需的绘制命令和属性的数据结构。
                dispatchGetDisplayList();
                ...
                return renderNode; // no work needed
            }
            ...
            //
            if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
                //开始记录"HWUI:"的systrace tag
                Trace.traceBegin(Trace.TRACE_TAG_VIEW, "HWUI:" + getClass().getName());
            }
            //返回一个RecordingCanvas类型的画布
            final RecordingCanvas canvas = renderNode.beginRecording(width, height);
            ...
            try {
                if (layerType == LAYER_TYPE_SOFTWARE) {//软绘
                    ...
                } else {//硬绘
                    ...
                    if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) {
                        //如果仅仅是ViewGroup,并且自身不用绘制,直接递归子View
                        dispatchDraw(canvas);
                        ...
                    } else {
                        //利用RecordingCanvas,在每个子View控件的onDraw绘制函数中调用drawRect等绘制操作时,创建对应的DisplayListOp绘制命令,并缓存记录到其内部的DisplayList持有的DisplayListData中
                        draw(canvas);
                    }
                }
            } finally {
                //将包含有DisplayListOp绘制命令缓存的DisplayList对象设置填充到RenderNode中
                renderNode.endRecording();
                ...
            }
            if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
                //结束记录"HWUI:"的systrace tag
                Trace.traceEnd(Trace.TRACE_TAG_VIEW);
            }
        }
        ...
    }

//frameworks/base/graphics/java/android/graphics/RenderNode.java
    public @NonNull RecordingCanvas beginRecording(int width, int height) {
        ...
        //调用RecordingCanvas的obtain函数,new一个RecordingCanvas对象
        mCurrentRecordingCanvas = RecordingCanvas.obtain(this, width, height);
        return mCurrentRecordingCanvas;
    }

//frameworks/base/core/java/android/view/View.java
    public void draw(@NonNull Canvas canvas) {
        ...
        //draw content view
        onDraw(canvas);
        ...
        //触发子view的draw操作
        dispatchDraw(canvas);
        ...
    }

//frameworks/base/graphics/java/android/graphics/RenderNode.java
    public void endRecording() {
        ...
        RecordingCanvas canvas = mCurrentRecordingCanvas;
        mCurrentRecordingCanvas = null;
        //从SkiaRecordingCanvas中获取SkiaDisplayList对象,并把SkiaDisplayList对象填充到RenderNode中
        canvas.finishRecording(this);
        canvas.recycle();
    }

6.2 执行渲染任务

    UI线程利用RenderProxy向RenderThread线程发送一个DrawFrameTask任务请求,RenderThread被唤醒,开始渲染。Renderthread主要做了以下工作:

  • 递归调用各个子View对应的RenderNode执行prepareTreeImpl函数,实现同步绘制命令树的操作
  • 调用OpenGL库API使用GPU,按照构建好的绘制命令完成界面的渲染
  • 将前面已经绘制渲染好的图形缓冲区Buffer交给SurfaceFlinger合成和显示
//frameworks/base/graphics/java/android/graphics/HardwareRenderer.java
    public int syncAndDrawFrame(@NonNull FrameInfo frameInfo) {
        return nSyncAndDrawFrame(mNativeProxy, frameInfo.frameInfo, frameInfo.frameInfo.length);
    }


//frameworks/base/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
static int android_view_ThreadedRenderer_syncAndDrawFrame(JNIEnv* env, jobject clazz,
                                                          jlong proxyPtr, jlongArray frameInfo,
                                                          jint frameInfoSize) {
    ...
    //UI线程利用RenderProxy向RenderThread线程发送一个DrawFrameTask任务请求,RenderThread被唤醒,开始渲染
    return proxy->syncAndDrawFrame();
}

//frameworks/base/libs/hwui/renderthread/RenderProxy.cpp
int RenderProxy::syncAndDrawFrame() {
    return mDrawFrameTask.drawFrame();
}

//frameworks/base/libs/hwui/renderthread/DrawFrameTask.cpp
int DrawFrameTask::drawFrame() {
    ...
    postAndWait();
    ...
}

//frameworks/base/libs/hwui/renderthread/DrawFrameTask.cpp
void DrawFrameTask::postAndWait() {
    ATRACE_CALL();
    //加锁,确保线程安全
    AutoMutex _lock(mLock);
    //向RenderThread渲染线程的MessageQueue消息队列放入一个待执行任务,以将其唤醒执行run函数
    mRenderThread->queue().post([this]() { run(); });
    //UI线程进入等待状态
    mSignal.wait(mLock);
}

//frameworks/base/libs/hwui/renderthread/DrawFrameTask.cpp
void DrawFrameTask::run() {
    ...
    //帧渲染绘制任务的systrace tag
    ATRACE_FORMAT("DrawFrames %" PRId64, vsyncId);
    ...
    {
        ...
        //将UI线程构建的DisplayListOp绘制命令树同步到RenderThread渲染线程
        canUnblockUiThread = syncFrameState(info);
        ...
    }
    ...
    //同步完成,解锁UI线程
    if (canUnblockUiThread) {
        unblockUiThread();
    }
    ...
    if (CC_LIKELY(canDrawThisFrame)) {
        //执行绘制操作
        context->draw(solelyTextureViewUpdates);
    } else {
        ...
    }
    ...
}

//frameworks/base/libs/hwui/renderthread/DrawFrameTask.cpp
bool DrawFrameTask::syncFrameState(TreeInfo& info) {
    ...
    //同步绘制命令树
    mContext->prepareTree(info, mFrameInfo, mSyncQueued, mTargetNode);
    ...
}

//frameworks/base/libs/hwui/renderthread/CanvasContext.cpp
void CanvasContext::prepareTree(TreeInfo& info, int64_t* uiFrameInfo, int64_t syncQueued,
                                RenderNode* target) {
    ...
    for (const sp<RenderNode>& node : mRenderNodes) {
        ...
        //递归调用各个子View对应的RenderNode执行prepareTree动作
        node->prepareTree(info);
        ...
    }
    ...
}

//frameworks/base/libs/hwui/RenderNode.cpp
void RenderNode::prepareTree(TreeInfo& info) {
    ATRACE_CALL();
    ...
    prepareTreeImpl(observer, info, false);
}

//frameworks/base/libs/hwui/RenderNode.cpp
void RenderNode::prepareTreeImpl(TreeObserver& observer, TreeInfo& info, bool functorsNeedLayer) {
    ...
    //准备layer
    prepareLayer(info, animatorDirtyMask);
    if (info.mode == TreeInfo::MODE_FULL) {
        //同步绘制命令树
        pushStagingDisplayListChanges(observer, info);
    }

    if (mDisplayList) {
        //遍历调用各个子View对应的RenderNode的prepareTreeImpl
        bool isDirty = mDisplayList.prepareListAndChildren(
                observer, info, childFunctorsNeedLayer,
                [this](RenderNode* child, TreeObserver& observer, TreeInfo& info,
                       bool functorsNeedLayer) {
                    child->prepareTreeImpl(observer, info, functorsNeedLayer);
                    mHasHolePunches |= child->hasHolePunches();
                });
        ...
    } else {
        ...
    }
    //更新layer,把layer标识为正在使用的
    pushLayerUpdate(info);
    ...
}

//frameworks/base/libs/hwui/RenderNode.cpp
void RenderNode::pushStagingDisplayListChanges(TreeObserver& observer, TreeInfo& info) {
    if (mNeedsDisplayListSync) {
        ...
        syncDisplayList(observer, &info);
        ...
    }
}

//frameworks/base/libs/hwui/RenderNode.cpp
void RenderNode::syncDisplayList(TreeObserver& observer, TreeInfo* info) {
    ...
    //完成赋值同步DisplayList对象
    mDisplayList = std::move(mStagingDisplayList);
    if (mDisplayList) {
        ...
        mDisplayList.syncContents(syncData);
        ...
    }
}

//frameworks/base/libs/hwui/renderthread/CanvasContext.cpp
void CanvasContext::draw(bool solelyTextureViewUpdates) {
    ...
    {
        //调用OpenGL库使用GPU,按照构建好的绘制命令完成界面的渲染
        drawResult = mRenderPipeline->draw(frame, windowDirty, dirty, mLightGeometry,
                                           &mLayerUpdateQueue, mContentDrawBounds, mOpaque,
                                           mLightInfo, mRenderNodes, &(profiler()), mBufferParams,
                                           profilerLock());
    }
    ...
    //等待GPU完成绘制操作
    waitOnFences();
    ...
    //将前面已经绘制渲染好的图形缓冲区Buffer上帧给SurfaceFlinger合成和显示
    bool didSwap = mRenderPipeline->swapBuffers(frame, drawResult, windowDirty, mCurrentFrameInfo,
                                                &requireSwap);
    ...
    //标记swap buffer已经完成
    mCurrentFrameInfo->markSwapBuffersCompleted();
}

Renderthread绘制过程从systrace上体现如下:

七: Surfaceflinger的合成显示

    surfaceflinger负责接收来自各个应用程序的图形缓冲区(即buffer),并将他们按照特定的规则和优先级进行合成。其合成的时机类似于Choreographer,接收vsync信号来进行合成显示,Choreographer接收的是vsync-app(app类型的vsync信号),surfaceflinger接收的是vsync-sf(sf类型的vsync信号)。下面简单介绍下surfaceflinger是合入管理来自各个应用的buffer的。
surfaceflinger内部有个BufferQueue,字如其名,它就是负责管理Buffer,它的工作流程如下:

  • app通过dequeueBuffer向BufferQueue申请一个可用的buffer,在拿到buffer后进行绘制,绘制完成通过queueBuffer将buffer返回到BufferQueue,并申请sf类型的vsync信号通知surfaceflinger及时进行合成
  • surfaceflinger合成完成后,通过releaseBuffer将BufferQueue置为free状态,更新到BufferQueue中

以上过程在systrace中体现如下:

八:总结

    应用冷启动流程到这里就完成了,优于笔者个人技术及篇幅限制,很多流程没有详细展开,后面会继续更新,出一些系列的文章来尽可能详细的展开描述。应用冷启动具体有哪些优化措施,也会考虑出专项文章。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值