在前面我们从源码层面分析了Android系统启动流程,了解它们也主要是为了我们开发App服务的。应用程序想要启动首先需要应用程序进程存在,而应用程序进程的创建需要SystemServer进程中的ActivityManagerService向Zygote进程发送消息,通过zygote进程fork自身来创建应用程序进程,新创建的应用程序进程就有zygote进程创建的虚拟机实例,同时创建了Binder线程池和Handler消息循环机制,便于进程间消息通信。今天就来从源码角度分析我们关心的Android应用程序进程的启动流程。


Android应用程序进程启动过程(基于9.0源码分析)

应用程序进程的启动我们分为两个部分来分析

  • AMS(ActivityManagerService, 后同) 通过调用startProcessLocked发送创建进程请求。
  • Zygote进程接受请求,创建应用程序进程

AMS向Zygote进程发送创建应用程序进程请求

时序图如下:

应用程序进程的创建是需要SystemServer进程中的ActivityManagerService向Zygote进程发送消息,进而由Zygote创建进程,然后启动应用程序进程,比如其中有一种AMS.startProcessLocked是在启动Activity时候,源码如下:

frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java

void startSpecificActivityLocked(ActivityRecord r,            boolean andResume, boolean checkConfig) {             // Is this activity's application already running?        ProcessRecord app = mService.getProcessRecordLocked(r.processName,                r.info.applicationInfo.uid, true);        if (app != null && app.thread != null) {                 try {                     ...                realStartActivityLocked(r, app, andResume, checkConfig);                return;            } catch (RemoteException e) {                   ...            }        }        // 1         mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,                "activity", r.intent.getComponent(), false, false, true);    }

在此方法中先判断应用程序进程是都存在,不存在的话就需要进入到注释1的startProcessLocked中,下面我们通过源码进行分析AMS发送请求到Zygote的过程,AMS.startProcessLocked源码如下:

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

final ProcessRecord startProcessLocked(String processName,            ApplicationInfo info, boolean knownToBeDead, int intentFlags,            String hostingType, ComponentName hostingName, boolean allowWhileBooting,            boolean isolated, boolean keepIfLarge) {             return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,                null /* crashHandler */);    }@GuardedBy("this")    private boolean startProcessLocked(String hostingType, String hostingNameStr, String entryPoint,            ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,            String seInfo, String requiredAbi, String instructionSet, String invokeWith,            long startTime) {                 // 1         final ProcessStartResult startResult = startProcess(app.hostingType, entryPoint,                            app, app.startUid, gids, runtimeFlags, mountExternal, app.seInfo,                            requiredAbi, instructionSet, invokeWith, app.startTime);                          }}

上面注释1处调用了startProcess方法,其中有一个参数是是entryPoint, 追溯源码就会发现它是String entryPoint = "android.app.ActivityThread",接着进入内部查看startProcess源码:

private ProcessStartResult startProcess(String hostingType, String entryPoint,            ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,            String seInfo, String requiredAbi, String instructionSet, String invokeWith,            long startTime) {                  /**启动一个进程*/             ProcessStartResult startResult = Process.start(entryPoint,                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,                        app.info.dataDir, invokeWith,                        new String[] {     PROC_START_SEQ_IDENT + app.startSeq});                }

上面参数中传入了uid和gid, 接着进入到了Process.start方法,源码如下:

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

public static final ProcessStartResult start(final String processClass,                                  final String niceName,                                  int uid, int gid, int[] gids,                                  int runtimeFlags, int mountExternal,                                  int targetSdkVersion,                                  String seInfo,                                  String abi,                                  String instructionSet,                                  String appDataDir,                                  String invokeWith,                                  String[] zygoteArgs) {             return zygoteProcess.start(processClass, niceName, uid, gid, gids,                    runtimeFlags, mountExternal, targetSdkVersion, seInfo,                    abi, instructionSet, appDataDir, invokeWith, zygoteArgs);    }

我们看到调用到了zygoteProcess.start方法,zygoteProcess是和zygote进程保持通信状态的,进入内部查看方法:
frameworks/base/services/core/java/com/android/os/ZygoteProcess.java

public final Process.ProcessStartResult start(final String processClass,                                                  final String niceName,                                                  int uid, int gid, int[] gids,                                                  int runtimeFlags, int mountExternal,                                                  int targetSdkVersion,                                                  String seInfo,                                                  String abi,                                                  String instructionSet,                                                  String appDataDir,                                                  String invokeWith,                                                  String[] zygoteArgs) {             try {                 return startViaZygote(processClass, niceName, uid, gid, gids,                    runtimeFlags, mountExternal, targetSdkVersion, seInfo,                    abi, instructionSet, appDataDir, invokeWith, false /* startChildZygote */,                    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方法:

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

private Process.ProcessStartResult startViaZygote(final String processClass,                                                      final String niceName,                                                      final int uid, final int gid,                                                      final int[] gids,                                                      int runtimeFlags, int mountExternal,                                                      int targetSdkVersion,                                                      String seInfo,                                                      String abi,                                                      String instructionSet,                                                      String appDataDir,                                                      String invokeWith,                                                      boolean startChildZygote,                                                      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);        argsForZygote.add("--runtime-flags=" + runtimeFlags);                ...        argsForZygote.add(processClass);        if (extraArgs != null) {                 for (String arg : extraArgs) {                     argsForZygote.add(arg);            }        }        synchronized(mLock) {                 return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);        }    }

可以看到前面大部分工作实在封装参数到argsForZygote,最后用于调用到zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote)。其中第一个参数是一个方法,返回ZygoteState,第二个就是封装的参数argsForZygote,用于zygote进程接受请求后创建进程使用。

我们先看openZygoteSocketIfNeeded,返回一个ZygoteState, 源码如下:

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

    private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {             Preconditions.checkState(Thread.holdsLock(mLock), "ZygoteProcess lock not held");        if (primaryZygoteState == null || primaryZygoteState.isClosed()) {                 try {                     /**1 与zygote进程建立连接*/                primaryZygoteState = ZygoteState.connect(mSocket);            } catch (IOException ioe) {                     throw new ZygoteStartFailedEx("Error connecting to primary zygote", ioe);            }        }        /**2 连接zygote主模式返回的ZygoteState是否与应用程序进程所需要的ABI匹配,匹配就return返回*/        if (primaryZygoteState.matches(abi)) {                 return primaryZygoteState;        }        /**3 如果主模式不匹配的话,尝试连接第二种辅助模式*/        if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) {                 try {                     secondaryZygoteState = ZygoteState.connect(mSecondarySocket);            } catch (IOException ioe) {                     throw new ZygoteStartFailedEx("Error connecting to secondary zygote", ioe);            }        }        /**4 如果辅助模式匹配的话就return返回*/        if (secondaryZygoteState.matches(abi)) {                 return secondaryZygoteState;        }        /**5 如果都不匹配的话就抛出异常*/        throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi);    }

我们在Zygote进程启动篇中分析过了在ZygoteInit的main函数中通过registerZygoteSocket注册了一个名字为zygote的socket, 这里就是尝试与zygote进程的socket通信,返回一个ZygoteState,如果最后都不匹配的话就抛出异常。

返回的ZygoteState作为参数被zygoteSendArgsAndGetResult调用,源码如下:

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

private static Process.ProcessStartResult zygoteSendArgsAndGetResult(            ZygoteState zygoteState, ArrayList<String> args)            throws ZygoteStartFailedEx {             try {             // 1            final BufferedWriter writer = zygoteState.writer;            final DataInputStream inputStream = zygoteState.inputStream;            writer.write(Integer.toString(args.size()));            writer.newLine();// 2            for (int i = 0; i < sz; i++) {                     String arg = args.get(i);                writer.write(arg);                writer.newLine();            }            writer.flush();            // Should there be a timeout on this?            Process.ProcessStartResult result = new Process.ProcessStartResult();            // Always read the entire result from the input stream to avoid leaving            // bytes in the stream for future process starts to accidentally stumble            // upon.            result.pid = inputStream.readInt();            result.usingWrapper = inputStream.readBoolean();            if (result.pid < 0) {                     throw new ZygoteStartFailedEx("fork() failed");            }            return result;        } catch (IOException ex) {                 zygoteState.close();            throw new ZygoteStartFailedEx(ex);        }    }

从上面注释1处和注释2处我们看到,此方法的主要目的就是将请求的参数args写入到ZygoteState中,ZygoteState是ZygoteProcess的静态内部类,用于表示与Zygote进程通信的状态,到此第一部分AMS发送请求分析完毕。


Zygote进程接受AMS请求创建应用程序进程

时序图如下:

我们首先回顾下Zygote进程如何处理AMS发送的请求的,不熟悉的小伙伴可以点击Zygote进程启动过程解析查看,它是通过runSelectLoop不停的循环来接受AMS发送的请求,ZygoteInit 9.0的源码和7.0的源码大同小异,我们看main方法:

frameworks/base/core/java/com/android/internal/os/ZygoteInit

public static void main(String argv[]) {             ZygoteServer zygoteServer = new ZygoteServer();        ...Runnable caller = zygoteServer.runSelectLoop(abiList);        } catch (Throwable ex) {             } finally {                 zygoteServer.closeServerSocket();        }        if (caller != null) {                 caller.run();        }

接着进入到了runSelectLoop,源码如下:

frameworks/base/core/java/com/android/internal/os/ZygoteServer

Runnable runSelectLoop(String abiList) {             ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();        ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();        fds.add(mServerSocket.getFileDescriptor());        peers.add(null);        while (true) {                 StructPollfd[] pollFds = new StructPollfd[fds.size()];            for (int i = 0; i < pollFds.length; ++i) {                     pollFds[i] = new StructPollfd();                pollFds[i].fd = fds.get(i);                pollFds[i].events = (short) POLLIN;            }                if (i == 0) {                         ZygoteConnection newPeer = acceptCommandPeer(abiList);                    peers.add(newPeer);                    fds.add(newPeer.getFileDesciptor());                } else {                         try {                             ZygoteConnection connection = peers.get(i);                        // 2                        final Runnable command = connection.processOneCommand(this);                        if (mIsForkChild) {                                 return command;                        } else {                                 if (connection.isClosedByPeer()) {                                     connection.closeSocket();                                peers.remove(i);                                fds.remove(i);                            }                        }                    } catch (Exception e) {                         }                }            }        }    }

在注释1处i==0说明zygote进程和system_server进程的AMS建立了连接, 通过acceptCommandPeer返回ZygoteConnection,然后将相关对象分别添加到peers和fds中。注释2处i>0说明ActivityManagerService向Zygote进程发送了一个创建应用进程的请求,然后调用ZygoteConnection的processOneCommand函数来创建一个新的应用程序进程, 进入查看源码:

frameworks/base/core/java/com/android/internal/os/ZygoteConnection

    Runnable processOneCommand(ZygoteServer zygoteServer) {             pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,                parsedArgs.runtimeFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,                parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.startChildZygote,                parsedArgs.instructionSet, parsedArgs.appDataDir);...// 1String args[] args = readArgumentList();                // 2 parsedArgs = new Arguments(args);// 3        pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,                parsedArgs.runtimeFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,                parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.startChildZygote,                parsedArgs.instructionSet, parsedArgs.appDataDir);                        try {                 if (pid == 0) {                     // in child                // 4                 return handleChildProc(parsedArgs, descriptors, childPipeFd,                        parsedArgs.startChildZygote);            } else {                     handleParentProc(pid, descriptors, serverPipeFd);                return null;            }        }    }

注释1处读取应用程序启动参数。注释2处将参数封装到Arguments对象中。注释3处开始通过Zygote.forkAndSpecialize创建应用程序进程,参数来自于注释2处,通过fork zygote进程创建应用程序进程,返回了一个pid的值,如果pid=0的话,说明是代码运行在子进程中,我们进入注释4处的handleChildProc查看:

frameworks/base/core/java/com/android/internal/os/ZygoteConnection

private Runnable handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors,            FileDescriptor pipeFd, boolean isZygote) {     ...return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs,                        null /* classLoader */);    }

进入到ZygoteInit类的zygoteInit方法,源码如下:

frameworks/base/core/java/com/android/internal/os/ZygoteInit

public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {             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         ZygoteInit.nativeZygoteInit();        // 2        return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);    }

在注释1启动Binder线程池,注释2处调用RuntimeInit.applicationInit方法:

frameworks/base/core/java/com/android/internal/os/RuntimeInit

protected static Runnable applicationInit(int targetSdkVersion, String[] argv,            ClassLoader classLoader) {             ...        final Arguments args = new Arguments(argv);        return findStaticMain(args.startClass, args.startArgs, classLoader);    }

findStaticMain方法源码如下:

protected static Runnable findStaticMain(String className, String[] argv,            ClassLoader classLoader) {             Class<?> cl;        try {                 cl = Class.forName(className, true, classLoader);        } catch (ClassNotFoundException ex) {             }        Method m;        try {                 m = cl.getMethod("main", new Class[] {      String[].class });        } catch (NoSuchMethodException ex) {             }return new MethodAndArgsCaller(m, argv);    }

findStaticMain中的className是ActivityThread,通过反射将m封装到MethodAndArgsCaller这个Runnable中,这个Runnable最终返回到了ZygoteInit的main方法中, 如下:

public static void main(String argv[]) {             ZygoteServer zygoteServer = new ZygoteServer();        ...Runnable caller = zygoteServer.runSelectLoop(abiList);        } catch (Throwable ex) {             } finally {                 zygoteServer.closeServerSocket();        }        if (caller != null) {         // 1             caller.run();        }

上面注释1处调用了run方法,也就是调用了ActivityThread的main方法,那么我们的应用程序进程就创建完成,并且运行了ActivityThread。到此应用程序进程启动源码分析结束。

更多相关文章

  1. 四步搞定Android(安卓)SDK环境
  2. Android架构纵横谈之――软件自愈能力 (2)
  3. Android(安卓)Binder设计与实现 – 设计篇
  4. 学习之Android运行原理
  5. 开发前奏曲之添加Android(安卓)SDK平台工具
  6. [Android开发实战]Android手势密码(支付宝手势密码)实现(支持2.x)
  7. Activity组件的启动过程
  8. 控制Android应用权限的五种方法
  9. 转:解开Android应用程序组件Activity的”singleTask”之谜

随机推荐

  1. Android(安卓)图片缩放,手势,事件
  2. Android中xml生成
  3. Android:Google Play services and OAuth
  4. android samsung note3  device not fou
  5. Android评论留言页面
  6. Android中下拉列表框操作
  7. android 脸部抠图
  8. Android(安卓)项目混编flutter报错
  9. Android回调事件传播-android学习之旅(四
  10. Android之常用功能代码