64位Android應用程序安裝與應用程序啓動分析

一、Android應用程序安裝到PackageManagerService過程


二、Android應用程序通過ActivityManagerService啓動過程

1.應用程序Activity組件啓動過程分析


2.應用程序Service組件啓動過程分析


3.與zygote進程交互

SystemServer進程

system    2032  1174  1616620 81100 ffffffff b59a2c84 S system_server

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

<span style="font-size:14px;">    private final void startProcessLocked(ProcessRecord app, String hostingType,
            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
            ......
            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); //ProcessRecord process
            ......
    }</span>
frameworks/base/core/java/android/os/Process.java 

<span style="font-size:14px;">    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) {
      ......
            return startViaZygote(processClass, niceName, uid, gid, gids,
                    debugFlags, mountExternal, targetSdkVersion, seInfo,
                    abi, instructionSet, appDataDir, zygoteArgs);
      ......
    }    
    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 {
      return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
    }


    //public static final String ZYGOTE_SOCKET = "zygote";


    private static 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();


            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;      
    }</span>
zygote進程

root      1174  1     1479696 62808 ffffffff b59a22c4 S zygote64
root      1175  1     1166056 55176 ffffffff f70ae9c8 S zygote
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

<span style="font-size:14px;">//String socketName = "zygote";


    public static void main(String argv[]) {
            String socketName = "zygote";
            registerZygoteSocket(socketName);
            gc();
            if (startSystemServer) {
                startSystemServer(abiList, socketName);
            }
            runSelectLoop(abiList);
    }
    private static void runSelectLoop(String abiList) throws MethodAndArgsCaller {
        while (true) {
                gc();
                done = peers.get(index).runOnce();
        }
    }</span>
frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java

<span style="font-size:14px;">    boolean runOnce() throws ZygoteInit.MethodAndArgsCaller {
            pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
                    parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
                    parsedArgs.niceName, fdsToClose, parsedArgs.instructionSet,
                    parsedArgs.appDataDir);
            if (pid == 0) {
                // in child
                IoUtils.closeQuietly(serverPipeFd);
                serverPipeFd = null;
                handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);


                // should never get here, the child is expected to either
                // throw ZygoteInit.MethodAndArgsCaller or exec().
                return true;
            } else {
                // in parent...pid of < 0 means failure
                IoUtils.closeQuietly(childPipeFd);
                childPipeFd = null;
                return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);
            }
    }</span>
frameworks/base/core/java/com/android/internal/os/Zygote.java

<span style="font-size:14px;">    public static int forkAndSpecialize(int uid, int gid, int[] gids, int debugFlags,
          int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
          String instructionSet, String appDataDir) {
        int pid = nativeForkAndSpecialize(
                  uid, gid, gids, debugFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
                  instructionSet, appDataDir);
    }</span>
frameworks/base/core/jni/com_android_internal_os_Zygote.cpp

<span style="font-size:14px;">static jint com_android_internal_os_Zygote_nativeForkAndSpecialize(
        JNIEnv* env, jclass, jint uid, jint gid, jintArray gids,
        jint debug_flags, jobjectArray rlimits,
        jint mount_external, jstring se_info, jstring se_name,
        jintArray fdsToClose, jstring instructionSet, jstring appDataDir) {
    return ForkAndSpecializeCommon(env, uid, gid, gids, debug_flags,
            rlimits, capabilities, capabilities, mount_external, se_info,
            se_name, false, fdsToClose, instructionSet, appDataDir);
}


static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray javaGids,
                                     jint debug_flags, jobjectArray javaRlimits,
                                     jlong permittedCapabilities, jlong effectiveCapabilities,
                                     jint mount_external,
                                     jstring java_se_info, jstring java_se_name,
                                     bool is_system_server, jintArray fdsToClose,
                                     jstring instructionSet, jstring dataDir) {
  pid_t pid = fork();
}</span>

4.應用程序zygote孵化

<span style="font-size:14px;">    primaryCpuAbi=null  //默認64bit
    secondaryCpuAbi=null

    primaryCpuAbi=armeabi  //32bit
    secondaryCpuAbi=null

    primaryCpuAbi=arm64-v8a //64bit
    secondaryCpuAbi=null</span>

參考如下prop屬性

shell@coconut_cq:/ # getprop ro.product.cpu.abilist
arm64-v8a,armeabi-v7a,armeabi


shell@coconut_cq:/ # getprop ro.product.cpu.abilist64
arm64-v8a
shell@coconut_cq:/ # getprop ro.product.cpu.abilist32                          
armeabi-v7a,armeabi


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章