应用程序进程简介:
要想启动一个应用程序,首先要保证这个应用程序所需要的应用程序进程已经启动。AMS在启动应用程序时会检查这个应用程序所需要的应用程序进程是否存在,不存在就会请求Zygote进程启动需要的应用程序进程。我们知道Zygote的Java框架层中会创建一个service端的socket,它等待AMS请求Zygote来创建新的应用程序进程。Zygote进程通过fork自身创建应用程序进程,这样应用程序进程就会获取Zygote进程启动时创建的虚拟机实例。当然除了这个外,还创建了Binder线程池和消息循环,这样运行在应用进程中的应用程序就可以方便的使用Binder进行进程之间通信以及处理消息了。
应用程序进程启动过程:
应用程序进程创建过程步骤比较多,可以分为两个部分,分别是AMS发送启动应用程序进程请求和Zygote接收请求并创建应用程序进程。
1.AMS发送启动应用程序进程请求:
AMS如果想要启动应用程序进程,就需要向Zygote进程发送创建应用程序进程请求,AMS会通过startProcessLocked方法向Zygote进程发送请求。
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
startProcessLocked方法主要先创建应用程序进程的用户ID,并且对用户组ID进行创建和赋值。然后判断entrypoint是否为null,是则赋值为android.app.ActivityThread(值是应用程序进程主线程的类名)。接着调用Process的start方法,并把用户ID,用户组ID,entrypoint等等参数传进去。而在Process的start方法中只调用了ZygoteProcess的start方法,ZygoteProcess类是用于保持与zygote进程的通信状态。它的start方法,调用了startViaZygote方法。startViaZygote方法主要创建了字符串列表用于保存应用进程的启动参数,最后调用zygoteSendArgsGetResult方法,并且给它传入字符串列表和openZygoteSocketIfNeeded方法的返回值(是一个zygoteState类对象)。它主要是将应用进程的启动参数写入zygoteState中,zygoteState是ZygoteProcess的静态内部类,用来表示与zygote进程通信的状态。而openZygoteSocketIfNeeded方法主要调用了zygoteState的connect方法与zygote的socket建立连接,并且返回zygoteState类型的primaryZygoteState对象。并且匹配zygote返回的zygoteState和应用程序进程所需要的ABI。
2.Zygote接收请求并创建应用程序进程:
我们来看ZygoteInit的main方法的ZygoteServer的runSelectLoop方法(该方法在系统启动的zygote进程启动也有介绍)。当AMS的请求数据到来时,其实创建应用程序进程是通过调用ZygoteConnection的runOnce函数来创建的。过程为:首先使用readArgumentList方法获取应用程序进程的参数,封装到Arguments类型的对象中。再把该对象作为参数的一部分传入forkAndSpecialize方法来创建应用程序进程,返回值为pid。pid为0时,说明当前代码逻辑运行在新创建的应用程序进程中,这时就会调用handleChildProc方法来处理应用程序进程。handleChildProc方法中调用了ZygoteInit的zygoteInit方法,zygoteInit方法会调用ZygoteInit的nativeZygoteInit方法在新创建的应用程序进程中创建Binder线程池,下一节会说。以及调用RunntimeInit的appLicationInit方法。
appLicationInit方法它会调用invokeStaticMain方法,该方法通过反射得到了android.app.ActivityThread类(上面有写一点),后续获取该类的main方法,并且把该main方法传入Zygote中MethodAndArgsCaller类的构造方法中。这个与系统启动的3.1.2:进入SystemServer的main方法一样。传入之后会在ZygoteInit.java的main方法中被捕获。捕获之后会调用MethodAndArgsCaller的run方法,该方法通过执行mMethod的invoke方法(mMethod指的是ActivityThread),使得ActivityThread的main方法被动态调用,也就是应用程序进程进入了ActivityThreadr的main方法中。应用程序进程创建完毕并且运行了主线程的管理类ActivityThread。
ZygoteConnection的runOnce函数位于:frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
Binder线程池启动过程:
在系统启动的3.SystemServer处理过程也写过,在上面写到使用handleChildProc方法来处理应用程序进程,handleChildProc方法中调用了ZygoteInit的zygoteInit方法,zygoteInit方法会调用ZygoteInit的nativeZygoteInit方法在新创建的应用程序进程中创建Binder线程池。
SystemServer是使用handleSystemServerProcess方法来处理SystemServer进程。
nativeZygoteInit方法这个方法也是一个Native方法。它对应的JNI文件在frameworks/base/core/jni/AndroidRuntime.cpp定义。而因为nativeZygoteInit方法是一个JNI方法,所以它对应的函数是com_android_internal_os_ZygoteInit_nativeZygoteInit函数。该函数使用了一个AndroidRuntime类型的指针gCurRuntime,指向AndroidRuntime的子类AppRuntime,该子类创建时就会调用AndroidRuntime的构造函数。该子类的onZygoteInit方法最后一行会调用ProcessState类的startThreadPool函数来启动Binder线程池。在每个支持Binder通信的进程中都有一个ProcessState类,默认值为false,在每次调用startThreadPool函数时都会检查这个值,从而确保Binder线程池只会被启动一次。启动后,设置为true,并且调用spawnPooledThread函数创建线程池的第一个线程,也就是线程池的主线程。可以看到Binder线程是一个poolThread线程。
PoolThread类继承了Thread类,它调用了IPCThreadState的joinThreadPool函数,将当前线程注册到Binder驱动程序中,这样创建的线程就进入了Binder线程池中,新的应用程序进程就支持Binder进程之间通信了。
消息循环创建过程:
应用程序进程启动之后就会创建消息循环,我们在2.Zygote接收请求并创建应用程序进程中知道通过执行mMethod的invoke方法(mMethod指的是ActivityThread),使得ActivityThread的main方法被动态调用,也就是应用程序进程进入了ActivityThreadr的main方法中。那么在main方法中会通过Looper类的prepareMainLooper方法创建主线程的消息循环Looper,后续通过Looper的loop方法,使得Looper开始处理消息,这样也是为了方便运行在应用程序进程的应用程序可以方便的使用消息处理机制。