Android系统启动系列7 进程创建流程

一 概述

本文要介绍的是进程的创建,先简单说说进程与线程的区别。

1.1 进程线程介绍

进程:每个 App 在启动前必须先创建一个进程,该进程是由 zygote fork 出来的,进程具有独立的资源空间,用于承载 App 上运行的各种 Activity,Service 等组件。进程对于上层应用来说是完全透明的,这也是谷歌有意为之,让 App 程序都运行在 Android Runtime 上。大多数情况一个 App 就运行在一个进程中,除非在 AndroidManifest.xml 中配置 Android:process 属性,或通过 native 代码 fork 进程。关于多进程内容请参考 Android多进程 android:process 属性

线程:线程对应用开发者来说非常熟悉,比如每次 new Thread().start() 都会创建一个新的线程,该线程并没有自己独立的地址空间,而是与其所在进程之间资源共享。从 Linux 角度来说进程与线程都是一个 task_struct 结构体,除了是否共享资源外,并没有其他本质的区别。

在接下来的介绍中,会涉及到 system_server 进程和 zygote 进程,下面重复简要介绍下这两个进程:

  • system_server 进程:是用于管理整个 Java framework 层,包含 AMS,PMS 等各种系统服务
  • zygote 进程:是 Android 系统的首个 Java 进程,zygote 是所有 Java 进程的父进程,包括 system_server 进程以及所有的 App 进程都是 zygote 的子进程,注意这里说的是子进程,而非子线程

1.2 涉及代码

/libcore/dalvik/src/main/java/dalvik/system/ZygoteHooks.java
/libcore/libart/src/main/java/java/lang/Daemons.java
/libcore/dalvik/src/main/java/dalvik/system/runtime.cc
/art/runtime/native/dalvik_system_ZygoteHooks.cc
/art/runtime/runtime.cc
/frameworks/base/core/jni/com_android_internal_os_Zygote.cpp	 
/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
/frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
/frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
/frameworks/base/core/java/com/android/internal/os/Zygote.java
/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
/frameworks/base/services/java/com/android/server/SystemServer.java
/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
/frameworks/base/services/core/java/com/android/server/am/ProcessList.java
/frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
/frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.java
/frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
/frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java
/frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
/frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java
/frameworks/base/services/core/java/com/android/server/wm/ClientLifecycleManager.java
/frameworks/base/core/java/android/os/Process.java
/frameworks/base/core/java/android/os/ZygoteProcess.java
/frameworks/base/core/java/android/app/LauncherActivity.java
/frameworks/base/core/java/android/app/ActivityThread.java
/frameworks/base/core/java/android/app/Activity.java
/frameworks/base/core/java/android/app/ActivityManagerInternal.java
/frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java
/frameworks/base/core/java/android/app/servertransaction/ClientTransaction.aidl
/frameworks/base/core/java/android/app/ClientTransactionHandler.java
/frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java
/frameworks/base/core/java/android/app/servertransaction/LaunchActivityItem.java
/frameworks/base/core/java/android/app/Instrumentation.java
/frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java

二 架构

2.1 进程创建图

对于大多数的应用开发者来说创建线程比较熟悉,而对于创建进程并没有太多的概念。对于系统工程师或者高级开发者,还是很有必要了解 Android 系统是如何一步步地创建出一个进程的。先来看一张进程创建过程的简要图:

在这里插入图片描述

  • App 发起进程:当从桌面启动应用,则发起进程便是 Launcher 所在进程;当从某 App 内启动远程进程,则发送进程便是该 App 所在进程。发起进程先通过 binder 发送消息给 system_server 进程
  • system_server 进程:调用 Process.start() 方法,通过 socket 向 zygote 进程发送创建新进程的请求
  • zygote 进程:在执行 ZygoteInit.main() 后便进入 runSelectLoop() 循环体内,当有客户端连接时便会执行 ZygoteConnection.runOnce() 方法,再经过层层调用后 fork 出新的应用进程
  • 新进程:执行 handleChildProc 方法,最后调用 ActivityThread.main() 方法

下图是详细调用栈
在这里插入图片描述

三 system_server发起请求

3.1 Process.start

frameworks/base/core/java/android/os/Process.java

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,
                                           @Nullable String[] zygoteArgs) {
        return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids,
                    runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                    abi, instructionSet, appDataDir, invokeWith, packageName,
                    /*useUsapPool=*/ true, zygoteArgs);
    }

frameworks/base/core/java/android/os/ZygoteProcess.java

public final Process.ProcessStartResult start(@NonNull final String processClass,
                                                  final String niceName,
                                                  int uid, int gid, @Nullable int[] gids,
                                                  ........
                                                  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, 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);
        }
    }

3.2 ZygoteProcess.startViaZygote

private Process.ProcessStartResult startViaZygote(@NonNull final String processClass,
                                                      @Nullable final String niceName,
                                                      final int uid, final int gid,
                                                      @Nullable final int[] gids,
                                                      ........
                                                      @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);
        ........
        if (niceName != null) {
            argsForZygote.add("--nice-name=" + niceName);
        }
        ........
        if (startChildZygote) {
            argsForZygote.add("--start-child-zygote");
        }
        if (packageName != null) {
            argsForZygote.add("--package-name=" + packageName);
        }
        //关键点:processClass = “android.app.ActivityThread”,把这个参数添加到argsForZygote中
        argsForZygote.add(processClass);
        if (extraArgs != null) {
            Collections.addAll(argsForZygote, extraArgs);
        }
        synchronized(mLock) {
            return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),
                                              useUsapPool,
                                              argsForZygote);
        }
    }

该过程主要工作是生成 argsForZygote 数组,该数组保存了进程的 uid、gid、groups、target-sdk、nice-name 等一系列参数,然后调用 zygoteSendArgsAndGetResult 方法,其中的第一个参数是调用 openZygoteSocketIfNeeded 方法得到 ZygoteState。

3.3 ZygoteProcess.zygoteSendArgsAndGetResult

private Process.ProcessStartResult zygoteSendArgsAndGetResult(
            ZygoteState zygoteState, boolean useUsapPool, @NonNull ArrayList<String> args)
            throws ZygoteStartFailedEx {
        for (String arg : args) {
            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");
            }
        }
        String msgStr = args.size() + "\n" + String.join("\n", args) + "\n";
        ........
        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;
            //把应用进程的一些参数写给前面连接的zygote进程
            //包括前面的processClass ="android.app.ActivityThread"
            zygoteWriter.write(msgStr);
            zygoteWriter.flush();
            //从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);
        }
    }

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

3.4 ZygoteProcess.openZygoteSocketIfNeeded

private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
        try {
            attemptConnectionToPrimaryZygote();
            if (primaryZygoteState.matches(abi)) {
                return primaryZygoteState;
            }
            if (mZygoteSecondarySocketAddress != null) {
                // The primary zygote didn't match. Try the secondary.
                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);
    }

根据当前的 abi 来选择与 zygote 还是 zygote64 来进行通信。

四 zygote fork进程

zygote 进程是由 init 进程创建的,zygote 进程启动之后,会调用 ZygoteInit.main() 方法,经过创建 socket 管道,预加载资源后,便执行 runSelectLoop() 方法,进入无限循环状态。详细流程请参考 Android系统启动系列3 zygote进程

4.1 ZygoteInit.main

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;
        }
    }
    ........
    //循环等待接收AMS在socket上发出的消息
    //最终通过调用processOneCommand()来进行进程的创建和初始化处理
    caller = zygoteServer.runSelectLoop(abiList);
    ........
    if (caller != null) {
    //fork 出子进程的话,会执行到这里,然后在子进程中
    //执行这个Runnable,其实就是通过反射调用ActivityThread的main函数
    //如果是zygote进程的话不会执行到这里,会一直在runSelectLoop里面循环阻塞
        caller.run(); 
    }
}

zygote 先 fork 出 SystemServer 进程,接着进入循环阻塞等待状态,接收 Socket 发来的消息,收到消息后会 fork 出其他应用进程,比如 Launcher。

4.2 ZygoteServer.runSelectLoop

frameworks\base\core\java\com\android\internal\os\ZygoteServer.java

 Runnable runSelectLoop(String abiList) {
        ArrayList<FileDescriptor> socketFDs = new ArrayList<FileDescriptor>();
        ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>(); 
        // 首先将 server socket 加入到 socketFDs
        socketFDs.add(mZygoteSocket.getFileDescriptor());
        peers.add(null); //对应的 ZygoteConnection 为 null
        
        while (true) {//无限循环用来等待AMS请求zygote创建新的应用进程
            fetchUsapPoolPolicyPropsWithMinInterval(); 
            int[] usapPipeFDs = null;
            // 每次循环,都重新创建需要监听的 pollFds
            StructPollfd[] pollFDs = null;             
            if (mUsapPoolEnabled) {
                usapPipeFDs = Zygote.getUsapPipeFDs();
           pollFDs = new StructPollfd[socketFDs.size() + 1 + usapPipeFDs.length];
            } else {
                pollFDs = new StructPollfd[socketFDs.size()];
            }
            int pollIndex = 0;
            for (FileDescriptor socketFD : socketFDs) {
                 //关注事件到来
                pollFDs[pollIndex] = new StructPollfd();
                pollFDs[pollIndex].fd = socketFD;
                pollFDs[pollIndex].events = (short) POLLIN;
                ++pollIndex;
            } 
            final int usapPoolEventFDIndex = pollIndex; 
            ........
            try {
                //阻塞状态,当 pollFdd 有事件到来则往下执行,否则阻塞在这里
                Os.poll(pollFDs, -1);
            } catch (ErrnoException ex) {
                throw new RuntimeException("poll failed", ex);
            } 
            boolean usapPoolFDRead = false; 
            // 倒序处理,即优先处理已建立链接的信息,后处理新建链接的请求
            while (--pollIndex >= 0) {
                if ((pollFDs[pollIndex].revents & POLLIN) == 0) {
                    continue;                } 
                // server socket 最先加入 fds, 因此这里是 server socket 收到数据
                if (pollIndex == 0) {
                    // 收到新的建立通信请求,调用 server socket 端的 accpet 函数建立连接
                    // zygote 进程与 system server 进程建立了连接
                    ZygoteConnection newPeer = acceptCommandPeer(abiList);
                    // 加入到 peers 和 fds, 即下一次也开始监听
                    peers.add(newPeer);
                    socketFDs.add(newPeer.getFileDescriptor()); 
                } else if (pollIndex < usapPoolEventFDIndex) {
                    // 说明接收到 AMS 发送过来创建应用程序的请求,调用
                    // processOneCommand 来创建新的应用程序进程
                    try {
                        // 有 socket 连接,创建 ZygoteConnection 对象,并添加到 fds。
                        ZygoteConnection connection = peers.get(pollIndex);
                        // 处理连接(用于 fork 新的进程)
                        final Runnable command = connection.processOneCommand(this);
                        if (mIsForkChild) {
                            if (command == null) {
                                throw new IllegalStateException("command == null");
                            } 
                            return command;// 子进程中,返回 Runnable,终止无限循环
                        } else {// 父进程中,fork 新的进程后,删除之前建立的连接,继续无限循环
                            // We're in the server - we should never have any 
                            //commands to run.
                            if (command != null) {
                                throw new IllegalStateException("command != null");
                            } 
                            if (connection.isClosedByPeer()) {
                                connection.closeSocket();
                                peers.remove(pollIndex); // 从 peers 中删除已经处理过的连接
                                //处理完则从 socketFDs 中移除该文件描述符
                                socketFDs.remove(pollIndex);
                            }
                        }
                    } catch (Exception e) {
                        ......
                    } finally {
                        mIsForkChild = false;
                    }
                } else {
                    //处理USAP pool的事件                    
                    ........
                }
            } 
            // Check to see if the USAP pool needs to be refilled.
            ........
        }
}

第一次 while(true) 时,socketFDs 只有一个元素即 ServerSocket,因此会走到 if (pollIndex == 0) 分支,结束时 socketFDs 有 2 个元素:ServerSocket 和 newPeer 对应的 Socket。peers 也有 2 个元素:null 和 newPeer。

第二次 while(true) 时,socketFDs 有 2 个元素,当走到 if (pollIndex < usapPoolEventFDIndex) 分支时,此时 pollIndex=1,peers 取出的元素为 newPeer,然后就会执行到 connection.processOneCommand()。

4.3 ZygoteConnection.processOneCommand

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;
    }
}

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

4.4 ZygoteConnection.handleChildProc

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 进程将会调用到这里,执行目标类 (ActivityThread) 的 main()方法
            return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
                    parsedArgs.mRemainingArgs, null /* classLoader */);
        } else {
            return ZygoteInit.childZygoteInit(parsedArgs.mTargetSdkVersion,
                    parsedArgs.mRemainingArgs, null /* classLoader */);
        }
    }
}

进入子进程中的操作,调用 ZygoteInit.zygoteInit,最终获得需要执行的 ActivityThread 的 main()。

4.4 ZygoteInit.zygoteInit

public static final Runnable zygoteInit(int targetSdkVersion, String[] argv,
            ClassLoader classLoader) {
        ........
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
        RuntimeInit.redirectLogStreams();// 日志重定向
        RuntimeInit.commonInit();// 通用的初始化工作
        ZygoteInit.nativeZygoteInit();// zygote初始化,完成 Binder 驱动的初始化和 Binder 线程的创建
        //应用的初始化
        return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}

zygoteInit 进行一些环境的初始化、启动 Binder 线程等操作

4.5 ZygoteInit.nativeZygoteInit

AndroidRuntime.cpp

static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
    gCurRuntime->onZygoteInit();
}

这个 gCurRuntime 就是 AndroidRuntime,它的实现类就是在 app_main.cpp 文件中的 AppRuntime,接下来我们来看这个方法的实现:

app_main.cpp

virtual void onZygoteInit()
    {
        sp<ProcessState> proc = ProcessState::self();
        ALOGV("App process: starting thread pool.\n");
        proc->startThreadPool();
    }

看到了吧?初始化了 ProcessState,我们之前学习 Binder 的时候,已经知道在这个过程中,完成了 Binder 的初始化,同时创建了 Binder 的线程池,使新创建的进程具备了 Binder 通信的条件,这个非常重要。

4.6 RuntimeInit.applicationInit

protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
            ClassLoader classLoader) {
        // true 代表应用程序退出时不调用 AppRuntime.onExit(),否则会在退出前调用
        nativeSetExitWithoutCleanup(true);
        // 设置虚拟机的内存利用率参数值为 0.75
        VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
        VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
        final Arguments args = new Arguments(argv);
        // The end of of the RuntimeInit event (see #zygoteInit).
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        // 调用 startClass 的 static 方法 main()
        return findStaticMain(args.startClass, args.startArgs, classLoader);
    }

此处 findStaticMain 的参数 args.startClass 为 “android.app.ActivityThread”。

4.7 RuntimeInit.findStaticMain

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);
    }
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,这是一个 Runnable,在这个 Runnable 中会通过反射调用 ActivityThread 的 main() 方法。这个 Runnable 会一路返回到 ZygoteInit 类的 main() 方法中,最终会在子进程中通过 caller.run 来执行这个 Runnable,从而完成 ActivityThread main 方法的执行。

五 应用进程入口ActivityThread.main

5.1 ActivityThread.main

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

5.2 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();
        }
        // Watch for getting close to heap limit. GC 监听
         BinderInternal.addGcWatcher(new Runnable() {
              @Override public void run() {
                  if (!mSomeActivitiesChanged) {// 是否有 Activity 生命周期发生变化
                      return;
                  }
                  Runtime runtime = Runtime.getRuntime();
                  long dalvikMax = runtime.maxMemory();
                  long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();
                  // 当虚拟机使用的内存超出最大内存的 3/4 时, 释放一些 Activity
          if (dalvikUsed > ((3*dalvikMax)/4)) {
               if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024)
                            + " total=" + (runtime.totalMemory()/1024)
                            + " used=" + (dalvikUsed/1024));
                    mSomeActivitiesChanged = false;
                   try {
              ActivityTaskManager.getService().releaseSomeActivities(mAppThread);
                       } catch (RemoteException e) {
                          throw e.rethrowFromSystemServer();
                      }
                  }
              }
          });
    } else {
        // 通过 system_server 启动 ActivityThread 对象
        ........
    } 
    // 为 ViewRootImpl 设置全局配置变化回调,
    // 当系统资源配置(如:系统字体)发生变化时,通知系统配置发生变化
    ViewRootImpl.ConfigChangedCallback configChangedCallback
            = (Configuration globalConfig) -> {
        synchronized (mResourcesManager) {
			........
        }
    };
    ViewRootImpl.addConfigCallback(configChangedCallback);
}

5.3 ActivityManagerService.attachApplication

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);
    }
}


private final boolean attachApplicationLocked(IApplicationThread thread,
        int pid, int callingUid, long startSeq) {
    ProcessRecord app;
    // 从 mPidsSelfLocked 列表根据 pid 查找进程
    if (pid != MY_PID && pid >= 0) {
        synchronized (mPidsSelfLocked) {
            app = mPidsSelfLocked.get(pid);
        }
        ........
    } else {
        app = null;
    }
    // 若上述查找 app 为空,则从 mPendingStarts 列表根据 startSeq 查找进程
    if (app == null && startSeq > 0) {
        final ProcessRecord pending = mProcessList.mPendingStarts.get(startSeq);
        if (pending != null && pending.startUid == callingUid && pending.startSeq == startSeq
                && mProcessList.handleProcessStartedLocked(pending, pid,
                pending.isUsingWrapper(), startSeq, true)) {
            app = pending;
        }
    }
	........
    // 如果当前的 Application 记录仍然依附到之前的进程中,则清理掉
    if (app.thread != null) {
        handleAppDiedLocked(app, true, true);
    }
 
    // mProcessesReady 这个变量在 AMS 的 systemReady 中被赋值为 true,
    //  所以这里的 normalMode 也为 true
    boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
	........
	if (app.isolatedEntryPoint != null) { // isolated进程
        // This is an isolated process which should just call an entry point instead of
        // being bound to an application.
        thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs);
    } else if (instr2 != null) {
	    // 绑定 App 进程
        thread.bindApplication(processName, appInfo, providers,
                instr2.mClass,
                profilerInfo, instr2.mArguments,
                instr2.mWatcher,
                instr2.mUiAutomationConnection, testMode,
                mBinderTransactionTrackingEnabled, enableTrackAllocation,
                isRestrictedBackupMode || !normalMode, app.isPersistent(),
                new Configuration(app.getWindowProcessController().getConfiguration()),
                app.compat, getCommonServicesLocked(app.isolated),
                mCoreSettingsObserver.getCoreSettingsLocked(),
                buildSerial, autofillOptions, contentCaptureOptions);
    } else {
        thread.bindApplication(processName, appInfo, providers, 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 active, 并更新 lru 进程信息
    app.makeActive(thread, mProcessStats);// 给 ProcessRecord 的 thread 赋值,表示绑定成功
    mProcessList.updateLruProcessLocked(app, false, null);
    app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
 
    // Remove this record from the list of starting applications.
    mPersistentStartingProcesses.remove(app);
    mProcessesOnHold.remove(app);
 
    boolean didSomething = false;    
    // 上面说到,这里为 true,进入 StackSupervisor 的 attachApplication 方法
    // 去真正启动 Activity
    if (normalMode) {
		//调用ATM的attachApplication()
        didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
		........
    }
    // Find any services that should be running in this process...
    // 启动进程中的服务. (启动服务过程本文暂不讲解)
    didSomething |= mServices.attachApplicationLocked(app, processName);
    // Check if a next-broadcast receiver is in this process...
    // 发送 pending 中的广播. (发送广播过程本文暂不讲解)
    if (isPendingBroadcastProcessLocked(pid)) {
        didSomething |= sendPendingBroadcastsLocked(app);
    }
    if (!didSomething) {
	    // 进程启动,更新 Adj
        updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_PROCESS_BEGIN);
    }
	........
    return true;
}

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

5.3.1 ActivityThread.bindApplication

private class ApplicationThread extends IApplicationThread.Stub {
	public final void bindApplication(String processName, ApplicationInfo appInfo,
	        List<ProviderInfo> providers, ComponentName instrumentationName,
	        ProfilerInfo profilerInfo, Bundle instrumentationArgs,
	        IInstrumentationWatcher instrumentationWatcher,
	        IUiAutomationConnection instrumentationUiConnection, int debugMode,
	        boolean enableBinderTracking, boolean trackAllocation,
	        boolean isRestrictedBackupMode, boolean persistent, Configuration config,
	        CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
	        String buildSerial, AutofillOptions autofillOptions,
	        ContentCaptureOptions contentCaptureOptions) {
	    ...
	    // 封装 App 进程绑定数据 AppBindData
	    AppBindData data = new AppBindData();
	    data.processName = processName;
	    data.appInfo = appInfo;
	    data.providers = providers;
	    data.instrumentationName = instrumentationName;
	    data.instrumentationArgs = instrumentationArgs;
	    data.instrumentationWatcher = instrumentationWatcher;
	    data.instrumentationUiAutomationConnection = instrumentationUiConnection;
	    data.debugMode = debugMode;
	    data.enableBinderTracking = enableBinderTracking;
	    data.trackAllocation = trackAllocation;
	    data.restrictedBackupMode = isRestrictedBackupMode;
	    data.persistent = persistent;
	    data.config = config;
	    data.compatInfo = compatInfo;
	    data.initProfilerInfo = profilerInfo;
	    data.buildSerial = buildSerial;
	    data.autofillOptions = autofillOptions;
	    data.contentCaptureOptions = contentCaptureOptions;
	    // 向 H 发送 BIND_APPLICATION 广播
	    sendMessage(H.BIND_APPLICATION, data);
	}
}

5.3.2 H.handleBindApplication

class H extends Handler {
    public static final int BIND_APPLICATION        = 110;
 
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case BIND_APPLICATION: // 处理App进程绑定
                AppBindData data = (AppBindData)msg.obj;
                handleBindApplication(data);
                break;
        }
    }
}

private void handleBindApplication(AppBindData data) {
    // 从 AppBindData 中取出 InstrumentationInfo 信息
    final InstrumentationInfo ii;
    if (data.instrumentationName != null) {
        ii = new ApplicationPackageManager(null, 
		        getPackageManager()).getInstrumentationInfo(data.instrumentationName, 0);
        mInstrumentationPackageName = ii.packageName;
        mInstrumentationAppDir = ii.sourceDir;
        mInstrumentationSplitAppDirs = ii.splitSourceDirs;
        mInstrumentationLibDir = getInstrumentationLibrary(data.appInfo, ii);
        mInstrumentedAppDir = data.info.getAppDir();
        mInstrumentedSplitAppDirs = data.info.getSplitAppDirs();
        mInstrumentedLibDir = data.info.getLibDir();
    } 
    // 创建 Context
    final ContextImpl appContext = ContextImpl.createAppContext(this, data.info); 
	// InstrumentationInfo 对象非空
    if (ii != null) { // 从 InstrumentationInfo 中取出各参数, 基于此创建和初始化 Instrumentation
        ApplicationInfo instrApp = getPackageManager()
		        .getApplicationInfo(ii.packageName, 0, UserHandle.myUserId());
        if (instrApp == null) {
            instrApp = new ApplicationInfo();
        }
        // 将 InstrumentationInfo 里的参数拷贝到 ApplicationInfo 对象
        ii.copyTo(instrApp);
        instrApp.initForUser(UserHandle.myUserId());
        final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo, 
		        appContext.getClassLoader(), false, true, false); 
        final ContextImpl instrContext = ContextImpl.createAppContext(this,
		        pi, appContext.getOpPackageName());
        final ClassLoader cl = instrContext.getClassLoader();
        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);
    } else { // 初始化Instrumentation
        mInstrumentation = new Instrumentation();
        mInstrumentation.basicInit(this);
    }
    // 创建 Application 对象
    Application app = data.info.makeApplication(data.restrictedBackupMode, null);
    mInitialApplication = app; 
    // 调用 Application.onCreate() 方法
    mInstrumentation.onCreate(data.instrumentationArgs);       
    mInstrumentation.callApplicationOnCreate(app);
    ........
}

5.3.3 LoadedApk.makeApplication

public Application makeApplication(boolean forceDefaultAppClass, 
		Instrumentation instrumentation) {
    if (mApplication != null) {
        return mApplication;
    } 
    String appClass = mApplicationInfo.className;
    // 设置默认 Application-   "android.app.Application"
    if (forceDefaultAppClass || appClass == null) {
        appClass = "android.app.Application";
    } 
    java.lang.ClassLoader cl = getClassLoader();
    if (!mPackageName.equals("android")) {
        initializeJavaContextClassLoader();
    }
    // 创建 AppContext
    ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
    // newApplication
    Application app = mActivityThread.mInstrumentation
		    .newApplication(cl, appClass, appContext);
    // 将 Application 设置到 AppContext
    appContext.setOuterContext(app);
    // 将 Application 添加到应用程序列表
    mActivityThread.mAllApplications.add(app);
    mApplication = app; 
    if (instrumentation != null) { // 此处 instrumentation=null
        instrumentation.callApplicationOnCreate(app);
    } 
    // Rewrite the R 'constants' for all library apks.
    SparseArray<String> packageIdentifiers = getAssets().getAssignedPackageIdentifiers();
    final int N = packageIdentifiers.size();
    for (int i = 0; i < N; i++) {
        final int id = packageIdentifiers.keyAt(i);
        if (id == 0x01 || id == 0x7f) {
            continue;
        } 
        rewriteRValues(getClassLoader(), packageIdentifiers.valueAt(i), id);
    } 
    return app;
}

5.3.4 Instrumentation

frameworks/base/core/java/android/app/Instrumentation.java

public void onCreate(Bundle arguments) {
}
 
public void callApplicationOnCreate(Application app) {
    app.onCreate();
}

5.4 ActivityTaskManagerService.attachApplication

// 启动 Activity
public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
    synchronized (mGlobalLockWithoutBoost) {
        return mRootActivityContainer.attachApplication(wpc);
    }
}

5.5 RootActivityContainer.attachApplication

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)) {
		            // 启动Activity
                    if (mStackSupervisor.realStartActivityLocked(activity, app,
		                    top == activity /* andResume */, true /* checkConfig */)) {
                        didSomething = true;
                    }
                }
            }
        }
    }
    if (!didSomething) {
        ensureActivitiesVisible(null, 0, false /* preserve_windows */);
    }
    return didSomething;
}

关于 ActivityStackSupervisor 的 realStartActivityLocked 本文暂不分析,在 Android四大组件系列2 Activity启动流程 中有详细介绍。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值