AMS家族:
AMS处理的逻辑多而复杂,因此AMS并不是孤军奋战,而是有一些类和它共同作战,这些类会帮助AMS完成相关的逻辑,AMS和这些共同作战的类就叫做AMS家族。
1.Android7.0的AMS家族:
ActivityManager是一个和AMS相关联的类,它主要对运行中的Activity进行管理,这些管理工作并不是由ActivityManager来处理的,而是交给AMS来处理的。ActivityManager中的方法会通过ActivityManagerNative(简称AMN)的gerDefault方法来得到ActivityManagerProxy(简称AMP),其中AMP是AMS的代理类,AMN是一个抽象类,它将功能交给子类AMS处理。这里举例:Android7.0的activity启动过程快进到Instrumentation的execStartActivity方法:它主要调用AMN的getDefault方法来获取AMS的代理类AMP,接着调用了AMP的startActivity方法。
AMN的getDefault方法中调用了mDefault的get方法,其中mDefault是一个Singleton类。然后调用了getService方法获取了Service的引用,也就是IBinder类型的AMS引用。接着调用asInterface方法将它封装为AMP类型对象,并且保存在gDefault中。
AMP的startActivity方法它把传入的参数写入Parcel类型的data中,通过IBinder类型的mRemote对象的transact方法向服务器端的AMS发送信息,那么服务器端的AMS就会从Binder线程池中读取客户端发送的数据,最终调用AMN的onTransact方法,它会调用AMS的startActivity方法。详见Activity启动过程的第二节。
2.Android8.0的AMS家族:
与Android7.0不同的是,举例:Android8.0的activity启动过程快进到Instrumentation的execStartActivity方法,而execStartActivity方法主要调用了ActivityManager的getService方法来获取AMS的代理对象。要实现进程之间的通信,服务器端也就是AMS只需要继承IActivityManager.Stub类并且实现相应的方法即可,采用AIDL之后就不需要使用AMS的代理类AMP了,因此Android8.0去掉了AMP,代替它的是IActivityManager,它是AMS本地的代理。
AMS的启动过程:
我们直接快进到startBootstrapServices方法用SystemServerManager启动了引导服务,其中AMS就包含其中。具体过程参考:系统启动的3.2:解析SystemServer进程。我们来看startBootstrapServices方法启动AMS的部分:主要调用了SystemServerManager的startService方法,并且传入参数ActivityManagerService.Lifecycle.class,之后调用getService方法返回AMS实例。
在startService方法中,把参数通过add方法添加到ArrayList类型的mService中完成注册。并且后续通过service的onStart方法完成该Service对象的启动。
而.Lifecycle是AMS的内部类,它的构造方法中创建了AMS的实例,当调用onStart方法时其实是调用AMS的start方法,而Lifecycle的getService方法也是返回的AMS实例。
AMS与应用程序进程:
在系统启动中,写到在Zygote的java框架层中,会创建一个Server端的socket,这个是用来等待AMS请求Zygote来创建新的应用程序进程的。所以总结一下AMS与应用程序进程之间的关系主要有:
- 启动应用程序时AMS会检查这个应用程序所需要的应用程序进程是否存在;
- 如果不存在,则AMS请求Zygote进程创建需要的应用程序进程。
AMS重要的数据结构:
AMS涉及了很多的数据结构,这一节分析一下ActivityRecord,TaskRecord,ActivityStack,也是Activity任务栈的基础。
1.解析ActivityRecord:
ActivityRecord它内部记录了Activity的所有信息,因此用它来描述一个Activity,它是在启动Activity的时候被创建的,具体是在ActivityStarter的startActivity方法被创建的,参考:2.AMS到ApplicationThread的调用过程。
ActivityRecord部分重要的成员变量:
名称 | 类型 | 说明 |
---|---|---|
service | ActivityManagerService | AMS的引用 |
info | ActivityInfo | Activity中代码和AndroidManifes设置的节点信息 |
launchedFromPackage | String | 启动Activity的包名 |
taskAffnity | String | Activity希望归属的栈 |
task | TaskRecord | ActivityRecord所在的TaskRecord |
app | ProcessRecord | ActivityRecord所在的应用程序进程 |
state | ActivityState | 当前Activity的状态 |
icon | int | Activity的图标资源标识符 |
theme | int | Activity的主题资源标识符 |
因为ActivityRecord存储了它所在的TaskRecord,这就将两者关联在一起。
2.解析TaskRecord:
TaskRecord用来描述一个Activity任务栈,其内部也有很多的成员变量。写出部分重要的成员变量:
名称 | 类型 | 说明 |
---|---|---|
taskId | int | 任务栈的唯一标识符 |
affinity | String | 任务栈的倾向性 |
intent | Intent | 启动这个任务栈的intent |
mActivities | ArrayList<ActivityRecord> | Activity的记录 |
mStack | ActivityStack | 当前归属的ActivityStack |
mService | ActivityManagerService | AMS的引用 |
3.解析ActivityStack:
ActivityStack是一个管理类,用来管理系统的Activity,其内部维护了Activity的所有状态,特殊状态的Activty以及和Activity相关的列表等数据。ActivityStack是由ActivityStackSupervisor来进行管理的,而ActivityStackSupervisor在AMS的构造方法通过createStackSupervisor方法来被创建。
3.1:ActivityStack的实例类型:
在ActivityStackSupervisor中有很多种的ActivityStack的实例类型。例如:mHomeStack用来存储Launcher App的所有Activity。mFocusedStack表示当前正在接收输入或者启动下一个Activity的所有Activity。mLastFocusedStack表示此前接收输入的所有Activity。ActivityStackSupervisor提供了获取上述ActivityStack的方法,比如要获取mFocusedStack,只需要调用ActivityStackSupervisor的getFocusedStack方法即可。
3.2:ActivityState:
在ActivityState中通过枚举存储了Activity的所有的状态,通过名称我们也可以轻易的知道这些状态所代表的含义。
3.3:特殊的Activity:
在ActivityStack中定义了一些特殊状态的Activity,这些特殊状态都是ActivityRecord类型的,ActivityRecord用来记录一个Activity所有的信息。
3.4:维护的ArrayList:
在ActivityStack中维护了ArrayList,这些ArrayList中的元素类型主要是ActivityRecord和TaskRecord。
ArrayList | 元素类型 | 说明 |
---|---|---|
mTaskHistory | TaskRecord | 所有没有被销毁的Activity任务栈 |
mLRUActivities | ActivityRecord | 正在运行的Activity,列表中的第一个条目是最近最少使用的Activity |
mNoAnimActivities | ActivityRecord | 不考虑转换动画的Activity |
mValidateAppTokens | TaskGroup | 用于与窗口管理器验证应用令牌 |
Activity栈管理:
我们来看:ActivityRecord是用来记录一个Activity的所有信息的,而TaskRecord中又包含了一个或者多个ActivityRecord,其中TaskRecord是用来表示Activity的任务栈,用来管理栈中的ActivityRecord,而一个ActivityStack又包含了一个或者多个TaskRecord,它是TaskRecord的管理者。Activity的栈管理是建立在Activity任务栈模型之上的,有了栈管理,我们可以对应用程序进行操作,应用可以复用应用中以及其他应用的Activity,节省了资源。
1.Launch Mode:
Launch Mode用于设定Activity的启动方式,无论哪一种启动方式,所启动的Activity都会位于Activity栈的栈顶,主要有以下4种Launch Mode:
- standerd:默认模式,每次启动Activity都会创建一个新的Activity实例。
- singleTop:如果要启动的Activity在栈顶,则不会重新创建,同时Activity的onNewIntent方法会被调用。如果要启动的Activity不在栈顶,则会重新创建。
- singleTask:如果要启动的Activity已经存在于它想要所属的栈中,那么不会创建Activity实例,将栈中位于该Activity上的所有的Activity出栈,同时该Activity的onNewIntent也会被调用。如果如果要启动的Activity已经不存在它想要所属的栈中,且栈已经启动,则会创建该Activity实例。如果栈不存在,则创建新栈,并且把创建的Activity压入栈中。
- singleInstance:和singleTask类似,不同的是,启动Activity时,会首先创建一个新栈,然后将创建该Activity实例压入栈中,栈中只会存在一个Activity实例。
2.Intent的FLAG:
在Intent中定义了很多的FLAG,其中有几个FLAG也可以设定Activity的启动方式,如果Launch Mode和FLAG设定的Activity的启动方式有冲突的话,则以FLAG设定的方式为标准。
- FLAG_ACTIVITY_SINGLE_TOP:和Launch Mode中的singleTop效果是一样的。
- FLAG_ACTIVITY_NEW_TASK:和Launch Mode中的singleTask效果是一样的。
- FLAG_ACTIVITY_CLEAR_TOP:在Launch Mode中没有与此对应的模式,如果要启动的Activity已经存在于栈中,则将所有位于它上面的Activity出栈。singleTask默认具有此标记位的效果。
除了上述这三个FLAG,还有一些FLAG对我们分析栈管理有些帮助。
- FLAG_ACTIVITY_NO_HISTORY:Activity一旦退出,就不会存在于栈中。同样地,也可以在AndroidManifest.xml中设置 android:noHistory。
- FLAG_ACTIVITY_MULTIPLE_TASK:需要和FLAG_ACTIVITY_NEW_TASK一同使用才有效果,系统会启动一个新的栈来容纳新启动的Activity。
- FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS:Activity 不会被放入到“最近启动的Activity”列表中。
- FLAG_ACTIVITY_BROUGHT_TO_FRONT :这个标志位通常不是由应用程序中的代 码设置的,而是 Launch Mode为singleTask时,由系统自动加上的。
- FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY:这个标志位通常不是由应用程序中的代码设置的,而是从历史记录中启动 的(长按Home 键调出)。
- FLAG_ACTIVITY_CLEAR_TASK:需要和FLAG_ACTIVITY_NEW_TASK一同使用才有效果,用于清除与启动的Activity相关栈的所有其他Activity。
3.taskAffinity:
我们可以在AndroidManifest.xml中设置android:taskAffinity,用来指定Activity希望归属的栈,在默认情况下,同一个应用程序的所有的Activity都有同样的taskAffinity。taskAffinity在下面两种情况下会产生效果:
- taskAffinity与FLAG_ACTIVITY_NEW_TASK或者singleTask配合。如果新启动的Activity的taskAffinity和栈的taskAffinity相同则加入到该栈中,如果不同,就会创建新栈。
- taskAffinity与allowTaskReparenting配合,如果allowTaskReparenting为true,说明Activity具有转移能力。主要看ActivityStack的findTaskLocked方法查找Activity最匹配的栈。