#从Activity开始(一)——启动流程
本文也发布于本人的知乎文章:https://zhuanlan.zhihu.com/p/393848606
(注:源代码为android-8.1)
##启动流程
通过我们常用的方法调用开始逐步向下探索。
通常来说,我们使用的最简单的启动Activity方法是startActivity(Intent intent)
,该方法的实现源码为:
(frameworks/base/core/java/android/app/Activity.java)
@Override
public void startActivity(Intent intent) {
this.startActivity(intent, null);
}
这里调用了同名重载函数startActivity(Intent intent, @Nullable Bundle options)
,该方法的源码实现为:
(frameworks/base/core/java/android/app/Activity.java)
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
// Note we want to go through this call for compatibility with
// applications that may have overridden the method.
startActivityForResult(intent, -1);
}
}
从这里我们发现,即使是普通的启动Activity方法,也是调用了startActivityForResult(Intent intent, int requestCode, Bundle options)
方法。其中requestCode < 0
时,不会调用onActivityResult()
方法。
该方法源码实现如下:
(frameworks/base/core/java/android/app/Activity.java)
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);
if (ar != null) {
mMainThread.sendActivityResult(mToken, mEmbeddedID, requestCode, ar.getResultCode(), ar.getResultData());
}
if (requestCode >= 0) {
mStartedActivity = true;
}
cancelInputsAndStartExitTransition(options);
} else {
if (options != null) {
mParent.startActivityFromChild(this, intent, requestCode, options);
} else {
mParent.startActivityFromChild(this, intent, requestCode);
}
}
}
在这个方法中会通过判断mParent
是否为空分为两支。该变量只有在Acitivity为内置Activity的时候才不为空,例如TabActivity
。在该方法中,关键的操作为mInstrumentation.execStartActivity
。可以看出,启动Activity
其实是通过Instrumentation
类执行的。
下面我们看一下execStartActivity方法的实现:
(frameworks/base/core/java/android/app/Instrumentation.java)
public ActivityResult execStartActivity(Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options) {
...
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
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()
方法。
(frameworks/base/core/java/android/app/ActivityManager.java)
public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}
private static final Singleton<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>() {
@Override
protected IActivityManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};
这里的意思就是获取了IActivityManager
类的一个单例。在创建IActivityManager
单例时,首先获取了名为Context.ACTIVITY_SERVICE
的Service
引用,然后通过asInstance
方法转换成IActivityManager
的对象。
ActivityManagerService
继承了IActivityManager.Stub
,说明了是ActivityManagerService
作为服务端,处理startActivity
方法。
(frameworks/base/core/java/android/server/am/ActivityManagerService.java)
@Override
public final int startActivity(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWh