6.3 startActivity分析
本节将重点分析Activity的启动过程,它是五条线中最难分析的一条,只要用心,相信读者能啃动这块“硬骨头”。
6.3.1 从am说起
am和pm(见4.4.2节)一样,也是一个脚本,它用来和AMS交互,如启动Activity、启动Service、发送广播等。其核心文件在Am.java中,代码如下:
[—>Am.java:main]
public static void main(String[]args){
try{
(new Am()).run(args);//构造一个am对象,并调用run函数
}……
}
am的用法很多,读者可通过adb shell登录手机,然后执行am,这样就能获取它的用法。
利用am启动一个activity的方法如下:
am start[-D][-W][-P<FILE>][—start-profiler<FILE>][-S]<INTENT>
其中:
方括号中的参数为可选项,尖括号中的参数为必选项。
<INTENT>参数有很多,主要是用于设置Intent的各项参数。
假设已知某个Activity的ComponentName(package名和Activity的Class名),启动这个Activity的相应命令如下:
am start-W-n com.dfp.test/.TestActivity
其中,-W选项表示am将会等目标Activity启动后才返回,-n表示后面的参数用于设置Intent的Component。就本例而言,com.dfp.test为Package名,.TestActivity为该Package下对应的Activity类名,所以将要启动的Activity的全路径名为com.dfp.test.TestActivity。
现在就以上面的命令为例来分析am的run函数,代码如下:
[—>Am.java:run]
private void run(String[]args)throws Exception{
mAm=ActivityManagerNative.getDefault();
mArgs=args;
String op=args[0];mNextArg=1;
if(op.equals("start"))runStart();//用于启动Activity
else if……//处理其他参数
}
runStart函数用于处理Activity启动请求,其代码如下:
[—>Am.java:runStart]
private void runStart()throws Exception{
Intent intent=makeIntent();
String mimeType=intent.getType();
//获取mimeType,
if(mimeType==null&&intent.getData()!=null
&&"content".equals(intent.getData().getScheme())){
mimeType=mAm.getProviderMimeType(intent.getData());
}
if(mStopOption){
……//处理-S选项,即先停止对应的Activity,再启动它
}
//FLAG_ACTIVITY_NEW_TASK这个标签很重要
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
ParcelFileDescriptor fd=null;
if(mProfileFile!=null){
try{……//处理-P选项,用于性能统计
fd=ParcelFileDescriptor.open(……)
}……
}
IActivityManager.WaitResult result=null;
int res;
if(mWaitOption){//mWaitOption控制是否等待启动结果,如果有-W选项,则该值为true
//调用AMS的startActivityAndWait函数
result=mAm.startActivityAndWait(null, intent, mimeType,
null,0,null, null,0,false, mDebugOption,
mProfileFile, fd, mProfileAutoStop);
res=result.result;
}……
……//打印结果
}
am最终将调用AMS的startActivityAndWait函数来处理这次启动请求。下面将深入到AMS内部去继续这次旅程。
提示 为什么选择从am来分析Activity的启动呢?这是因为如果选择从一个Activity来分析如何启动另一个Activity,则将给人一种鸡生蛋、蛋孵鸡的感觉,故此处选择从am入手。除此之外,从am来分析Activity的启动也是Activity启动分析中相对简单的一条路线。