How does the application process start?

When AMS starts an Activity or Service, it checks to see if the application process exists and asks Zygote to start the required application process if it does not.


public class ActivityStack {...private final void startSpecificActivityLocked(ActivityRecord r,
			boolean andResume, boolean checkConfig) {
		// Is this activity's application already running?ProcessRecord app = mService.getProcessRecordLocked(r.processName, r.info.applicationInfo.uid); .//app.thread is the IApplicationThread in AMS
		if(app ! =null&& app.thread ! =null) {
		// The process has started and the component is ready to start.
			try {
				realStartActivityLocked(r, app, andResume, checkConfig);
				return;
			} catch(RemoteException e) { ...... }}// Start the component process
		mService.startProcessLocked(r.processName, r.info.applicationInfo, true.0."activity", r.intent.getComponent(), false); }}public final class ActivityThread {...final ApplicationThread mAppThread = newApplicationThread(); .public static void main(String[] args) {
        Looper.prepareMainLooper();

        ActivityThread thread = new ActivityThread();
        thread.attach(false);

        Looper.loop();

        throw new RuntimeException("Main thread loop unexpectedly exited");
    }
 
     private void attach(boolean system) {...final IActivityManager mgr = ActivityManager.getService();
        try {
            mgr.attachApplication(mAppThread);
        } catch (RemoteException ex) {
            throwex.rethrowFromSystemServer(); }... }}Copy the code


 boolean runOnce() throws ZygoteInit.MethodAndArgsCaller {
        String args[];
        args = readArgumentList(); / / parametersif(pid == 0) {// child process handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);return true;
            } else{// Parent processreturnhandleParentProc(pid, descriptors, serverPipeFd, parsedArgs); }}}Copy the code
  1. AMS calls the startProcessLocked method.
  2. Run openZygoteSocketIfNeeded to open the local socket.
  3. Sent via zygoteSendArgsAndGetResult argument list.
  4. Zygote if the created process pid=0, which means it is a child process, will execute the main method of the passed parameter, if not 0, return pid.

Why AMS and Zygote communicate through sockets?

  1. Because Binder communication is multithreaded, proxy objects are called by the Binder thread and need to be operated by Hander calling the main thread.
  2. The parent binder thread has a lock, and the main thread of the binder child is waiting for resources from its child thread, but the child is not copied from the parent, resulting in a deadlock. Therefore, multiple threads are not allowed in fork. As it happens, Binder communication happens to be multithreaded, so the parent process (Zgote) doesn’t use Binder threads at all.

Why not leave incubation to SystemServer instead of designing a Zygote?

  1. Use fork () function gets the child is a replica of the parent, the child process completely copy the parent process of resources, including the process context, code, data, heap, stack, memory information, open the file of the file descriptor, signal processing function, process, priority process group number, the current working directory, the root directory, resource constraints and control terminals, such as information, The child process differs from the parent process by process number, resource usage, timer, and so on.
  2. Linux uses copy-on-write technology to share zygote process resources directly. This is the value of zygote, which SystemServer can not replace. This is mainly because SystemServer runs a bunch of system services that cannot be inherited from application processes.

reference

  • Android application startup process source code analysis
  • Android Application Process Startup (Part 1)
  • Process day 2 (fork function & child & parent & daemon)
  • Linux copy-on-write
  • Talk about understanding Zygote in Android
  • Be careful with forks in multiple threads
  • Zygote