美文网首页
Launcher 启动应用程序

Launcher 启动应用程序

作者: 石器时代小古董 | 来源:发表于2020-03-17 16:12 被阅读0次

    请求 AMS 创建应用服务进程

    Launcher 通过调用 AMS 请求创建应用程序的进程

    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, int isolatedUid, boolean keepIfLarge,
                String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
                    
      .....
        // 获取要创建应用程序进程的用户 ID
        final int userId = UserHandle.getUserId(app.uid);
        int uid = app.uid;
        // 给用户组的 id 进行赋值
        int[] gids = null;
        gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
        gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
        gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
        // 启动进程
        startResult = Process.start(entryPoint,
                            app.processName, uid, uid, gids, debugFlags, mountExternal,
                            app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                            app.info.dataDir, invokeWith, entryPointArgs);
    }
    

    Process 的实例对象是 ZygoteProcess,这里是请求 ZygoteProcess 创建一个进程,并且创建成功后悔调用它的 main 函数

    frameworks/base/core/java/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 {
                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);
            }
        }
    

    start和startViaZygote实际上是通过 openZygoteSocketIfNeed 函数请求和 Zygote 服务建立 Socket 通信

     private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
            if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
                try {
                    primaryZygoteState = ZygoteState.connect(mSocket);
                } catch (IOException ioe) {
                    throw new ZygoteStartFailedEx("Error connecting to primary zygote", ioe);
                }
            }
    
            if (primaryZygoteState.matches(abi)) {
                return primaryZygoteState;
            }
    
            // The primary zygote didn't match. Try the secondary.
            if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) {
                try {
                    secondaryZygoteState = ZygoteState.connect(mSecondarySocket);
                } catch (IOException ioe) {
                    throw new ZygoteStartFailedEx("Error connecting to secondary zygote", ioe);
                }
            }
    
     }
    

    ZygoteInit 服务接收到 AMS 的 Socket 链接

    Zygote 服务在被 init 服务创建的时候就启动了一个 Socket 服务,等待着 AMS 的接入

    zygoteServer.runSelectLoop(abiList);
    

    ZygoteServer 的 runSelectLoop

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

    在请求第一次进入的时候,会将请求放入到集合中管理,再发起下一次轮训的时候会调用 ZygoteConnection 的 runOnce 方法解析请求

     Runnable runSelectLoop(String abiList) {
            ArrayList<FileDescriptor> socketFDs = new ArrayList<>();
            ArrayList<ZygoteConnection> peers = new ArrayList<>();
        
         while (true) {
             ....
              for (int i = pollFds.length - 1; i >= 0; --i) {
                    if ((pollFds[i].revents & POLLIN) == 0) {
                        continue;
                    }
                    if (i == 0) {
                        ZygoteConnection newPeer = acceptCommandPeer(abiList);
                        peers.add(newPeer);
                        fds.add(newPeer.getFileDesciptor());
                    } else {
                        boolean done = peers.get(i).runOnce(this);
                        if (done) {
                            peers.remove(i);
                            fds.remove(i);
                        }
                    }
                }
             ....
         }       
     }
    

    ZygoteConnection 的 runOnce 方法

    1. 解析启动进程的参数
    2. 创建应用的进程
    3. 处理子进程
     boolean runOnce(ZygoteServer zygoteServer) throws Zygote.MethodAndArgsCaller {
      
            Arguments parsedArgs = null;
            FileDescriptor[] descriptors;
    
            try {
                args = readArgumentList();
                // 根据传入的参数创建进程
                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(IOException ex){
                return true;
            }
            // 创建好进程,让后续的代码运行在自进程中
            // 如果在子进程中,关闭之前为 Zygote 创建的服务,因为子进程是 fork 自 zygote 的,会持有 zygote 的全部内容。
            if (pid == 0) {
                    // in child
                    zygoteServer.closeServerSocket();
                    IoUtils.closeQuietly(serverPipeFd);
                    serverPipeFd = null;
                    // 处理子进程
                    handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);
    
                    // should never get here, the child is expected to either
                    // throw Zygote.MethodAndArgsCaller or exec().
                    return true;
            }
     }
    

    handleChildProc 会在fork出来的进程中运行,调用了 ZygoteInit

     ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion,
                        parsedArgs.remainingArgs, null /* classLoader */);
    

    调用 ZygoteInit 为当前的应用进程创建 Binder 线程池

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

       public static final Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,
                String[] argv, ClassLoader classLoader) {
            .....
            RuntimeInit.commonInit();
            // 创建 Binder 线程池
            ZygoteInit.nativeZygoteInit();
            // 调用应用程序的 ActivityThread 的 main 函数
            return RuntimeInit.applicationInit(targetSdkVersion,disabledCompatChanges, argv,
                    classLoader);
        }
    
    

    RuntimeInit.application 会调用 ActivityThread 的 main 函数

     protected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges,
                String[] argv, ClassLoader classLoader) {
            // 在新的进程环境下调用 ActivityThread 的 main 函数
            invokeStaticMain(args.startClass, args.startArgs, classLoader);              
    } 
    

    ActivityThread 的 main 函数

            ActivityThread thread = new ActivityThread();
            thread.attach(false, startSeq);
    
            if (sMainThreadHandler == null) {
                sMainThreadHandler = thread.getHandler();
            }
    
            if (false) {
                Looper.myLooper().setMessageLogging(new
                        LogPrinter(Log.DEBUG, "ActivityThread"));
            }
    
            // End of event ActivityThreadMain.
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            Looper.loop();
       
    

    相关文章

      网友评论

          本文标题:Launcher 启动应用程序

          本文链接:https://www.haomeiwen.com/subject/enityhtx.html