前言
最近看代码发现了一个小技巧:看源码的时候,我们可以一边画UML图,一边看代码,需要注意的是,画UML图的时候,也将对应的包名标注上,相同包名的放在一起,这样可以给我们自己在心里做个标记。Android/Java分包和我们平时一样,都是按照模块或者相似功能放在一起处理,并没有将类进行很细致的多次分包(当然这里也可能是我一厢情愿的理解,但多少帮我解释了同一个包下上百个类,google大神为啥不细分来以便更好维护)。同时需要注意的是某些类即使是在同包下,但真实却是在不同的进程中。
进入正题
先看ActivityManagerService相关的类图
在上一节中我们知道,Android手机在启动之后,会启动ActivityManagerService服务,这篇重点介绍与ActivityManagerService相关的类,及ActivityManagerService的大致工作内容。
首先是看ActivityManagerService,对于其负责的内容,整理了网络上的介绍:
1)管理应用进程的生命周期
2)应用进程的管理服务端,直接的控制了应用程序的各个行为,保证了系统中不同的应用程序之间能够和谐的合理的进行调度运行
2)进程下四大组件生命周期
3)派发消息事件
4)内存管理等功能
Tip:在思维理解上需要重点提一下
1)ActivityManagerService是运行在其独立进程里面,和我们的APP不是同一个进程。
2)以上所有的类都集中在手机Rom里面,平时开发看到的不一定是真实的,可能是被对应的手机厂商修改过的。反编译APK的时候,android包下只能看到supprot,这里也要注意一下使用AndroidStudio直接查看APK的dex文件,这里貌似主动将SDK的源码补充上去了。
好了,本着以上内容的校验去查看源码。
从分析几个核心类开始。
1、首先看ActivityManagerProxy
这个类是ActivityManagerNative的内部类,是在android.app包下。其重点工作UML图中也罗列了,主要是执行四大组件、Appliacaiton等生命周期相关的工作,执行的方法可以直接看IActivityManager接口定义。需要说一下的是ActivityManagerNative也实现了IActivityManager接口,但是在代码里面new的是ActivityManagerProxy类,可以看下面的代码:
ActivityManagerNative.java
static public IActivityManager getDefault() {
return gDefault.get();
}
private static final Singleton<IActivityManager> gDefault = new
Singleton<IActivityManager>() {
protected IActivityManager create() {
IBinder b = ServiceManager.getService("activity");
if (false) {
Log.v("ActivityManager", "default service binder = " + b);
}
IActivityManager am = asInterface(b);
if (false) {
Log.v("ActivityManager", "default service = " + am);
}
return am;
}
};
static public IActivityManager asInterface(IBinder obj) {
if (obj == null) {
return null;
}
IActivityManager in = (IActivityManager)obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
}
return new ActivityManagerProxy(obj);
}
通常android.app包下的类使用ActivityManagerNative里面的方法,直接静态使用getDefault()来使用。这里就将ActivityManagerNative关联起来了,同时AMS继承与ActivityManagerNative,所以ActivityManagerProxy其实是在AMS进程里面的,不要被包名误导了。
2、ActivityManager,简称AM,也是一个系统服务
可以看ActivityManager类上有注解:@SystemService(Context.ACTIVITY_SERVICE,此类提供有关Activity、Service和包含的进程的信息,并与之交互。
获取ActivityManager的方式
ActivityManager am = (ActivityManager) getContext().getSystemService(
Context.ACTIVITY_SERVICE); // String ACTIVITY_SERVICE = "activity";
使用方式:看上方介绍ActivityManagerNative.java时,
IBinder b = ServiceManager.getService("activity");
ActivityManager作为IBinder的形式植入到ActivityManagerProxy中,这时,我们就将AM和ActivityManagerProxy联系起来了,两者都实现了IActivityManager接口,可以看到代理类名副其实了。
至于RecentTaskInfo、RunningAppProcessInfo、RunningTaskInfo、AppTask等类,是用于记录及处理进程/Activity所在的Task的信息,这里不展开介绍了。
3、TaskRecord\ActivityRecord
顾名思义,ActivityRecord是记录Activity活动信息的,真实也确实如此,其类的注释:An entry in the history stack, representing an activity.翻译即:代表一个进入历史堆栈的Activity状态。其次是TaskRecord,是记录一个Task活动的:至于一个Activity处于哪一个Task中,我们可以通过设定Activity的launchMode,指定是否处于之前Task还是新建Task,又或者独立的Task中。
4、ActivityStack:单个Activity堆栈的状态和管理。
1)所有以前(可能仍在运行)活动的后台历史记录。它包含taskrecord对象。
/**
* The back history of all previous (and possibly still
* running) activities. It contains #TaskRecord objects.
*/
private final ArrayList<TaskRecord> mTaskHistory = new ArrayList<>();
2)正在运行的活动的列表,按最近使用情况排序。列表中的第一个条目是最近使用最少的条目。它包含HistoryRecord对象。
/**
* List of running activities, sorted by recent usage.
* The first entry in the list is the least recently used.
* It contains HistoryRecord objects.
*/
final ArrayList<ActivityRecord> mLRUActivities = new ArrayList<>();
3)某一个Activity的一种状态记录:
ActivityRecord mPausingActivity = null;
ActivityRecord mLastPausedActivity = null;
ActivityRecord mLastNoHistoryActivity = null;
ActivityRecord mResumedActivity = null;
5、 ActivityStackSupervisor
管理所有Ativity堆栈信息,即管理所有ActivityStack,同时执行来至AMS的指令,再分发到指定的ActivityStack去执行
6、RecentTasks
其继承与ArrayList<TaskRecord>,在AMS构造器里面就被初始化,所以在AMS进程中也只有一个RecentTasks,像ActivityStackSupervisor等类里面引用的都是同一个对象。实际使用中我们就想到了adb shell dumpsys activity activities等命令,及Android系统的任务管理器,通过这些我们就可以看到最近的Task集合。
综上:我们可以看出,ActivityStackSupervisor/ActivityStack等相关类做的操作是,保存Activity的一系列的历史状态,或者说是Activity的收藏夹更合适一些,用以AMS在特定情况下的恢复之用。AM则是指运行时四大组件的运行情况的记录。
其它
代码中经常看到ServiceManager,也补充下上一篇讲的SystemServer:SystemServer添加服务,启动服务靠的是SystemServiceManager。平常我们查找系统服务也是借助ServiceManager,比如,上方ActivityManagerNative我们获取AM,就是通过ServiceManager:
IBinder b = ServiceManager.getService("activity");