安卓应用程序进程启动过程,就这么简单?

应用程序进程启动过程

在这里插入图片描述
当用户点击图标时,会调用AMS的startProcessLocked方法向Zygote进程发送请求,请求创建应用程序进程。Zygote进程接收请求后,开始创建应用程序进程。
若对Zygote进程或者SystemServer进程不了解,可以参考上一篇:Android系统启动流程

一.AMS通过调用startProcessLocked方法向Zygote进程发送请求

ActivityManagerService.java中startProcessLocked方法的执行过程:

    1.获取要创建的应用程序进程的用户id
    2.创建用户组id并赋值
    3.若字符串entryPoint为null,则将其赋值为”android.app.ActivityThread”
    该值为应用程序进程主线程的类名
    4.调用Process的start方法,传入用户id、用户组id、字符串entryPoint作为参数

Process.java中start方法的执行过程:

    调用zygoteProcess对象的start方法

ZygoteProcess.java中start方法的执行过程:

    调用startViaZygote方法

ZygoteProcess.java中startViaZygote方法的执行过程:

    1.创建ArrayList对象,保存应用进程的启动参数
    2.调用openZygoteSocketIfNeeded方法获取ZygoteSocket对象
        1).调用ZygoteState的connect方法与Zygote进程建立主模式的Socket连接,返回ZygoteState对象。mSocket=”zygote”
        2).判断主模式返回的ZygoteState对象是否与启动应用程序进程所需的ABI匹配
        若匹配,则返回
        3).若不匹配,调用ZygoteState的connect方法与Zygote进程建立辅模式的Socket连接,返回ZygoteState对象。mSecondarySocket=”zygote_secondary”
        4). 判断辅模式返回的ZygoteState对象是否与启动应用程序进程所需的ABI匹配
        若匹配,则返回。若不匹配,则抛出ZygoteStartFailedEx异常
    3.调用zygoteSendArgsAndGetResult方法,传入ArrayList对象和ZygoteSocket对象作为参数

ZygoteProcess.java中zygoteSendArgsAndGetResult方法的执行过程:

    将保存在ArrayList中的启动参数写入ZygoteState对象中。
    ZygoteState是ZygoteProcess的静态内部类,用于表示Zygote进程的通信状态。

二.Zygote进程接收请求并创建应用程序进程

    在Zygote进程启动后,会调用ZygoteServer对象的runSelectLoop方法,循环等待AMS的请求。此时,通过zygoteSendArgsAndGetResult方法,将保存在ArrayList中的启动参数写入ZygoteState对象中。Zygote进程会收到创建新的应用程序的请求。当Zygote进程收到创建新的应用程序的请求时,在runSelectLoop方法中会调用对应ZygoteConnection对象的runOnce方法。

ZygoteConnection.java中runOnce方法的执行过程:

    1.调用readArgumentList方法获取String[]类型的启动参数
    2.将String[]类型的启动参数封装成Arguments类型的对象
    3.调用Zygote的forkAndSpecialize方法,传入Arguments对象作为参数
    创建应用程序进程。返回值为pid
    4.由于当前代码逻辑运行在新建的子进程中,所以pid为0。
    由于pid为0,会调用handleChildProc方法对应用程序进程进行处理

ZygoteConnection.java中handleChildProc方法的执行过程:

    调用ZygoteInit的zygoteInit方法

ZygoteInit.java中zygoteInit方法的执行过程:

    1.调用ZygoteInit的nativeZygoteInit方法
        1).在新建的应用程序进程中创建Binder线程池。该方法为JNI方法,对应AndroidRuntime.cpp中的com_android_internal_os_ZygoteInit_nativeZygoteInit函数。
        2).com_android_internal_os_ZygoteInit_nativeZygoteInit函数内部调用AppRuntime对象的onZygoteInit函数(app_main.cpp)。
        3).onZygoteInit函数内部会调用ProcessState对象的startThreadPool函数(ProcessState.cpp)启动Binder线程池。
        4).startThreadPool函数内部会判断一个bool类型的变量的值是否为false(默认为false),该变量表示Binder线程池是否已经启动。若该变量为false,则设置该变量为true,并调用spawnPooledThread函数创建Binder线程池的第一个线程。
        5). spawnPooledThread函数内部创建PoolThread对象,并调用PoolThread对象的方法启动一个新线程。
        6).PoolThread类继承了Thread类,内部threadLoop函数通过调用IPCThreadState的joinThreadPool函数将当前线程注册到Binder驱动程序中。
    2.调用RuntimeInit的applicationInit方法

RuntimeInit.java中applicationInit方法的执行过程:

    调用invokeStaticMain方法,其中一个参数className为”android.app.ActivityThread”

RuntimeInit.java中invokeStaticMain方法的执行过程:

    1.通过类名获取android.app.ActivityThread类
    2.获取android.app.ActivityThread类的main方法
    3.创建Zygote.MethodAndArgsCaller对象,传入main方法
    抛出Zygote.MethodAndArgsCaller异常,通过抛异常的方式启动进程

    ZygoteInit.java的main方法会对异常进行捕获,调用Zygote.MethodAndArgsCaller对象的run方法。run方法内部会通过反射的方式,调用新建应用程序进程的main方法,即android.app.ActivityThread的main方法。

ActivityThread.java中main方法的执行过程:

    1.调用Looper的prepareMainLooper方法创建主线程Looper
    2.创建ActivityThread对象
    3.通过调用ActivityThread对象的getHandler方法获取主线程H类对象
    H类继承了Handler类,是ActivityThread的内部类,用于处理线程的消息循环
    4.调用Looper的loop方法开启消息循环


应用程序进程创建完毕

发布了12 篇原创文章 · 获赞 5 · 访问量 2284

猜你喜欢

转载自blog.csdn.net/LeeDuoZuiShuai/article/details/104095562