美文网首页Android framework
Android系统源码情景分析-学习笔记-12

Android系统源码情景分析-学习笔记-12

作者: 海在路上 | 来源:发表于2022-04-23 11:23 被阅读0次

    Android 应用程序的启动过程

         ActivityManangerService 再启动一个组件的时候,如果这个组件所在的应用程序还没有启动起来,它就会请求Zygote进程,将这个应用程序启动起来。
         Zygote进程通过复制自身的方式来创建一个新的应用程序。由于zygote进程在启动时会在内部创建一个虚拟机实例,因此,通过复制它而得到的应用程序进程就自然得到了一个应用程序实例拷贝。
         应用程序进程在启动过程中,还可以获得一个Binder线程池和一个消息循环,

    应用程序进程的创建过程

         每当ActivityManagerService 需要创建一个新的应用程序来启动一个应用程序组件时,就是通过startProcessLocked 方法向Zygote进程发送一个创建应用程序的请求,

        private final void startProcessLocked(ProcessRecord app,
                String hostingType, String hostingNameStr) {
            
            try {
                int uid = app.info.uid;
                int[] gids = null;
                try {
                    gids = mContext.getPackageManager().getPackageGids(
                            app.info.packageName);
                } catch (PackageManager.NameNotFoundException e) { ... }
                
                
                int pid = Process.start("android.app.ActivityThread",
                        mSimpleProcessManagement ? app.processName : null, uid, uid,
                        gids, debugFlags, null);
                
            } catch (RuntimeException e) { ... }
        }
    
    Process#start
        public static final int start(final String processClass,
                                      final String niceName,
                                      int uid, int gid, int[] gids,
                                      int debugFlags,
                                      String[] zygoteArgs)
        {
            if (supportsProcesses()) {  // 判断是否支持支持Binder进程间通信
                try {
                    return startViaZygote(processClass, niceName, uid, gid, gids,
                            debugFlags, zygoteArgs);
                } catch (ZygoteStartFailedEx ex) { ... }
            } else {
                // 不支持Binder进程间通信机制,然后创建一个线程来模拟一个应用程序
                ...
            }
        }
    
    Process#startViaZygote
        private static int startViaZygote(final String processClass,
                                      final String niceName,
                                      final int uid, final int gid,
                                      final int[] gids,
                                      int debugFlags,
                                      String[] extraArgs)
                                      throws ZygoteStartFailedEx {
            int pid;
    
            synchronized(Process.class) {
                ArrayList<String> argsForZygote = new ArrayList<String>();
    
                // --runtime-init, --setuid=, --setgid=,
                // and --setgroups= must go first
                argsForZygote.add("--runtime-init");
                argsForZygote.add("--setuid=" + uid);
                argsForZygote.add("--setgid=" + gid);
    
                //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);
                }
    
                argsForZygote.add(processClass);
    
                if (extraArgs != null) {
                    for (String arg : extraArgs) {
                        argsForZygote.add(arg);
                    }
                }
                
                pid = zygoteSendArgsAndGetPid(argsForZygote);
            }
    
            return pid;
        }
    
    Process#zygoteSendArgsAndGetPid

    向 zygote 进程发送一个参数列表,该进程启动一个新子进程并返回该子进程的 pid。

        private static int zygoteSendArgsAndGetPid(ArrayList<String> args)
                throws ZygoteStartFailedEx {
    
            int pid;
            // 创建一个连接到Zygote进程的LocalSocket对象
            openZygoteSocketIfNeeded();
    
            try {
                // 将启动参数传递给Zygote进程
                sZygoteWriter.write(Integer.toString(args.size()));
                sZygoteWriter.newLine();
    
                int sz = args.size();
                for (int i = 0; i < sz; i++) {
                    String arg = args.get(i);
                    
                    sZygoteWriter.write(arg);
                    sZygoteWriter.newLine();
                }
    
                sZygoteWriter.flush();
    
                // Should there be a timeout on this?
                pid = sZygoteInputStream.readInt();
    
                ...
            } catch (IOException ex) { ... }
    
            return pid;
        }
    
    ZygoteInit#runSelectLoopMode

         Zygote进程在启动完成之后,会在一个名称为“zygote” 的Socket上等待ActivityManagerService 向它发送创建新的应用程序进程的请求。因此,这一步执行完成之后,Zygote进程就会在ZygoteInit类的静态成员函数runSelectLoopMode中接受到一个创建新的应用程序进程的请求

        private static void runSelectLoopMode() throws MethodAndArgsCaller {
            ArrayList<FileDescriptor> fds = new ArrayList();
            ArrayList<ZygoteConnection> peers = new ArrayList();
            FileDescriptor[] fdArray = new FileDescriptor[4];
    
            fds.add(sServerSocket.getFileDescriptor());
            peers.add(null);
    
            int loopCount = GC_LOOP_COUNT;
            while (true) {
                int index;
    
    
                try {
                    fdArray = fds.toArray(fdArray);
                    index = selectReadable(fdArray);
                } catch (IOException ex) {
                    throw new RuntimeException("Error in select()", ex);
                }
    
                if (index < 0) {
                    throw new RuntimeException("Error in select()");
                } else if (index == 0) {
                    ZygoteConnection newPeer = acceptCommandPeer();
                    peers.add(newPeer);
                    fds.add(newPeer.getFileDesciptor());
                } else {
                    boolean done;
                    done = peers.get(index).runOnce();
    
                    if (done) {
                        peers.remove(index);
                        fds.remove(index);
                    }
                }
            }
        }
    
    ZygoteConnection # runOnce
        boolean runOnce() throws ZygoteInit.MethodAndArgsCaller {
    
            String args[];
            Arguments parsedArgs = null;
            FileDescriptor[] descriptors;
    
            try {
                // 获取创建的应用程序进程的启动参数
                args = readArgumentList();
                descriptors = mSocket.getAncillaryFileDescriptors();
            } catch (IOException ex) {
                ...
            }
    
            ...
    
            int pid;
    
            try {
                parsedArgs = new Arguments(args);
    
                ...
    
                pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid,
                        parsedArgs.gids, parsedArgs.debugFlags, rlimits);
            }
    
            if (pid == 0) {
                // in child
                handleChildProc(parsedArgs, descriptors, newStderr);
                // should never happen
                return true;
            } 
        }
    
    ZygoteConnection # handleChildProc

    通过调用handleChildProc来启动这个子进程

        private void handleChildProc(Arguments parsedArgs,
                FileDescriptor[] descriptors, PrintStream newStderr)
                throws ZygoteInit.MethodAndArgsCaller {
            // 存在参数 “--runtime-init” 参数
            if (parsedArgs.runtimeInit) {
                RuntimeInit.zygoteInit(parsedArgs.remainingArgs);
            } else {
                ...
            }
        }
    
    RuntimeInit # zygoteInit
        public static final void zygoteInit(String[] argv)
                throws ZygoteInit.MethodAndArgsCaller {
    
            commonInit();
            // 启动一个Binder线程池
            zygoteInitNative();
    
            // 启动ActivityThread类的main函数中
            invokeStaticMain(startClass, startArgs);
        }
    

    12.2 Binder线程池的启动过程

    RuntimeInit类的zygoteInitNative的函数来启动一个Binder线程池

    RuntimeInit # zygoteInitNative
        public static final native void zygoteInitNative();
    
    AndroidRuntime # com_android_internal_os_RuntimeInit_zygoteInit
    static void com_android_internal_os_RuntimeInit_zygoteInit(JNIEnv* env, jobject clazz)
    {
        gCurRuntime->onZygoteInit();
    }
    
    app_main.cpp # onZygoteInit
        virtual void onZygoteInit()
        {
            sp<ProcessState> proc = ProcessState::self();
            if (proc->supportsProcesses()) {
                LOGV("App process: starting thread pool.\n");
                proc->startThreadPool();
            }       
        }
    
    ProcessState # startThreadPool
    sp<ProcessState> ProcessState::self()
    {
        if (gProcess != NULL) return gProcess;
        
        AutoMutex _l(gProcessMutex);
        if (gProcess == NULL) gProcess = new ProcessState;
        return gProcess;
    }
    
    ProcessState::ProcessState()
        : mDriverFD(open_driver())
        , mVMStart(MAP_FAILED)
        , mManagesContexts(false)
        , mBinderContextCheckFunc(NULL)
        , mBinderContextUserData(NULL)
        , mThreadPoolStarted(false)
        , mThreadPoolSeq(1)
    {
        if (mDriverFD >= 0) {
            // mmap binder,提供一块虚拟地址空间来接收事务。
            mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
        }
    }
    
    void ProcessState::startThreadPool()
    {
        AutoMutex _l(mLock);
        // 每个支持Binder进程间通信机制的进程内部,只会启动一个Binder线程池,
        if (!mThreadPoolStarted) {
            mThreadPoolStarted = true;
            spawnPooledThread(true);
        }
    }
    
    void ProcessState::spawnPooledThread(bool isMain)
    {
        if (mThreadPoolStarted) {
            int32_t s = android_atomic_add(1, &mThreadPoolSeq);
            char buf[32];
            
            sp<Thread> t = new PoolThread(isMain);
            t->run(buf);
        }
    }
    
    class PoolThread : public Thread
    {
        
    protected:
        virtual bool threadLoop()
        {
            IPCThreadState::self()->joinThreadPool(mIsMain);
            return false;
        }
        
        const bool mIsMain;
    };
    

    消息循环的创建过程

    ActivityThread 的 main 函数中,会创建一个消息循环

        public static final void main(String[] args) {
            
            Looper.prepareMainLooper();
            if (sMainThreadHandler == null) {
                sMainThreadHandler = new Handler();
            }
    
            ActivityThread thread = new ActivityThread();
            thread.attach(false);
    
            Looper.loop();
    
            thread.detach();
        }
    

    相关文章

      网友评论

        本文标题:Android系统源码情景分析-学习笔记-12

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