• 浅析Android系统中的Activity启动过程


                                                   浅析Android系统中的Activity启动过程

    一、Activity的启动分为三种类型
    1.根Activity的启动,通常就是程序的MainActivity的启动,这个是通过用户点击桌面程序(Launcher)的App的图标,
    从而导致对应的App在一个新的进程中被启动起来
    2.在同一个进程启动子Activity
    3.在新的进程启动子Activity

    对应第一种类型来讲,主要是有如下分析:
    首先根ACtivity的启动涉及到三个不同的进程,依次是Launcher所在进程,MainActivity所在进程,ActivityManagerService所在进程。
    其中ActivityManagerService是系统关键服务,他是用来管理系统Activity组件的一个服务,优先级特别高。任何app的Activity的活动都需要与它交互。既然涉及到这么多个进程的交互,那么必然涉及到Android系统中的Binder进程通讯。

    其次就是Launcher启动MainActivity的过程分析,大致分为6个阶段

     

    p1:当用户点击桌面app的图标时,Launcher(其实就是一个Activity。或者叫做继承自Activity)就获取到App的一些信息(比如,包名,路径等)(这些信息其实是Launcher通过查询PackageManagerService获得的),Launcher拿着这些信息然后去向ActivityManagerService请求一次进程间通信,表示我想要启动某个App的MainActivity。

    p1.1

    p1.2

     

    p2.ActivityManagerService收到进程间请求后,会做两件事情,第一将刚刚收到的关于启动MainActivity的信息保存下来(这些信息包括ActivityRecord等), 第二向Launcher发送一次进程间通信请求,请求Launcher进入Pause状态,这样有利于Launcher在MainActivity启动起来时,自己可以做一些操作,例如保存状态信息,以便于Launcher后面Resume。

    p2

    p3.Launcher收到了ActivityManagerService的进程间通信请求后,就会进入到Paused状态,进入到状态后,会立马向ActivityManagerService再次发送一次进程间通信请求,表示我已经进入了Paused状态,你可以放心的去启动MainActivity了。值得注意的是,ActivityManagerSerice有一个超时机制,如果Launcher在指定的时间没有进入Paused状态,即ActivityManagerService没有及时收到Launcher组件的再一次进程间通信请求,ActivityManagerService会认为Launcher无响应。

     


    p3

    p4.ActivityManagerService收到了Launcher再次发来的进程间通信请求后,它知道是时候为启动MainActivity干点正事了,它根据启动MainActivity的信息发现了MainActivity所在的运行进程并不存在,因此就会新启动一个新的进程来运行MainActivity,新的进程程序入口是ActivityThread的public final static void main(String[] args)

    p4

    p5.新的进程启动完成以后,(进程的程序入口 是ActivityThread的public final static void main(String[] args)),就会向ActivityManagerService发送一个进程间通信请求,表示新的进程已经准备就绪,随时可以起飞,请指示。

    p5

    p6.ActivityManagerService收到以后,会将p2阶段保存下来的关于MainActivity的信息做一次进程间通信请求,将信息发送给新进程,让新进程运行MainActivity。

    p6

    自此一个新的App进程被创建,MainActivity被启动起来,运行在这个新的进程中。

    这里一个6个阶段,共涉及到5次进程间通信,其中Launcher与ActivityManagerService之间进行了3次,ActivityManagerService与MainActivity所在进程之间进行了2次。
    其中涉及到的进程间通信请求具体如下:
    -----------------------------------------------------------------------------------------------------------------------
    id     phase                            detail
    -----------------------------------------------------------------------------------------------------------------------
    #1      p1:      Launcher所在进程 ----START_ACTIVITY_TRANSACTION----> ActivityManagerService所在进程

    #2   p2:     ActivityManagerService所在进程 ----SCHEDULE_PAUSE_ACTIVITY_TRANSACTION----> Launcher所在进程

    #3   p3:    Launcher所在进程 ----ACTIVITY_PAUSED_TRANSACTION----> ActivityManagerService所在进程

    #4   p5:    MainActivity(新建进程) ----ATTACH_APPLICATION_TRANSACTION----> ActivityManagerService

    #5   p6:     ActivityManagerService所在进程 ----SCHEDULE_LANUCHER_ACTIVITY_TRANSACTION----> MainActivity(新建进程)
    -----------------------------------------------------------------------------------------------------------------------



    二、对应第二种类型分析如下:
    由于在同一个进程中,一个Activity启动另一个Activity,这两个Activity都是运行在同一个进程中的,因此相比于前面分析的第一种类型,就少了ActivityManagerService去新建一个进程和新建进程对ActivityManagerService做一次ATTACH_APPLICATION_TRANSACTION请求这个步骤
    值得注意的是,由于MainActivity去启动一个子Activity是在同一个App中进行的并且没有特别指明taskAffinity,因此他们启动后再ActivityManagerService中都是同属于一个Task的,而非不同的Task。

    三、对应于第三种类型分析如下:
    由于是在同一个App中,但是两个Activity试运行在不同的进程中的,因此相比于第一种类型,有一点相似之处,但是不同的是两个Activity所属于的Task是一样的,因为他们虽然不属于同一个进程,但是他们是属于一个app的,是属于密切联系的一个用户任务,因此理所当然的就应该是在同一task中了。

    每一个Activity都是运行在一个Task中的,Task是一个比进程更加高级和抽象的概念,由于Android的App可以拥有多个不同的进程,用Task去描述一系列相关的功能比用进程去描述更加容易理解和描述。一个Task可以包含运行在不同进程中的Activity,因此可以很好的提高Activity的可重用性。(比如你的App想要查看一张照片,那么任何App提供查看照片能力的Activity都可以添加到你的App所在的Task中,虽然他们是运行在不同进程,而且甚至是不同uid中的,但是由于Task的存在,用户丝毫感觉不到是两个App, 这样查看照片的Activity就可以得到复用)

    四、总结
    这个过程涉及到几个主要的类:
    <span style="font-size:18px;">ActivityThread
    ApplicationThread
    ActivityManagerService
    
    Instrumentation
    
    ActivityRecord
    ProcessRecord
    TaskRecord
    ActivityStack
    
    ActivityManagerProxy
    ApplocationThreadProxy</span>

    参考文献:

    [1]罗升阳.Android系统源代码情景分析[M].北京:电子工业出版社,2012:393-443


  • 相关阅读:
    不可或缺 Windows Native (15)
    不可或缺 Windows Native (14)
    不可或缺 Windows Native (13)
    不可或缺 Windows Native (12)
    不可或缺 Windows Native (11)
    不可或缺 Windows Native (10)
    不可或缺 Windows Native (9)
    不可或缺 Windows Native (8)
    不可或缺 Windows Native (7)
    不可或缺 Windows Native (6)
  • 原文地址:https://www.cnblogs.com/Spground/p/8536162.html
Copyright © 2020-2023  润新知