美文网首页
Android源码分析之-进程启动

Android源码分析之-进程启动

作者: 没有了遇见 | 来源:发表于2024-04-16 19:17 被阅读0次

    源码分析之打开非本App的Activity,启动进程

    bulid 28

    Intent 打开一个其他进程的Activity的时候会判断Activity所属的这个进程是否存在,当进程不存在的时候就会先启动进程再启动进程的这个Activity.

    流程:

    
    1. Android启动调用ZygoteInit.main()方法,初始化SystemServer和创建ZygoteServer(fock进程的Socket连接),并执行一个死循环等大进程创建.
    
    2. 当ActivityStackSupervisor.startSpecificActivityLocked()打开Activity的时候发现进程不存在就打开一个进程
    
    3. ZygoteServer收到创建一个进程 call.run()方法收到一个Runable 反射调用了ActivityThread的main()方法
    
    4. ActivityThread的main() 调用了attch() 方法开启了创建Application和调用Activity的流程
    
    
    

    1.Android系统启动后启动Socket连接等待App进程创建

    1.1 ZygoteInit启动ZygoteServer 开启长连接等待进程创建

    源码位置:
    /frameworks/base/cmds/app_process/app_main.cpp
    /system/core/rootdir/init.zygote64_32.rc

    1.1.1 init.zygote64_32.rc
    // --zygote 表示打开zygote进程
    //--start-system-server  表示打开 SystemServer 进程
    
    service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
        class main
        priority -20
        user root
        group root readproc reserved_disk
        socket zygote stream 660 root system
        onrestart write /sys/android_power/request_state wake
        onrestart write /sys/power/state on
        onrestart restart audioserver
        onrestart restart cameraserver
        onrestart restart media
        onrestart restart netd
        onrestart restart wificond
        writepid /dev/cpuset/foreground/tasks
    
    service zygote_secondary /system/bin/app_process32 -Xzygote /system/bin --zygote --socket-name=zygote_secondary --enable-lazy-preload
        class main
        priority -20
        user root
        group root readproc reserved_disk
        socket zygote_secondary stream 660 root system
        onrestart restart zygote
        writepid /dev/cpuset/foreground/tasks
    
    
    1.2 app_main.cpp
    int main(int argc, char* const argv[])
    {
      
          .....
        //启动AppRunTime
        AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
    
      
        bool zygote = false;
        bool startSystemServer = false;
        bool application = false;
        String8 niceName;
        String8 className;
    ...
        while (i < argc) {
            const char* arg = argv[i++];
            if (strcmp(arg, "--zygote") == 0) {
              //配置启动Zygote
                zygote = true;
                niceName = ZYGOTE_NICE_NAME;
            } else if (strcmp(arg, "--start-system-server") == 0) {
    //配置启动SystemServer
                startSystemServer = true;
            } else if (strcmp(arg, "--application") == 0) {
                application = true;
            } else if (strncmp(arg, "--nice-name=", 12) == 0) {
                niceName.setTo(arg + 12);
            } else if (strncmp(arg, "--", 2) != 0) {
                className.setTo(arg);
                break;
            } else {
                --i;
                break;
            }
        }
    
        Vector<String8> args;
        if (!className.isEmpty()) {
     
            args.add(application ? String8("application") : String8("tool"));
            runtime.setClassNameAndArgs(className, argc - i, argv + i);
    
            if (!LOG_NDEBUG) {
              String8 restOfArgs;
              char* const* argv_new = argv + i;
              int argc_new = argc - i;
              for (int k = 0; k < argc_new; ++k) {
                restOfArgs.append("\"");
                restOfArgs.append(argv_new[k]);
                restOfArgs.append("\" ");
              }
              ALOGV("Class name = %s, args = %s", className.string(), restOfArgs.string());
            }
        } else {
            // We're in zygote mode.
            maybeCreateDalvikCache();
    
            if (startSystemServer) {
           // 1:配置是否启动SystemServer
                args.add(String8("start-system-server"));
            }
    
            char prop[PROP_VALUE_MAX];
            if (property_get(ABI_LIST_PROPERTY, prop, NULL) == 0) {
                return 11;
            }
    
            String8 abiFlag("--abi-list=");
            abiFlag.append(prop);
            args.add(abiFlag);
    
            // In zygote mode, pass all remaining arguments to the zygote
            // main() method.
            for (; i < argc; ++i) {
                args.add(String8(argv[i]));
            }
        }
    
        if (!niceName.isEmpty()) {
            runtime.setArgv0(niceName.string(), true /* setProcName */);
        }
    
        if (zygote) {
    //启动ZygoteInit.java 代码 进入Android 的第一行代码
            runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
        } else if (className) {
    //执行RuntimeInit代码
            runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
        } else {
            fprintf(stderr, "Error: no class name or --zygote supplied.\n");
            app_usage();
            LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
        }
    }
    
    
    1.3 ZygoteInit.java Android世界的第一行代码
        public static void main(String argv[]) {
          // 创建ZygoteServer  创建了一个Scoket长连接的服务的 用于 等待创建进程
            ZygoteServer zygoteServer = new ZygoteServer();
    
                // 从1.1 可以得知   包含start-system-server 参数所以 startSystemServer =true
                boolean startSystemServer = false;
    
                String socketName = "zygote";
                String abiList = null;
                boolean enableLazyPreload = false;
                for (int i = 1; i < argv.length; i++) {
                    if ("start-system-server".equals(argv[i])) {
                // 从1.1可以得知   包含start-system-server 参数所以 startSystemServer =true
                        startSystemServer = true;
                    } else if ("--enable-lazy-preload".equals(argv[i])) {
                        enableLazyPreload = true;
                    } else if (argv[i].startsWith(ABI_LIST_ARG)) {
                        abiList = argv[i].substring(ABI_LIST_ARG.length());
                    } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
                        socketName = argv[i].substring(SOCKET_NAME_ARG.length());
                    } else {
                        throw new RuntimeException("Unknown command line argument: " + argv[i]);
                    }
                }
              //创建Socket的服务
              zygoteServer.registerServerSocketFromEnv(socketName);
        ....
                ZygoteHooks.stopZygoteNoThreadCreation();
                //创建SystemServer 进程 且执行SystemSer().run()代码
                if (startSystemServer) {
                    Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
    
                    // {@code r == null} in the parent (zygote) process, and {@code r != null} in the
                    // child (system_server) process.
                    if (r != null) {
                        r.run();
                        return;
                    }
                }
    
                Log.i(TAG, "Accepting command socket connections");
    
                // The select loop returns early in the child process after a fork and
                // loops forever in the zygote.
    //开启死循环获取进程创建的信息
                caller = zygoteServer.runSelectLoop(abiList);
            } catch (Throwable ex) {
                Log.e(TAG, "System zygote died with exception", ex);
                throw ex;
            } finally {
                zygoteServer.closeServerSocket();
            }
    
            // We're in the child process and have exited the select loop. Proceed to execute the
            // command.
            if (caller != null) {
    //获取信息后执行runable
                caller.run();
            }
        }
    
    

    1.4 ZygoteServer.java 进程fock的Socket服务端 用于等待进程创建

    class ZygoteServer {
      
        ZygoteServer() {
        }
    
        void setForkChild() {
            mIsForkChild = true;
        }
    
     
        void registerServerSocketFromEnv(String socketName) {
            if (mServerSocket == null) {
                int fileDesc;
                final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;
                try {
                    String env = System.getenv(fullSocketName);
                    fileDesc = Integer.parseInt(env);
                } catch (RuntimeException ex) {
                    throw new RuntimeException(fullSocketName + " unset or invalid", ex);
                }
    
                try {
                    FileDescriptor fd = new FileDescriptor();
                    fd.setInt$(fileDesc);
                // 创建LocalServerSocket
                    mServerSocket = new LocalServerSocket(fd);
                    mCloseSocketFd = true;
                } catch (IOException ex) {
                    throw new RuntimeException(
                            "Error binding to local socket '" + fileDesc + "'", ex);
                }
            }
        }
    
        void registerServerSocketAtAbstractName(String socketName) {
            if (mServerSocket == null) {
                try {
                    mServerSocket = new LocalServerSocket(socketName);
                    mCloseSocketFd = false;
                } catch (IOException ex) {
                    throw new RuntimeException(
                            "Error binding to abstract socket '" + socketName + "'", ex);
                }
            }
        }
    
     
        private ZygoteConnection acceptCommandPeer(String abiList) {
            try {
                return createNewConnection(mServerSocket.accept(), abiList);
            } catch (IOException ex) {
                throw new RuntimeException(
                        "IOException during accept()", ex);
            }
        }
    
        protected ZygoteConnection createNewConnection(LocalSocket socket, String abiList)
                throws IOException {
            return new ZygoteConnection(socket, abiList);
        }
    
    
         //执行一个死循环获取Socket传递过来的数据  需要传递过来创建进程
        Runnable runSelectLoop(String abiList) {
            ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
            ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
    
            fds.add(mServerSocket.getFileDescriptor());
            peers.add(null);
    
            while (true) {
                StructPollfd[] pollFds = new StructPollfd[fds.size()];
                for (int i = 0; i < pollFds.length; ++i) {
                    pollFds[i] = new StructPollfd();
                    pollFds[i].fd = fds.get(i);
                    pollFds[i].events = (short) POLLIN;
                }
                try {
                    Os.poll(pollFds, -1);
                } catch (ErrnoException ex) {
                    throw new RuntimeException("poll failed", ex);
                }
                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 {
                        try {
                            ZygoteConnection connection = peers.get(i);
                            //获取数据执行进程创建
                            final Runnable command = connection.processOneCommand(this);
    
                            if (mIsForkChild) {
                             
                                if (command == null) {
                                    throw new IllegalStateException("command == null");
                                }
    
                                return command;
                            } else {
                             
                                if (command != null) {
                                    throw new IllegalStateException("command != null");
                                }
    
                                
                                if (connection.isClosedByPeer()) {
                                    connection.closeSocket();
                                    peers.remove(i);
                                    fds.remove(i);
                                }
                            }
                        } catch (Exception e) {
                            if (!mIsForkChild) {
                              
                 
                    }
                }
            }
        }
    }
    
    

    1.5 ZygoteConnection Socket的长连接

    1.5.1 processOneCommand() 收到Socket传来的数据创建进程
        Runnable processOneCommand(ZygoteServer zygoteServer) {
            String args[];
            Arguments parsedArgs = null;
            FileDescriptor[] descriptors;
    
         
            int pid = -1;
            FileDescriptor childPipeFd = null;
            FileDescriptor serverPipeFd = null;
    
            parsedArgs = new Arguments(args);
    
            int[][] rlimits = null;
    
           
            if (parsedArgs.invokeWith != null) {
                try {
                    FileDescriptor[] pipeFds = Os.pipe2(O_CLOEXEC);
                    childPipeFd = pipeFds[1];
                    serverPipeFd = pipeFds[0];
                    Os.fcntlInt(childPipeFd, F_SETFD, 0);
                    fdsToIgnore = new int[]{childPipeFd.getInt$(), serverPipeFd.getInt$()};
                } catch (ErrnoException errnoEx) {
                    throw new IllegalStateException("Unable to set up pipe for invoke-with", errnoEx);
                }
            }
    
            
            int [] fdsToClose = { -1, -1 };
    
            FileDescriptor fd = mSocket.getFileDescriptor();
    
            if (fd != null) {
                fdsToClose[0] = fd.getInt$();
            }
    
            fd = zygoteServer.getServerSocketFileDescriptor();
    
            if (fd != null) {
                fdsToClose[1] = fd.getInt$();
            }
    
            fd = null;
    
            pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
                    parsedArgs.runtimeFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
                    parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.startChildZygote,
                    parsedArgs.instructionSet, parsedArgs.appDataDir);
    
            try {
            //fock 子进程后通知子进程后续操作   Zygote.forkAndSpecialize() 如果是子进程返回子进程Id(项目中生命的进程) 如果是主进程返回0
              // ==0 表示主进程 
                if (pid == 0) {
                    //处理子进程
                    zygoteServer.setForkChild();
    
                    zygoteServer.closeServerSocket();
                    IoUtils.closeQuietly(serverPipeFd);
                    serverPipeFd = null;
                    //处理创建进程后的后续操作(Application创建)
                    return handleChildProc(parsedArgs, descriptors, childPipeFd,
                            parsedArgs.startChildZygote);
                } else {
                    // In the parent. A pid < 0 indicates a failure and will be handled in
                    // handleParentProc.
                    IoUtils.closeQuietly(childPipeFd);
                    childPipeFd = null;
                    handleParentProc(pid, descriptors, serverPipeFd);
                    return null;
                }
            } finally {
                IoUtils.closeQuietly(childPipeFd);
                IoUtils.closeQuietly(serverPipeFd);
            }
        }
    
    1.5.2 handleChildProc

    处理进程创建后(进程资源的初始化,Application ActivityThread Instrumentation 等的创建和页面的打开)

     private Runnable handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors,
           
    
            closeSocket();
            if (descriptors != null) {
                try {
                    Os.dup2(descriptors[0], STDIN_FILENO);
                    Os.dup2(descriptors[1], STDOUT_FILENO);
                    Os.dup2(descriptors[2], STDERR_FILENO);
    
                    for (FileDescriptor fd: descriptors) {
                        IoUtils.closeQuietly(fd);
                    }
                } catch (ErrnoException ex) {
                    Log.e(TAG, "Error reopening stdio", ex);
                }
            }
    
            if (parsedArgs.niceName != null) {
                Process.setArgV0(parsedArgs.niceName);
            }
    
            // End of the postFork event.
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            if (parsedArgs.invokeWith != null) {
                WrapperInit.execApplication(parsedArgs.invokeWith,
                        parsedArgs.niceName, parsedArgs.targetSdkVersion,
                        VMRuntime.getCurrentInstructionSet(),
                        pipeFd, parsedArgs.remainingArgs);
    
                // Should not get here.
                throw new IllegalStateException("WrapperInit.execApplication unexpectedly returned");
            } else {
            
            
            //新建进程的时候 isZygote 为false 所以执行  ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs,  
            //if (arg.equals("--start-child-zygote")) {startChildZygote = true;} start-child-zygote这个参数没传 所以
                if (!isZygote) {
    //重点方法:  ZygoteInit.zygoteInit() 执行新进程的
                    return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs,
                            null /* classLoader */);
                } else {
                    return ZygoteInit.childZygoteInit(parsedArgs.targetSdkVersion,
                            parsedArgs.remainingArgs, null /* classLoader */);
                }
            }
        }
    
    1.1.6 ZygoteInit.zygoteInit() 初始化新进程的环境

    1:ZygoteInit.zygoteInit()

     public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
            if (RuntimeInit.DEBUG) {
                Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
            }
    
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
            RuntimeInit.redirectLogStreams();
     RuntimeInit.redirectLogStreams();
      
            
           //为当前的VM设置未捕获异常器
            RuntimeInit.commonInit();
            //Binder驱动初始化,该方法完成后,可通过Binder进行进程通信
            ZygoteInit.nativeZygoteInit();
          //调用ActivityThread 的main方法
            return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
        }
    

    2:RuntimeInit.applicationInit()

        protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
                ClassLoader classLoader) {
      
            nativeSetExitWithoutCleanup(true);
    
            VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
            VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
            //处理参数
            final Arguments args = new Arguments(argv);
    
            // Remaining arguments are passed to the start class's static main
          //反射调用 ActivityThread main 方法
            return findStaticMain(args.startClass, args.startArgs, classLoader);
        }
    
    

    2:RuntimeInit.findStaticMain() 返回一个 MethodAndArgsCaller 是一个Runable 给ZygoteInit main中的 call 去执行

      protected static Runnable findStaticMain(String className, String[] argv,
                ClassLoader classLoader) {
            Class<?> cl;
            try {
    //重点 这个类是 ActivityThread startActivity 传递过来
                cl = Class.forName(className, true, classLoader);
            } catch (ClassNotFoundException ex) {
            }
    
            Method m;
            try {
                m = cl.getMethod("main", new Class[] { String[].class });
            } catch (NoSuchMethodException ex) {
            } catch (SecurityException ex) {
            }
    
            int modifiers = m.getModifiers();
          
    
            return new MethodAndArgsCaller(m, argv);
        }
    

    4: startProcessLocked 传递ActivityThread 用于启动

      final String entryPoint = "android.app.ActivityThread";
    
                return startProcessLocked(hostingType, hostingNameStr, entryPoint, app, uid, gids,
                        runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
                        startTime);
    

    2.执行到了进入了新进程的ActivityThread 的main方法

    2.1 ActivityThread main()

      public static void main(String[] args) {
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
    
            // CloseGuard defaults to true and can be quite spammy.  We
            // disable it here, but selectively enable it later (via
            // StrictMode) on debug builds, but using DropBox, not logs.
            CloseGuard.setEnabled(false);
    
            Environment.initForCurrentUser();
    
            // Set the reporter for event logging in libcore
            EventLogger.setReporter(new EventLoggingReporter());
    
            // Make sure TrustedCertificateStore looks in the right place for CA certificates
            final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
            TrustedCertificateStore.setDefaultUserDirectory(configDir);
    
            Process.setArgV0("<pre-initialized>");
          //重点:初始化UI线程的Looper  UI线程的Looper 不允许退出
            Looper.prepareMainLooper();
            //执行ActivityThread的 attach()  
            ActivityThread thread = new ActivityThread();
            //传递的是 false  非系统进程
            thread.attach(false, startSeq);
    
            if (sMainThreadHandler == null) {
                sMainThreadHandler = thread.getHandler();
            }
    
           //开启UI线程的Looper
            Looper.loop();
    
            throw new RuntimeException("Main thread loop unexpectedly exited");
        }
    

    2.2 ActivityThread attch()操作 跳转到Ams attachApplication() 创建Application

        private void attach(boolean system, long startSeq) {
        
            sCurrentActivityThread = this;
            mSystemThread = system;
            // system 是否四系统项目  传递过来的是false  非系统进程
            if (!system) {
            //执行非系统进程的逻辑
                ViewRootImpl.addFirstDrawHandler(new Runnable() {
                    @Override
                    public void run() {
                        ensureJitEnabled();
                    }
                });
                android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
                                                        UserHandle.myUserId());
                RuntimeInit.setApplicationObject(mAppThread.asBinder());
                //获取AMS 的实例  调用Ams attachApplication
                final IActivityManager mgr = ActivityManager.getService();
                try {
                    mgr.attachApplication(mAppThread, startSeq);
                } catch (RemoteException ex) {
                    throw ex.rethrowFromSystemServer();
                }
                // Watch for getting close to heap limit.
                BinderInternal.addGcWatcher(new Runnable() {
                    @Override public void run() {
                        if (!mSomeActivitiesChanged) {
                            return;
                        }
                        Runtime runtime = Runtime.getRuntime();
                        long dalvikMax = runtime.maxMemory();
                        long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();
                        if (dalvikUsed > ((3*dalvikMax)/4)) {
                            if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024)
                                    + " total=" + (runtime.totalMemory()/1024)
                                    + " used=" + (dalvikUsed/1024));
                            mSomeActivitiesChanged = false;
                            try {
                                mgr.releaseSomeActivities(mAppThread);
                            } catch (RemoteException e) {
                                throw e.rethrowFromSystemServer();
                            }
                        }
                    }
                });
            } else {
                // 处理系统进程
                android.ddm.DdmHandleAppName.setAppName("system_process",
                        UserHandle.myUserId());
                try {
                    mInstrumentation = new Instrumentation();
                    mInstrumentation.basicInit(this);
                    ContextImpl context = ContextImpl.createAppContext(
                            this, getSystemContext().mPackageInfo);
                    mInitialApplication = context.mPackageInfo.makeApplication(true, null);
                    mInitialApplication.onCreate();
                } catch (Exception e) {
                    throw new RuntimeException(
                            "Unable to instantiate Application():" + e.toString(), e);
                }
            }
            ...
        }
    

    2.3 AMS attachApplicationLocked()---> 跳转到ActivityThread 的bindApplication()

     private final boolean attachApplicationLocked(IApplicationThread thread,
                int pid, int callingUid, long startSeq) {
    
         
            ProcessRecord app;
            long startTime = SystemClock.uptimeMillis();
            if (pid != MY_PID && pid >= 0) {
                synchronized (mPidsSelfLocked) {
                    app = mPidsSelfLocked.get(pid);
                }
            } else {
                app = null;
            }
    
            if (app == null && startSeq > 0) {
                final ProcessRecord pending = mPendingStarts.get(startSeq);
                if (pending != null && pending.startUid == callingUid
                        && handleProcessStartedLocked(pending, pid, pending.usingWrapper,
                                startSeq, true)) {
                    app = pending;
                }
            }
    
            if (app == null) {
          
                if (pid > 0 && pid != MY_PID) {
                    killProcessQuiet(pid);
                } else {
                    try {
                        thread.scheduleExit();
                    } catch (Exception e) {
                        // Ignore exceptions.
                    }
                }
                return false;
            }
    
            //ActivityThread 不存在清空进程
            if (app.thread != null) {
                handleAppDiedLocked(app, true, true);
            }
    
            final String processName = app.processName;
            //注册死亡连接
            try {
                AppDeathRecipient adr = new AppDeathRecipient(
                        app, pid, thread);
                thread.asBinder().linkToDeath(adr, 0);
                app.deathRecipient = adr;
            } catch (RemoteException e) {
                app.resetPackageList(mProcessStats);
                startProcessLocked(app, "link fail", processName);
                return false;
            }
    
            app.makeActive(thread, mProcessStats);
            app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
            app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
            app.forcingToImportant = null;
            updateProcessForegroundLocked(app, false, false);
            app.hasShownUi = false;
            app.debugging = false;
            app.cached = false;
            app.killedByAm = false;
            app.killed = false;
            app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
    
            mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
            //进程是否准备 true isAllowedWhileBooting() 是否是白名单
            boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
            List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
    
            if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
                Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
                msg.obj = app;
                mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
            }
            
           
            
         
                
                if (app.instr != null) {
                    notifyPackageUse(app.instr.mClass.getPackageName(),
                                     PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
                }
          
                ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
                app.compat = compatibilityInfoForPackageLocked(appInfo);
    
                
            
                if (mActiveInstrumentation.size() > 0 && app.instr == null) {
                    for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
                        ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
                        if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
                            if (aInstr.mTargetProcesses.length == 0) {
                                // This is the wildcard mode, where every process brought up for
                                // the target instrumentation should be included.
                                if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
                                    app.instr = aInstr;
                                    aInstr.mRunningProcesses.add(app);
                                }
                            } else {
                                for (String proc : aInstr.mTargetProcesses) {
                                    if (proc.equals(app.processName)) {
                                        app.instr = aInstr;
                                        aInstr.mRunningProcesses.add(app);
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
    
            
               
                mStackSupervisor.getActivityMetricsLogger().notifyBindApplication(app);
                if (app.isolatedEntryPoint != null) {
                    // This is an isolated process which should just call an entry point instead of
                    // being bound to an application.
                    thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs);
                } else if (app.instr != null) {
                //重点: app.instr 当前App 进程是否运行  thread  是ActivityThread
                    thread.bindApplication(processName, appInfo, providers,
                            app.instr.mClass,
                            profilerInfo, app.instr.mArguments,
                            app.instr.mWatcher,
                            app.instr.mUiAutomationConnection, testMode,
                            mBinderTransactionTrackingEnabled, enableTrackAllocation,
                            isRestrictedBackupMode || !normalMode, app.persistent,
                            new Configuration(getGlobalConfiguration()), app.compat,
                            getCommonServicesLocked(app.isolated),
                            mCoreSettingsObserver.getCoreSettingsLocked(),
                            buildSerial, isAutofillCompatEnabled);
                } else {
                // 重点: app.instr 当前App 进程是否运行 
                    thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
                            null, null, null, testMode,
                            mBinderTransactionTrackingEnabled, enableTrackAllocation,
                            isRestrictedBackupMode || !normalMode, app.persistent,
                            new Configuration(getGlobalConfiguration()), app.compat,
                            getCommonServicesLocked(app.isolated),
                            mCoreSettingsObserver.getCoreSettingsLocked(),
                            buildSerial, isAutofillCompatEnabled);
                }
             
       
                updateLruProcessLocked(app, false, null);
    
            } catch (Exception e) {
         
                Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
    
                app.resetPackageList(mProcessStats);
                app.unlinkDeathRecipient();
                startProcessLocked(app, "bind fail", processName);
                return false;
            }
    
            mPersistentStartingProcesses.remove(app);
            mProcessesOnHold.remove(app);
    
            boolean badApp = false;
            boolean didSomething = false;
    
            // See if the top visible activity is waiting to run in this process...
            if (normalMode) {
                try {
    
    //重点--->:创建完成Application且调用完onCreate  执行后要加载要打开的页面 3.+
    
                    if (mStackSupervisor.attachApplicationLocked(app)) {
                        didSomething = true;
                    }
                } catch (Exception e) {
                    badApp = true;
                }
            }
    
            if (!badApp) {
                try {
                    didSomething |= mServices.attachApplicationLocked(app, processName);
                    checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
                } catch (Exception e) {
                    Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
                    badApp = true;
                }
            }
    
            // Check if a next-broadcast receiver is in this process...
            if (!badApp && isPendingBroadcastProcessLocked(pid)) {
                try {
                    didSomething |= sendPendingBroadcastsLocked(app);
                    checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
                } catch (Exception e) {
                    // If the app died trying to launch the receiver we declare it 'bad'
                    Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
                    badApp = true;
                }
            }
    
            // Check whether the next backup agent is in this process...
            if (!badApp && mBackupTarget != null && mBackupTarget.app == app) {
                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
                        "New app is backup target, launching agent for " + app);
                notifyPackageUse(mBackupTarget.appInfo.packageName,
                                 PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
                try {
                    thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
                            compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
                            mBackupTarget.backupMode);
                } catch (Exception e) {
                    Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
                    badApp = true;
                }
            }
    
            if (badApp) {
                app.kill("error during init", true);
                handleAppDiedLocked(app, false, true);
                return false;
            }
    
            if (!didSomething) {
                updateOomAdjLocked();
                checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
            }
    
            return true;
        }
    

    2.4 ActivityThread 的 bindApplication()

    -->bindApplication()
    --->sendMessage(H.BIND_APPLICATION, data);
    -->mH(Handler) 的 BIND_APPLICATION
    -->handleBindApplication()

    public final void bindApplication()
    
                AppBindData data = new AppBindData();
                data.processName = processName;
                data.appInfo = appInfo;
                data.providers = providers;
                data.instrumentationName = instrumentationName;
                data.instrumentationArgs = instrumentationArgs;
                data.instrumentationWatcher = instrumentationWatcher;
                data.instrumentationUiAutomationConnection = instrumentationUiConnection;
                data.debugMode = debugMode;
                data.enableBinderTracking = enableBinderTracking;
                data.trackAllocation = trackAllocation;
                data.restrictedBackupMode = isRestrictedBackupMode;
                data.persistent = persistent;
                data.config = config;
                data.compatInfo = compatInfo;
                data.initProfilerInfo = profilerInfo;
                data.buildSerial = buildSerial;
                data.autofillCompatibilityEnabled = autofillCompatibilityEnabled;
                sendMessage(H.BIND_APPLICATION, data);
            }
    
    

    2.5 handleBindApplication() 创建Application 调用attch() 加载ContentProvider 调用Application的onCreate方法

       private void handleBindApplication(AppBindData data) {
            // Register the UI Thread as a sensitive thread to the runtime.
            VMRuntime.registerSensitiveThread();
          
    
            synchronized (mResourcesManager) {
                /*
                 * Update the system configuration since its preloaded and might not
                 * reflect configuration changes. The configuration object passed
                 * in AppBindData can be safely assumed to be up to date
                 */
                mResourcesManager.applyConfigurationToResourcesLocked(data.config, data.compatInfo);
                mCurDefaultDisplayDpi = data.config.densityDpi;
    
                // This calls mResourcesManager so keep it within the synchronized block.
                applyCompatConfiguration(mCurDefaultDisplayDpi);
            }
    
            data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
    
            if (agent != null) {
                handleAttachAgent(agent, data.info);
            }
    
            /**
             * Switch this process to density compatibility mode if needed.
             */
            if ((data.appInfo.flags&ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES)
                    == 0) {
                mDensityCompatMode = true;
                Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT);
            }
            updateDefaultDensity();
    
            final String use24HourSetting = mCoreSettings.getString(Settings.System.TIME_12_24);
            Boolean is24Hr = null;
            if (use24HourSetting != null) {
                is24Hr = "24".equals(use24HourSetting) ? Boolean.TRUE : Boolean.FALSE;
            }
         
            DateFormat.set24HourTimePref(is24Hr);
    
            View.mDebugViewAttributes =
                    mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0;
    
            StrictMode.initThreadDefaults(data.appInfo);
            StrictMode.initVmDefaults(data.appInfo);
    
            try {
                Field field = Build.class.getDeclaredField("SERIAL");
                field.setAccessible(true);
                field.set(Build.class, data.buildSerial);
            } catch (NoSuchFieldException | IllegalAccessException e) {
                /* ignore */
            }
    
            //处理Debug模式   运行项目的时候弹出 的Debug等待框
            if (data.debugMode != ApplicationThreadConstants.DEBUG_OFF) {
                // XXX should have option to change the port.
                Debug.changeDebugPort(8100);
                if (data.debugMode == ApplicationThreadConstants.DEBUG_WAIT) {
             
                    IActivityManager mgr = ActivityManager.getService();
                    try {
                        mgr.showWaitingForDebugger(mAppThread, true);
                    } catch (RemoteException ex) {
                        throw ex.rethrowFromSystemServer();
                    }
    
                    Debug.waitForDebugger();
    
                    try {
                        mgr.showWaitingForDebugger(mAppThread, false);
                    } catch (RemoteException ex) {
                        throw ex.rethrowFromSystemServer();
                    }
    
                } else {
               
                }
            }
    
            // Allow application-generated systrace messages if we're debuggable.
            boolean isAppDebuggable = (data.appInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
            Trace.setAppTracingAllowed(isAppDebuggable);
            ThreadedRenderer.setDebuggingEnabled(isAppDebuggable || Build.IS_DEBUGGABLE);
            if (isAppDebuggable && data.enableBinderTracking) {
                Binder.enableTracing();
            }
    
            // Instrumentation对象的封装数据
            final InstrumentationInfo ii;
            if (data.instrumentationName != null) {
                try {
                //创建InstrumentationInfo
                    ii = new ApplicationPackageManager(null, getPackageManager())
                            .getInstrumentationInfo(data.instrumentationName, 0);
                } catch (PackageManager.NameNotFoundException e) {
                    throw new RuntimeException(
                            "Unable to find instrumentation info for: " + data.instrumentationName);
                }
    
                mInstrumentationPackageName = ii.packageName;
                mInstrumentationAppDir = ii.sourceDir;
                mInstrumentationSplitAppDirs = ii.splitSourceDirs;
                mInstrumentationLibDir = getInstrumentationLibrary(data.appInfo, ii);
                mInstrumentedAppDir = data.info.getAppDir();
                mInstrumentedSplitAppDirs = data.info.getSplitAppDirs();
                mInstrumentedLibDir = data.info.getLibDir();
            } else {
                ii = null;
            }
    
            final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
            updateLocaleListFromAppContext(appContext,
                    mResourcesManager.getConfiguration().getLocales());
                    
            // 网络适配的Provider 加载
            NetworkSecurityConfigProvider.install(appContext);
           
    
            // Continue loading instrumentation.
            if (ii != null) {
            //Application的创建数据
                ApplicationInfo instrApp;
                try {
                    instrApp = getPackageManager().getApplicationInfo(ii.packageName, 0,
                            UserHandle.myUserId());
                } catch (RemoteException e) {
                    instrApp = null;
                }
                if (instrApp == null) {
                    instrApp = new ApplicationInfo();
                }
                ii.copyTo(instrApp);
                instrApp.initForUser(UserHandle.myUserId());
                final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
                        appContext.getClassLoader(), false, true, false);
                final ContextImpl instrContext = ContextImpl.createAppContext(this, pi);
    
                try {
                    final ClassLoader cl = instrContext.getClassLoader();
                    //反射创建Instrumentation 
                    mInstrumentation = (Instrumentation)
                        cl.loadClass(data.instrumentationName.getClassName()).newInstance();
                } catch (Exception e) {
                    throw new RuntimeException(
                        "Unable to instantiate instrumentation "
                        + data.instrumentationName + ": " + e.toString(), e);
                }
    
                final ComponentName component = new ComponentName(ii.packageName, ii.name);
                //mInstrumentation 初始化
                mInstrumentation.init(this, instrContext, appContext, component,
                        data.instrumentationWatcher, data.instrumentationUiAutomationConnection);
    
                if (mProfiler.profileFile != null && !ii.handleProfiling
                        && mProfiler.profileFd == null) {
                    mProfiler.handlingProfiling = true;
                    final File file = new File(mProfiler.profileFile);
                    file.getParentFile().mkdirs();
                    Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
                }
            } else {
                mInstrumentation = new Instrumentation();
                mInstrumentation.basicInit(this);
            }
    
            // 开始处理 Application 
            Application app;
            final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();
            final StrictMode.ThreadPolicy writesAllowedPolicy = StrictMode.getThreadPolicy();
            try {
                // If the app is being launched for full backup or restore, bring it up in
                // a restricted environment with the base application class.
                //处理备份 的Application  (不是正常创建)
                app = data.info.makeApplication(data.restrictedBackupMode, null);
                // 注意:LoadedApk.java  makeApplication()方法中 instrumentation 是null  makeApplication() 中不执行Application的onCreate方法
                //makeApplication(boolean forceDefaultAppClass,Instrumentation instrumentation) 
    
                // Propagate autofill compat state
                app.setAutofillCompatibilityEnabled(data.autofillCompatibilityEnabled);
    
                mInitialApplication = app;
    
                // don't bring up providers in restricted mode; they may depend on the
                // app's custom Application class
                if (!data.restrictedBackupMode) {
                    if (!ArrayUtils.isEmpty(data.providers)) {
                    
                    //重点: 加载ContentProvider 执行OnCreate方法
                    
                        installContentProviders(app, data.providers);
                        // For process that contains content providers, we want to
                        // ensure that the JIT is enabled "at some point".
                        mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
                    }
                }
    
                // Do this after providers, since instrumentation tests generally start their
                // test thread at this point, and we don't want that racing.
                try {
                //调用Instrumenttation 的onCreate 方法
                    mInstrumentation.onCreate(data.instrumentationArgs);
                }
                catch (Exception e) {
                    throw new RuntimeException(
                        "Exception thrown in onCreate() of "
                        + data.instrumentationName + ": " + e.toString(), e);
                }
                try {
                    //重点: 调用Application 的onCreate 方法
                    mInstrumentation.callApplicationOnCreate(app);
                } catch (Exception e) {
                    if (!mInstrumentation.onException(app, e)) {
                        throw new RuntimeException(
                          "Unable to create application " + app.getClass().getName()
                          + ": " + e.toString(), e);
                    }
                }
            } finally {
                // If the app targets < O-MR1, or doesn't change the thread policy
                // during startup, clobber the policy to maintain behavior of b/36951662
                if (data.appInfo.targetSdkVersion < Build.VERSION_CODES.O_MR1
                        || StrictMode.getThreadPolicy().equals(writesAllowedPolicy)) {
                    StrictMode.setThreadPolicy(savedPolicy);
                }
            }
    
            // Preload fonts resources 加载文字资源
            FontsContract.setApplicationContextForResources(appContext);
            if (!Process.isIsolated()) {
                try {
                    final ApplicationInfo info =
                            getPackageManager().getApplicationInfo(
                                    data.appInfo.packageName,
                                    PackageManager.GET_META_DATA /*flags*/,
                                    UserHandle.myUserId());
                    if (info.metaData != null) {
                        final int preloadedFontsResource = info.metaData.getInt(
                                ApplicationInfo.METADATA_PRELOADED_FONTS, 0);
                        if (preloadedFontsResource != 0) {
                            data.info.getResources().preloadFonts(preloadedFontsResource);
                        }
                    }
                } catch (RemoteException e) {
                    throw e.rethrowFromSystemServer();
                }
            }
        }
    
    

    2.6 创建Application 调用Application的attach()方法

        public Application makeApplication(boolean forceDefaultAppClass,
                Instrumentation instrumentation) {
            if (mApplication != null) {
                return mApplication;
            }
    
            Application app = null;
            String appClass = mApplicationInfo.className;
            if (forceDefaultAppClass || (appClass == null)) {
                appClass = "android.app.Application";
            }
    
            try {
                java.lang.ClassLoader cl = getClassLoader();
                if (!mPackageName.equals("android")) {
                  
                    initializeJavaContextClassLoader();
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                }
                ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
                
                //重点: 创建Application 调用Application 的attch方法
                app = mActivityThread.mInstrumentation.newApplication(
                        cl, appClass, appContext);
                appContext.setOuterContext(app);
                
                
            } catch (Exception e) {
                if (!mActivityThread.mInstrumentation.onException(app, e)) {
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    throw new RuntimeException(
                        "Unable to instantiate application " + appClass
                        + ": " + e.toString(), e);
                }
            }
            mActivityThread.mAllApplications.add(app);
            mApplication = app;
            //重点 传递过来的instrumentation ==null 所以不执行 Application的onCrate()方法
            if (instrumentation != null) {
                try {
                    instrumentation.callApplicationOnCreate(app);
                } catch (Exception e) {
                    if (!instrumentation.onException(app, e)) {
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                        throw new RuntimeException(
                            "Unable to create application " + app.getClass().getName()
                            + ": " + e.toString(), e);
                    }
                }
            }
    
            // Rewrite the R 'constants' for all library apks.
            SparseArray<String> packageIdentifiers = getAssets().getAssignedPackageIdentifiers();
            final int N = packageIdentifiers.size();
            for (int i = 0; i < N; i++) {
                final int id = packageIdentifiers.keyAt(i);
                if (id == 0x01 || id == 0x7f) {
                    continue;
                }
    
                rewriteRValues(getClassLoader(), packageIdentifiers.valueAt(i), id);
            }
    
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    
            return app;
        }
    

    2.7 创建Application 调用Application的attach()方法

     public Application newApplication(ClassLoader cl, String className, Context context)
                throws InstantiationException, IllegalAccessException, 
                ClassNotFoundException {
            Application app = getFactory(context.getPackageName())
                    .instantiateApplication(cl, className);
            app.attach(context);
            return app;
        }
    

    3.创建完Application后加载Activity 打开首页后者携带的Activity页面

    ActivityStackSupervisor.attachApplicationLocked()

    
    boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
            final String processName = app.processName;
            boolean didSomething = false;
            for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
                final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
                for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
                    final ActivityStack stack = display.getChildAt(stackNdx);
                    if (!isFocusedStack(stack)) {
                        continue;
                    }
                    stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList);
                  // 重点 获取前台stack中栈顶第一个非 finishing 状态的 Activity
                    final ActivityRecord top = stack.topRunningActivityLocked();
                    final int size = mTmpActivityList.size();
                    for (int i = 0; i < size; i++) {
                        final ActivityRecord activity = mTmpActivityList.get(i);
                        if (activity.app == null && app.uid == activity.info.applicationInfo.uid
                                && processName.equals(activity.processName)) {
                            try {  
                                //重点: 真正启动Activity
                                if (realStartActivityLocked(activity, app,
                                        top == activity /* andResume */, true /* checkConfig */)) {
                                    didSomething = true;
                                }
                            } catch (RemoteException e) {
                                Slog.w(TAG, "Exception in new application when starting activity "
                                        + top.intent.getComponent().flattenToShortString(), e);
                                throw e;
                            }
                        }
                    }
                }
            }
            if (!didSomething) {
                ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
            }
            return didSomething;
        }
    

    总结:

    打开其他进程流程:

    startActivity
    --->Process.start()给ZygoteServer维护的Socket 提交一个信息(ZygoteConnection是连接)
    --->ZygoteServer接收到这个信息去创建一个进程 RuntimeInit 调用ActivityThread的main()方法
    ---->ActivityThread attch() 方法创建和加载Application
    -----而后加载Activity()

    相关文章

      网友评论

          本文标题:Android源码分析之-进程启动

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