进程启动源码分析

来源:互联网 发布:nginx lua module 编辑:程序博客网 时间:2024/05/19 12:14

1, 概述

在android中,进程的概念被弱化了,主要是四大组件,但是四大组件也运行于进程中;AMS负责管理和调度进程,

主要体现在启动进程,动态地根据组件调整进程在mLruProcesses列表中的位置,还可以调整进程的优先级,

这2项都和系统的内存回收相关。并且,一个进程里面可以运行多个apk(通过Shareuid的方法),

一个apk也可以运行在多个进程里(通过配置Android:process)

2, 进程启动

进程看不见摸不着,是在启动四大组件之前启动的。就是说,启动四大组件时会查看组件所在的进程是否启动,如果没有启动就首先启动该进程。

并且都会调用AMS的startProcessLocked方法来启动进程。


启动进程实在AMS的startProcessLocked方法中,当客户端调用startActivity时,会直接调用Activity.java的对应函数

private final void startProcessLocked(ProcessRecord app, String hostingType,String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {        long startTime = SystemClock.elapsedRealtime();        •••    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);   •••}

直接看最主要的Process.start方法,

public static final ProcessStartResult start(final String processClass,                                  final String niceName,                                  int uid, int gid, int[] gids,                                  int debugFlags, int mountExternal,                                  int targetSdkVersion,                                  String seInfo,                                  String abi,                                  String instructionSet,                                  String appDataDir,                                  String[] zygoteArgs) {        try {            return startViaZygote(processClass, niceName, uid, gid, gids,                    debugFlags, mountExternal, targetSdkVersion, seInfo,                    abi, instructionSet, appDataDir, zygoteArgs);        } catch (ZygoteStartFailedEx ex) {            Log.e(LOG_TAG, "Starting VM process through Zygote failed");            throw new RuntimeException(                    "Starting VM process through Zygote failed", ex);        }    }


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=,            // and --setgroups= must go first            argsForZygote.add("--runtime-args");            argsForZygote.add("--setuid=" + uid);            argsForZygote.add("--setgid=" + gid);            if ((debugFlags & Zygote.DEBUG_ENABLE_JNI_LOGGING) != 0) {                argsForZygote.add("--enable-jni-logging");            }            if ((debugFlags & Zygote.DEBUG_ENABLE_SAFEMODE) != 0) {                argsForZygote.add("--enable-safemode");            }            if ((debugFlags & Zygote.DEBUG_ENABLE_DEBUGGER) != 0) {                argsForZygote.add("--enable-debugger");            }            if ((debugFlags & Zygote.DEBUG_ENABLE_CHECKJNI) != 0) {                argsForZygote.add("--enable-checkjni");            }            if ((debugFlags & Zygote.DEBUG_ENABLE_JIT) != 0) {                argsForZygote.add("--enable-jit");            }            if ((debugFlags & Zygote.DEBUG_GENERATE_DEBUG_INFO) != 0) {                argsForZygote.add("--generate-debug-info");            }            if ((debugFlags & Zygote.DEBUG_ENABLE_ASSERT) != 0) {                argsForZygote.add("--enable-assert");            }            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");            }            argsForZygote.add("--target-sdk-version=" + targetSdkVersion);            //TODO optionally enable debuger            //argsForZygote.add("--enable-debugger");            // --setgroups is a comma-separated list            if (gids != null && gids.length > 0) {                StringBuilder sb = new StringBuilder();                sb.append("--setgroups=");                int sz = gids.length;                for (int i = 0; i < sz; i++) {                    if (i != 0) {                        sb.append(',');                    }                    sb.append(gids[i]);                }                argsForZygote.add(sb.toString());            }            if (niceName != null) {                argsForZygote.add("--nice-name=" + niceName);            }            if (seInfo != null) {                argsForZygote.add("--seinfo=" + seInfo);            }            if (instructionSet != null) {                argsForZygote.add("--instruction-set=" + instructionSet);            }            if (appDataDir != null) {                argsForZygote.add("--app-data-dir=" + appDataDir);            }            argsForZygote.add(processClass);            if (extraArgs != null) {                for (String arg : extraArgs) {                    argsForZygote.add(arg);                }            }            return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);        }    }

ProcessStartResult方法主要是保存所要启动进程的各种信息,

然后通过zygoteSendArgsAndGetResult方法将这些信息发送到zygoteState进程中。

private static ProcessStartResult zygoteSendArgsAndGetResult(            ZygoteState zygoteState, ArrayList<String> args)            throws ZygoteStartFailedEx {        try {            /**             * See com.android.internal.os.ZygoteInit.readArgumentList()             * Presently the wire format to the zygote process is:             * a) a count of arguments (argc, in essence)             * b) a number of newline-separated argument strings equal to count             *             * After the zygote process reads these it will write the pid of             * the child or -1 on failure, followed by boolean to             * indicate whether a wrapper process was used.             */            final BufferedWriter writer = zygoteState.writer;            final DataInputStream inputStream = zygoteState.inputStream;            writer.write(Integer.toString(args.size()));            writer.newLine();            int sz = args.size();            for (int i = 0; i < sz; i++) {                String arg = args.get(i);                if (arg.indexOf('\n') >= 0) {                    throw new ZygoteStartFailedEx(                            "embedded newlines not allowed");                }                writer.write(arg);                writer.newLine();            }            writer.flush();            // Should there be a timeout on this?            ProcessStartResult result = new ProcessStartResult();            result.pid = inputStream.readInt();            if (result.pid < 0) {                throw new ZygoteStartFailedEx("fork() failed");            }            result.usingWrapper = inputStream.readBoolean();            return result;        } catch (IOException ex) {            zygoteState.close();            throw new ZygoteStartFailedEx(ex);        }    }

zygoteSendArgsAndGetResult通过socket向zygoteState进程发送创建进程的请求,

实际创建进程的是zygoteState进程中。在zygoteState进程中创建进程在此就不论述了。

进程的创建主要分为3大步:

1, system_server进程:AMS通过通过Process.start()方法发起创建新进程请求,

   会先收集各种新进程uid、gid、nice-name等相关的参数,然后通过socket通道发送给zygote进程,向zygoteState发送启动进程的请求

2, zygote进程: runSelectLoop方法创建并初始化进程,handleChildProc()方法回调新进程的main方法。

3, 新进程:进程初始化(启动组件)

0 0
原创粉丝点击