0
点赞
收藏
分享

微信扫一扫

Android 10.0 Launcher桌面启动流程分析

月白色的大狒 2021-09-30 阅读 90
Android

概述

ActivityManagerService的最后启动了Launcher进程,今天我们来真正分析下桌面的启动流程.

[ActivityManagerService.java]

public void systemReady(final Runnable goingCallback, TimingsTraceLog 
traceLog) {
    ...
    //启动Home Activity
    //mAtmInternal 对象是ActivityTaskManagerInternal 抽象类 实现类为ATM的LocalServer对象
    mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");
    ...
}

Launcher的启动主要由三部分完成

  • SystemServer完成启动Launcher Activity的调用
  • Zygote进行Launcher进程的fork操作
  • 进入ActivityThread的main()方法,完成最终Launcher的onCreate操作

接下来我们分别从源码部分来分析这个三个启动过程。

ActivityTaskManagerService.java#startHomeOnAllDisplays()
[ActivityTaskManagerService.java#LocalService.class]

final class LocalService extends ActivityTaskManagerInternal {
             ....................

   @Override
        public boolean startHomeOnAllDisplays(int userId, String reason) {
            synchronized (mGlobalLock) {
                return mRootActivityContainer.startHomeOnAllDisplays(userId, reason);
            }
        }
        .................
}

RootActivityContainer.java#startHomeOnDisplay()
boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting,
            boolean fromHomeKey) {
        // Fallback to top focused display if the displayId is invalid.
        if (displayId == INVALID_DISPLAY) {
            displayId = getTopDisplayFocusedStack().mDisplayId;
        }

        Intent homeIntent = null;
        ActivityInfo aInfo = null;
        if (displayId == DEFAULT_DISPLAY) {
            //构建一个category为CATEGORY_HOME的Intent,表明是Home Activity
            homeIntent = mService.getHomeIntent();
              //通过PackageManagerService从系统已安装的列表中,找到一个符合Home Intent的Activity
            aInfo = resolveHomeActivity(userId, homeIntent);
        } else if (shouldPlaceSecondaryHomeOnDisplay(displayId)) {
            Pair<ActivityInfo, Intent> info = resolveSecondaryHomeActivity(userId, displayId);
            aInfo = info.first;
            homeIntent = info.second;
        }
        if (aInfo == null || homeIntent == null) {
            return false;
        }

        if (!canStartHomeOnDisplay(aInfo, displayId, allowInstrumenting)) {
            return false;
        }

        // Updates the home component of the intent.
        homeIntent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
        homeIntent.setFlags(homeIntent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
        // Updates the extra information of the intent.
        if (fromHomeKey) {
            homeIntent.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY, true);
        }
        // Update the reason for ANR debugging to verify if the user activity is the one that
        // actually launched.
        final String myReason = reason + ":" + userId + ":" + UserHandle.getUserId(
                aInfo.applicationInfo.uid) + ":" + displayId;
          
 //启动Home Activity
mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,
                displayId);
        return true;
    }
ActivityStartController.java#startHomeActivity()

正在启动Home Activity入口。obtainStarter() 方法返回的是 ActivityStarter 对象,它负责 Activity 的启动,一系列 setXXX() 方法传入启动所需的各种参数,最后的 execute() 是真正的启动逻辑。另外如果home activity处于顶层的resume activity中,则Home Activity 将被初始化,但不会被恢复。并将保持这种状态,直到有东西再次触发它。我们需要进行另一次恢复

void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason, int displayId) {
    ....
    //返回一个 ActivityStarter 对象,它负责 Activity 的启动
    //一系列 setXXX() 方法传入启动所需的各种参数,最后的 execute() 是真正的启动逻辑
    //最后执行 ActivityStarter的execute方法
    mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason)
            .setOutActivity(tmpOutRecord)
            .setCallingUid(0)
            .setActivityInfo(aInfo)
            .setActivityOptions(options.toBundle())
            .execute();  
    mLastHomeActivityStartRecord = tmpOutRecord[0];
    final ActivityDisplay display =
            mService.mRootActivityContainer.getActivityDisplay(displayId);
    final ActivityStack homeStack = display != null ? display.getHomeStack() : null;
 
    if (homeStack != null && homeStack.mInResumeTopActivity) {
        //如果home activity 处于顶层的resume activity中,则Home Activity 将被初始化,但不会被恢复(以避免递归恢复),
        //并将保持这种状态,直到有东西再次触发它。我们需要进行另一次恢复。
        mSupervisor.scheduleResumeTopActivities();
    }
}
ActivityStarter.java#execute()

ObtainStarter没有调用setMayWait的方法,因此mRequest.mayWait为false,走startActivity流程

int execute() {
    ...
    if (mRequest.mayWait) {
        return startActivityMayWait(...)
    } else {
         return startActivity(...) 
    }
    ...
}
ActivityStarter.java#startActivity()

延时布局,然后通过startActivityUnchecked()来处理启动标记flag,要启动的任务栈,最后恢复布局

private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity, boolean restrictedBgActivity) {
    ...
    try {
        //延时布局
        mService.mWindowManager.deferSurfaceLayout();
        //调用 startActivityUnchecked ,一路调用到resumeFocusedStacksTopActivities(),
        result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
                startFlags, doResume, options, inTask, outActivity, restrictedBgActivity);
    } finally {
        //恢复布局
        mService.mWindowManager.continueSurfaceLayout();
    }
    ...
}
RootActivityContainer.java#resumeFocusedStacksTopActivities
boolean resumeFocusedStacksTopActivities(
        ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
    ...
    //如果秒表栈就是栈顶Activity,启动resumeTopActivityUncheckedLocked()
    if (targetStack != null && (targetStack.isTopStackOnDisplay()
        || getTopDisplayFocusedStack() == targetStack)) {
    result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
    ...
    if (!resumedOnDisplay) {
        // 获取  栈顶的 ActivityRecord
        final ActivityStack focusedStack = display.getFocusedStack();
        if (focusedStack != null) {
            //最终调用startSpecificActivityLocked()
            focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
        }
    }
  }
}
ActivityStackSupervisor.java#startSpecificActivityLocked

发布消息以启动进程,避免在ATM锁保持的情况下调用AMS时可能出现死锁,最终调用到ATM的startProcess()

void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
    ...
    //发布消息以启动进程,以避免在ATM锁保持的情况下调用AMS时可能出现死锁
    //最终调用到AMS的startProcess(),
    final Message msg = PooledLambda.obtainMessage(
            ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
            r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());
    mService.mH.sendMessage(msg);
    ...
}
ActivityManagerService.java#startProcess()

一路调用Process.start()最终到ZygoteProcess的attempUsepSendArgsAndGetResult(),用来fork一个新的Launcher进程。

[ActivityManagerService.java#LocalServer.class]

 @Override
        public void startProcess(String processName, ApplicationInfo info,
                boolean knownToBeDead, String hostingType, ComponentName hostingName) {
            try {
                if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "startProcess:"
                            + processName);
                }
                synchronized (ActivityManagerService.this) {
                    //注释1
                    startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,
                            new HostingRecord(hostingType, hostingName),
                            false /* allowWhileBooting */, false /* isolated */,
                            true /* keepIfLarge */);
                }
            } finally {
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            }
        }


   @GuardedBy("this")
    final ProcessRecord startProcessLocked(String processName,
            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
            HostingRecord hostingRecord, boolean allowWhileBooting,
            boolean isolated, boolean keepIfLarge) {
                //注释2
        return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
                hostingRecord, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
                null /* crashHandler */);
    }


ProcessList.java#startProcessLocked()
@GuardedBy("mService")
    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
            boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord,
            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
             ............................

        checkSlow(startTime, "startProcess: stepping in to startProcess");
          
        final boolean success = startProcessLocked(app, hostingRecord, abiOverride);
        checkSlow(startTime, "startProcess: done starting proc!");
        return success ? app : null;
    }


@GuardedBy("mService")
    final boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
            String abiOverride) {
        return startProcessLocked(app, hostingRecord,
                false /* disableHiddenApiChecks */, false /* mountExtStorageFull */, abiOverride);
    }


  /**
     * @return {@code true} if process start is successful, false otherwise.
     * @param app
     * @param hostingRecord
     * @param disableHiddenApiChecks
     * @param abiOverride
     */
    @GuardedBy("mService")
    boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
            boolean disableHiddenApiChecks, boolean mountExtStorageFull,
            String abiOverride) {
             ........................
            // Start the process.  It will either succeed and return a result containing
            // the PID of the new process, or else throw a RuntimeException.
               // 1重要 
            final String entryPoint = "android.app.ActivityThread";
             
            return startProcessLocked(hostingRecord, entryPoint, app, uid, gids,
                    runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
                    startTime);
        } catch (RuntimeException e) {
            Slog.e(ActivityManagerService.TAG, "Failure starting process " + app.processName, e);

            // Something went very wrong while trying to start this process; one
            // common case is when the package is frozen due to an active
            // upgrade. To recover, clean up any active bookkeeping related to
            // starting this process. (We already invoked this method once when
            // the package was initially frozen through KILL_APPLICATION_MSG, so
            // it doesn't hurt to use it again.)
            mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
                    false, false, true, false, false, app.userId, "start failure");
            return false;
        }
    }


 @GuardedBy("mService")
    boolean startProcessLocked(HostingRecord hostingRecord,
            String entryPoint,
            ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
            String seInfo, String requiredAbi, String instructionSet, String invokeWith,
            long startTime) {
        app.pendingStart = true;
        app.killedByAm = false;
        app.removed = false;
        app.killed = false;
        if (app.startSeq != 0) {
            Slog.wtf(TAG, "startProcessLocked processName:" + app.processName
                    + " with non-zero startSeq:" + app.startSeq);
        }
        if (app.pid != 0) {
            Slog.wtf(TAG, "startProcessLocked processName:" + app.processName
                    + " with non-zero pid:" + app.pid);
        }
        final long startSeq = app.startSeq = ++mProcStartSeqCounter;
        app.setStartParams(uid, hostingRecord, seInfo, startTime);
        app.setUsingWrapper(invokeWith != null
                || SystemProperties.get("wrap." + app.processName) != null);
        mPendingStarts.put(startSeq, app);

        if (mService.mConstants.FLAG_PROCESS_START_ASYNC) {
            if (DEBUG_PROCESSES) Slog.i(TAG_PROCESSES,
                    "Posting procStart msg for " + app.toShortString());
            mService.mProcStartHandler.post(() -> {
                try {
                    //注释2
                    final Process.ProcessStartResult startResult = startProcess(app.hostingRecord,
                            entryPoint, app, app.startUid, gids, runtimeFlags, mountExternal,
                            app.seInfo, requiredAbi, instructionSet, invokeWith, app.startTime);
                    synchronized (mService) {
                        handleProcessStartedLocked(app, startResult, startSeq);
                    }
                } catch (RuntimeException e) {
                    synchronized (mService) {
                        Slog.e(ActivityManagerService.TAG, "Failure starting process "
                                + app.processName, e);
                        mPendingStarts.remove(startSeq);
                        app.pendingStart = false;
                        mService.forceStopPackageLocked(app.info.packageName,
                                UserHandle.getAppId(app.uid),
                                false, false, true, false, false, app.userId, "start failure");
                    }
                }
            });
            return true;
        } else {
            try {
                final Process.ProcessStartResult startResult = startProcess(hostingRecord,
                        entryPoint, app,
                        uid, gids, runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet,
                        invokeWith, startTime);
                handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
                        startSeq, false);
            } catch (RuntimeException e) {
                Slog.e(ActivityManagerService.TAG, "Failure starting process "
                        + app.processName, e);
                app.pendingStart = false;
                mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
                        false, false, true, false, false, app.userId, "start failure");
            }
            return app.pid > 0;
        }
    }


private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,
            ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
            String seInfo, String requiredAbi, String instructionSet, String invokeWith,
            long startTime) {
        try {
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
                    app.processName);
            checkSlow(startTime, "startProcess: asking zygote to start proc");
            final Process.ProcessStartResult startResult;
            if (hostingRecord.usesWebviewZygote()) {
                startResult = startWebView(entryPoint,
                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                        app.info.dataDir, null, app.info.packageName,
                        new String[] {PROC_START_SEQ_IDENT + app.startSeq});
            } else if (hostingRecord.usesAppZygote()) {
                final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app);

                startResult = appZygote.getProcess().start(entryPoint,
                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                        app.info.dataDir, null, app.info.packageName,
                        /*useUsapPool=*/ false,
                        new String[] {PROC_START_SEQ_IDENT + app.startSeq});
            } else {
                   //注释3
                startResult = Process.start(entryPoint,
                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                        app.info.dataDir, invokeWith, app.info.packageName,
                        new String[] {PROC_START_SEQ_IDENT + app.startSeq});
            }
            checkSlow(startTime, "startProcess: returned from zygote!");
            return startResult;
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        }
    }

注释1处初始化了entryPoint的值为android.app.ActivityThread,这就是我们应用程序的入口,执行这个类的main方法。

Process.java#start()

  public static ProcessStartResult start(@NonNull final String processClass,
                                           @Nullable final String niceName,
                                           int uid, int gid, @Nullable int[] gids,
                                           int runtimeFlags,
                                           int mountExternal,
                                           int targetSdkVersion,
                                           @Nullable String seInfo,
                                           @NonNull String abi,
                                           @Nullable String instructionSet,
                                           @Nullable String appDataDir,
                                           @Nullable String invokeWith,
                                           @Nullable String packageName,
                                           @Nullable String[] zygoteArgs) {
        //注释1
        return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids,
                    runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                    abi, instructionSet, appDataDir, invokeWith, packageName,
                    /*useUsapPool=*/ true, zygoteArgs);
    }

ZygoteProcess.java#start()

 public final Process.ProcessStartResult start(@NonNull final String processClass,
                                                  final String niceName,
                                                  int uid, int gid, @Nullable int[] gids,
                                                  int runtimeFlags, int mountExternal,
                                                  int targetSdkVersion,
                                                  @Nullable String seInfo,
                                                  @NonNull String abi,
                                                  @Nullable String instructionSet,
                                                  @Nullable String appDataDir,
                                                  @Nullable String invokeWith,
                                                  @Nullable String packageName,
                                                  boolean useUsapPool,
                                                  @Nullable String[] zygoteArgs) {
        // TODO (chriswailes): Is there a better place to check this value?
        if (fetchUsapPoolEnabledPropWithMinInterval()) {
            informZygotesOfUsapPoolStatus();
        }

        try {
              
            return startViaZygote(processClass, niceName, uid, gid, gids,
                    runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                    abi, instructionSet, appDataDir, invokeWith, /*startChildZygote=*/ false,
                    packageName, useUsapPool, zygoteArgs);
        } catch (ZygoteStartFailedEx ex) {
            Log.e(LOG_TAG,
                    "Starting VM process through Zygote failed");
            throw new RuntimeException(
                    "Starting VM process through Zygote failed", ex);
        }
    }


 private Process.ProcessStartResult startViaZygote(@NonNull final String processClass,
                                                      @Nullable final String niceName,
                                                      final int uid, final int gid,
                                                      @Nullable final int[] gids,
                                                      int runtimeFlags, int mountExternal,
                                                      int targetSdkVersion,
                                                      @Nullable String seInfo,
                                                      @NonNull String abi,
                                                      @Nullable String instructionSet,
                                                      @Nullable String appDataDir,
                                                      @Nullable String invokeWith,
                                                      boolean startChildZygote,
                                                      @Nullable String packageName,
                                                      boolean useUsapPool,
                                                      @Nullable String[] extraArgs)
                                                      throws ZygoteStartFailedEx {
        ArrayList<String> argsForZygote = new ArrayList<>();

        // --runtime-args, --setuid=, --setgid=,
        // and --setgroups= must go first
        argsForZygote.add("--runtime-args");
        argsForZygote.add("--setuid=" + uid);
        argsForZygote.add("--setgid=" + gid);
        argsForZygote.add("--runtime-flags=" + runtimeFlags);
        if (mountExternal == Zygote.MOUNT_EXTERNAL_DEFAULT) {
            argsForZygote.add("--mount-external-default");
        } else if (mountExternal == Zygote.MOUNT_EXTERNAL_READ) {
            argsForZygote.add("--mount-external-read");
        } else if (mountExternal == Zygote.MOUNT_EXTERNAL_WRITE) {
            argsForZygote.add("--mount-external-write");
        } else if (mountExternal == Zygote.MOUNT_EXTERNAL_FULL) {
            argsForZygote.add("--mount-external-full");
        } else if (mountExternal == Zygote.MOUNT_EXTERNAL_INSTALLER) {
            argsForZygote.add("--mount-external-installer");
        } else if (mountExternal == Zygote.MOUNT_EXTERNAL_LEGACY) {
            argsForZygote.add("--mount-external-legacy");
        }

        argsForZygote.add("--target-sdk-version=" + targetSdkVersion);

        // --setgroups is a comma-separated list
        if (gids != null && gids.length > 0) {
            StringBuilder sb = new StringBuilder();
            sb.append("--setgroups=");

            int sz = gids.length;
            for (int i = 0; i < sz; i++) {
                if (i != 0) {
                    sb.append(',');
                }
                sb.append(gids[i]);
            }

            argsForZygote.add(sb.toString());
        }

        if (niceName != null) {
            argsForZygote.add("--nice-name=" + niceName);
        }

        if (seInfo != null) {
            argsForZygote.add("--seinfo=" + seInfo);
        }

        if (instructionSet != null) {
            argsForZygote.add("--instruction-set=" + instructionSet);
        }

        if (appDataDir != null) {
            argsForZygote.add("--app-data-dir=" + appDataDir);
        }

        if (invokeWith != null) {
            argsForZygote.add("--invoke-with");
            argsForZygote.add(invokeWith);
        }

        if (startChildZygote) {
            argsForZygote.add("--start-child-zygote");
        }

        if (packageName != null) {
            argsForZygote.add("--package-name=" + packageName);
        }

        argsForZygote.add(processClass);

        if (extraArgs != null) {
            Collections.addAll(argsForZygote, extraArgs);
        }

        synchronized(mLock) {
            // The USAP pool can not be used if the application will not use the systems graphics
            // driver.  If that driver is requested use the Zygote application start path.
            return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),
                                              useUsapPool,
                                              argsForZygote);
        }
    }

/**
     * Sends an argument list to the zygote process, which starts a new child
     * and returns the child's pid. Please note: the present implementation
     * replaces newlines in the argument list with spaces.
     *
     * @throws ZygoteStartFailedEx if process start failed for any reason
     */
    @GuardedBy("mLock")
    private Process.ProcessStartResult zygoteSendArgsAndGetResult(
            ZygoteState zygoteState, boolean useUsapPool, @NonNull ArrayList<String> args)
            throws ZygoteStartFailedEx {
        // Throw early if any of the arguments are malformed. This means we can
        // avoid writing a partial response to the zygote.
        for (String arg : args) {
            // Making two indexOf calls here is faster than running a manually fused loop due
            // to the fact that indexOf is a optimized intrinsic.
            if (arg.indexOf('\n') >= 0) {
                throw new ZygoteStartFailedEx("Embedded newlines not allowed");
            } else if (arg.indexOf('\r') >= 0) {
                throw new ZygoteStartFailedEx("Embedded carriage returns not allowed");
            }
        }

        /*
         * See com.android.internal.os.ZygoteArguments.parseArgs()
         * Presently the wire format to the zygote process is:
         * a) a count of arguments (argc, in essence)
         * b) a number of newline-separated argument strings equal to count
         *
         * After the zygote process reads these it will write the pid of
         * the child or -1 on failure, followed by boolean to
         * indicate whether a wrapper process was used.
         */
        String msgStr = args.size() + "\n" + String.join("\n", args) + "\n";

        if (useUsapPool && mUsapPoolEnabled && canAttemptUsap(args)) {
            try {
                return attemptUsapSendArgsAndGetResult(zygoteState, msgStr);
            } catch (IOException ex) {
                // If there was an IOException using the USAP pool we will log the error and
                // attempt to start the process through the Zygote.
                Log.e(LOG_TAG, "IO Exception while communicating with USAP pool - "
                        + ex.getMessage());
            }
        }

        return attemptZygoteSendArgsAndGetResult(zygoteState, msgStr);
    }


ZygoteProcess.java#attemptZygoteSendArgsAndGetResult()

通过Socket连接Zygote进程,把之前组装的msg发给Zygote,其中processClass="android.app.ActivityThread",通过Zygote进程fork出一个新的进程,并执行"android.app.ActivityThread"的main方法。

private Process.ProcessStartResult attemptZygoteSendArgsAndGetResult(
        ZygoteState zygoteState, String msgStr) throws ZygoteStartFailedEx {
    try {
        //传入的zygoteState为openZygoteSocketIfNeeded(),里面会通过abi来检查是第一个zygote还是第二个
        final BufferedWriter zygoteWriter = zygoteState.mZygoteOutputWriter;
        final DataInputStream zygoteInputStream = zygoteState.mZygoteInputStream;
 
        zygoteWriter.write(msgStr);  //把应用进程的一些参数写给前面连接的zygote进程,包括前面的processClass ="android.app.ActivityThread"
        zygoteWriter.flush(); //进入Zygote进程,处于阻塞状态
         //从socket中得到zygote创建的应用pid,赋值给 ProcessStartResult的对象
        Process.ProcessStartResult result = new Process.ProcessStartResult();
        result.pid = zygoteInputStream.readInt();
        result.usingWrapper = zygoteInputStream.readBoolean();
 
        if (result.pid < 0) {
            throw new ZygoteStartFailedEx("fork() failed");
        }
 
        return result;
    } catch (IOException ex) {
        zygoteState.close();
        Log.e(LOG_TAG, "IO Exception while communicating with Zygote - "
                + ex.toString());
        throw new ZygoteStartFailedEx(ex);
    }
}

第二阶段Zygote fork一个Launcher进程

Zygote的启动过程我们前面有详细讲到过。SystemServer的AMS服务向启动Home Activity发起一个fork请求,Zygote进程通过Linux的fork函数,孵化出一个新的进程。由于Zygote进程在启动时会创建Java虚拟机,因此通过fork而创建的Launcher程序进程可以在内部获取一个Java虚拟机的实例拷贝。fork采用copy-on-write机制,有些类如果不做改变,甚至都不用复制,子进程可以和父进程共享这部分数据,从而省去不少内存的占用。

ZygoteInit.java#main()

Zygote先fork出SystemServer,接着进入循环等待,用来接收Socket发来的消息,用来fork出其他应用进程。比如Launcher

public static void main(String argv[]) {
    ...
    Runnable caller;
    ....
    if (startSystemServer) {
        //Zygote Fork出的第一个进程 SystmeServer
        Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
 
        if (r != null) {
            r.run();
            return;
        }
    }
    ...
    //循环等待fork出其他的应用进程,比如Launcher
    //最终通过调用processOneCommand()来进行进程的处理
    caller = zygoteServer.runSelectLoop(abiList);
    ...
    if (caller != null) {
        caller.run(); //执行返回的Runnable对象,进入子进程
    }
}

ZygoteConnection.java#processOneCommand()

通过forkAndSpecialize()来fork出Launcher的子进程,并执行handleChildProc,进入子进程的处理

Runnable processOneCommand(ZygoteServer zygoteServer) {
    int pid = -1;
    ...
    //Fork子进程,得到一个新的pid
    /fork子进程,采用copy on write方式,这里执行一次,会返回两次
    ///pid=0 表示Zygote  fork子进程成功
    //pid > 0 表示子进程 的真正的PID
    pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids,
            parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo,
            parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,
            parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mTargetSdkVersion);
    ...
    if (pid == 0) {
        // in child, fork成功,第一次返回的pid = 0
        ...
      
        return handleChildProc(parsedArgs, descriptors, childPipeFd,
                parsedArgs.mStartChildZygote);
    } else {
        //in parent
        ...
        childPipeFd = null;
        handleParentProc(pid, descriptors, serverPipeFd);
        return null;
    }
}

ZygoteConneciton.java#handleChildProc()

进行子进程的操作,最终获得需要执行的ActivityThread的main()

private Runnable handleChildProc(ZygoteArguments parsedArgs, FileDescriptor[] descriptors,
        FileDescriptor pipeFd, boolean isZygote) {
    ...
    if (parsedArgs.mInvokeWith != null) {
        ...
        throw new IllegalStateException("WrapperInit.execApplication unexpectedly returned");
    } else {
        if (!isZygote) {
            // App进程将会调用到这里,执行目标类的main()方法
            return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
                    parsedArgs.mRemainingArgs, null /* classLoader */);
        } else {
            return ZygoteInit.childZygoteInit(parsedArgs.mTargetSdkVersion,
                    parsedArgs.mRemainingArgs, null /* classLoader */);
        }
    }
}

ZygoteInit进行一些环境的初始化,启动Binder进程等操作

public static final Runnable zygoteInit(int targetSdkVersion, String[] argv,
        ClassLoader classLoader) {
    RuntimeInit.commonInit(); //初始化运行环境 
    ZygoteInit.nativeZygoteInit(); //启动Binder线程池 
     //调用程序入口函数  
    return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}

把之前传来的"android.app.ActivityThread"传给findStaticMain:

protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
        ClassLoader classLoader) {
    ...
    // startClass: 如果AMS通过socket传递过来的是 ActivityThread
    return findStaticMain(args.startClass, args.startArgs, classLoader);
}

通过反射,拿到ActivityThread的main()方法:

protected static Runnable findStaticMain(String className, String[] argv,
        ClassLoader classLoader) {
    Class<?> cl;
 
    try {
        cl = Class.forName(className, true, classLoader);
    } catch (ClassNotFoundException ex) {
        throw new RuntimeException(
                "Missing class when invoking static main " + className,
                ex);
    }
 
    Method m;
    try {
        m = cl.getMethod("main", new Class[] { String[].class });
    } catch (NoSuchMethodException ex) {
        throw new RuntimeException(
                "Missing static main on " + className, ex);
    } catch (SecurityException ex) {
        throw new RuntimeException(
                "Problem getting static main on " + className, ex);
    }
 
    int modifiers = m.getModifiers();
    if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
        throw new RuntimeException(
                "Main method is not public and static on " + className);
    }
    return new MethodAndArgsCaller(m, argv);
}

把反射得来的ActivityThread main入口返回给ZygoteInit的main,通过caller.run()进行调用.

第三个阶段,Launcher在自己的进程中进行onCreate等后面的动作

从上面可知,Zygote fork出Launcher的进程,并把接下来的Launcher启动任务交给了ActivityThread来进行,接下来我们可以从ActivityThread main方法来分析Launcher的创建过程。

ActivityThread.java #main()

主线程处理,创建ActivityThread对象,调用attach进行处理,最终进入Looper循环

public static void main(String[] args) {
    // 安装选择性的系统调用拦截
    AndroidOs.install();
  ...
  //主线程处理
    Looper.prepareMainLooper();
  ...
  
  //之前SystemServer调用attach传入的是true,这里到应用进程传入false就行
    ActivityThread thread = new ActivityThread();
    thread.attach(false, startSeq);
  ...
  //一直循环,如果退出,说明程序关闭
    Looper.loop();
 
    throw new RuntimeException("Main thread loop unexpectedly exited");
}

调用ActivityThread的attach进行处理

private void attach(boolean system, long startSeq) {
  sCurrentActivityThread = this;
  mSystemThread = system;
  if (!system) {
    //应用进程启动,走该流程
    ...
    RuntimeInit.setApplicationObject(mAppThread.asBinder());
     //获取AMS的本地代理类
    final IActivityManager mgr = ActivityManager.getService();
    try {
      //通过Binder调用AMS的attachApplication方法
      mgr.attachApplication(mAppThread, startSeq);
    } catch (RemoteException ex) {
      throw ex.rethrowFromSystemServer();
    }
    ...
  } else {
    //通过system_server启动ActivityThread对象
    ...
  }
 
  // 为 ViewRootImpl 设置配置更新回调,
  当系统资源配置(如:系统字体)发生变化时,通知系统配置发生变化
  ViewRootImpl.ConfigChangedCallback configChangedCallback
      = (Configuration globalConfig) -> {
    synchronized (mResourcesManager) {
      ...
    }
  };
  ViewRootImpl.addConfigCallback(configChangedCallback);
}

ActivityManagerService.java#attachApplicaiton()

清除一些无用的记录,最终调用ActivityStackSupervisor.java的realStartActivityLocked,进行Activity的启动

public final void attachApplication(IApplicationThread thread, long startSeq) {
    synchronized (this) {
    //通过Binder获取传入的pid信息
        int callingPid = Binder.getCallingPid();
        final int callingUid = Binder.getCallingUid();
        final long origId = Binder.clearCallingIdentity();
        attachApplicationLocked(thread, callingPid, callingUid, startSeq);
        Binder.restoreCallingIdentity(origId);
    }
}
public ActivityTaskManagerInternal mAtmInternal;
private final boolean attachApplicationLocked(IApplicationThread thread,
        int pid, int callingUid, long startSeq) {
  ...
    //如果当前的Application记录仍然依附到之前的进程中,则清理掉
    if (app.thread != null) {
        handleAppDiedLocked(app, true, true);
    }·
 
    //mProcessesReady这个变量在AMS的 systemReady 中被赋值为true,
    //所以这里的normalMode也为true
    boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
  ...
    //上面说到,这里为true,进入StackSupervisor的attachApplication方法
    //去真正启动Activity
    if (normalMode) {
    ...
      //调用ATM的attachApplication(),最终层层调用到ActivityStackSupervisor.java的 realStartActivityLocked()
      //
            didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
    ...
    }
  ...
    return true;
}
[ActivityTaskManagerService.java # LocalServer.class]

 @HotPath(caller = HotPath.PROCESS_CHANGE)
        @Override
        public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
            synchronized (mGlobalLockWithoutBoost) {
                return mRootActivityContainer.attachApplication(wpc);
            }
        }

[RootActivityContainer.java #attachApplicaton()]

boolean attachApplication(WindowProcessController app) throws RemoteException {
        final String processName = app.mName;
        boolean didSomething = false;
        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
            final ActivityDisplay display = mActivityDisplays.get(displayNdx);
            final ActivityStack stack = display.getFocusedStack();
            if (stack != null) {
                stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList);
                final ActivityRecord top = stack.topRunningActivityLocked();
                final int size = mTmpActivityList.size();
                for (int i = 0; i < size; i++) {
                    final ActivityRecord activity = mTmpActivityList.get(i);
                    if (activity.app == null && app.mUid == activity.info.applicationInfo.uid
                            && processName.equals(activity.processName)) {
                        try {
                                //1
                            if (mStackSupervisor.realStartActivityLocked(activity, app,
                                    top == activity /* andResume */, true /* checkConfig */)) {
                                didSomething = true;
                            }
                        } catch (RemoteException e) {
                            Slog.w(TAG, "Exception in new application when starting activity "
                                    + top.intent.getComponent().flattenToShortString(), e);
                            throw e;
                        }
                    }
                }
            }
        }
        if (!didSomething) {
            ensureActivitiesVisible(null, 0, false /* preserve_windows */);
        }
        return didSomething;
    }


  [ActivityStackSupervisor.java#realStartActivityLocked()]

boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
        boolean andResume, boolean checkConfig) throws RemoteException {
     // 直到所有的 onPause() 执行结束才会去启动新的 activity
    if (!mRootActivityContainer.allPausedActivitiesComplete()) {
    ...
        return false;
    }
  try {
            // Create activity launch transaction.
            // 添加 LaunchActivityItem
            final ClientTransaction clientTransaction = ClientTransaction.obtain(
                    proc.getThread(), r.appToken);
      //LaunchActivityItem.obtain(new Intent(r.intent)作为回调参数
            clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                    System.identityHashCode(r), r.info,
                    // TODO: Have this take the merged configuration instead of separate global
                    // and override configs.
                    mergedConfiguration.getGlobalConfiguration(),
                    mergedConfiguration.getOverrideConfiguration(), r.compat,
                    r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
                    r.icicle, r.persistentState, results, newIntents,
                    dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
                            r.assistToken));
 
      ...
      // 设置生命周期状态
            final ActivityLifecycleItem lifecycleItem;
            if (andResume) {
                lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
            } else {
                lifecycleItem = PauseActivityItem.obtain();
            }
            clientTransaction.setLifecycleStateRequest(lifecycleItem);
 
            // Schedule transaction.
            // 重点关注:调用 ClientLifecycleManager.scheduleTransaction(),得到上面addCallback的LaunchActivityItem的execute()方法

            mService.getLifecycleManager().scheduleTransaction(clientTransaction);
 
        } catch (RemoteException e) {
            if (r.launchFailed) {
                 // 第二次启动失败,finish activity
                stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
                        "2nd-crash", false);
                return false;
            }
            // 第一次失败,重启进程并重试
            r.launchFailed = true;
            proc.removeActivity(r);
            throw e;
        }
    } finally {
        endDeferResume();
    }
  ...
    return true;
}
TransactionExecutor.java#execute()

执行之前realStartActivityLocked中的clientTransaction.addCallBack

public void execute(ClientTransaction transaction) {
  ...
     // 执行 callBack,参考上面的调用栈,执行回调方法,
   //最终调用到ActivityThread的handleLaunchActivity()
    executeCallbacks(transaction);
 
     // 执行生命周期状态
    executeLifecycleState(transaction);
    mPendingActions.clear();
}
ActivityThread.java#handleLaunchActivity()

主要时干了两件事,第一件:初始化WindowManagerGlobal;第二件:调用performLaunchActivity方法


public Activity handleLaunchActivity(ActivityClientRecord r,
        PendingTransactionActions pendingActions, Intent customIntent) {
  ...
  //初始化WindowManagerGlobal
    WindowManagerGlobal.initialize();
  ...
  //调用performLaunchActivity,来处理Activity
    final Activity a = performLaunchActivity(r, customIntent);
  ..
    return a;

ActivityThread.java#perfromLaunchActivity

获取ComponentName,Context,反射创建Activity,设置Activity的一些内容,比如主题等;最终调用callActivityOnCreate()来执行Activity的onCreate方法

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
     // 获取 ComponentName
    ComponentName component = r.intent.getComponent();
  ...
     // 获取 Context
    ContextImpl appContext = createBaseContextForActivity(r);
    Activity activity = null;
    try {
         // 反射创建 Activity
        java.lang.ClassLoader cl = appContext.getClassLoader();
        activity = mInstrumentation.newActivity(
                cl, component.getClassName(), r.intent);
        StrictMode.incrementExpectedActivityCount(activity.getClass());
        r.intent.setExtrasClassLoader(cl);
        r.intent.prepareToEnterProcess();
        if (r.state != null) {
            r.state.setClassLoader(cl);
        }
    } catch (Exception e) {
    ...
    }
 
    try {
        // 获取 Application
        Application app = r.packageInfo.makeApplication(false, mInstrumentation);
        if (activity != null) {
      ...
      //Activity的一些处理
            activity.attach(appContext, this, getInstrumentation(), r.token,
                    r.ident, app, r.intent, r.activityInfo, title, r.parent,
                    r.embeddedID, r.lastNonConfigurationInstances, config,
                    r.referrer, r.voiceInteractor, window, r.configCallback,
                    r.assistToken);
 
            if (customIntent != null) {
                activity.mIntent = customIntent;
            }
      ...
            int theme = r.activityInfo.getThemeResource();
            if (theme != 0) {
              // 设置主题
                activity.setTheme(theme);
            }
 
            activity.mCalled = false;
            // 执行 onCreate()
            if (r.isPersistable()) {
                mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
            } else {
                mInstrumentation.callActivityOnCreate(activity, r.state);
            }
      ...
            r.activity = activity;
        }
    //当前状态为ON_CREATE
        r.setState(ON_CREATE);
    ...
    } catch (SuperNotCalledException e) {
        throw e;
    } catch (Exception e) {
    ...
    }
    return activity;
}

callActivityOnCreate先执行activity onCreate的预处理,再去调用Activity的onCreate,最终完成Create创建后的内容处理

public void callActivityOnCreate(Activity activity, Bundle icicle,
        PersistableBundle persistentState) {
    prePerformCreate(activity); //activity onCreate的预处理
    activity.performCreate(icicle, persistentState);//执行onCreate()
    postPerformCreate(activity); //activity onCreate创建后的一些信息处理
}

performCreate主要调用Activity的onCreate()

final void performCreate(Bundle icicle, PersistableBundle persistentState) {
  ...
    if (persistentState != null) {
        onCreate(icicle, persistentState);
    } else {
        onCreate(icicle);
    }
  ...
}

至此,看到了我们最熟悉的Activity的onCreate(),Launcher的启动完成,Launcher被真正创建起来。

总结

看到onCreate()后,进入到我们最熟悉的Activity的入口,Launcher的启动告一段落。整个Android的启动流程,我们也完整的分析完成。

Launcher的启动经过了三个阶段:

  • 第一个阶段:SystemServer完成启动Launcher Activity的调用。

  • 第二个阶段:Zygote()进行Launcher进程的Fork操作。

  • 第三个阶段:进入ActivityThread的main(),完成最终Launcher的onCreate操作。

举报

相关推荐

0 条评论