Android 应用程序进程启动过程

应用程序进程启动分为三个大的步骤:

  1. AMS通过socket向zygote发送创建应用程序进程请求;
  2. zygote接收请求并创建应用程序进程
  3. 应用进程创建后会启动Binder线程池以及开启消息循环机制

那么现在来从源码具体的看一下应用程序进程如何启动:

1. AMS通过startProcessLocked()向zygote进程发起创建应用程序进程的请求,代码如下:
private final void startProcessLocked(...params) {
	try {
            try {
            
                final int userId = UserHandle.getUserId(app.uid);
                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
            } catch (RemoteException e) {
                throw e.rethrowAsRuntimeException();
            }
			 //1. 获取要创建的应用程序进程的用户ID
            int uid = app.uid;
            int[] gids = null;
            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
            if (!app.isolated) {
                ...
                //2.对gids即用户组id进行创建和赋值
                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) entryPoint = "android.app.ActivityThread";
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
                    app.processName);
            checkTime(startTime, "startProcess: asking zygote to start proc");
            
            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.启动应用程序进程,Process.start()内部调用的是ZygoteProcess的start()方法,而ZygoteProcess内部调用的又是startViaZygote()方法
                startResult = Process.start(entryPoint,
                        app.processName, uid, uid, gids, debugFlags, mountExternal,
                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                        app.info.dataDir, invokeWith, entryPointArgs);
            }
            ...
          }
        }
      }
   }         
                
2. ZygoteProcess.startViaZygote():
private Process.ProcessStartResult startViaZygote(final String processClass...){
   //1.创建字符串列表argsForZygote,并将应用进程的启动参数保存在argsForZygote中。
   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);
   
   synchronized(mLock) {
     //2. 将应用程序启动参数写入到ZygoteState中,ZygoteState是ZygoteProcess的静态内部类,用于表示与Zygote进程通信状态,这样zygote进行就会收到一个创建新的程序请求
     return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
   }
        
        
3. ZygoteProcess.openZygoteSocketIfNeeded()
private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
  Preconditions.checkState(Thread.holdsLock(mLock), "ZygoteProcess lock not held");

        if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
            try {
            	//1. 与Zygote进程的“zygote” socket建立Socket链接
                primaryZygoteState = ZygoteState.connect(mSocket);
            } catch (IOException ioe) {
                throw new ZygoteStartFailedEx("Error connecting to primary zygote", ioe);
            }
        }
			//2. 链接zygote主模式返回的ZygoteState是否与启动应用程序进程所需要的ABI匹配
        if (primaryZygoteState.matches(abi)) {
            return primaryZygoteState;
        }

        // The primary zygote didn't match. Try the secondary.
        if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) {
            try {
            		//3. 如果不匹配,则尝试连接Zygote辅模式,即连接名为“zygote_secondary"的socket
                secondaryZygoteState = ZygoteState.connect(mSecondarySocket);
            } catch (IOException ioe) {
                throw new ZygoteStartFailedEx("Error connecting to secondary zygote", ioe);
            }
        }
		 //4. 	链接zygote辅模式返回的ZygoteState是否与启动应用程序进程所需要的ABI匹配,socket连接成功则返回ZygoteState对象
		   if (secondaryZygoteState.matches(abi)) {
            return secondaryZygoteState;
        }

        throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi);
    }	
4. 创建zygote进程时,会在zygote进程的main()里面开启一个等待AMS请求的操作,即runSelectLoop(),在上篇Android系统启动时已经提及:
 void runSelectLoop(String abiList) throws Zygote.MethodAndArgsCaller {
        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 {
                  //当有新的请求时,会调用这里的代码,这里是如何去创建新的请求?
                    boolean done = peers.get(i).runOnce(this);
                    if (done) {
                        peers.remove(i);
                        fds.remove(i);
                    }
                }
            }
        }
    }
5. ZygoteConnection.runOnce():
boolean runOnce(ZygoteServer zygoteServer) throws Zygote.MethodAndArgsCaller {

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

        try {
        		//1. 读取应用程序启动参数
            args = readArgumentList();
        }    
        ...
        
        try {
        	//2.将上面的参数封装到Argument中 	
            parsedArgs = new Arguments(args);
        ...
        }
        
        //3.通过zygote fork去创建应用程序进程,返回pid,pid == 0,说明代码运行在子进程中
        pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
                    parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
                    parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.instructionSet,
                    parsedArgs.appDataDir);
                    
         try {
          // 4. 当前代码运行在子进程中
            if (pid == 0) {
                // in child
                zygoteServer.closeServerSocket();
                IoUtils.closeQuietly(serverPipeFd);
                serverPipeFd = null;
                //5. 处理应用程序进程,这里又是如何去处理的?内部调用了ZygoteInit的zyogetInit()方法
                handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);
                return true;
            } else {
                // in parent...pid of < 0 means failure
                IoUtils.closeQuietly(childPipeFd);
                childPipeFd = null;
                return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);
            }
        } finally {
            IoUtils.closeQuietly(childPipeFd);
            IoUtils.closeQuietly(serverPipeFd);
        }                   
            
6. ZygoteInit.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();
        ZygoteInit.nativeZygoteInit(); //1. 这里会在新创建的应用程序进程中创建Binder线程池
        RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);  //2. 这里内部调用了 RuntimeInit的invokeStaticMain()方法
    }
7. RuntimeInit.invokeStaticMain()
private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader) throws Zygote.MethodAndArgsCaller {
        Class<?> cl;

        try {
            cl = Class.forName(className, true, classLoader);  //这个className就是第一步中的ActivityThread,通过反射获取它的实例
        } catch (ClassNotFoundException ex) {
            throw new RuntimeException(
                    "Missing class when invoking static main " + className,
                    ex);
        }

        Method m;
        try {
        	  //2. 获取ActivityThread的main()方法
            m = cl.getMethod("main", new Class[] { String[].class });
        } catch (NoSuchMethodException ex) {
            throw new RuntimeException(
                    "Missing static main on " + className, ex);
        } catch (SecurityException ex) {
            throw new RuntimeException(
                    "Problem getting static main on " + className, ex);
        }

        int modifiers = m.getModifiers();
        if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
            throw new RuntimeException(
                    "Main method is not public and static on " + className);
        }

        throw new Zygote.MethodAndArgsCaller(m, argv); //3. 这里抛出的异常会被ZygoteInit的main()捕获
    }
8. ZygoteInit.main():
public static void main(String argv[]) {
   ...
   zygoteServer.closeServerSocket();
        } catch (Zygote.MethodAndArgsCaller caller) {
            caller.run(); //1. 当捕获到MethodAndArgsCaller异常时,就会调用MethodAndArgsCaller的run()方法,那它的run方法又做了什么?
        } catch (Throwable ex) {
            Log.e(TAG, "System zygote died with exception", ex);
            zygoteServer.closeServerSocket();
            throw ex;
        }
9. MethodAndArgsCaller.run()
public void run() {
            try {
           //这里调用了ActivityThread的main()方法,那么至此,应用程序进程经过这么长的步骤终于进入主线程ActivityThread的main()方法中,应用程序进程就算创建完成且启动了主线程
                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 new RuntimeException(ex);
            }
        }

Binder线程池启动过程

应用程序进程创建后,会做两个工作,一个创建Binder线程池,而是去调用ActivityThread的main()方法,调用main()方法的过程上面以及分析过了,现在来看看Binder线程池的启动过程。

从上面代码可知,启动线程池的入口在ZygoteInit的nativeZygoteInit()中,源码位于frameworks/base/core/jni/AndroidRuntime.cpp中,内部调用的是frameworks/base/cmds/app_process/app_main.cpp的onZygoteInit()方法,具体如下:

 virtual void onZygoteInit(){    
    sp<ProcessState> proc = ProcessState::self();
	 ALOGV("App process: starting thread pool.\n");
    proc->startThreadPool();  //通过调用ProcessState的startThreadPool()来创建Binder线程池
  }

ProcessState创建Binder线程池的具体代码:

void ProcessState::spawnPooledThread(bool isMain)
{
    if (mThreadPoolStarted) {
        String8 name = makeBinderThreadName();
       ALOGV("Spawning new pooled thread, name=%s\n", name.string());
        sp<Thread> t = new PoolThread(isMain); //创建线程池的主线程
        t->run(name.string()); //启动主线程
    }
}

消息循环创建过程

上面步骤中,调用了ActivityThread的main()方法去启动应用程序主线程,那么这个main()里面做了什么工作?

public static void main(String[] args) {

//1. 创建主线程looper
 Looper.prepareMainLooper();

 //2. 创建ActivityThread,用于管理当前应用程序进程的主线程
 ActivityThread thread = new ActivityThread();
 thread.attach(false);


 if (sMainThreadHandler == null) {
 	//3.获取ActivityThread内部的H类赋给sMainThreadHandler,H继承自Handler,用于处理主线程的消息循环。
    sMainThreadHandler = thread.getHandler();
  }
  
 if (false) {
  	Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread"));
  }

   Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
   //4. Looper开始工作,这样应用程序就可以方便的使用消息处理机制。
   Looper.loop();

   throw new RuntimeException("Main thread loop unexpectedly exited"); 
   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值