一、梳理源码流程干什么
Activity是四大组件中最重要的组件之一,下面来分析Activity的启动过程,了解Activity的启动过程能帮助我们更好的对组件Activity的理解,也能帮助我们更好的把控Activity生命周期的变化过程。
当然Activity作为四大组件之首,10.0版本的Activity的代码函数在8000行,关联的一些类Instrumentation、ActivityTaskManager、ActivityStarter等等,怎么也是几万行的代码,一次完全分析起来会很困难,这里面主要通过启动的核心流程源码分析,帮我们理清楚Activity的启动流程,内部其实有很多细节,这些细节和我们的日常开发也都非常相关,关于这部分细节性的代码,由于篇幅问题,本文并不会全部体现。
先上Activity启动流程梳理图:
上图非完整的启动流程,在后续源码分析中,还有第二条分支,就是当application未创建的情况下,会去创建进程,fork应用进程等,后文的源码分析中会简单提到,详细流程也适合做专题分析。
通过这样的一个梳理图,主要是清晰系统进程和应用进程中的代码调用流程,建议先初步看一下梳理图,在看后面的源码分析过程中不断的回到图中来,加深自己的理解和印象,在文章末尾,源码分析之后,也会对梳理图中的核心类进行说明。
二、源码流程分析
下面主要从源码角度来进行分析,分析的入口就是startActivity(),分析源码中的Activity.java中的startActivity()方法
2.1 应用进程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(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
if (mParent == null) {
//标注1
options = transferSpringboardActivityOptions(options);
//标注2
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);
// TODO Consider clearing/flushing other event sources and events for child windows.
} else {
//标注3
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);
}
}
}
在startActivityForResult方法体中,先看到了标注1的位置是一个条件判断mParent==null。mParent代表的是ActivityGroup,Api13已经被废弃,这里面其实我们标注3的内容就不用太多去关注了,当然从方法名上mParent.startActivityFromChild也能看出来,的确是子Activity来启动Activity。我们把关注点仍然回到标注2的位置
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
mInstumentation好像很面熟,当然这个类比我们想象的要强大的多,Instrumentation为仪表盘,管理着Activity和Application的生命周期,一个进程对应了一个Instrumentation。
在后续的分析过程中,我们会看到Instrumentation在整个Activity启动过程中的强大作用,接下来我们继续分析execStartActivity的核心流程
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
省去非核心流程代码...
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
//这块的代码和8.0的是有区别,这块也是我们启动流程里面的核心代码
//8.0里面的源码:ActivityManagerNative.getDefault()
int result = ActivityTaskManager.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;
}
上述标注1的位置,可以看到启动activity的真正实现交给了ActivityTaskManager.getService()的startActivity的方法了。
public static IActivityTaskManager getService() {
return IActivityTaskManagerSingleton.get();
}
private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
new Singleton<IActivityTaskManager>() {
@Override
protected IActivityTaskManager create() {
//获得Binder对象实例
final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);
return IActivityTaskManager.Stub.asInterface(b);
}
};
从这里可以推测,此处把application启动的过程要转交给通过ActivityTaskManager获得IActivityTaskManagerSingleton的单例对象去处理,上述备注部分,可以看出返回的是一个Aidl的接口实例。
我们也查看IActivityTaskManager的实现类,通过源码我们找到了ActivityTaskManagerService继承了IActivityTaskManager。
public class ActivityTaskManagerService extends IActivityTaskManager.Stub{
...省去...}
从这里,也可以印证:同一个应用A activity启动一个B activity 本质上也是一个跨进程调用的过程。
为什么这里面需要用AMS的Binder对象呢?
看到Binder,有些android知识储备的应该能想到这是跨进程通信,那么到底哪两个进程进行了跨进程的通信?这里面需要了解到ActivityManagerService实际上是在android系统启动的时候,这个服务就被开启了,这个服务被运行在系统进程中,即ActivityMangerService是运行在android system进程中的,并且系统一启动,这个service就会被启动。这里面显然是我们自己的app进程和system进程之间进行了ipc调用。
2.2进入到ATMS进程startActivity
ATMS,即ActivityTaskServiceManager,运行在系统服务进程中,继续看ActivityTaskManagerService中的源码:
@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()。startActvityAsUser()的实现:
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) {
...
// TODO: Switch to user app stacks here.
return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
.setCaller(caller)
.setCallingPackage(callingPackage)
.setResolvedType(resolvedType)
.setResultTo(resultTo)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setStartFlags(startFlags)
.setProfilerInfo(profilerInfo)
.setActivityOptions(bOptions)
.setMayWait(userId)
.execute();//实际调用的是ActivityStarter的excute的方法
}
execute的方法实际ActivityStarter类在执行,之后再调用到startActivityUnchecked(),再调用到RootActivityContainer类中resumeFocusedStacksTopActivities(),最终会调用到ActivityStack的resumeTopActivityUncheckdeLocked(),RootActivityContainer类中的代码调用如下
if (!resumedOnDisplay) {
// 查找符合条件的任务栈
final ActivityStack focusedStack = display.getFocusedStack();
if (focusedStack != null) {
focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
}
ActivityStack中的resumeTopActivityUncheckedLocked()的源码:
/**
* 确定栈顶Activity是否是resumed
*/
@GuardedBy("mService")
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
if (mInResumeTopActivity) {
// Don't even start recursing.
return false;
}
boolean result = false;
try {
mInResumeTopActivity = true;
//核心代码:
result = resumeTopActivityInnerLocked(prev, options);
// 栈顶有resuming的activity,有必要进行pause
final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
if (next == null ||