理解ActivityManagerService:

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启动过程的第二节。

588e6c55e2474f83adad9c4c471c438d.png

 

7beed549f7c045fd9ec250009cba37a4.png

 

 

 

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本地的代理。

f738f72d678843189f29e20bfa428cf4.png

 

 

 

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部分重要的成员变量

名称类型说明
serviceActivityManagerServiceAMS的引用
infoActivityInfoActivity中代码和AndroidManifes设置的节点信息
launchedFromPackageString启动Activity的包名
taskAffnityStringActivity希望归属的栈
taskTaskRecordActivityRecord所在的TaskRecord
appProcessRecordActivityRecord所在的应用程序进程
stateActivityState当前Activity的状态
iconintActivity的图标资源标识符
themeintActivity的主题资源标识符

 

因为ActivityRecord存储了它所在的TaskRecord,这就将两者关联在一起。

 

 

 

2.解析TaskRecord:

TaskRecord用来描述一个Activity任务栈,其内部也有很多的成员变量。写出部分重要的成员变量:

名称类型说明
taskIdint任务栈的唯一标识符
affinityString任务栈的倾向性
intentIntent启动这个任务栈的intent
mActivitiesArrayList<ActivityRecord>Activity的记录
mStackActivityStack当前归属的ActivityStack
mServiceActivityManagerServiceAMS的引用

 

 

 

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中的元素类型及其说明
ArrayList元素类型说明
mTaskHistoryTaskRecord所有没有被销毁的Activity任务栈
mLRUActivitiesActivityRecord正在运行的Activity,列表中的第一个条目是最近最少使用的Activity
mNoAnimActivitiesActivityRecord不考虑转换动画的Activity
mValidateAppTokensTaskGroup用于与窗口管理器验证应用令牌

 

 

 

 

Activity栈管理:

f0ae7e4958e84d60adedc41ef206f3dd.png

 

我们来看: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在下面两种情况下会产生效果:

  1. taskAffinity与FLAG_ACTIVITY_NEW_TASK或者singleTask配合。如果新启动的Activity的taskAffinity和栈的taskAffinity相同则加入到该栈中,如果不同,就会创建新栈。
  2. taskAffinity与allowTaskReparenting配合,如果allowTaskReparenting为true,说明Activity具有转移能力。主要看ActivityStack的findTaskLocked方法查找Activity最匹配的栈。

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mo@

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值