Android ActivityThread

启动Activity所属的应用进程

  • 大概流程如下所示

    ActivityManagerService.startProcessLocked()
    Process.start()
    ActivityThread.main()
    ActivityThread.attach()
    ActivityManagerNative.getDefault().attachApplication()
    ActivityManagerService.attachApplication()

  • 首先看一下startProcessLocked()方法的具体实现:

    1
    2
    3
    4
    5
    private final void startProcessLocked(ProcessRecord app,
    String hostingType, String hostingNameStr) {
    startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
    null /* entryPoint */, null /* entryPointArgs */);
    }
  • 然后回调了其重载的startProcessLocked方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    private final void startProcessLocked(ProcessRecord app, String hostingType,
    String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
    ...
    boolean isActivityProcess = (entryPoint == null);
    if (entryPoint == null) entryPoint = "android.app.ActivityThread";
    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
    app.processName);
    checkTime(startTime, "startProcess: asking zygote to start proc");
    Process.ProcessStartResult startResult = Process.start(entryPoint,
    app.processName, uid, uid, gids, debugFlags, mountExternal,
    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
    app.info.dataDir, entryPointArgs);
    checkTime(startTime, "startProcess: returned from zygote!");
    ...
    }
  • 可以发现其经过一系列的初始化操作之后调用了Process.start方法,并且传入了启动的类名“android.app.ActivityThread”:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    public static final ProcessStartResult start(final String processClass,
    final String niceName,
    int uid, int gid, int[] gids,
    int debugFlags, int mountExternal,
    int targetSdkVersion,
    String seInfo,
    String abi,
    String instructionSet,
    String appDataDir,
    String[] zygoteArgs) {
    try {
    return startViaZygote(processClass, niceName, uid, gid, gids,
    debugFlags, mountExternal, targetSdkVersion, seInfo,
    abi, instructionSet, appDataDir, zygoteArgs);
    } catch (ZygoteStartFailedEx ex) {
    Log.e(LOG_TAG,
    "Starting VM process through Zygote failed");
    throw new RuntimeException(
    "Starting VM process through Zygote failed", ex);
    }
    }
  • 然后调用了startViaZygote方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    private static ProcessStartResult startViaZygote(final String processClass,
    final String niceName,
    final int uid, final int gid,
    final int[] gids,
    int debugFlags, int mountExternal,
    int targetSdkVersion,
    String seInfo,
    String abi,
    String instructionSet,
    String appDataDir,
    String[] extraArgs)
    throws ZygoteStartFailedEx {
    synchronized(Process.class) {
    ...

    return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
    }
    }
  • 继续查看一下zygoteSendArgsAndGetResult方法的实现:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    private static ProcessStartResult zygoteSendArgsAndGetResult(
    ZygoteState zygoteState, ArrayList<String> args)
    throws ZygoteStartFailedEx {
    try {
    /**
    * See com.android.internal.os.ZygoteInit.readArgumentList()
    * 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.
    */
    final BufferedWriter writer = zygoteState.writer;
    final DataInputStream inputStream = zygoteState.inputStream;

    writer.write(Integer.toString(args.size()));
    writer.newLine();

    int sz = args.size();
    for (int i = 0; i < sz; i++) {
    String arg = args.get(i);
    if (arg.indexOf('\n') >= 0) {
    throw new ZygoteStartFailedEx(
    "embedded newlines not allowed");
    }
    writer.write(arg);
    writer.newLine();
    }

    writer.flush();

    // Should there be a timeout on this?
    ProcessStartResult result = new ProcessStartResult();
    result.pid = inputStream.readInt();
    if (result.pid < 0) {
    throw new ZygoteStartFailedEx("fork() failed");
    }
    result.usingWrapper = inputStream.readBoolean();
    return result;
    } catch (IOException ex) {
    zygoteState.close();
    throw new ZygoteStartFailedEx(ex);
    }
    }
  • 可以发现其最终调用了Zygote并通过socket通信的方式让Zygote进程fork除了一个新的进程,并根据我们刚刚传递的”android.app.ActivityThread”字符串,反射出该对象并执行ActivityThread的main方法。这样我们所要启动的应用进程这时候其实已经启动了,但是还没有执行相应的初始化操作。

ActivityThread的main方法

  • 为什么我们平时都将ActivityThread称之为ui线程或者是主线程,这里可以看出,应用进程被创建之后首先执行的是ActivityThread的main方法,所以我们将ActivityThread成为主线程。

  • 这时候我们看一下ActivityThread的main方法的实现逻辑。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    public static void main(String[] args) {
    ...
    Process.setArgV0("<pre-initialized>");

    Looper.prepareMainLooper();

    ActivityThread thread = new ActivityThread();
    thread.attach(false);

    if (sMainThreadHandler == null) {
    sMainThreadHandler = thread.getHandler();
    }

    if (false) {
    Looper.myLooper().setMessageLogging(new
    LogPrinter(Log.DEBUG, "ActivityThread"));
    }

    // End of event ActivityThreadMain.
    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    Looper.loop();

    throw new RuntimeException("Main thread loop unexpectedly exited");
    }
    • 在main方法中主要执行了一些初始化的逻辑,并且创建了一个UI线程消息队列,这也就是为什么我们可以在主线程中随意的创建Handler而不会报错的原因,这里提出一个问题,大家可以思考一下:子线程可以创建Handler么?可以的话应该怎么做?
  • 然后执行了ActivityThread的attach方法,这里我们看一下attach方法执行了那些逻辑操作。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    private void attach(boolean system) {
    ...
    final IActivityManager mgr = ActivityManagerNative.getDefault();
    try {
    mgr.attachApplication(mAppThread);
    } catch (RemoteException ex) {
    // Ignore
    }
    ...
    }
  • 刚刚已经分析过ActivityManagerNative是ActivityManagerService的Binder client,所以这里调用了attachApplication实际上就是通过Binder机制调用了ActivityManagerService的attachApplication,具体调用的过程,我们看一下ActivityManagerService是如何实现的:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    @Override
    public final void attachApplication(IApplicationThread thread) {
    synchronized (this) {
    int callingPid = Binder.getCallingPid();
    final long origId = Binder.clearCallingIdentity();
    attachApplicationLocked(thread, callingPid);
    Binder.restoreCallingIdentity(origId);
    }
    }
  • 可以发现其回调了attachApplicationLocked方法,我们看一下这个方法的实现逻辑。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    private final boolean attachApplicationLocked(IApplicationThread thread,
    int pid) {

    ...
    // See if the top visible activity is waiting to run in this process...
    if (normalMode) {
    try {
    if (mStackSupervisor.attachApplicationLocked(app)) {
    didSomething = true;
    }
    } catch (Exception e) {
    Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
    badApp = true;
    }
    }
    ...

    return true;
    }
  • 该方法执行了一系列的初始化操作,这样我们整个应用进程已经启动起来了。