文章参考:
《Android进阶解密》四大组件的工作过程。
前言:
Activity可以说是四大组件中最常见的的一个组件,我们平时打交道也是最多的。那么它到底是如何启动的呢?今天我们来一探究竟
anctivity的启动流程分析(基于Android8.0)
一般而言我们要启动一个activty,只需要调用Activity的startActivity方法即可。而activity最后会调用到它的startActivtyForResult方法。
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而设计,现在已经被Fragment代替。我们直接关注mParent即可。
这样activity的启动流转到Instrumentation的execStartActivity。
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;
}
在分析Activity的启动前我们先说一个比较熟悉的东西checkStartActivityResult。我们就不去看源代码了。这个函数主要对activity的启动返回值进行检查。在里面我们可以看到常见的Activity启动异常。感兴趣的朋友可以自己去查看源代码。
我们回到分析Activity的启动流程 ActivityManager.getService返回的是IActivityManager我们来看看具体的代码实现
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;
}
};
这里可以看到我们的老朋友:Binder,有不清楚Binder的朋友可以看看我以前的一篇学习笔记:Binder 学习笔记 了解基本的Binder通信过程。
这里获取的是ActivityManagerService在客户端的代理对象IActivityManager , IActivityManager通过Binder调用ActivityManagerService的相关方法。这也是为什么在使用Intent传递其它的对象的时候需要序列化的原因。这样Activity的启动流程转换到ActivityManagerService。在ActivityManagerService的startActivity会调用到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();
}
这里的obtainStarter方法返回的是一个ActivityStarter对象。ActivityStarter的setMayWait方法如下:
ActivityStarter setMayWait(int userId) {
mRequest.mayWait = true;
mRequest.userId = userId;
return this;
}
ActivityStarter的execute 的实现如下
int execute() {
try {
// TODO(b/64750076): Look into passing request directly to these methods to allow
// for transactional diffs and preprocessing.
if (mRequest.mayWait) {
return startActivityMayWait(mRequest.caller, mRequest.callingUid,
mRequest.callingPackage, mRequest.intent, mRequest.resolvedType,
mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
mRequest.inTask, mRequest.reason,
mRequest.allowPendingRemoteAnimationRegistryLookup);
} else {
//...
}
} finally {
onExecutionComplete();
}
}
根据前面的参数配置可以知道启动Activity调用到了startActivityMayWait方法。它的实现如下
private int startActivityMayWait(IApplicationThread caller, int callingUid,
String callingPackage, Intent intent, String resolvedType,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
IBinder resultTo, String resultWho, int requestCode, int startFlags,