根Activity的启动流程(基于Android 11.0)

前面我们分析了普通Activity的启动流程,下面我们接着分析根Activity的启动流程,根Activity的启动流程相对更加复杂,里面涉及到应用进程的创建过程。

Launcher调起ATMS

根Activity的启动流程的起点是从点击Launcher上一个未启动的应用的图标开始的。

Launcher是系统的桌面,它也是一个应用,它通过PackageManagerService来获取已安装的所有应用程序的信息,然后通过列表的形式展示出来。

Launcher的源码在//packages/apps/Launcher3路径下,点击桌面上某个应用的图标会调用com.android.launcher3.touch包路径下的ItemClickHandler的onClick()方法:

java 复制代码
public class ItemClickHandler {

    private static void onClick(View v, String sourceContainer) {
        // Make sure that rogue clicks don't get through while allapps is launching, or after the
        // view has detached (it's possible for this to happen if the view is removed mid touch).
        if (v.getWindowToken() == null) return;

        Launcher launcher = Launcher.getLauncher(v.getContext());
        if (!launcher.getWorkspace().isFinishedSwitchingState()) return;

        Object tag = v.getTag();
        if (tag instanceof WorkspaceItemInfo) {
            onClickAppShortcut(v, (WorkspaceItemInfo) tag, launcher, sourceContainer);
        } else if (tag instanceof FolderInfo) {
            if (v instanceof FolderIcon) {
                onClickFolderIcon(v);
            }
        } else if (tag instanceof AppInfo) {
            //点击应用图标的跳转入口
            startAppShortcutOrInfoActivity(v, (AppInfo) tag, launcher,
                    sourceContainer == null ? CONTAINER_ALL_APPS: sourceContainer);
        } else if (tag instanceof LauncherAppWidgetInfo) {
            if (v instanceof PendingAppWidgetHostView) {
                onClickPendingWidget((PendingAppWidgetHostView) v, launcher);
            }
        }
    }
    
    private static void startAppShortcutOrInfoActivity(View v, ItemInfo item, Launcher launcher,
            @Nullable String sourceContainer) {
        ...
        launcher.startActivitySafely(v, intent, item, sourceContainer);
    }
}

startAppShortcutOrInfoActivity()方法调用了Launcher的startActivitySafely()方法:

java 复制代码
public class Launcher extends StatefulActivity<LauncherState> implements LauncherExterns,
        Callbacks, InvariantDeviceProfile.OnIDPChangeListener, PluginListener<OverlayPlugin>,
        LauncherOverlayCallbacks {
        
    @Override
    public boolean startActivitySafely(View v, Intent intent, ItemInfo item) {
        ...
        boolean success = super.startActivitySafely(v, intent, item);
        ...
        return success;
    }
}

里面调用了Launcher的父类的父类(BaseDraggingActivity)的startActivitySafely()方法:

java 复制代码
public abstract class BaseDraggingActivity extends BaseActivity
        implements OnColorsChangedListener, DisplayInfoChangeListener {

	 public boolean startActivitySafely(View v, Intent intent, @Nullable ItemInfo item) {
        ...
        startActivity(intent, optsBundle);
        ...
        return false;
    }
}

BaseDraggingActivity的startActivitySafely()方法调用Activity的startActivity()方法,最终还是调用Activity的startActivityForResult()方法:

java 复制代码
public class Activity{

    @Override
    public void startActivity(Intent intent, @Nullable Bundle options) {
        ...
        if (options != null) {
            startActivityForResult(intent, -1, options);
        } else {
            // Note we want to go through this call for compatibility with
            // applications that may have overridden the method.
            startActivityForResult(intent, -1);
        }
    }

    public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
        if (mParent == null) {
            ...
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
            ...
        } else {
            ...
        }
    }
}    

后面的流程与普通Activity的启动流程一致,直到进入ActivityStackSupervisor的startSpecificActivity()方法:

java 复制代码
public class ActivityStackSupervisor{

    void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
        //该activity所在的应用已经在运行了吗?
        final WindowProcessController wpc =
                mService.getProcessController(r.processName, r.info.applicationInfo.uid);

        boolean knownToBeDead = false;
        //wpc.hasThread()通过判断IApplicationThread是否被赋值,如果已赋值,即应用已运行 
        //应用已运行,则是普通Activity的启动流程,走realStartActivityLocked()方法
        if (wpc != null && wpc.hasThread()) {
            try {
                realStartActivityLocked(r, wpc, andResume, checkConfig);
                return;
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception when starting activity "
                        + r.intent.getComponent().flattenToShortString(), e);
            }

            // If a dead object exception was thrown -- fall through to
            // restart the application.
            knownToBeDead = true;
        }

        r.notifyUnknownVisibilityLaunchedForKeyguardTransition();

        final boolean isTop = andResume && r.isTopRunningActivity();
        //否则需要ATMS的startProcessAsync()方法请求创建进程
        mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity");
    }
}   

此时应用进程还不存在,需要调用ATMS的startProcessAsync()来创建应用进程:

java 复制代码
public class ActivityTaskManagerService extends IActivityTaskManager.Stub {

    void startProcessAsync(ActivityRecord activity, boolean knownToBeDead, boolean isTop,
            String hostingType) {
        ...
        //通过发送消息来启动进程,避免在持有ATMS锁的情况下调用AMS可能发生的死锁
        final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::startProcess,
                mAmInternal, activity.processName, activity.info.applicationInfo, knownToBeDead,
                isTop, hostingType, activity.intent.getComponent());
        mH.sendMessage(m);
        ...
    }
}

这里使用Handler发送消息来启动进程,获取Message对象跟我们平时的使用方式不太一样,这里用到PooledLambda的obtainMessage()方法,实际就是调用了ActivityManagerInternal的startProcess()方法。

ActivityManagerInternal是一个抽象类,它是ActivityManager本地系统服务接口,代码如下:

java 复制代码
public abstract class ActivityManagerInternal {

    /** Starts a given process. */
    public abstract void startProcess(String processName, ApplicationInfo info,
            boolean knownToBeDead, boolean isTop, String hostingType, ComponentName hostingName);

}

ActivityManagerInternal的实现类为AMS的内部类LocalService,这样就把创建进程的请求传递给了AMS去处理。

LocalServices可以理解为是一个公开缓存池,内部使用ArrayMap来存储本地服务对象。SystemServer进程中每个服务都可以通过LocalServices的addService()方法注册到LocalServices中,需要使用时通过LocalServices的getService()获取注册的本地服务。

AMS请求Zygote创建进程

java 复制代码
public class ActivityManagerService extends IActivityManager.Stub
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
        
    public final class LocalService extends ActivityManagerInternal {
        
        @Override
        public void startProcess(String processName, ApplicationInfo info, boolean knownToBeDead,
                boolean isTop, String hostingType, ComponentName hostingName) {
            ...    
            startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,
                    new HostingRecord(hostingType, hostingName, isTop),
                    ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE, false /* allowWhileBooting */,
                    false /* isolated */, true /* keepIfLarge */);
            ...
        }
    }
    
    final ProcessRecord startProcessLocked(String processName,
            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
            HostingRecord hostingRecord, int zygotePolicyFlags, boolean allowWhileBooting,
            boolean isolated, boolean keepIfLarge) {
        return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
                hostingRecord, zygotePolicyFlags, allowWhileBooting, isolated, 0 /* isolatedUid */,
                keepIfLarge, null /* ABI override */, null /* entryPoint */,
                null /* entryPointArgs */, null /* crashHandler */);
    }
}

startProcess()方法调用了startProcessLocked()方法,startProcessLocked()方法又调用了ProcessList的startProcessLocked()方法:

java 复制代码
public final class ProcessList {
    
    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
            boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord,
            int zygotePolicyFlags, boolean allowWhileBooting, boolean isolated, int isolatedUid,
            boolean keepIfLarge, String abiOverride, String entryPoint, String[] entryPointArgs,
            Runnable crashHandler) {
        ...
        //ProcessRecord记录每个进程的信息,进程名、uid等
        ProcessRecord app;
        if (!isolated) {
            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
            ...
        } else {
            app = null;
        }
        ...
        final boolean success =
                startProcessLocked(app, hostingRecord, zygotePolicyFlags, abiOverride);
        ...
        return success ? app : null;
    }
    
    final boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
            int zygotePolicyFlags, String abiOverride) {
        return startProcessLocked(app, hostingRecord, zygotePolicyFlags,
                false /* disableHiddenApiChecks */, false /* disableTestApiChecks */,
                false /* mountExtStorageFull */, abiOverride);
    }


    boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
            int zygotePolicyFlags, boolean disableHiddenApiChecks, boolean disableTestApiChecks,
            boolean mountExtStorageFull, String abiOverride) {
        ...    
        app.gids = gids;
        app.setRequiredAbi(requiredAbi);
        app.instructionSet = instructionSet;
        
        // 启动进程,成功就返回进程的的pid,失败就抛出RuntimeException
        final String entryPoint = "android.app.ActivityThread";
        return startProcessLocked(hostingRecord, entryPoint, app, uid, gids,
                runtimeFlags, zygotePolicyFlags, mountExternal, seInfo, requiredAbi,
                instructionSet, invokeWith, startTime);    
        ...
    }
    
    boolean startProcessLocked(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) {
        ...
        if (mService.mConstants.FLAG_PROCESS_START_ASYNC) {
            ...
        } else {
            try {
                final Process.ProcessStartResult startResult = startProcess(hostingRecord,
                        entryPoint, app,
                        uid, gids, runtimeFlags, zygotePolicyFlags, mountExternal, seInfo,
                        requiredAbi, instructionSet, invokeWith, startTime);
                handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
                        startSeq, false);
            }
            ...
            return app.pid > 0;
        }
    }
    
    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) {        
            ...
            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, app.mDisabledCompatChanges,
                        new String[]{PROC_START_SEQ_IDENT + app.startSeq});
            } 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(entryPoint,
                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                        app.info.dataDir, null, app.info.packageName,
                        /*zygotePolicyFlags=*/ ZYGOTE_POLICY_FLAG_EMPTY, isTopApp,
                        app.mDisabledCompatChanges, pkgDataInfoMap, whitelistedAppDataInfoMap,
                        false, false,
                        new String[]{PROC_START_SEQ_IDENT + app.startSeq});
            } else {
                startResult = Process.start(entryPoint,
                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                        app.info.dataDir, invokeWith, app.info.packageName, zygotePolicyFlags,
                        isTopApp, app.mDisabledCompatChanges, pkgDataInfoMap,
                        whitelistedAppDataInfoMap, bindMountAppsData, bindMountAppStorageDirs,
                        new String[]{PROC_START_SEQ_IDENT + app.startSeq});
            }
            return startResult;
    }
}

在ProcessList中经过4个startProcessLocked()方法后,调用了startProcess()方法,在startProcess()方法里根据不同的参数调用不同的方法启动进程,继续跟进到Process的start()方法:

java 复制代码
public class Process {

    public static final ZygoteProcess ZYGOTE_PROCESS = new ZygoteProcess();

    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,
                                           int zygotePolicyFlags,
                                           boolean isTopApp,
                                           @Nullable long[] disabledCompatChanges,
                                           @Nullable Map<String, Pair<String, Long>>
                                                   pkgDataInfoMap,
                                           @Nullable Map<String, Pair<String, Long>>
                                                   whitelistedDataInfoMap,
                                           boolean bindMountAppsData,
                                           boolean bindMountAppStorageDirs,
                                           @Nullable String[] zygoteArgs) {
        return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids,
                    runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                    abi, instructionSet, appDataDir, invokeWith, packageName,
                    zygotePolicyFlags, isTopApp, disabledCompatChanges,
                    pkgDataInfoMap, whitelistedDataInfoMap, bindMountAppsData,
                    bindMountAppStorageDirs, zygoteArgs);
    }
}

ZYGOTE_PROCESS是ZygoteProcess在Process类中的static final类型的实例,继续进入ZygoteProcess的start()方法:

java 复制代码
public class ZygoteProcess {


    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,
                                                  int zygotePolicyFlags,
                                                  boolean isTopApp,
                                                  @Nullable long[] disabledCompatChanges,
                                                  @Nullable Map<String, Pair<String, Long>>
                                                          pkgDataInfoMap,
                                                  @Nullable Map<String, Pair<String, Long>>
                                                          whitelistedDataInfoMap,
                                                  boolean bindMountAppsData,
                                                  boolean bindMountAppStorageDirs,
                                                  @Nullable String[] zygoteArgs) {
        ...
        //startViaZygote,即为通过Zygote启动进程
        return startViaZygote(processClass, niceName, uid, gid, gids,
                runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                abi, instructionSet, appDataDir, invokeWith, /*startChildZygote=*/ false,
                packageName, zygotePolicyFlags, isTopApp, disabledCompatChanges,
                pkgDataInfoMap, whitelistedDataInfoMap, bindMountAppsData,
                bindMountAppStorageDirs, zygoteArgs);
        ...
    }
    
    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,
                                                      int zygotePolicyFlags,
                                                      boolean isTopApp,
                                                      @Nullable long[] disabledCompatChanges,
                                                      @Nullable Map<String, Pair<String, Long>>
                                                              pkgDataInfoMap,
                                                      @Nullable Map<String, Pair<String, Long>>
                                                              whitelistedDataInfoMap,
                                                      boolean bindMountAppsData,
                                                      boolean bindMountAppStorageDirs,
                                                      @Nullable String[] extraArgs)
                                                      throws ZygoteStartFailedEx {
        //创建argsForZygote                                            
        ArrayList<String> argsForZygote = new ArrayList<>();

        //存入uid、gid等参数
        argsForZygote.add("--runtime-args");
        argsForZygote.add("--setuid=" + uid);
        argsForZygote.add("--setgid=" + gid);
        
        ...

        synchronized(mLock) {
            return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),
                                              zygotePolicyFlags,
                                              argsForZygote);
        }
    }
}

ZygoteProcess的start()方法中调用了startViaZygote()方法,即为通过Zygote来启动进程,该方法流程如下:

  1. 新建参数列表argsForZygote,将应用进程的启动参数保存在argsForZygote中,包括uid、gid、targetSdkVersion、应用进程的启动文件(android.app.ActivityThread)等参数。
  2. 调用openZygoteSocketIfNeeded()方法,如果与Zygote进程的Socket连接未开启,则尝试开启,可能会产生阻塞和重试。连接调用的是ZygoteState的connect()方法,ZygoteState是ZygoteProcess的内部类。
  3. 调用zygoteSendArgsAndGetResult()方法,向Zygote进程发送参数列表,启动一个新的子进程并返回子进程的 pid。注意:当前实现将参数列表中的换行符替换为空格。

先来看看openZygoteSocketIfNeeded()方法:

java 复制代码
public class ZygoteProcess {

    private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
        try {
            //尝试与PrimaryZygote建立Socket连接
            attemptConnectionToPrimaryZygote();

            if (primaryZygoteState.matches(abi)) {
                return primaryZygoteState;
            }

            if (mZygoteSecondarySocketAddress != null) {
                //如果PrimaryZygote不匹配,试试SecondaryZygote
                attemptConnectionToSecondaryZygote();

                if (secondaryZygoteState.matches(abi)) {
                    return secondaryZygoteState;
                }
            }
        } catch (IOException ioe) {
            throw new ZygoteStartFailedEx("Error connecting to zygote", ioe);
        }

        throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi);
    }
    
    /**
     * Creates a ZygoteState for the primary zygote if it doesn't exist or has been disconnected.
     */
    private void attemptConnectionToPrimaryZygote() throws IOException {
        if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
            primaryZygoteState =
                    ZygoteState.connect(mZygoteSocketAddress, mUsapPoolSocketAddress);

            maybeSetApiBlacklistExemptions(primaryZygoteState, false);
            maybeSetHiddenApiAccessLogSampleRate(primaryZygoteState);
        }
    }

    /**
     * Creates a ZygoteState for the secondary zygote if it doesn't exist or has been disconnected.
     */
    private void attemptConnectionToSecondaryZygote() throws IOException {
        if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) {
            secondaryZygoteState =
                    ZygoteState.connect(mZygoteSecondarySocketAddress,
                            mUsapPoolSecondarySocketAddress);

            maybeSetApiBlacklistExemptions(secondaryZygoteState, false);
            maybeSetHiddenApiAccessLogSampleRate(secondaryZygoteState);
        }
    }
 }

通过openZygoteSocketIfNeeded()方法打开与Zygote进程的Socket连接,里面有涉及到与PrimaryZygote和SecondaryZygote的连接,两个都是调用ZygoteState的connect()方法来创建一个与给定Zygote Socket地址的Socket连接:

java 复制代码
public class ZygoteProcess {

    private static class ZygoteState implements AutoCloseable {

        /**
         * 通过与指定的Zygote socket建立连接创建ZygoteState实例,并保存指定的USAP socket地址
         */
        static ZygoteState connect(@NonNull LocalSocketAddress zygoteSocketAddress,
                @Nullable LocalSocketAddress usapSocketAddress)
                throws IOException {

            DataInputStream zygoteInputStream;
            BufferedWriter zygoteOutputWriter;
            final LocalSocket zygoteSessionSocket = new LocalSocket();

            if (zygoteSocketAddress == null) {
                throw new IllegalArgumentException("zygoteSocketAddress can't be null");
            }

            try {
                zygoteSessionSocket.connect(zygoteSocketAddress);
                zygoteInputStream = new DataInputStream(zygoteSessionSocket.getInputStream());
                zygoteOutputWriter =
                        new BufferedWriter(
                                new OutputStreamWriter(zygoteSessionSocket.getOutputStream()),
                                Zygote.SOCKET_BUFFER_SIZE);
            } catch (IOException ex) {
                try {
                    zygoteSessionSocket.close();
                } catch (IOException ignore) { }

                throw ex;
            }

            return new ZygoteState(zygoteSocketAddress, usapSocketAddress,
                                   zygoteSessionSocket, zygoteInputStream, zygoteOutputWriter,
                                   getAbiList(zygoteOutputWriter, zygoteInputStream));
        }
    }
}

连接上Zygote进程后,会创建BufferedWriter和DataInputStream进行参数数据的传输与读取,最后将一系列参数封装成ZygoteState对象返回给zygoteSendArgsAndGetResult()方法。

接下来看看zygoteSendArgsAndGetResult()方法:

java 复制代码
public class ZygoteProcess {

    //把参数列表发送给Zygote进程,启动新进程,并返回新进程的pid
    private Process.ProcessStartResult zygoteSendArgsAndGetResult(
            ZygoteState zygoteState, int zygotePolicyFlags, @NonNull ArrayList<String> args)
            throws ZygoteStartFailedEx {
        ...
        if (shouldAttemptUsapLaunch(zygotePolicyFlags, 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);
    }
    
    
    private Process.ProcessStartResult attemptZygoteSendArgsAndGetResult(
            ZygoteState zygoteState, String msgStr) throws ZygoteStartFailedEx {
        try {
            final BufferedWriter zygoteWriter = zygoteState.mZygoteOutputWriter;
            final DataInputStream zygoteInputStream = zygoteState.mZygoteInputStream;

            zygoteWriter.write(msgStr);
            zygoteWriter.flush();

            // Always read the entire result from the input stream to avoid leaving
            // bytes in the stream for future process starts to accidentally stumble
            // upon.
            Process.ProcessStartResult result = new Process.ProcessStartResult();
            //读取zygoteInputStream中的值
            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);
        }
    }
}    

ZygoteProcess的attemptZygoteSendArgsAndGetResult()方法中使用ZygoteState中保存的BufferedWriter和DataInputStream来进行Socket通信,进行数据流的传输和读取,最后把pid和usingWrapper封装到ProcessStartResult中返回。

Zygote创建进程并执行ActivityThread的main()方法

Android系统是基于Linux开发的,init进程是Linux系统用户进程的第一个进程,其它所有的用户进程都是init进程的子进程,Zygote进程也是由init进程创建的,Zygote启动之后会调用ZygoteInit的main()方法,我们先从main()方法来看Socket的创建和消息读取,代码如下:

java 复制代码
public class ZygoteInit {

    //这里是Zygote进程的入口,它创建了ZygoteServer,加载资源,并准备其他创建进程相关的事务
    public static void main(String argv[]) {
        ZygoteServer zygoteServer = null;
        ...
        Runnable caller;
        try {
            ...
            boolean startSystemServer = false;
            String zygoteSocketName = "zygote";
            String abiList = null;
            boolean enableLazyPreload = false;
            for (int i = 1; i < argv.length; i++) {
                if ("start-system-server".equals(argv[i])) {
                    startSystemServer = true;
                } else if ("--enable-lazy-preload".equals(argv[i])) {
                    enableLazyPreload = true;
                } else if (argv[i].startsWith(ABI_LIST_ARG)) {
                    abiList = argv[i].substring(ABI_LIST_ARG.length());
                } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
                    zygoteSocketName = argv[i].substring(SOCKET_NAME_ARG.length());
                } else {
                    throw new RuntimeException("Unknown command line argument: " + argv[i]);
                }
            }
            ...
            zygoteServer = new ZygoteServer(isPrimaryZygote);

            if (startSystemServer) {
                Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);

                // {@code r == null} in the parent (zygote) process, and {@code r != null} in the
                // child (system_server) process.
                if (r != null) {
                    r.run();
                    return;
                }
            }

            Log.i(TAG, "Accepting command socket connections");

            // The select loop returns early in the child process after a fork and
            // loops forever in the zygote.
            // runSelectLoop()方法在子进程中后会立即return,在Zygote中会loop forever
            caller = zygoteServer.runSelectLoop(abiList);
        } catch (Throwable ex) {
            Log.e(TAG, "System zygote died with exception", ex);
            throw ex;
        } finally {
            if (zygoteServer != null) {
                zygoteServer.closeServerSocket();
            }
        }

        // We're in the child process and have exited the select loop. Proceed to execute the
        // command.
        // 子进程的启动
        if (caller != null) {
            caller.run();
        }
    }

}

在main()方法中新建ZygoteServer实例对象,调用ZygoteServer的runSelectLoop()方法,runSelectLoop()方法在子进程中后会立即返回,在Zygote中会开启无限循环来监听Socket客户端发来的消息。

下面我们看看ZygoteServer的runSelectLoop()方法:

java 复制代码
class ZygoteServer {

    //用Zygote server socket, USAP pool server socket和USAP pool event FD初始化Zygote Server
    ZygoteServer(boolean isPrimaryZygote) {
        mUsapPoolEventFD = Zygote.getUsapPoolEventFD();

        if (isPrimaryZygote) {
            mZygoteSocket = Zygote.createManagedSocketFromInitSocket(Zygote.PRIMARY_SOCKET_NAME);
            mUsapPoolSocket =
                    Zygote.createManagedSocketFromInitSocket(
                            Zygote.USAP_POOL_PRIMARY_SOCKET_NAME);
        } else {
            mZygoteSocket = Zygote.createManagedSocketFromInitSocket(Zygote.SECONDARY_SOCKET_NAME);
            mUsapPoolSocket =
                    Zygote.createManagedSocketFromInitSocket(
                            Zygote.USAP_POOL_SECONDARY_SOCKET_NAME);
        }

        mUsapPoolSupported = true;
        fetchUsapPoolPolicyProps();
    }
    
    
    /**
     * Runs the zygote process's select loop. Accepts new connections as
     * they happen, and reads commands from connections one spawn-request's
     * worth at a time.
     */
    Runnable runSelectLoop(String abiList) {
        ArrayList<FileDescriptor> socketFDs = new ArrayList<>();
        ArrayList<ZygoteConnection> peers = new ArrayList<>();

        socketFDs.add(mZygoteSocket.getFileDescriptor());
        peers.add(null);

        mUsapPoolRefillTriggerTimestamp = INVALID_TIMESTAMP;

        //开启无限循环
        while (true) {
            ...
            int pollReturnValue;
            try {
                //处理轮询状态,当pollFDs有事件到来则往下执行,否则阻塞在这里
                pollReturnValue = Os.poll(pollFDs, pollTimeoutMs);
            } catch (ErrnoException ex) {
                throw new RuntimeException("poll failed", ex);
            }

            if (pollReturnValue == 0) {
                mUsapPoolRefillTriggerTimestamp = INVALID_TIMESTAMP;
                mUsapPoolRefillAction = UsapPoolRefillAction.DELAYED;
            } else {
                boolean usapPoolFDRead = false;
                //倒序处理,即优先处理已建立连接的信息,后处理新建连接的请求
                while (--pollIndex >= 0) {
                    // 采用I/O多路复用epoll机制,当接收到客户端请求到来,则往下执行;否则跳出本次循环
                    if ((pollFDs[pollIndex].revents & POLLIN) == 0) {
                        continue;
                    }

                    if (pollIndex == 0) {
                        // Zygote server socket
                        // pollIndex==0表示有新的客户端请求连接到来,调用Server Socket端的accept函数建立通信连接 
                        // Zygote进程与System Server进程建立了连接
                        ZygoteConnection newPeer = acceptCommandPeer(abiList);
                        // 加入到peers和fds, 即开始下一次监听
                        peers.add(newPeer);
                        socketFDs.add(newPeer.getFileDescriptor());

                    } else if (pollIndex < usapPoolEventFDIndex) {
                        // Session socket accepted from the Zygote server socket
                        // socket 连接成功之后从 Zygote 服务器的 socket 接受到的 Session socket
                        try {
                            ZygoteConnection connection = peers.get(pollIndex);
                            final Runnable command = connection.processOneCommand(this);

                            // TODO (chriswailes): Is this extra check necessary?
                            if (mIsForkChild) {
                                ...
                                return command;
                            } else {
                                // We're in the server - we should never have any commands to run.
                                // 如果不是fork子进程则关闭连接,删除当前fd消息
                                if (connection.isClosedByPeer()) {
                                    connection.closeSocket();
                                    peers.remove(pollIndex);
                                    socketFDs.remove(pollIndex);
                                }
                            }
                        } catch (Exception e) {
                            ...
                        } finally {
                            mIsForkChild = false;
                        }

                    } else {
                       ...
                    }
                }

               ...
            }
            ...
        }
    }
}

runSelectLoop()方法中获取zygoteSendArgsAndGetResult()方法传输过来的应用进程的启动参数,即和Zygote进程建立起连接,其方法流程如下:

  1. 开启Loop死循环监听Socket事件,没有连接时就阻塞在那里,当有连接到来时唤醒继续往下执行。
  2. pollIndex==0 时,说明收到请求连接的事件,请求和Zygote建立Socket连接,调用acceptCommandPeer()方法创建ZygoteConnection对象,并调用ZygoteSocket的accept()方法建立Socket连接,然后添加到监听列表peers中,等待与该Socket有关的命令的到来。
  3. pollIndex < usapPoolEventFDIndex 时,表示是已经连接的Socket上的命令到来,此时调用 ZygoteConnection的processOneCommand()方法来接收客户端传输过来的应用进程的启动参数,并执行进程创建工作,处理完后,就会断开与客户端的连接,并把用于连接的Socket从监听列表peers中移除。

接着进入ZygoteConnection的processOneCommand()方法:

java 复制代码
class ZygoteConnection {

    /**
     * Reads one start command from the command socket. If successful, a child is forked and a
     * {@code Runnable} that calls the childs main method (or equivalent) is returned in the child
     * process. {@code null} is always returned in the parent process (the zygote).
     *
     * If the client closes the socket, an {@code EOF} condition is set, which callers can test
     * for by calling {@code ZygoteConnection.isClosedByPeer}.
     */
    Runnable processOneCommand(ZygoteServer zygoteServer) {
        String[] args;

        try {
            // 逐行读取客户端端通过Socket write过来的启动参数(字符串数组)
            args = Zygote.readArgumentList(mSocketReader);
        } catch (IOException ex) {
            throw new IllegalStateException("IOException on command socket", ex);
        }

        ...

        int pid;
        FileDescriptor childPipeFd = null;
        FileDescriptor serverPipeFd = null;
        // 将参数解析成ZygoteArguments格式
        ZygoteArguments parsedArgs = new ZygoteArguments(args);
        ...        
        int[][] rlimits = null;

        if (parsedArgs.mRLimits != null) {
            rlimits = parsedArgs.mRLimits.toArray(Zygote.INT_ARRAY_2D);
        }

        int[] fdsToIgnore = null;

        if (parsedArgs.mInvokeWith != null) {
            try {
                FileDescriptor[] pipeFds = Os.pipe2(O_CLOEXEC);
                childPipeFd = pipeFds[1];
                serverPipeFd = pipeFds[0];
                Os.fcntlInt(childPipeFd, F_SETFD, 0);
                fdsToIgnore = new int[]{childPipeFd.getInt$(), serverPipeFd.getInt$()};
            } catch (ErrnoException errnoEx) {
                throw new IllegalStateException("Unable to set up pipe for invoke-with", errnoEx);
            }
        }

        // 将Client端fd和Server端fd存入fdsToClose数组中,然后fd置为null
        int [] fdsToClose = { -1, -1 };

        FileDescriptor fd = mSocket.getFileDescriptor();

        if (fd != null) {
            fdsToClose[0] = fd.getInt$();
        }

        fd = zygoteServer.getZygoteSocketFileDescriptor();

        if (fd != null) {
            fdsToClose[1] = fd.getInt$();
        }

        // 调用Zygote的forkAndSpecialize()方法来fork子进程
        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.mIsTopApp,
                parsedArgs.mPkgDataInfoList, parsedArgs.mWhitelistedDataInfoList,
                parsedArgs.mBindMountAppDataDirs, parsedArgs.mBindMountAppStorageDirs);

        try {
            if (pid == 0) {
                // pid == 0 表示创建成功,则进入子进程中,即应用程序进程
                zygoteServer.setForkChild();
                // 关闭 socket 连接
                zygoteServer.closeServerSocket();
                IoUtils.closeQuietly(serverPipeFd);
                serverPipeFd = null;
                // 进入子进程执行相关操作
                return handleChildProc(parsedArgs, childPipeFd, parsedArgs.mStartChildZygote);
            } else {
                // In the parent. A pid < 0 indicates a failure and will be handled in
                // handleParentProc.
                // pid < 0表示创建失败,则进入父进程返回消息给Client Socket表示启动失败
                IoUtils.closeQuietly(childPipeFd);
                childPipeFd = null;
                // 进入父进程执行相关操作
                handleParentProc(pid, serverPipeFd);
                return null;
            }
        } finally {
            IoUtils.closeQuietly(childPipeFd);
            IoUtils.closeQuietly(serverPipeFd);
        }
    }
}

该方法主要作用如下:

  1. 读取SystemServer端Socket写入的数据,并将存入字符串数组的数据封装成ZygoteArguments格式。
  2. 调用Zygote的forkAndSpecialize()方法来fork子进程,并返回pid,这里的pid并非是进程id,而是返回结果值,0 表示创建成功,-1 表示创建失败。
  3. 子进程创建成功后进入子进程执行。

看看Zygote的forkAndSpecialize()方法:

java 复制代码
public final class Zygote {

    static int forkAndSpecialize(int uid, int gid, int[] gids, int runtimeFlags,
            int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
            int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir,
            boolean isTopApp, String[] pkgDataInfoList, String[] whitelistedDataInfoList,
            boolean bindMountAppDataDirs, boolean bindMountAppStorageDirs) {
        ZygoteHooks.preFork();
	      //通过JNI调用native层方法
        int pid = nativeForkAndSpecialize(
                uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
                fdsToIgnore, startChildZygote, instructionSet, appDataDir, isTopApp,
                pkgDataInfoList, whitelistedDataInfoList, bindMountAppDataDirs,
                bindMountAppStorageDirs);
        if (pid == 0) {
            // Note that this event ends at the end of handleChildProc,
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork");
            // If no GIDs were specified, don't make any permissions changes based on groups.
            if (gids != null && gids.length > 0) {
                NetworkUtils.setAllowNetworkingForProcess(containsInetGid(gids));
            }
        }
        // Set the Java Language thread priority to the default value for new apps.
        Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
        ZygoteHooks.postForkCommon();
        return pid;
    }
}    

方法中调用native层的nativeForkAndSpecialize()方法创建进程,然后返回进程的pid(父进程中,返回新建的子进程的pid,子进程中,则返回 0,出现错误时返回负数),具体native层的源码就不跟了,大致过程如下:

  1. 调用Linux的fork()方法创建进程,设置进程的主线程的name,如果是null或者SystemServer,则为 SystemServer。
  2. 调用CallStaticVoidMethod()方法返回Zygote的callPostForkChildHooks()方法处理fork子线程之后的gc/线程池管理等操作。

进入ZygoteConnection的handleChildProc()方法:

java 复制代码
class ZygoteConnection {

    private Runnable handleChildProc(ZygoteArguments parsedArgs,
            FileDescriptor pipeFd, boolean isZygote) {
	      //关闭Socket连接
        closeSocket();
	      // 设置应用进程名
        Zygote.setAppProcessName(parsedArgs, TAG);

        // End of the postFork event.
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        if (parsedArgs.mInvokeWith != null) {
            WrapperInit.execApplication(parsedArgs.mInvokeWith,
                    parsedArgs.mNiceName, parsedArgs.mTargetSdkVersion,
                    VMRuntime.getCurrentInstructionSet(),
                    pipeFd, parsedArgs.mRemainingArgs);

            // Should not get here.
            throw new IllegalStateException("WrapperInit.execApplication unexpectedly returned");
        } else {
            if (!isZygote) {
                return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
                        parsedArgs.mDisabledCompatChanges,
                        parsedArgs.mRemainingArgs, null /* classLoader */);
            } else {
                return ZygoteInit.childZygoteInit(parsedArgs.mTargetSdkVersion,
                        parsedArgs.mRemainingArgs, null /* classLoader */);
            }
        }
    }
}

该方法就是进入子进程执行不同的初始化操作,因为已经fork()成功,关闭Socket连接等释放资源,设置应用进程名,最后调用ZygoteInit的zygoteInit()方法初始化Zygote:

java 复制代码
public class ZygoteInit {

    public static final Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,
            String[] argv, ClassLoader classLoader) {
    	......
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
        RuntimeInit.redirectLogStreams();
	      //进程初始化配置,如设置异常捕获Handler、时区、重置LogManager等等
        RuntimeInit.commonInit();
        //native层初始化--打开/dev/binder驱动,映射内核的地址空间,创建binder线程用于IPC通信
        ZygoteInit.nativeZygoteInit();
        return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,
                classLoader);
    }

}

zygoteInit()方法流程如下:

  1. 日志流重定向,将系统输出和系统错误重定向到Android日志。
  2. 进程初始化配置,如设置异常捕获Handler、时区、重置LogManager等等。
  3. native层初始化,打开/dev/binder驱动,映射内核的地址空间,创建Binder线程用于IPC通信。
  4. 调用RuntimeInit的applicationInit()方法,返回创建的Runnable对象。

接下来执行RuntimeInit的applicationInit()方法:

java 复制代码
public class RuntimeInit {

    protected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges,
            String[] argv, ClassLoader classLoader) {
        //如果应用程序调用了System.exit()方法立即终止进程,可能会导致剩余的运行线程在进程实际退出之前崩溃
        nativeSetExitWithoutCleanup(true);

        VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
        VMRuntime.getRuntime().setDisabledCompatChanges(disabledCompatChanges);

        final Arguments args = new Arguments(argv);

        // The end of of the RuntimeInit event (see #zygoteInit).
        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) {
       	// 待加载的类,这里是指ActivityThread,也就是我们第三节中在ProcessList中指明的entryPoint
        Class<?> cl; 
        try {
        	// 加载 android.app.ActivityThread 类
            cl = Class.forName(className, true, classLoader);
        } catch (ClassNotFoundException ex) {
            throw new RuntimeException(
                    "Missing class when invoking static main " + className, ex);
        }
	      
        Method m;
        try {
        	// 获取ActivityThread的main()函数
            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);
        }
		// 判断main()方法是不是 public static 类型
        int modifiers = m.getModifiers();
        if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
            throw new RuntimeException("Main method is not public and static on " + className);
        }
		// 返回 Caller,即本小节第一部分的 ZygoteInit.main() 中的 caller
        return new MethodAndArgsCaller(m, argv);
    }
 }

applicationInit()方法中首先做了一个System.exit()的保护,防止退出进程时发生Crash,设置 targetSDKVersion 等参数,最后调用findStaticMain()方法去加载ActivityThread类以及方法。

findStaticMain()方法中通过ClassLoader加载获取目标类ActivityThread,后获取其静态main()方法,然后封装成MethodAndArgsCaller对象返回,MethodAndArgsCaller实现了Runnable接口。即ZygoteInit的main()方法的 caller,如果caller != null 会调用这个caller的run()方法:

java 复制代码
public class RuntimeInit {

    static class MethodAndArgsCaller implements Runnable {
        /** method to call */
        private final Method mMethod;
        /** argument array */
        private final String[] mArgs;

        public MethodAndArgsCaller(Method method, String[] args) {
            mMethod = method;
            mArgs = args;
        }

        public void run() {
            try {
                mMethod.invoke(null, new Object[] { mArgs });
            } catch (IllegalAccessException ex) {
                throw new RuntimeException(ex);
            } catch (InvocationTargetException ex) {
                ......
            }
        }
    }
}

MethodAndArgsCaller的run()方法中使用了invoke反射调用,至此ActivityThread的main()方法得以执行,应用进程也就成功启动了ActivityThread。

Zygote进程启动流程:

  1. init进程为用户空间(相对于内核空间)的第一个进程,通过解析init.rc启动Zygote进程。
  2. Zygote进程启动步骤:创建虚拟机、注册JNI、执行 ZygoteInit的main()方法。
  3. Zygote进程启动SystemServer进程(Zygote启动的第一个进程),这个本小节没有具体分析。
  4. Zygote创建Socket连接通道,阻塞并等待新建进程的指令到来,收到指令后通过fork新建用户进程。
  5. Zygote新加了一个优化进程创建的机制,UsapPool------------池化机制,我跟了一下源码,是预先缓存了几个进程。

根Activity的启动

ActivityThread运行在主线程中,ActivityThread的入口是它的main()方法:

java 复制代码
public final class ActivityThread extends ClientTransactionHandler {

    //初始化ApplicationThread
    final ApplicationThread mAppThread = new ApplicationThread();
    //初始化Handler,给ApplicationThread与ActivityThread通信使用
    final H mH = new H();

    public static void main(String[] args) {
        ...
        //准备主线程的Looper
        Looper.prepareMainLooper();
        
        //获取startSeq      
        long startSeq = 0;
        if (args != null) {
            for (int i = args.length - 1; i >= 0; --i) {
                if (args[i] != null && args[i].startsWith(PROC_START_SEQ_IDENT)) {
                    startSeq = Long.parseLong(
                            args[i].substring(PROC_START_SEQ_IDENT.length()));
                }
            }
        }

        //这里实例化ActivityThread,也就实例化了上面的mH
        ActivityThread thread = new ActivityThread();
        //调用ActivityThread的attach()方法
        thread.attach(false, startSeq);
        
        //获取Handler
        if (sMainThreadHandler == null) {
             // sMainThreadHandler = mH
            sMainThreadHandler = thread.getHandler();
        }

        ...
        //开启主线程Looper循环
        Looper.loop();
        //因为主线程的Looper是不能退出的,退出就无法接受事件了。一旦意外退出,会抛出异常
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }
    
    private void attach(boolean system, long startSeq) {
        ...
        if (!system) {
            ...
            final IActivityManager mgr = ActivityManager.getService();
            ...
            mgr.attachApplication(mAppThread, startSeq);
            ...
        } else {
            ...
        }
	      ...
    }
}

ActivityThread的attach()方法中使用Binder通信跨进程调用了AMS的attachApplication()方法,并将ApplicationThread作为参数传递过去。

下面执行AMS绑定ApplicationThread:

java 复制代码
public class ActivityManagerService extends IActivityManager.Stub
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
        
  // ActivityTaskManagerInternal是一个抽象类,实现类是ATMS的内部类LocalService
	// ATMS启动的时候,通过LocalServices的addService()方法注册进LocalServices
	public ActivityTaskManagerInternal mAtmInternal;
	
	public ActivityManagerService(Context systemContext, ActivityTaskManagerService atm) {
     ...
     mAtmInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
     ...
	}
	
  @Override
  public final void attachApplication(IApplicationThread thread, long startSeq) {
      if (thread == null) {
          throw new SecurityException("Invalid application interface");
      }
      synchronized (this) {
          int callingPid = Binder.getCallingPid();
          final int callingUid = Binder.getCallingUid();
          final long origId = Binder.clearCallingIdentity();
          attachApplicationLocked(thread, callingPid, callingUid, startSeq);
          Binder.restoreCallingIdentity(origId);
      }
  }
    
	@GuardedBy("this")
    private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
            int pid, int callingUid, long startSeq) {
	     
	      // 保存当前正在运行的进程的所有信息
        ProcessRecord app;
        ...
        try {
        	      ...
                // 跨进程调用应用进程ApplicationThread的bindApplication()创建绑定Application
                thread.bindApplication(processName, appInfo, providerList, null, profilerInfo,
                        null, null, null, testMode,
                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
                        isRestrictedBackupMode || !normalMode, app.isPersistent(),
                        new Configuration(app.getWindowProcessController().getConfiguration()),
                        app.compat, getCommonServicesLocked(app.isolated),
                        mCoreSettingsObserver.getCoreSettingsLocked(),
                        buildSerial, autofillOptions, contentCaptureOptions,
                        app.mDisabledCompatChanges);
            ...
            // Make app active after binding application or client may be running requests (e.g
            // starting activities) before it is ready.
            //给WindowProcessController中的变量mThread赋值 
            app.makeActive(thread, mProcessStats);
            ...
        }
        ...

        // See if the top visible activity is waiting to run in this process...
        if (normalMode) {
            try {
                //通过ATMS启动根Activity
                didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
            } 
            ......
        }

        return true;
    }   
}        

AMS的attachApplication()方法在获取到 pid、uid后继续调用AMS的attachApplicationLocked()方法。AMS的attachApplicationLocked()方法中关注以下流程:

  1. 通过跨进程通信调用应用进程中ApplicationThread的bindApplication()创建并绑定Application。
  2. ProcessRecord调用makeActive()方法给WindowProcessController中的变量mThread赋值。
  3. 通过ActivityTaskManagerInternal本地服务过渡到ATMS启动根Activity。

先来看看makeActive()方法代码如下:

java 复制代码
class ProcessRecord implements WindowProcessListener {

	 public void makeActive(IApplicationThread _thread, ProcessStatsService tracker) {
        ......
        thread = _thread;
        mWindowProcessController.setThread(thread);
    }
}    

里面调用了WindowProcessController的setThread()方法存储IApplicationThread实例,代码如下:

java 复制代码
public class WindowProcessController extends ConfigurationContainer<ConfigurationContainer>
        implements ConfigurationContainerListener {
   	private IApplicationThread mThread;
            
    @HotPath(caller = HotPath.PROCESS_CHANGE)
    public void setThread(IApplicationThread thread) {
        synchronized (mAtm.mGlobalLockWithoutBoost) {
            mThread = thread;
            if (thread != null) {
                setLastReportedConfiguration(getConfiguration());
            }
        }
    }
    
    IApplicationThread getThread() {
        return mThread;
    }

    boolean hasThread() {
        return mThread != null;
    }
}

WindowProcessController的setThread()方法中将传入的IApplicationThread实例赋值给mThread保存,前面进程不存在的情况下,startSpecificActivity()方法中通过wpc.hasThread()拿到的值为false,因为进程创建完成后才给WindowProcessController中的mThread赋值。

IApplicationThread的bindApplication()方法调用的是应用进程中的实现类ApplicationThread的bindApplication()方法,方法中通过内部类H发送Handler消息,进而调用到ActivityThread的handleBindApplication()方法,代码如下:

java 复制代码
public final class ActivityThread extends ClientTransactionHandler {

    private void handleBindApplication(AppBindData data) {
	      ...
        final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
        updateLocaleListFromAppContext(appContext,
                mResourcesManager.getConfiguration().getLocales());
        ...
        if (ii != null) {
            ...
            final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
                    appContext.getClassLoader(), false, true, false);
            final ContextImpl instrContext = ContextImpl.createAppContext(this, pi,
                    appContext.getOpPackageName());
            try {
            	// 获取ClassLoader加载类文件
                final ClassLoader cl = instrContext.getClassLoader();
                // 构建Instrumentation实例
                mInstrumentation = (Instrumentation)
                    cl.loadClass(data.instrumentationName.getClassName()).newInstance();
            }
			...
            final ComponentName component = new ComponentName(ii.packageName, ii.name);
            mInstrumentation.init(this, instrContext, appContext, component,
                    data.instrumentationWatcher, data.instrumentationUiAutomationConnection);
			...
        } 
        ...
        Application app;
	      ...
        try {
        	  // 创建Application
            app = data.info.makeApplication(data.restrictedBackupMode, null);
	          ...
            mInitialApplication = app;
	          ...
            try {
                mInstrumentation.onCreate(data.instrumentationArgs);
            }
            ...
            try {
                // 内部调用了Application的onCreate()的方法
                mInstrumentation.callApplicationOnCreate(app);
            }
            ...
        }
        ...
    }
}

在handleBindApplication()方法中创建了Instrumentation实例和Application实例,调用了mInstrumentation.callApplicationOnCreate(app),里面调用了Application的onCreate()的方法。ActivityThread的performLaunchActivity()方法中也有创建Application实例的操作,里面会先判断Application是否已存在。也就是说,正常情况下Application的初始化是在handleBindApplication方法中的,并且是创建进程后调用的。performLaunchActivity()中只是做了一个检测,异常情况Application不存在时才会创建。

这里注意一点,创建Application后,马上会执行Application的attach()方法,attach()内部会调用attachBaseContext()方法,后面才是Application的onCreate()方法。

回到前面的ATMS中的attachApplication()方法:

java 复制代码
public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
	// 启动的时候注册到 LocalServices 中
	private void start() {
      LocalServices.addService(ActivityTaskManagerInternal.class, mInternal);
  }

	final class LocalService extends ActivityTaskManagerInternal {
	      ...
	      @HotPath(caller = HotPath.PROCESS_CHANGE)
        @Override
        public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
            synchronized (mGlobalLockWithoutBoost) {
                if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {
                    Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "attachApplication:" + wpc.mName);
                }
                try {
                	  //调用RootWindowContainer的attachApplication()方法 
                    return mRootWindowContainer.attachApplication(wpc);
                } finally {
                    Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
                }
            }
        }
        ...
	}
}

ActivityTaskManagerInternal是一个抽象类,实现类是ATMS的内部类LocalService,所以AMS中调用 ActivityTaskManagerInternal的方法,实际上调用的是ATMS中的实现类LocalService的方法。该方法继续调用 RootWindowContainer的attachApplication()方法,启动流程交给RootWindowContainer处理。

RootWindowContainer的attachApplication()方法代码如下:

java 复制代码
class RootWindowContainer extends WindowContainer<DisplayContent>
        implements DisplayManager.DisplayListener {

    boolean attachApplication(WindowProcessController app) throws RemoteException {
        final String processName = app.mName;
        boolean didSomething = false;
        for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
            final DisplayContent display = getChildAt(displayNdx);
            final ActivityStack stack = display.getFocusedStack();
            if (stack == null) {
                continue;
            }

            mTmpRemoteException = null;
            mTmpBoolean = false; // Set to true if an activity was started.
            final PooledFunction c = PooledLambda.obtainFunction(
                    RootWindowContainer::startActivityForAttachedApplicationIfNeeded, this,
                    PooledLambda.__(ActivityRecord.class), app, stack.topRunningActivity());
            stack.forAllActivities(c);
            c.recycle();
            if (mTmpRemoteException != null) {
                throw mTmpRemoteException;
            }
            didSomething |= mTmpBoolean;
        }
        if (!didSomething) {
            ensureActivitiesVisible(null, 0, false /* preserve_windows */);
        }
        return didSomething;
    }
    
    private boolean startActivityForAttachedApplicationIfNeeded(ActivityRecord r,
            WindowProcessController app, ActivityRecord top) {
        if (r.finishing || !r.okToShowLocked() || !r.visibleIgnoringKeyguard || r.app != null
                || app.mUid != r.info.applicationInfo.uid || !app.mName.equals(r.processName)) {
            return false;
        }

        try {
            if (mStackSupervisor.realStartActivityLocked(r, app, top == r /*andResume*/,
                    true /*checkConfig*/)) {
                mTmpBoolean = true;
            }
        } catch (RemoteException e) {
            .....
            return true;
        }
        return false;
    }
}

RootWindowContainer的attachApplication()方法中,调用到RootWindowContainer的startActivityForAttachedApplicationIfNeeded()方法。RootWindowContainer的 startActivityForAttachedApplicationIfNeeded()方法中继续调用ActivityStackSupervisor的 realStartActivityLocked()方法。从这里开始,又跟普通Activity的启动流程一样了。

我们发现,根Activity启动前需要创建进程,然后执行ActivityThread的main()方法,开启主线程循环,初始化并绑定Application、赋值IApplicationThread,最后真正的启动过程和普通Activity是一致的。

相关推荐
程序猿麦小七3 小时前
今天给在家介绍一篇基于jsp的旅游网站设计与实现
java·源码·旅游·景区·酒店
工业互联网专业21 小时前
Python毕业设计选题:基于Django+uniapp的公司订餐系统小程序
vue.js·python·小程序·django·uni-app·源码·课程设计
程序员小海绵【vincewm】1 天前
【设计模式】结合Tomcat源码,分析外观模式/门面模式的特性和应用场景
设计模式·tomcat·源码·外观模式·1024程序员节·门面模式
工业互联网专业1 天前
Python毕业设计选题:基于django+vue的仓库管理系统设计
vue.js·python·django·毕业设计·源码·课程设计
北巷!!3 天前
SpringSecurity源码中核心类
源码·springsecurity
工业互联网专业5 天前
Python毕业设计选题:基于django+vue的论坛BBS系统
vue.js·python·django·毕业设计·源码·课程设计·bbs论坛
工业互联网专业5 天前
Python毕业设计选题:基于django+vue的荣誉证书管理系统
python·django·vue·毕业设计·源码·课程设计
工业互联网专业6 天前
Python毕业设计选题:基于django+vue的网上购物系统的设计与实现
vue.js·python·django·毕业设计·源码·课程设计
工业互联网专业8 天前
Python毕业设计选题:基于Hadoop的租房数据分析系统的设计与实现
vue.js·hadoop·python·flask·毕业设计·源码·课程设计