Android应用程序进程启动流程

frameworks\base\services\core\java\com\android\server\am\
    - ActivityStackSupervisor.java
    - ActivityManagerService.java
    
frameworks\base\core\java\android\
    - os\Process.java
    - app\ActivityThread.java

frameworks\base\core\java\com\android\internal\os\
    - ZygoteInit.java
    - ZygoteConnection.java
    - RuntimeInit.java
    
frameworks\base\core\jni\AndroidRuntime.cpp
frameworks\base\cmds\app_process\app_main.cpp

应用程序进程启动流程

1 AMS 请求 Zygote 创建应用程序进程

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

void startSpecificActivityLocked(ActivityRecord r,
        boolean andResume, boolean checkConfig) {
    // 获取 Activity 组件所在的进程信息
    ProcessRecord app = mService.getProcessRecordLocked(r.processName,
            r.info.applicationInfo.uid, true);
    if (app != null && app.thread != null) {
        try {
	        // 启动 Activity 组件
            realStartActivityLocked(r, app, andResume, checkConfig);
            return;
        } catch (RemoteException e) {
        }
    }
	// 创建应用程序进程
    mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
            "activity", r.intent.getComponent(), false, false, true);
}

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) {
    // 参数 entryPoint/entryPointArgs 为 null
    return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
            hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
            null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
            null /* crashHandler */);
}

// entryPoint = null
final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
        boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
        boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
        String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
    ProcessRecord app;
    ...
    if (app == null) {
        // AMS 通过 ProcessRecord 记录每个进程的信息
        app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
        ...
    } else {
    }
    ...
    // 继续执行启动进程操作
    startProcessLocked(
            app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
    ...
    return (app.pid != 0) ? app : null;
}

private final void startProcessLocked(ProcessRecord app, String hostingType,
        String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
    ...
    try {
    	...
        // 根据前面入参可以知道 entryPoint = null,设置启动文件为 ActivityThread
        if (entryPoint == null) entryPoint = "android.app.ActivityThread";
        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);
        ...
    } catch (RuntimeException e) {
    }
}

frameworks\base\core\java\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[] zygoteArgs) {
    try {
        return startViaZygote(processClass, niceName, uid, gid, gids,
                debugFlags, mountExternal, targetSdkVersion, seInfo,
                abi, instructionSet, appDataDir, zygoteArgs);
    } catch (ZygoteStartFailedEx ex) {
    }
}

// processClass = android.app.ActivityThread
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) {
        // 保存进程信息参数
        ArrayList<String> argsForZygote = new ArrayList<String>();

        // --runtime-args, --setuid=, --setgid=,
        // 配置 uid,gid
        argsForZygote.add("--runtime-args");
        argsForZygote.add("--setuid=" + uid);
        argsForZygote.add("--setgid=" + gid);
        ...
        // 配置进程名称
        if (niceName != null) { // 
            argsForZygote.add("--nice-name=" + niceName);
        }
        ...
        // 配置进程启动文件 android.app.ActivityThread
        argsForZygote.add(processClass);
        ...
        return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
    }
}

// 向 zygote 进程的 socket 发送启动数据
private static ProcessStartResult zygoteSendArgsAndGetResult(
        ZygoteState zygoteState, ArrayList<String> args)
        throws ZygoteStartFailedEx {
    try {
        // 获取 Zygote 进程中名为 zygote 的 socket 的输出流对象
        final BufferedWriter writer = zygoteState.writer;
        // 获取 Zygote 进程中名为 zygote 的 socket 的输入流对象
        final DataInputStream inputStream = zygoteState.inputStream;
        // 向 socket 发送参数数量
        writer.write(Integer.toString(args.size()));
        writer.newLine();
        // 依次发送列表中的数据
        int sz = args.size();
        for (int i = 0; i < sz; i++) {
            String arg = args.get(i);
            writer.write(arg);
            writer.newLine();
        }

        writer.flush();
        // 等待 zygote 进程的返回
        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) {
    }
}
  1. AMS 判断需要启动的 Activity 组件所在的进程是否已经存在,AMS 通过 ProcessRecord 对象来管理应用程序进程, ProcessRecord == null 表示需要启动应用程序进程(接下来按照 ProcessRecord = null 流程执行);
  2. AMS 将目标进程的启动参数保存到列表中包括: uidgidniceName以及应用程序进程启动文件 android.app.ActivityThread;
  3. 通过 socket 向注册在 Zygote 进程中名为 zygotesocket 发送创建应用程序进程的请求;

以上三步都是在 AMS 进程中执行的;

2 Zygote 接收请求 fork 应用程序进程

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

public static void main(String argv[]) {
    try {
        ...
        // 创建 zygote socket
        registerZygoteSocket(socketName);
        ...
        // 等待 AMS 请求创建应用程序进程
        runSelectLoop(abiList);
        
    } catch (MethodAndArgsCaller caller) {
        // 通过异常的方式回到 main() 中
        caller.run();
    } catch (RuntimeException ex) {
    }
}

// zygote 进程等待 AMS 进程请求
private static void runSelectLoop(String abiList) throws MethodAndArgsCaller {
    ...
    while (true) {  // 开启循环等待
        StructPollfd[] pollFds = new StructPollfd[fds.size()];
        ...
        try {
            // 处理轮询状态,当 pollFds 中有事件到来时往下执行,否则阻塞在这里
            Os.poll(pollFds, -1);
        } catch (ErrnoException ex) {
        }
        for (int i = pollFds.length - 1; i >= 0; --i) {
            ...
            if (i == 0) {   // i = 0 表示有新的客户端请求到来
                ZygoteConnection newPeer = acceptCommandPeer(abiList);
                peers.add(newPeer);
                fds.add(newPeer.getFileDesciptor());
            } else {    // i != 0 表示接收到 socket 客户端的消息
                boolean done = peers.get(i).runOnce();
                ...
            }
        }
    }
}

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

boolean runOnce() throws ZygoteInit.MethodAndArgsCaller {

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

    try {
        // 从 socket 中读取应用程序进程的启动参数(字符数组)
        args = readArgumentList();
        descriptors = mSocket.getAncillaryFileDescriptors();
    } catch (IOException ex) {
    }
    ...
    try {
        // 封装应用程序进程启动参数
        parsedArgs = new Arguments(args);
        ...
        // 创建应用程序进程
        pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
                parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
                parsedArgs.niceName, fdsToClose, parsedArgs.instructionSet,
                parsedArgs.appDataDir);
    } catch (ErrnoException ex) {
    } catch (IllegalArgumentException ex) {
    } catch (ZygoteSecurityException ex) {
    }

    try {
        if (pid == 0) { // 返回的应用程序进程中调用
            // in child
            handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);
            ...
            return true;
        } else {    // 返回的 zygote 进程中调用
            ...
            return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);
        }
    } finally {
    }
}

private void handleChildProc(Arguments parsedArgs,
        FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr)
        throws ZygoteInit.MethodAndArgsCaller {
    // 关闭从 zygote 进程中复制过来的 socket
    closeSocket();
    ZygoteInit.closeServerSocket();
    ...
    if (parsedArgs.niceName != null) {
        // 设置应用程序进程的名称
        Process.setArgV0(parsedArgs.niceName);
    }

    if (parsedArgs.invokeWith != null) {
        ...
    } else {
        // 进一步初始化应用程序进程
        // 执行的流程跟 SystemServer 进程类似
        RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion,
                parsedArgs.remainingArgs, null /* classLoader */);
    }
}
  1. Zygote 进程通过 socket 监听 AMS 进程发送过来的请求;
  2. Zygote接收到请求后,通过 ZygoteConnection 读取启动参数,然后根据启动参数 fork 一个子进程(应用程序进程),fork 会有两次返回;
    • pid > 0: 表示 zygote 进程中返回;
    • pid = 0: 表示子进程中返回,此时代码运行在子进程中;
  3. 子进程中返回后,首先会关闭从 zygote 进程中拷贝过来的 socket 然后设置进程名称,接下来就是初始化应用程序进程的相关信息;

3 初始化应用程序进程并通知AMS

应用程序进程的初始化操作跟 SystemServer 进程的初始化操作类似,其主要流程如下

  1. 调用 commonInit() 设置 应用程序 进程的时区/键盘等信息;
  2. 通过 nativeZygoteInit() 调用 ProcessState::self()->startThreadPool() 创建 应用程序 进程的 Binder 线程池;
  3. 应用初始化:
    1. 设置虚拟机内存利用率为 0.75;
    2. 加载 android.app.ActivityThread 类信息等并包装到 ZygoteInit.MethodAndArgsCaller 异常对象中;
    3. 通过抛出异常的方式回到 ZygoteInit.main() 中;
    4. 捕获第 3 步中的异常信息,通过反射执行 ActivityThread.main();

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

public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
        throws ZygoteInit.MethodAndArgsCaller {
    // 定向输出 log
    redirectLogStreams();
    // 通用模块初始化
    commonInit();
    // 通过 ProcessState 为应用程序进程创建 Binder 线程池
    nativeZygoteInit();
    // 应用程序进程初始化
    applicationInit(targetSdkVersion, argv, classLoader);
}

private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
        throws ZygoteInit.MethodAndArgsCaller {
    ...
    final Arguments args;
    try {
        // 封装启动参数
        args = new Arguments(argv);
    } catch (IllegalArgumentException ex) {
    }
    
    invokeStaticMain(args.startClass, args.startArgs, classLoader);
}

// className = android.app.ActivityThread
private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
        throws ZygoteInit.MethodAndArgsCaller {
    Class<?> cl;

    try {
        // 加载 android.app.ActivityThread 类
        cl = Class.forName(className, true, classLoader);
    } catch (ClassNotFoundException ex) {
    }

    Method m;
    try {
        // 获取 ActivityThread.main() 函数
        m = cl.getMethod("main", new Class[] { String[].class });
    } catch (NoSuchMethodException ex) {
    } catch (SecurityException ex) {
    }
    ...
    // 通过抛出异常回到 ZygoteInit.main(),然后调用 ZygoteInit.MethodAndArgsCaller.run()
    throw new ZygoteInit.MethodAndArgsCaller(m, argv);
}

3.1 创建 Binder 线程池

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

// native 函数
private static final native void nativeZygoteInit();

frameworks\base\core\jni\AndroidRuntime.cpp

static void com_android_internal_os_RuntimeInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
    // gCurRuntime 指针指向一个类型为 AndroidRuntime 类型的对象
    // AndroidRuntime 为一个抽象类,实际指向的是一个 AppRuntime 对象
    gCurRuntime->onZygoteInit();
}

frameworks\base\cmds\app_process\app_main.cpp

// AppRuntime 继承自 AndroidRuntime
class AppRuntime : public AndroidRuntime
{
public:
    ...
    virtual void onZygoteInit()
    {
        // 获取每个进程单例的 ProcessState 对象
        // ProcessState 对象创建的时候会打开 Binder 驱动
        sp<ProcessState> proc = ProcessState::self();
        // 通过 ProcessState 对象创建 Binder 线程池
        proc->startThreadPool();
    }
    ...
};

nativeZygoteInit() 对应 nativeAndroidRuntime.cpp 中的 com_android_internal_os_RuntimeInit_nativeZygoteInit(),其内部持有一个 AndroidRuntime 类型的指针gCurRuntime, Zygote 进程在启动的时候会创建一个 AndroidRuntime 的子类 AppRuntime 对象,应用程序进程 forkZygote 进程,因此 gCurRuntime->onZygoteInit() 调用的是 AppRuntime 中的函数;

AppRuntime.onZygoteInit() 首先通过 ProcessState.self() 获取一个进程单例的 ProcessState 对象,ProcessState 在其初始化的时候会打开 Binder 驱动,然后通过 ProcessState.startThreadPool() 为应用程序进程创建 Binder 线程池;

3.2 创建 ActivityThread 启动消息循环并通知 AMS

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

public class ZygoteInit {
    ...
    public static class MethodAndArgsCaller extends Exception
            implements Runnable {
        ...
        public MethodAndArgsCaller(Method method, String[] args) {
            mMethod = method;
            mArgs = args;
        }

        public void run() {
            try {
                // 通过反射调用 ActivitThread.main()
                mMethod.invoke(null, new Object[] { mArgs });
            } catch (IllegalAccessException ex) {
            } catch (InvocationTargetException ex) {
            }
        }
    }
}

frameworks\base\core\java\android\app\ActivityThread.java

public static void main(String[] args) {
    ...
    // 创建应用程序进程主线程的消息队列
    Looper.prepareMainLooper();
    ActivityThread thread = new ActivityThread();
    // 应用程序进程创建完毕,通知 AMS 进程
    thread.attach(false);
    if (sMainThreadHandler == null) {
        // 获取主线程Handler(H类)
        sMainThreadHandler = thread.getHandler();
    }
    ...
    // 启动消息循环
    Looper.loop();
}

private void attach(boolean system) {
    ...
    if (!system) {  // 非系统进程
        // 获取 AMS 代理对象
        final IActivityManager mgr = ActivityManagerNative.getDefault();
        try {
            // 通知 AMS 应用程序进程创建完毕
            mgr.attachApplication(mAppThread);
        } catch (RemoteException ex) {
        }
        ...
    } else {
        ...
    }
    ...
}

应用程序进程通过 AMS 传递过来的启动文件 android.app.ActivityThread 加载类信息,并找到其内部的静态函数 main(),然后将启动参数和 main() 函数封装到一个实现了 Runnable 接口的异常类 MethodAndArgsCaller 中抛出。接着该异常会在 ZygoteInit.main() 中捕获并执行 MethodAndArgsCaller.run() 通过反射调用 ActivityThread.main() ,其主要功能如下:

  1. 创建应用程序进程主线程的消息队列 Looper.prepareMainLooper();
  2. 为应用程序创建一个 ActivityThread 对象并调用 attach(false) 通知 AMS 进程应用程序进程创建完毕;
  3. 启动消息循环 Looper.loop();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值