根 Activity 启动过程
根 Activity 的启动过程一般也可以理解为应用程序的启动过程。
根 Activity 的启动过程比较复杂,可以分为三个部分:
- Launcher 请求 AMS 过程
- AMS 到 ApplicationThread 的调用过程
- ActivityThread 启动 Activity
Launcher 请求 AMS 过程
整个流程图为:
![](https://img.haomeiwen.com/i8945592/1675f96db3dfe5ff.png)
Launcher 其实也是一个 Activity,( Launcher extend BaseActivity )。
Launcher 启动后会将已安装的应用程序的快捷图标显示在桌面上,这些图标就是启动根 Activity 的入口,当我们点击图标时,就会通过 Launcher 请求 AMS 来启动应用程序。
当我们点击应用程序的快捷图标时,就会调用 Launcher 的 startActivitySafely 方法:
public boolean startActivitySafely(View v, Intent intent, ItemInfo item) {
//...
// Prepare intent
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); //新的任务栈
if (v != null) {
intent.setSourceBounds(getViewBounds(v));
}
try {
//...
startActivity(intent, optsBundle); //启动根 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 其实也是一个 Activity,而这个 startActivity 在 Activity 中的实现是:
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
startActivityForResult(intent, -1);
}
}
然后就传到了 startActivityForResult 方法,它的第二个参数为 -1,表示 Launcher 不需要知道 Activity 启动的结果。
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 类型的,表示当前 Activity 的父类,因为此时启动的是根 Activity,所以 mParent == null 成立,接着就到 Instrumentation 的 execStartActivity 方法,Instrumentation 主要用来监控应用程序和系统的交互。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;
}
首先通过 ActivityManager#getService 方法来获取 AMS 代理对象,接着调用它的 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);
//再转换成 IActivityManager 类型,采用的是 ALDL
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};
AMS 到 ApplicationThread 的调用过程
第一步已经把 startActivity 的请求转给了 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());
}
直接返回调用了 startActivityAsUser 方法,该方法比 startActivity 多最后一个参数 UserHandle.getCallingUserId ,这个方法会获得调用者的 UserId,AMS 根据这个 UserId 来确定调用者的权限。
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) {
//判断调用者进程是否被隔离
enforceNotIsolatedCaller("startActivity");
//检查调用者权限
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();
}
看名字能猜到它是启动 Activity 的控制类,ActivityStartController#obtainStarter:
ActivityStarter obtainStarter(Intent intent, String reason) {
return mFactory.obtain().setIntent(intent).setReason(reason);
}
网友评论