根 Activity 啟動(dòng)過(guò)程
根 Activity 的啟動(dòng)過(guò)程一般也可以理解為應(yīng)用程序的啟動(dòng)過(guò)程正塌。
根 Activity 的啟動(dòng)過(guò)程比較復(fù)雜,可以分為三個(gè)部分:
- Launcher 請(qǐng)求 AMS 過(guò)程
- AMS 到 ApplicationThread 的調(diào)用過(guò)程
- ActivityThread 啟動(dòng) Activity
Launcher 請(qǐng)求 AMS 過(guò)程
整個(gè)流程圖為:
Launcher 其實(shí)也是一個(gè) Activity惰蜜,( Launcher extend BaseActivity )。
Launcher 啟動(dòng)后會(huì)將已安裝的應(yīng)用程序的快捷圖標(biāo)顯示在桌面上,這些圖標(biāo)就是啟動(dòng)根 Activity 的入口蝴韭,當(dāng)我們點(diǎn)擊圖標(biāo)時(shí),就會(huì)通過(guò) Launcher 請(qǐng)求 AMS 來(lái)啟動(dòng)應(yīng)用程序熙侍。
當(dāng)我們點(diǎn)擊應(yīng)用程序的快捷圖標(biāo)時(shí)榄鉴,就會(huì)調(diào)用 Launcher 的 startActivitySafely 方法:
public boolean startActivitySafely(View v, Intent intent, ItemInfo item) {
//...
// Prepare intent
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); //新的任務(wù)棧
if (v != null) {
intent.setSourceBounds(getViewBounds(v));
}
try {
//...
startActivity(intent, optsBundle); //啟動(dòng)根 Activity
return true;
} catch (ActivityNotFoundException|SecurityException e) {
Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
Log.e(TAG, "Unable to launch. tag=" + item + " intent=" + intent, e);
}
return false;
}
上面提到 Launcher 其實(shí)也是一個(gè) Activity,而這個(gè) startActivity 在 Activity 中的實(shí)現(xiàn)是:
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
startActivityForResult(intent, -1);
}
}
然后就傳到了 startActivityForResult 方法蛉抓,它的第二個(gè)參數(shù)為 -1庆尘,表示 Launcher 不需要知道 Activity 啟動(dòng)的結(jié)果。
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
if (mParent == null) {
options = transferSpringboardActivityOptions(options);
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
//...
} else {
//...
}
}
mParent 是 Activity 類型的巷送,表示當(dāng)前 Activity 的父類驶忌,因?yàn)榇藭r(shí)啟動(dòng)的是根 Activity,所以 mParent == null 成立笑跛,接著就到 Instrumentation 的 execStartActivity 方法位岔,Instrumentation 主要用來(lái)監(jiān)控應(yīng)用程序和系統(tǒng)的交互。Instrumentation#execStartActivity 方法如下:
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
//...
try {
//...
int result = ActivityManager.getService()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
首先通過(guò) ActivityManager#getService 方法來(lái)獲取 AMS 代理對(duì)象堡牡,接著調(diào)用它的 startActivity 方法抒抬。
public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}
private static final Singleton<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>() {
@Override
protected IActivityManager create() {
//獲取 IBinder 類型的 AMS 引用
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
//再轉(zhuǎn)換成 IActivityManager 類型,采用的是 ALDL
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};
AMS 到 ApplicationThread 的調(diào)用過(guò)程
第一步已經(jīng)把 startActivity 的請(qǐng)求轉(zhuǎn)給了 AMS 的 startActivity晤柄,該方法源碼為:
@Override
public final int startActivity(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
resultWho, requestCode, startFlags, profilerInfo, bOptions,
UserHandle.getCallingUserId());
}
直接返回調(diào)用了 startActivityAsUser 方法擦剑,該方法比 startActivity 多最后一個(gè)參數(shù) UserHandle.getCallingUserId ,這個(gè)方法會(huì)獲得調(diào)用者的 UserId芥颈,AMS 根據(jù)這個(gè) UserId 來(lái)確定調(diào)用者的權(quán)限惠勒。
AMS#startActivityAsUser:
public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
boolean validateIncomingUser) {
//判斷調(diào)用者進(jìn)程是否被隔離
enforceNotIsolatedCaller("startActivity");
//檢查調(diào)用者權(quán)限
userId = mActivityStartController.checkTargetUser(userId, validateIncomingUser,
Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
// TODO: Switch to user app stacks here.
return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
.setCaller(caller)
.setCallingPackage(callingPackage)
.setResolvedType(resolvedType)
.setResultTo(resultTo)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setStartFlags(startFlags)
.setProfilerInfo(profilerInfo)
.setActivityOptions(bOptions)
.setMayWait(userId)
.execute();
}
看名字能猜到它是啟動(dòng) Activity 的控制類,ActivityStartController#obtainStarter:
ActivityStarter obtainStarter(Intent intent, String reason) {
return mFactory.obtain().setIntent(intent).setReason(reason);
}