Android 8.0 源码分析 (三) 应用程序进程建立到应用程序启动的过程

前言

咱们熟知通常 Android 工程师都是在应用层上开发,不会涉及系统源码,可是若是你想往底层发展,或者深刻插件化、Framework 系统层等开发工做,若是不了解 Android 源码但是不行的,那么接下来我基于本身的理解跟学习来记录跟 Android 开发息息相关的源码分析,大概从 Android 中的 SystemServer 启动、四大组件启动、AMS、PMS 等几个维度来介绍,下面是个人计划,固然在将来也有可能改变。java

尚未关注的小伙伴,能够先关注一波,系列文章会持续更新。android

Android 8.0 源码分析 (一) SystemServer 进程启动web

Android 8.0 源码分析 (二) Launcher 启动数组

Android 8.0 源码分析 (三) 应用程序进程建立到应用程序启动的过程app

Android 8.0 源码分析 (四) Activity 启动框架

Android 8.0 源码分析 (五) Service 启动socket

Android 8.0 源码分析 (六) BroadcastReceiver 启动ide

Android 8.0 源码分析 (七) ContentProvider 启动函数

介绍

前面 2 篇咱们学习了 Android 的系统服务进程启动和桌面 Launcher 的启动,那么基于前面学的内容,这一篇将带来应用程序进程的启动过程分析,若是对 Zygote、SystemServer、Launcher 启动原理还不了解的建议先看下我前面文章。oop

应用程序进程简介

想要启动一个应用程序,首先要保证这个应用程序所须要的应用程序进程已经启动。 AMS 在启动应用程序时会检查这个应用程序须要的应用程序进程是否存在,不存在就会请求 Zygote 进程启动须要的应用程序进程。在 Android 8.0 源码分析 (一) SystemServer 进程启动 中咱们知道在 Zygote 的 Java 框架层中会建立一个 Server 端的 Socket , 这个 Socket 就是用来等待 AMS 请求 Zygote 建立新的应用程序进程。Zygote 进程经过 fock 自身建立的应用程序进程,这样应用程序就会得到 Zygote 进程在启动时建立的虚拟机实例。固然,在应用程序进程建立过程当中除了获取虚拟机实例外,还建立了 Bindler 线程池和消息循环,这样运行在应用进程中的应用程序就能够方便的使用 Binder 进行进程间通讯以及处理消息了。

应用程序进程启动过程介绍

应用程序进程建立过程的步骤比较多,这里分为两个部分来说解,分别是 AMS 发送启动应用程序进程请求,以及 Zygote 接收请求并建立应用程序进程。

AMS 发送启动应用程序进程请求

先来看一下 AMS 发送启动应用程序进程请求过程的时序图,而后对每个步骤进行详细分析。

KykGXn.png

AMS 若是想要启动应用程序进程,就须要向 Zygote 进程发送建立应用程序进程的请求, AMS 会经过调用 startProcessLocked 函数向 Zygote 进程发送请求,以下所示:

//com.android.server.am; ActivityManagerService.java

    /** * 启动进程的函数 * @param app * @param hostingType * @param hostingNameStr * @param abiOverride * @param entryPoint * @param entryPointArgs */
    private final void startProcessLocked( ProcessRecord app, String hostingType, String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs){
      
        ...
          
        try {
            try {
                final int userId = UserHandle.getUserId(app.uid);
                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
            } catch (RemoteException e) {
                throw e.rethrowAsRuntimeException();
            }

            /** * 1. 获取要建立的应用程序进程的 用户 id */
            int uid = app.uid;
            int[] gids = null;
            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
            if (!app.isolated) {
              ...

                /** * 2. 对 gids 进行建立和赋值 */
                if (ArrayUtils.isEmpty(permGids)) {
                    gids = new int[3];
                } else {
                    gids = new int[permGids.length + 3];
                    System.arraycopy(permGids, 0, gids, 3, permGids.length);
                }
                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
                gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
                gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
            }
           ...
            boolean isActivityProcess = (entryPoint == null);
            /** * 3. 若是 entryPoint == null 那么将 ActivityThread 全类名赋值给 entryPoint */
            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");
            ProcessStartResult startResult;
            if (hostingType.equals("webview_service")) {
                startResult = startWebView(entryPoint,
                        app.processName, uid, uid, gids, debugFlags, mountExternal,
                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                        app.info.dataDir, null, entryPointArgs);
            } else {

                /** * 4. 在 AMS 中调用 start 函数进行通知 Zygote fork 进程 */
                startResult = Process.start(entryPoint,
                        app.processName, uid, uid, gids, debugFlags, mountExternal,
                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                        app.info.dataDir, invokeWith, entryPointArgs);
            }
          ...
    }
复制代码

总结下上面代码意思,可分为 4 个步骤:

    1. 获取建立应用程序进程的用户 ID
    1. 对用户组 ID(gids)进行建立和赋值
    1. 若是 entryPoint 为 null ,就把 ActivityThread 全类名赋值给它
    1. 调用 Process 的 start 函数

Process.start 的第一个函数就是 android.app.ActivityThread ,后面小节会用到它,它就是关键所在,好了下面咱们看下 Process 的 start 函数:

//android.os; Process.java

    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 invokeWith, String[] zygoteArgs) {
      	//1. 经过 ZygoteProcess 调用 start 函数
        return zygoteProcess.start(processClass, niceName, uid, gid, gids,
                    debugFlags, mountExternal, targetSdkVersion, seInfo,
                    abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
    }

复制代码

在 Process.start 静态函数中咱们看到,又调用了 ZygoteProcess 的 start 函数,其实 ZygoteProcess 是用于与 Zygote 进程保持通讯的状态,该 start 函数以下:

//android.os; ZygoteProcess.java

    public final Process.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 invokeWith, String[] zygoteArgs) {
        try {
            /** * 继续调用当前类的 startViaZygote 函数 */
            return startViaZygote(processClass, niceName, uid, gid, gids,
                    debugFlags, mountExternal, targetSdkVersion, seInfo,
                    abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
        } catch (ZygoteStartFailedEx ex) {
            Log.e(LOG_TAG,
                    "Starting VM process through Zygote failed");
            throw new RuntimeException(
                    "Starting VM process through Zygote failed", ex);
        }
    }

    private Process.ProcessStartResult startViaZygote(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 invokeWith, String[] extraArgs) throws ZygoteStartFailedEx {

        //建立一个集合 将应用程序进程启动参数保存
        ArrayList<String> argsForZygote = new ArrayList<String>();

        // --runtime-args, --setuid=, --setgid=,
        // and --setgroups= must go first
        argsForZygote.add("--runtime-args");
        argsForZygote.add("--setuid=" + uid);
        argsForZygote.add("--setgid=" + gid);
       ...//省略部分代码

        synchronized(mLock) {
         //继续调用内部函数
            return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
        }
    }
复制代码

经过上面代码咱们知道主要就是将应用程序进程启动参数告诉 zygoteSendArgsAndGetResult 而后经过 Socket 传递给 zygote 进程,咱们先来看 openZygoteSocketIfNeeded(abi) 实现

//android.os; ZygoteProcess.java
    @GuardedBy("mLock")
    private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
        Preconditions.checkState(Thread.holdsLock(mLock), "ZygoteProcess lock not held");

        if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
            try {
                /** * 1. 链接 zygote 名称为 "zygote" 服务端的 Socket ,创建进程间通讯 */
                primaryZygoteState = ZygoteState.connect(mSocket);
            } catch (IOException ioe) {
                throw new ZygoteStartFailedEx("Error connecting to primary zygote", ioe);
            }
        }

        /** * 2. 链接 Zygote 主模式返回的 ZygoteState 是否与启动应用程序进程所须要的 ABI 匹配 */
        if (primaryZygoteState.matches(abi)) {
            return primaryZygoteState;
        }

        // 若是不匹配,则尝试链接 zygote 辅模式
        if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) {
            try {
                /** * 3. 若是不匹配那么就尝试链接 name 为 "zygote_secondary" 的 Socket */
                secondaryZygoteState = ZygoteState.connect(mSecondarySocket);
            } catch (IOException ioe) {
                throw new ZygoteStartFailedEx("Error connecting to secondary zygote", ioe);
            }
        }

        /** * 4. 链接 Zygote 辅模式返回的 ZygoteState 是否与启动应用程序进程所须要的 ABI 匹配 */
        if (secondaryZygoteState.matches(abi)) {
            return secondaryZygoteState;
        }

        //若是都不匹配那么就抛一个异常
        throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi);
    }
复制代码

经过上面的代码跟注释咱们知道就是与 zygote 进程经过 Socket 进行一个链接,链接成功以后会返回一个 ZygoteState,而后对传递进来的 abi 进行匹配,这里链接和匹配 abi 涉及到 Zygote 的启动脚本,感兴趣的能够查阅相关资料,通俗的来说就是若是 Zygote 进程采用的是 init.zygote32_64.rc 脚本启动,那么它就是属于主模式为 “name” 名称的服务端 Socket, 若是采用的是 init.zygote64_32.rc 脚本启动,那么它就是属于辅模式为 “zygote_secondary” 名称的服务端 Socket。最后若是都不匹配说明链接或者匹配异常了。若是链接成功以后咱们看 zygoteSendArgsAndGetResult 函数主要作了些什么工做:

//android.os; ZygoteProcess.java
    private static Process.ProcessStartResult zygoteSendArgsAndGetResult( ZygoteState zygoteState, ArrayList<String> args) throws ZygoteStartFailedEx {
       			...
            final BufferedWriter writer = zygoteState.writer;
            final DataInputStream inputStream = zygoteState.inputStream;

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

            for (int i = 0; i < sz; i++) {
                String arg = args.get(i);
                writer.write(arg);
                writer.newLine();
            }

            writer.flush();

            ...
            }
            return result;
        } catch (IOException ex) {
            zygoteState.close();
            throw new ZygoteStartFailedEx(ex);
        }
    }
复制代码

经过上面代码咱们知道,若是与 zygote 进程的服务端 Socket 链接成功,那么就将存储起来的应用程序进程启动参数写入到 ZygoteState 中。最后就是 Zygote 进程接收后的处理工做了,下面一小节来详细为你们介绍接收以后的工做。

Zygote 接收请求并建立应用程序进程

若是有看过 Android 8.0 源码分析 (一) SystemServer 进程启动 该文章的必定清楚,其实 SystemServer 跟应用进程启动在 Zygote 处理 的方式类似,这里我们为了复习一下以前的内容,咱们就再来温习一遍吧,先来看一个时序图。

KymKkq.png

上面咱们讲了在温习一下 ZygoteInit main 函数,那么咱们在看一下 服务端的 Socket 建立

//com.android.internal.os.ZygoteInit.java
    public static void main(String argv[]) {

	    ....

        try {
          
          ...
            //是否开启 SystemServer 标记
            boolean startSystemServer = false;
          	//服务端 Socket 名称
            String socketName = "zygote";

          	//根据 JNI 层传递过来的信息,来判断是否启动系统服务
            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)) {
                    socketName = argv[i].substring(SOCKET_NAME_ARG.length());
                } else {
                    throw new RuntimeException("Unknown command line argument: " + argv[i]);
                }
            }
          

            /** * 1. 建立服务端的 Socket ,名称为 "zygote" */

            zygoteServer.registerServerSocket(socketName);
           
            if (!enableLazyPreload) {
                bootTimingsTraceLog.traceBegin("ZygotePreload");
                EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
                    SystemClock.uptimeMillis());
                /** * 2. 用来预加载资源 */
                preload(bootTimingsTraceLog);
                EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
                    SystemClock.uptimeMillis());
                bootTimingsTraceLog.traceEnd(); // ZygotePreload
            } else {
                Zygote.resetNicePriority();
            }

            ...

            if (startSystemServer) {
                /** * 3. 启动 SystemServer 进程 * */
                startSystemServer(abiList, socketName, zygoteServer);
            }

            Log.i(TAG, "Accepting command socket connections");
            /** * 4. 等待 AMS 请求 */
            zygoteServer.runSelectLoop(abiList);
						//清理或者关闭对应的 Socket
            zygoteServer.closeServerSocket();
        } catch (Zygote.MethodAndArgsCaller caller) {
            caller.run();
        } catch (Throwable ex) {
            Log.e(TAG, "System zygote died with exception", ex);
            zygoteServer.closeServerSocket();
            throw ex;
        }
    }

复制代码

在上面注释 1 处经过 registerZygoteSocket 函数来建立一个名称为 “name” 的服务端 Socket, 这个 Socket 是用于等待 AMS 发起建立新的应用程序进程的请求,关于 AMS 后面我会详细讲解。注释 3 启动服务进程,注释 4 等待 AMS 的请求,咱们直接看 注释 4 的代码实现

// com.android.internal.os ZygoteInit.main->runSelectLoop

    void runSelectLoop(String abiList) throws Zygote.MethodAndArgsCaller {
        ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
        ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();

        /** * 1. 添加得到该 Socket 的 fd 字段的值 */
        fds.add(mServerSocket.getFileDescriptor());
        peers.add(null);

        /** * 死循环等待 AMS 的请求 */
        while (true) {
            StructPollfd[] pollFds = new StructPollfd[fds.size()];
            /** * 2. 将 fds 信息转存到 pollFds 数组中。 */
            for (int i = 0; i < pollFds.length; ++i) {
                pollFds[i] = new StructPollfd();
                pollFds[i].fd = fds.get(i);
                pollFds[i].events = (short) POLLIN;
            }
            try {
                Os.poll(pollFds, -1);
            } catch (ErrnoException ex) {
                throw new RuntimeException("poll failed", ex);
            }

            /** * 3.对 pollFds 信息进行遍历 */
            for (int i = pollFds.length - 1; i >= 0; --i) {

                if ((pollFds[i].revents & POLLIN) == 0) {
                    continue;
                }
                //若是 i == 0 那么就认为 服务端 Socket 与客户端链接上了,就是与 AMS 创建了链接
                if (i == 0) {
                    /** * 4. */
                    ZygoteConnection newPeer = acceptCommandPeer(abiList);
                    //将 ZygoteConnection 添加到 Socket 链接列表中
                    peers.add(newPeer);
                    //将 ZygoteConnection 的文件描述符 添加到 fds 列表中
                    fds.add(newPeer.getFileDesciptor());
                } else {//若是不等于 0 ,那么就说明 AMS 向 Zygote 发送了一个建立应用进程的请求
                    /** * 5. 调用 ZygoteConnection 的 runOnce 函数来建立一个新的应用进程,并在成功建立后将这个链接从 Socket 链接列表中 peers、fd 列表中关闭 */
                    boolean done = peers.get(i).runOnce(this);
                    if (done) {
                        peers.remove(i);
                        fds.remove(i);
                    }
                }
            }
        }
    }

复制代码

经过上面注释咱们知道,若是 AMS 发来了一个新的请求任务,会走注释 5 经过 peers.get(i).runOnce(this); 来处理请求数据,咱们直接看 runOnce 函数具体实现:

//com.android.internal.os; ZygoteConnection.java
    boolean runOnce(ZygoteServer zygoteServer) throws Zygote.MethodAndArgsCaller {

        String args[];
        Arguments parsedArgs = null;
        FileDescriptor[] descriptors;

        try {
            /** * 1. 获取应用程序进程的启动参数 */
            args = readArgumentList();
            descriptors = mSocket.getAncillaryFileDescriptors();
        } catch (IOException ex) {
            Log.w(TAG, "IOException on command socket " + ex.getMessage());
            closeSocket();
            return true;
        }
				...
        int pid = -1;
        FileDescriptor childPipeFd = null;
        FileDescriptor serverPipeFd = null;

        try {
            /** * 2. 将获取到启动应用程序进程的启动参数 args 数组 封装到 Arguments 类型的 parsedArgs 对象中 */
            parsedArgs = new Arguments(args);

           ...
            fd = null;

            /** * 3. 经过 Zygote 来建立应用程序进程 */
            pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
                    parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
                    parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.instructionSet,
                    parsedArgs.appDataDir);
        } catch (ErrnoException ex) {
          ...
        }

        try {
            //当前代码逻辑运行在被建立出来的子进程中
            if (pid == 0) {
                // in child
                zygoteServer.closeServerSocket();
                IoUtils.closeQuietly(serverPipeFd);
                serverPipeFd = null;
                //4. 处理应用程序进程
                handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);

                // should never get here, the child is expected to either
                // throw Zygote.MethodAndArgsCaller or exec().
                return true;
            } else {
                // in parent...pid of < 0 means failure
                IoUtils.closeQuietly(childPipeFd);
                childPipeFd = null;
                return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);
            }
        } finally {
            IoUtils.closeQuietly(childPipeFd);
            IoUtils.closeQuietly(serverPipeFd);
        }
    }
复制代码

经过上面代码咱们知道这里 runOnce 首先获取到启动应用程序进程的参数,而后进行一个 Argument 的包装,最后经过 Zygote.forkAndSpecialize 建立 AMS 传递过来启动进程信息,内部实际上是 native 函数来进行建立。接下来咱们看 注释 4 处理建立完成的应用程序进程,以下代码:

//com.android.internal.os; ZygoteConnection.java 
		private void handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr) throws Zygote.MethodAndArgsCaller {
        ...
        if (parsedArgs.invokeWith != null) {
            ...
        } else {
            //调用 ZygoteInit 的 zygoteInit 函数
            ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion,
                    parsedArgs.remainingArgs, null /* classLoader */);
        }
    }
复制代码

handleChildProc 内部又调用了 ZygoteInit 的 zygoteInit 函数,具体咱们看下源码:

// com.android.internal.os ZygoteInit

    public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) throws Zygote.MethodAndArgsCaller {
        if (RuntimeInit.DEBUG) {
            Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
        }

        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
        RuntimeInit.redirectLogStreams();

        RuntimeInit.commonInit();
        /** * 1. 启动 Binder 线程池 */
        ZygoteInit.nativeZygoteInit();
        /** * 2. 进入 ActivityThread 的 main 方法 */
        RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
    }

复制代码

注释 1 处先启动 Binder 线程池,用于进程间通讯,咱们注解看注释 2 内部实现

//com.android.internal.os RuntimeInit.java
    protected static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) throws Zygote.MethodAndArgsCaller {
       	...
        invokeStaticMain(args.startClass, args.startArgs, classLoader);
    }

    private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader) throws Zygote.MethodAndArgsCaller {
        Class<?> cl;

        try {
            /** *1. 经过 className("android.app.ActivityThread" )反射获得 ActivityThread 类 * className 经过 AMS 等其它地方传递过来的,并非惟一 */
            cl = Class.forName(className, true, classLoader);
        } catch (ClassNotFoundException ex) {
            throw new RuntimeException(
                    "Missing class when invoking static main " + className,
                    ex);
        }

        Method m;
        try {
            /** * 2. 拿到 ActivityThread main 函数 */
            m = cl.getMethod("main", new Class[] { String[].class });
        } catch (NoSuchMethodException ex) {
            ...
        } catch (SecurityException ex) {
            ...
        }

        int modifiers = m.getModifiers();
        if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
           ...
        }

        /** * 3. 将 m 、argv 传入 MethodAndArgsCaller,而后抛一个异常,并在 ZygoteInit.main 中进行捕获异常 */
        throw new Zygote.MethodAndArgsCaller(m, argv);
    }

复制代码

经过上面代码首先根据 AMS 传递过来的启动参数 android.app.ActivityThread 而后进行反射拿到 ActivityThread 实例,在经过它的实例拿到 main 函数,最后交于 Zygote.MethodAndArgsCaller(m, argv); 异常来处理,直接看 ZygoteInit.main() 函数

//com.android.internal.os.ZygoteInit.java
    public static void main(String argv[]) {

	    ....

        try {
          
          ...

          	//服务端 Socket 名称
            String socketName = "zygote";

					...
          

            /** * 1. 建立服务端的 Socket ,名称为 "zygote" */

            zygoteServer.registerServerSocket(socketName);
           
        		...
            /** * 2. 等待 AMS 请求 */
            zygoteServer.runSelectLoop(abiList);

        } catch (Zygote.MethodAndArgsCaller caller) {
          	//3. 捕获到 RuntimeInit applicationInit 中的异常
            caller.run();
        } catch (Throwable ex) {
            Log.e(TAG, "System zygote died with exception", ex);
            zygoteServer.closeServerSocket();
            throw ex;
        }
    }


复制代码

根据注释 3 咱们知道捕获到了 RuntimeInit applicationInit 中的异常,而后进入它的 run 函数

////com.android.internal.os Zygote.java

    public static class MethodAndArgsCaller extends Exception 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 {
                /** * 1. 这里就开始执行 ActivityThread main 方法了 */
                mMethod.invoke(null, new Object[] { mArgs });
            } catch (IllegalAccessException ex) {
                throw new RuntimeException(ex);
            } catch (InvocationTargetException ex) {
                Throwable cause = ex.getCause();
                if (cause instanceof RuntimeException) {
                    throw (RuntimeException) cause;
                } else if (cause instanceof Error) {
                    throw (Error) cause;
                }
                throw new RuntimeException(ex);
            }
        }
    }

复制代码

到了这里 应用程序的进程建立和 应用程序进程的入口 ActivityThread main 都已经执行了,下面咱们来看 ActivityThead main 函数实现:

//android.app; ActivityThread.java
    //经过 ZygoteInit 反射调用执行的
    public static void main(String[] args) {
        ...
        //1. 主线程消息循环 Looper 建立
        Looper.prepareMainLooper();
        //2. 建立 ActivityThread 对象
        ActivityThread thread = new ActivityThread();
        //3. Application,Activity ......入口
        thread.attach(false);
				//4. 拿到 H -> Handler
        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }

        ...
        //5. 开启 Looper 循环,处理主线程消息
        Looper.loop();

        throw new RuntimeException("Main thread loop unexpectedly exited");
    }
复制代码

经过上面代码咱们知道 ActivityThread main 函数主要作了 5 件事:

    1. 主线程消息循环 Looper 建立
    1. 建立 ActivityThread 对象
    1. 开启 Application,Activity ......入口
    1. 拿到 H -> Handler
    1. 开启 Looper 循环,处理主线程消息

咱们直接跳到注释 3 处

//

    private void attach(boolean system) {
       	....
          //1. 拿到 IActivityManager aidl 接口
            final IActivityManager mgr = ActivityManager.getService();
            try {
                //2. 关联 Application
                mgr.attachApplication(mAppThread);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
            ...
            try {
                mInstrumentation = new Instrumentation();
              	//3. 建立系统级别的 Context
                ContextImpl context = ContextImpl.createAppContext(
                        this, getSystemContext().mPackageInfo);
              	//4. 建立 Application 对象
                mInitialApplication = context.mPackageInfo.makeApplication(true, null);
              	//5. Application oncreate 生命周期调用
                mInitialApplication.onCreate();
            } catch (Exception e) {
                throw new RuntimeException(
                        "Unable to instantiate Application():" + e.toString(), e);
            }
        }

        ...
    }
复制代码

咱们直接看应用程序 Application 建立吧,跳到注释 4

//android.app; LoadedApk.java
    public Application makeApplication(boolean forceDefaultAppClass, Instrumentation instrumentation) {
        if (mApplication != null) {
            return mApplication;
        }

       ...
            ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
            //1. 建立一个新的 Application
            app = mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);
           
        } catch (Exception e) {
           ..}
        mApplication = app;

        if (instrumentation != null) {
            try {
                instrumentation.callApplicationOnCreate(app);
            } catch (Exception e) {
               ...

        return app;
    }
复制代码

咱们继续看注释 1 的实现

//android.app; Instrumentation.java
    public Application newApplication(ClassLoader cl, String className, Context context) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
              //调用内部的 newApplication 函数
        return newApplication(cl.loadClass(className), context);
    }

    static public Application newApplication(Class<?> clazz, Context context) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
        //反射进行实例化 Application
        Application app = (Application)clazz.newInstance();
        //执行 Application 生命周期函数 attach
        app.attach(context);
        return app;
    }
复制代码

到这里应用程序进程的建立 再到应用程序的 Application 的启动已经介绍完了

总结

本篇文章涉及到的知识点不少有 Zygote、AMS、ActivityThread、Application 等等,相信若是跟着个人系列文章来阅读的话,收获确定仍是有的。

在这里就简单的总结下应用程序进程的启动,首先经过 Launcher 中的点击事件触摸手机屏幕中的应用图标,AMS 会收到启动应用程序进程的信息,而后经过 Socket 传递给 Zygote 进程,Zygote 进程收到 AMS 传递过来的启动信息进行 native 层建立子进程,最后经过反射调用 ActivityThead main 函数,最终在 ActivityThead attach 函数中经过反射实例化了 Application 并执行了对应的生命周期函数 。到这里该应用程序进程就 执行到了 Application 中了。下一篇文章将为你们带来四大组件中的 Activity 源码分析,敬请期待!

参考

  • 《Android 进阶解密》
相关文章
相关标签/搜索