问题:Activity的启动过程是怎样的?
关键词:activity,启动过程
分析角度:源码
首先启动一个Activity是通过Intent跳转,调用startActivity()来启动。
下面看startActivity的源码:
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);
}
}
可以看到startActivity最终还是调用了startActivityForResult方法;
startActivityForResult的源码:
public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
if (mParent == null) {
//当前Activity没有父类
//Instrumentation 启动Activity
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) {
// If this start is requesting a result, we can avoid making
// the activity visible until the result is received. Setting
// this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
// activity hidden during this time, to avoid flickering.
// This can only be done when a result is requested because
// that guarantees we will get information back when the
// activity is finished, no matter what happens to it.
mStartedActivity = true;
}
final View decor = mWindow != null ? mWindow.peekDecorView() : null;
if (decor != null) {
decor.cancelPendingInputEvents();
}
// TODO Consider clearing/flushing other event sources and events for child windows.
} else {
//当前Activity有父类,options是Bundle类型
if (options != null) {
mParent.startActivityFromChild(this, intent, requestCode, options);
} else {
// Note we want to go through this method for compatibility with
// existing applications that may have overridden it.
mParent.startActivityFromChild(this, intent, requestCode);
}
}
if (options != null && !isTopOfTask()) {
mActivityTransitionState.startExitOutTransition(this, options);
}
}
这里只关心mParent==null 的条件
启动的时候调用了mInstrumentation.execStartActivity()方法;
看看这个源码:
Instrumentation.Java
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
if (mActivityMonitors != null) {
synchronized (mSync) {
final int N = mActivityMonitors.size();
for (int i=0; i<N; i++) {
final ActivityMonitor am = mActivityMonitors.get(i);
if (am.match(who, null, intent)) {
am.mHits++;
if (am.isBlocking()) {
return requestCode >= 0 ? am.getResult() : null;
}
break;
}
}
}
}
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess();
int result = ActivityManagerNative.getDefault()
.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) {
}
return null;
}
最后调用了这个方法去startActivity:
int result = ActivityManagerNative.getDefault()
.startActivity
并且返回对返回结果check:
checkStartActivityResult(result, intent);
checkStartActivityResult(result, intent);这个方法中做了一些拦截异常并抛出的处理:
public static void checkStartActivityResult(int res, Object intent) {
if (res >= ActivityManager.START_SUCCESS) {
return;
}
switch (res) {
case ActivityManager.START_INTENT_NOT_RESOLVED:
case ActivityManager.START_CLASS_NOT_FOUND:
if (intent instanceof Intent && ((Intent)intent).getComponent() != null)
throw new ActivityNotFoundException(
"Unable to find explicit activity class "
+ ((Intent)intent).getComponent().toShortString()
+ "; have you declared this activity in your AndroidManifest.xml?");
throw new ActivityNotFoundException(
"No Activity found to handle " + intent);
case ActivityManager.START_PERMISSION_DENIED:
throw new SecurityException("Not allowed to start activity "
+ intent);
case ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT:
throw new AndroidRuntimeException(
"FORWARD_RESULT_FLAG used while also requesting a result");
case ActivityManager.START_NOT_ACTIVITY:
throw new IllegalArgumentException(
"PendingIntent is not an activity");
case ActivityManager.START_NOT_VOICE_COMPATIBLE:
throw new SecurityException(
"Starting under voice control not allowed for: " + intent);
default:
throw new AndroidRuntimeException("Unknown error code "
+ res + " when starting " + intent);
}
}
重要的是这一步:int result = ActivityManagerNative.getDefault().startActivity
ActivityMaagerNative.getDefault返回结果是 IActivityManager这个接口。
首先找到这个接口的实现类并找到startActivity方法:ActivityManagerNative
![](https://img.haomeiwen.com/i4322600/09e80e700ac48ef6.png)
这个方法中最终调用了mRemote.transact来执行事务。那么mRemote是什么?
![](https://img.haomeiwen.com/i4322600/514a0b4501dddd36.png)
一个IBinder,所以实际上Activity的启动也是通过跨进程通信的方式实现的。
之前调用了ActivityManagerNative.getDefault(),实际上getDefault最终是一个单例实现的,最终返回IActivityManager.
![](https://img.haomeiwen.com/i4322600/689107811f68a8a2.png)
网友评论