一、ActivityManagerService提供的主要功能:
(1)统一调度各应用程序的Activity
(2)内存管理
(3)进程管理
二、启动一个Activity的方式有以下几种:
(1)在应用程序中调用startActivity启动指定的Activity
(2)在Home程序中单击一个应用图标,启动新的Activity
(3)按“Back”键,结束当前Activity,返回到上一个Activity
(4)长按“Home”键,显示出当前正在运行的程序列表,从中选择一个启动
这四种启动方式的主体处理流程都会按照第一种启动方式运行,后面三种方式只是在前端消息处理上各有不同。
三、进程数据类ProcessRecord
该类的源代码在~\frameworks\base\services\java\com\android\server\am路径下。
一般情况下,一个APK文件运行时会对应一个进程,ProcessRecord用来记录一个进程中的相关信息,主要包含的变量有:
(1)进程文件信息:与该进程对应的APK文件的内部信息,如
final ApplicationInfo info; // all about the first app in the process
final String processName; // name of the process
final ArrayMap pkgList
= new ArrayMap(); //保存进程中所有APK文件包名
(2)进程的内存状态信息:用于Linux系统的out of memory(OOM)情况的处理,当发生内存紧张时,Linux系统会根据进程的内存状态信息杀掉低优先级的进程,包括的变量有
int maxAdj; // Maximum OOM adjustment for this process
int curRawAdj; // Current OOM unlimited adjustment for this process
int setRawAdj; // Last set OOM unlimited adjustment for this process
int curAdj; // Current OOM adjustment for this process
int setAdj; // Last set OOM adjustment for this process
变量中Adj的含义是调整值(adjustment)
(3)进程中包含的Activity、Provider、Service等,如下
final ArrayList activities = new ArrayList();
final ArraySet services = new ArraySet();
final ArraySet executingServices = new ArraySet();
final ArraySet connections = new ArraySet();
final ArraySet receivers = new ArraySet();
final ArrayMap
pubProviders = new ArrayMap
ContentProviderRecord>();
final ArrayList conProviders = new ArrayList();
四、ActivityRecord数据类(Android 2.3以前版本叫HistoryRecord类)
ActivityManagerService使用ActivityRecord数据类来保存每个Activity的信息,ActivityRecord类基于IApplicationToken.Stub类,也是一个Binder,所以可以被IPC调用。
主要包含的变量有:
(1)环境信息:Activity的工作环境,比如进程名称、文件路径、数据路径、图标、主题等,这些信息一般是固定的,比如以下变量
final String packageName; // the package implementing intent's component
final String processName; // process where this component wants to run
final String baseDir; // where activity source (resources etc) located
final String resDir; // where public activity source (public resources etc) located
final String dataDir; // where activity data should go
int theme; // resource identifier of activity's theme.
int realTheme; // actual theme resource we will use, never 0.
(2)运行状态数据信息:如idle、stop、finishing等,一般为boolean类型,如下
boolean haveState; // have we gotten the last activity state?
boolean stopped; // is activity pause finished?
boolean delayedResume; // not yet resumed because of stopped app switches?
boolean finishing; // activity in pending finish list?
boolean configDestroy; // need to destroy due to config change?
五、TaskRecord类
ActivityManagerService中使用任务的概念来确保Activity启动和退出的顺序。
TaskRecord中的几个重要变量如下:
final int taskId; // 每个任务的标识.
Intent intent; // 创建该任务时对应的intent
int numActivities; //该任务中的Activity数目
final ArrayList mActivities = new ArrayList(); //按照出现的先后顺序列出该任务中的所有Activity
六、ActivityManagerService中一些重要的与调度相关的变量
(1)记录最近启动的Activity,如果RAM容量较小,则记录的最大值为10个,否则为20个,超过该值后,Ams会舍弃最早记录的Activity
static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20;
(2)当Ams通知应用程序启动(Launch)某个Activity时,如果超过10s,Ams就会放弃
static final int PROC_START_TIMEOUT = 10*1000;
(3)当Ams启动某个客户进程后,客户进程必须在10s之内报告Ams自己已经启动,否则Ams会认为指定的客户进程不存在
static final int PROC_START_TIMEOUT = 10*1000;
(4)等待序列:
当Ams内部还没有准备好时,如果客户进程请求启动某个Activity,那么会被暂时保存到该变量中,
final ArrayList mPendingActivityLaunches
= new ArrayList();
(5)优先启动,其次再停止。进程A1包含两个Activity,启动顺序为A1->A2,当用户请求启动A2时,如果A1正在运行,Ams会先暂停A1,然后启动A2,当A2启动后再停止A1。
private final ArrayList mRecentTasks = new ArrayList();
七、startActivity()的流程
当用户单击某个应用图标后,执行程序会在该图标的onClick()事件中调用startActivity()方法,该方法会调用
startActivityForResult(),在这个方法内部会调用Instrumentation对象的
executeStartActivity()方法,每个Activity内部都有一个Instrumentation对象的引用,它就是一个管
家,ActivityThread要创建或者暂停某个Activity都是通过它实现的。
流程图如下所示:
下面附上ActivityManagerService的完整源代码,有兴趣的童鞋可以深入研究。