基于android10.0源码分析Activity的启动流程
Posted hymKing
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于android10.0源码分析Activity的启动流程相关的知识,希望对你有一定的参考价值。
一、梳理源码流程干什么
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 || !next.canTurnScreenOn()) {
checkReadyForSleep();
}
} finally {
mInResumeTopActivity = false;
}
return result;
}
可以看到在ActivityStack的resumeTopActivityUncheckeLocked方法中个,继续调用了resumeTopActivityInnerLocked();在此方法中,针对于activity启动流程环节,要使得栈中的resume的Activity进行暂停:
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
.....
if (mResumedActivity != null) {
if (DEBUG_STATES) Slog.d(TAG_STATES,
"resumeTopActivityLocked: Pausing " + mResumedActivity);
pausing |= startPausingLocked(userLeaving, false, next, false);
}
....
}
关于pause栈顶Activity的内部流程,这块不做详细分析(在源码分析Activity生命周期专题中再做分析)。我们要继续回调启动Activity的核心流程里面来,在上述方法中,通过一系列的处理,最终会调用到启动Activity的方法里面来:
if (next.attachedToProcess()) {
...
mService.getLifecycleManager().scheduleTransaction(transaction);
....
}else{
// Whoops, need to restart this activity!
if (!next.hasBeenLaunched) {
next.hasBeenLaunched = true;
} else {
if (SHOW_APP_STARTING_PREVIEW) {
next.showStartingWindow(null /* prev */, false /* newTask */,
false /* taskSwich */);
}
if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next);
}
if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next);
mStackSupervisor.startSpecificActivityLocked(next, true, true);
}
如上代码片段,一堆处理后,同样在resumeTopActivityInnerLocked方法中,会调用mStackSupervisor.startSpecificActivityLocked()。此方法的源码:
void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
// 判断当前要启动的Activity的application是否已经存在
final WindowProcessController wpc =
mService.getProcessController(r.processName, r.info.applicationInfo.uid);
boolean knownToBeDead = false;
// 如果已经存在,主线程也正常
if (wpc != null && wpc.hasThread()) {
try {
//调用真实启动Activity的方法
realStartActivityLocked(r, wpc, andResume, checkConfig);
//return 后续的逻辑都不会走
return;
} catch (RemoteException e) {
... //出现异常
}
//出现异常重启application(现在好多手机,应用奔溃后,都能自启,待验证)
knownToBeDead = true;
}
if (getKeyguardController().isKeyguardLocked()) {
r.notifyUnknownVisibilityLaunched();
}
try {
...
// 走到这里,说明进程未创建,意义启动进程的消息
final Message msg = PooledLambda.obtainMessage(
ActivityManagerInternal::startProcess, mService.mAmInternal,r.processName,r.info.applicationInfo, knownToBeDead, "activity",r.intent.getComponent());
//通过ActivityTaskManagerService中的Handler发送消息,创建一个新的进程
mService.mH.sendMessage(msg);
} finally {
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
}
在这个流程中,实际存在两个分支逻辑,一条分支是在当前的application中去启动Activity,另一个分支先创建当前要启动的Activity所需要的进程。先看mStackSupervisor.realStartActivityLocked():
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
boolean andResume, boolean checkConfig) throws RemoteException {
...
try {
if (!proc.hasThread()) {
//远程调用异常
throw new RemoteException();
}
......
// 创建Activity启动事务.proc.getThread()是applicationThread
final ClientTransaction clientTransaction = ClientTransaction.obtain(
proc.getThread(), r.appToken);
final DisplayContent dc = r.getDisplay().mDisplayContent;
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
System.identityHashCode(r), r.info,
// TODO: Have this take the merged configuration instead of separate global
// and override configs.
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
r.icicle, r.persistentState, results, newIntents,
dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
r.assistToken));
// 设置预期的最终状态
final ActivityLifecycleItem lifecycleItem;
if (andResume) {
lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
} else {
lifecycleItem = PauseActivityItem.obtain();
}
clientTransaction.setLifecycleStateRequest(lifecycleItem);
// 启动事务
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
} catch (RemoteException e) {
//远程调用异常
}
ClientTransaction是啥呢,简单看一下这个例的文档注释:
/**
* 持有一系列消息,用于和client交互(app进程)
* This includes a list of callbacks and a final lifecycle state.
*/
public class ClientTransaction implements Parcelable, ObjectPoolItem {}
回到realStartActivityLocked()方法的源码中来,也特地贴出了catch的异常,很显然这部分代码的执行,仍然是在系统进程中执行。上述代码中添加了核心代码的中文注释,可以看到这段代码中,主要是创建事务,同时传入ApplicationThread,而ApplicationThread继承于Binder,传入的目的就是后面要和目标App进程进行通信。mService.getLifecycleManager().scheduleTransaction(clientTransaction);这句代码,是计划启动事务。继续看这部分的源码:
/**
* 计划一个事务,包含多个callbacks和lifecycle request
*/
void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
final IApplicationThread client = transaction.getClient();
//核心代码
transaction.schedule();
if (!(client instanceof Binder)) {
transaction.recycle();
}
}
接下来就是ClientTransaction:
public void schedule() throws RemoteException {
mClient.scheduleTransaction(this);
}
实际调用额是mClient.scheduleTransaction(),mClient这个全局变量是什么呢?
在上述代码片段中有创建ClientTransaction的方法调用:
final ClientTransaction clientTransaction = ClientTransaction.obtain(
proc.getThread(), r.appToken);
追一下这个obtain方法的源码:
/** Obtain an instance initialized with provided params. */
public static ClientTransaction obtain(IApplicationThread client, IBinder activityToken) {
ClientTransaction instance = ObjectPool.obtain(ClientTransaction.class);
if (instance == null) {
instance = new ClientTransaction(以上是关于基于android10.0源码分析Activity的启动流程的主要内容,如果未能解决你的问题,请参考以下文章
基于android10.0源码分析Activity的启动流程
Android的PackageManagerService10.0源码解读(AndroidManifest.xml解析)
Android的PackageManagerService10.0源码解读(AndroidManifest.xml解析)
Android的PackageManagerService10.0源码解读(AndroidManifest.xml解析)
Android的PackageManagerService10.0源码解读(AndroidManifest.xml解析)