preface

We know that the general Android engineers are in the application layer development, will not involve system source code, but if you want to go to the bottom, or in-depth plug-in, Framework system layer development work, if you do not understand Android source code but not, So the next I based on their own understanding and learning to record with Android development is closely related to the source analysis, probably from the Android SystemServer start, four components start, AMS, PMS and other dimensions to introduce, the following is my plan, of course, may change in the future.

If you haven’t paid attention to it yet, you can pay attention to it first. The series of articles will be updated continuously.

Android 8.0 source code analysis (a) SystemServer process started

Android 8.0 source code analysis (ii) Launcher

Android 8.0 source code analysis (three) application process creation to the application startup process

Android 8.0 source code analysis (four) Activity start

Android 8.0 source code analysis (5) Service startup

Android 8.0 source code analysis (6) BroadcastReceiver launch

Android 8.0 source code analysis (seven) ContentProvider start

ActivityManagerService

Android 8.0 source code analysis (nine) WindowManager

Android 8.0 source code analysis (ten) WindowManagerService window management

introduce

In the previous two chapters, we learned about the startup of the Android system service process and the desktop Launcher. Based on what we have learned, this chapter will bring an analysis of the startup process of the application process. If you don’t know the startup principle of Zygote, SystemServer, and Launcher, please read my previous article.

Introduction to the application process

To start an application, first ensure that the application process required by the application is started. When AMS starts an application, it checks to see if the required application process exists and asks Zygote to start it if it does not. In Android 8.0 source analysis (a) SystemServer process startup we know in Zygote Java framework layer will create a Server Socket, This Socket is used to wait for AMS to request Zygote to create a new application process. The Zygote process passes through the application process fock created itself, so that the application gets the virtual machine instance that the Zygote process created at startup. Of course, Bindler thread pools and message loops are created during application process creation in addition to virtual machine acquisition, so that applications running in application processes can easily use Binder to communicate with each other and process messages.

This section describes how to start an application process

There are many steps in the application process creation process, which are explained in two parts: AMS sends the request to start the application process, and Zygote receives the request and creates the application process.

AMS sends a request to start the application process

Take a look at the sequence diagram of how AMS sends the request to start the application process, then examine each step in detail.

If AMS wants to start the application process, it needs to send a request to the Zygote process to create the application process. AMS sends the request to the Zygote process by calling startProcessLocked, as shown below:

//com.android.server.am; ActivityManagerService.java

    /** * Start process function *@param app
     * @param hostingType
     * @param hostingNameStr
     * @param abiOverride
     * @param entryPoint
     * @param entryPointArgs
     */
    private final void startProcessLocked( ProcessRecord app, String hostingType, String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs){...try {
            try {
                final int userId = UserHandle.getUserId(app.uid);
                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
            } catch (RemoteException e) {
                throw e.rethrowAsRuntimeException();
            }

            /** * 1. Obtain the user ID of the application process to be created */
            int uid = app.uid;
            int[] gids = null;
            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
            if(! app.isolated) { .../** * 2. Create and assign the gids */
                if (ArrayUtils.isEmpty(permGids)) {
                    gids = new int[3];
                } else {
                    gids = new int[permGids.length + 3];
                    System.arraycopy(permGids, 0, gids, 3, permGids.length);
                }
                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
                gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
                gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid)); }...boolean isActivityProcess = (entryPoint == null);
            /** * 3. If entryPoint == null then assign the entire class name of ActivityThread to entryPoint */
            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
                    app.processName);
            checkTime(startTime, "startProcess: asking zygote to start proc");
            ProcessStartResult startResult;
            if (hostingType.equals("webview_service")) {
                startResult = startWebView(entryPoint,
                        app.processName, uid, uid, gids, debugFlags, mountExternal,
                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                        app.info.dataDir, null, entryPointArgs);
            } else {

                /** * 4. Call start in AMS to notify Zygote fork */startResult = Process.start(entryPoint, app.processName, uid, uid, gids, debugFlags, mountExternal, app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet, app.info.dataDir, invokeWith, entryPointArgs); }... }Copy the code

To summarize the meaning of the above code, it can be divided into four steps:

    1. Gets the ID of the user that created the application process
    1. Create and assign user group ids (Gids)
    1. If entryPoint is null, assign the ActivityThread full class name to it
    1. Call the start function of Process

Process. The start of the first function is android. App. ActivityThread, the following section will use it, it is the key to, well let’s look at the start of the Process function:

//android.os; Process.java

    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 invokeWith,
                                  String[] zygoteArgs) {
      	//1. Call start from ZygoteProcess
        return zygoteProcess.start(processClass, niceName, uid, gid, gids,
                    debugFlags, mountExternal, targetSdkVersion, seInfo,
                    abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
    }

Copy the code

ZygoteProcess is used to communicate with the ZygoteProcess. ZygoteProcess is used to communicate with the ZygoteProcess. ZygoteProcess is used to communicate with ZygoteProcess.

//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 {
            /** * Continue to call the startViaZygote function of the current class */
            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); }}private Process.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 invokeWith,
                                                      String[] extraArgs)
                                                      throws ZygoteStartFailedEx {

        // Create a collection to save the application process startup parameters
        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); .// Omit some code

        synchronized(mLock) {
         // Continue to call the inner function
            returnzygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote); }}Copy the code

We know through the code above is mainly start application process parameters to tell zygoteSendArgsAndGetResult then passed through a Socket zygote process, we first look at openZygoteSocketIfNeeded (abi)

//android.os; ZygoteProcess.java
    @GuardedBy("mLock")
    private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
        Preconditions.checkState(Thread.holdsLock(mLock), "ZygoteProcess lock not held");

        if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
            try {
                /** * 1. Connect to the server Socket with the zygote name "zygote" to establish interprocess communication */
                primaryZygoteState = ZygoteState.connect(mSocket);
            } catch (IOException ioe) {
                throw new ZygoteStartFailedEx("Error connecting to primary zygote", ioe); }}/** * 2. ZygoteState returned from Zygote main mode matches the ABI required to start the application process */
        if (primaryZygoteState.matches(abi)) {
            return primaryZygoteState;
        }

        // If there is no match, try to connect to zygote auxiliary mode
        if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) {
            try {
                /** * 3. If there is no match then try to connect to Socket */ with name "zygote_secondary"
                secondaryZygoteState = ZygoteState.connect(mSecondarySocket);
            } catch (IOException ioe) {
                throw new ZygoteStartFailedEx("Error connecting to secondary zygote", ioe); }}/** * 4. ZygoteState returned by Zygote auxiliary mode matches the ABI required to start the application process */
        if (secondaryZygoteState.matches(abi)) {
            return secondaryZygoteState;
        }

        // If neither match then throw an exception
        throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi);
    }
Copy the code

Connect to zygote process through Socket, return a ZygoteState, and match the ABI passed in. Connect and match the ABI, which involves the startup script of Zygote. If the Zygote process is started with the init. Zygote32_64. rc script, It is the server Socket with the primary mode name “name”, or the server Socket with the secondary mode name “zygote_secondary” if it is started with init.zygote64_32.rc. If none of them match, the connection or match is abnormal. If the connection is successful after we see zygoteSendArgsAndGetResult function main work done:

//android.os; ZygoteProcess.java
    private static Process.ProcessStartResult zygoteSendArgsAndGetResult( ZygoteState zygoteState, ArrayList
       
         args)
       
            throws ZygoteStartFailedEx {...final BufferedWriter writer = zygoteState.writer;
            final DataInputStream inputStream = zygoteState.inputStream;

            writer.write(Integer.toString(args.size()));
            writer.newLine();

            for (int i = 0; i < sz; i++) { String arg = args.get(i); writer.write(arg); writer.newLine(); } writer.flush(); . }return result;
        } catch (IOException ex) {
            zygoteState.close();
            throw newZygoteStartFailedEx(ex); }}Copy the code

If the connection to the server Socket of the Zygote process is successful, the stored application process startup parameters are written to the ZygoteState. Finally, the Zygote process after receiving the processing work, the following section to introduce you in detail after receiving the work.

Zygote receives the request and creates the application process

If you have seen Android 8.0 source code analysis (a) SystemServer process start the article must be clear, in fact, SystemServer with application process start in Zygote processing similar, here we in order to review the previous content, Let’s go over it again, starting with a sequence diagram.

After reviewing the ZygoteInit main function, let’s look at server Socket creation

//com.android.internal.os.ZygoteInit.java
    public static void main(String argv[]) {...try{...// Whether to enable the SystemServer flag
            boolean startSystemServer = false;
          	// Server Socket name
            String socketName = "zygote";

          	// Determine whether to start the system service according to the information passed by the JNI layer
            for (int i = 1; i < argv.length; i++) {
                if ("start-system-server".equals(argv[i])) {
                    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]); }}/** * 1. Create a server Socket named "zygote" */

            zygoteServer.registerServerSocket(socketName);
           
            if(! enableLazyPreload) { bootTimingsTraceLog.traceBegin("ZygotePreload");
                EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
                    SystemClock.uptimeMillis());
                /** * 2. Use to preload resources */
                preload(bootTimingsTraceLog);
                EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
                    SystemClock.uptimeMillis());
                bootTimingsTraceLog.traceEnd(); // ZygotePreload
            } else{ Zygote.resetNicePriority(); }...if (startSystemServer) {
                /** * 3. Start the SystemServer process ** /
                startSystemServer(abiList, socketName, zygoteServer);
            }

            Log.i(TAG, "Accepting command socket connections");
            /** * 4. Wait for AMS request */
            zygoteServer.runSelectLoop(abiList);
						// Clear or close the corresponding Socket
            zygoteServer.closeServerSocket();
        } catch (Zygote.MethodAndArgsCaller caller) {
            caller.run();
        } catch (Throwable ex) {
            Log.e(TAG, "System zygote died with exception", ex);
            zygoteServer.closeServerSocket();
            throwex; }}Copy the code

RegisterZygoteSocket creates a server Socket named “name” through the registerZygoteSocket function in comment 1 above. This Socket is used to wait for AMS to initiate a request to create a new application process, about which I’ll explain later. Note 3 starts the service process, and note 4 waits for AMS’s request. Let’s look directly at the code implementation of note 4

// com.android.internal.os ZygoteInit.main->runSelectLoop

    void runSelectLoop(String abiList) throws Zygote.MethodAndArgsCaller {
        ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
        ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();

        /** * 1. Add the value of the fd field of the Socket */
        fds.add(mServerSocket.getFileDescriptor());
        peers.add(null);

        /** * wait for AMS request */ in an infinite loop
        while (true) {
            StructPollfd[] pollFds = new StructPollfd[fds.size()];
            /** * 2. Dump FDS information into the pollFds array. * /
            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);
            }

            /** * 3. Iterate over the pollFds information */
            for (int i = pollFds.length - 1; i >= 0; --i) {

                if ((pollFds[i].revents & POLLIN) == 0) {
                    continue;
                }
                // If I == 0, the server Socket is connected to the client
                if (i == 0) {
                    4 / * * * * /
                    ZygoteConnection newPeer = acceptCommandPeer(abiList);
                    // Add ZygoteConnection to the Socket connection list
                    peers.add(newPeer);
                    // Add ZygoteConnection's file descriptor to the FDS list
                    fds.add(newPeer.getFileDesciptor());
                } else {// If not, AMS sent Zygote a request to create an application process
                    Call ZygoteConnection's runOnce function to create a new application process and close the connection from the list of Socket connections */
                    boolean done = peers.get(i).runOnce(this);
                    if (done) {
                        peers.remove(i);
                        fds.remove(i);
                    }
                }
            }
        }
    }

Copy the code

If AMS sends a request for a new task, it will go to comment 5 via peers. Get (I).runonce (this); To process request data, let’s look directly at the implementation of the runOnce function:

//com.android.internal.os; ZygoteConnection.java
    boolean runOnce(ZygoteServer zygoteServer) throws Zygote.MethodAndArgsCaller {

        String args[];
        Arguments parsedArgs = null;
        FileDescriptor[] descriptors;

        try {
            /** * 1. Obtain the startup parameter of the application process */
            args = readArgumentList();
            descriptors = mSocket.getAncillaryFileDescriptors();
        } catch (IOException ex) {
            Log.w(TAG, "IOException on command socket " + ex.getMessage());
            closeSocket();
            return true; }...int pid = -1;
        FileDescriptor childPipeFd = null;
        FileDescriptor serverPipeFd = null;

        try {
            /** * 2. Wrap the args array that gets the start application process into a parsedArgs object of type Arguments */
            parsedArgs = newArguments(args); . fd =null;

            /** * 3. Use Zygote to create an application process */
            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 (ErrnoException ex) {
          ...
        }

        try {
            // The current code logic runs in the created child process
            if (pid == 0) {
                // in child
                zygoteServer.closeServerSocket();
                IoUtils.closeQuietly(serverPipeFd);
                serverPipeFd = null;
                //4. Process the application process
                handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);

                // should never get here, the child is expected to either
                // throw Zygote.MethodAndArgsCaller or exec().
                return true;
            } else {
                // in parent... pid of < 0 means failure
                IoUtils.closeQuietly(childPipeFd);
                childPipeFd = null;
                returnhandleParentProc(pid, descriptors, serverPipeFd, parsedArgs); }}finally{ IoUtils.closeQuietly(childPipeFd); IoUtils.closeQuietly(serverPipeFd); }}Copy the code

From the code above we know that runOnce first gets the parameters to start the application process, then wraps an Argument, and finally passes in the start process information via Zygote. Forkandwbte creates AMS. The interior is actually a native function to create. Let’s look at comment 4 to handle the completed application process, as follows:

//com.android.internal.os; ZygoteConnection.java    
		private void handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr)
            throws Zygote.MethodAndArgsCaller {...if(parsedArgs.invokeWith ! =null) {... }else {
            // Call the ZygoteInit function
            ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion,
                    parsedArgs.remainingArgs, null /* classLoader */); }}Copy the code

The ZygoteInit function is called inside handleChildProc.

// com.android.internal.os ZygoteInit

    public static final void zygoteInit(int targetSdkVersion, String[] argv,
            ClassLoader classLoader) throws Zygote.MethodAndArgsCaller {
        if (RuntimeInit.DEBUG) {
            Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
        }

        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
        RuntimeInit.redirectLogStreams();

        RuntimeInit.commonInit();
        /** * 1. Start the Binder thread pool */
        ZygoteInit.nativeZygoteInit();
        /** * 2. Enter the ActivityThread main method */
        RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
    }

Copy the code

Binder thread pools are started in note 1 for interprocess communication and we note the internal implementation in Note 2

  //com.android.internal.os RuntimeInit.java
    protected static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
            throws Zygote.MethodAndArgsCaller {... invokeStaticMain(args.startClass, args.startArgs, classLoader); }private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
            throws Zygote.MethodAndArgsCaller 
    { Class<? > cl;try {
            / * * * 1. Through the className (" android. App. ActivityThread ") reflection get ActivityThread class * className passed through the AMS and other places, is not the only * /
            cl = Class.forName(className, true, classLoader);
        } catch (ClassNotFoundException ex) {
            throw new RuntimeException(
                    "Missing class when invoking static main " + className,
                    ex);
        }

        Method m;
        try {
            /** * 2. Get ActivityThread main */
            m = cl.getMethod("main".new Class[] { String[].class });
        } catch (NoSuchMethodException ex) {
            ...
        } catch (SecurityException ex) {
            ...
        }

        int modifiers = m.getModifiers();
        if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
           ...
        }

        /** * 3. Pass m and argv to MethodAndArgsCaller, throw an exception, and catch the exception in zygoteinit. main */
        throw new Zygote.MethodAndArgsCaller(m, argv);
    }

Copy the code

Through the above code first according to the launch parameters of AMS passed android. The app. ActivityThread then to reflect ActivityThread instance, through the instance of it to the main function, Finally to Zygote. MethodAndArgsCaller (m, argv); To handle exceptions, look directly at the zygoteinit.main () function

//com.android.internal.os.ZygoteInit.java
    public static void main(String argv[]) {...try{...// Server Socket name
            String socketName = "zygote"; ./** * 1. Create a server Socket named "zygote" */zygoteServer.registerServerSocket(socketName); ./** * 2. Wait for AMS request */
            zygoteServer.runSelectLoop(abiList);

        } catch (Zygote.MethodAndArgsCaller caller) {
          	An exception was caught in RuntimeInit applicationInit
            caller.run();
        } catch (Throwable ex) {
            Log.e(TAG, "System zygote died with exception", ex);
            zygoteServer.closeServerSocket();
            throwex; }}Copy the code

According to comment 3 we know that we caught an exception in RuntimeInit applicationInit and then entered its run function

////com.android.internal.os Zygote.java

    public static class MethodAndArgsCaller extends Exception
            implements Runnable {
        /** method to call */
        private final Method mMethod;

        /** argument array */
        private final String[] mArgs;

        public MethodAndArgsCaller(Method method, String[] args) {
            mMethod = method;
            mArgs = args;
        }

        public void run(a) {
            try {
                /** * 1. The ActivityThread main method is executed */
                mMethod.invoke(null.new Object[] { mArgs });
            } catch (IllegalAccessException ex) {
                throw new RuntimeException(ex);
            } catch (InvocationTargetException ex) {
                Throwable cause = ex.getCause();
                if (cause instanceof RuntimeException) {
                    throw (RuntimeException) cause;
                } else if (cause instanceof Error) {
                    throw (Error) cause;
                }
                throw newRuntimeException(ex); }}}Copy the code

At this point, both the application process creation and the application process entry, ActivityThread main, have been executed. Let’s look at the ActivityThead main function implementation:

//android.app; ActivityThread.java
    // through a ZygoteInit reflection call
    public static void main(String[] args) {...//1. The main thread message loop Looper is created
        Looper.prepareMainLooper();
        2. Create an ActivityThread object
        ActivityThread thread = new ActivityThread();
        //3. Application,Activity ...... The entrance
        thread.attach(false);
				//4. Get H -> Handler
        if (sMainThreadHandler == null) { sMainThreadHandler = thread.getHandler(); }...//5. Start Looper loop to process main thread messages
        Looper.loop();

        throw new RuntimeException("Main thread loop unexpectedly exited");
    }
Copy the code

The ActivityThread main function does five things:

    1. Main thread message loop Looper created
    1. Create an ActivityThread object
    1. Open the Application, the Activity… The entrance
    1. Get H -> Handler
    1. Start Looper loop to process main thread messages

Let’s skip straight to comment 3

//

    private void attach(boolean system) {...//1. Get IActivityManager aiDL interface
            final IActivityManager mgr = ActivityManager.getService();
            try {
                / / 2. The associated Application
                mgr.attachApplication(mAppThread);
            } catch (RemoteException ex) {
                throwex.rethrowFromSystemServer(); }...try {
                mInstrumentation = new Instrumentation();
              	//3. Create system-level Context
                ContextImpl context = ContextImpl.createAppContext(
                        this, getSystemContext().mPackageInfo);
              	//4. Create Application object
                mInitialApplication = context.mPackageInfo.makeApplication(true.null);
              	//5. Application onCreate lifecycle call
                mInitialApplication.onCreate();
            } catch (Exception e) {
                throw new RuntimeException(
                        "Unable to instantiate Application():"+ e.toString(), e); }}... }Copy the code

Let’s jump right to the Application creation, skip to comment 4

//android.app; LoadedApk.java
    public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) {
        if(mApplication ! =null) {
            returnmApplication; }... ContextImpl appContext = ContextImpl.createAppContext(mActivityThread,this);
            Create a new Application
            app = mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);
           
        } catch(Exception e) { .. } mApplication = app;if(instrumentation ! =null) {
            try {
                instrumentation.callApplicationOnCreate(app);
            } catch (Exception e) {
               ...

        return app;
    }
Copy the code

Let’s move on to the implementation of comment 1

//android.app; Instrumentation.java
    public Application newApplication(ClassLoader cl, String className, Context context)
            throws InstantiationException, IllegalAccessException, 
            ClassNotFoundException {
              // Call the internal newApplication function
        return newApplication(cl.loadClass(className), context);
    }

    static public Application newApplication(Class
        clazz, Context context)
            throws InstantiationException, IllegalAccessException, 
            ClassNotFoundException {
        // Reflection instantiates Application
        Application app = (Application)clazz.newInstance();
        // Execute the Application lifecycle function attach
        app.attach(context);
        return app;
    }
Copy the code

The creation of the Application process and the launching of the Application are covered here

conclusion

This article involves many knowledge points such as Zygote, AMS, ActivityThread, Application and so on. I believe that if you follow my series of articles to read, you will definitely gain some.

Here is a brief summary of the startup of the application process. First, touch the application icon on the phone screen through the click event in the Launcher. AMS will receive the information of starting the application process, and then transmit it to Zygote process through Socket. The Zygote process receives the startup information from AMS to create the native layer child process, and finally calls ActivityThead main via reflection. Finally, in the ActivityThead Attach function, the Application is instantiated by reflection and the corresponding lifecycle function is executed. At this point the Application process is executed in the Application. The next article will bring you the source analysis of the Activity in the four components, stay tuned!

reference

  • Android Advanced Decryption