前言
先来张Android 系统整体启动流程图

1. Activity 启动前提(文末附详情图)
进程检查
Activity 必须在AndroidManifest.xml中定义,并可以指定运行在不同的进程中,Activity 启动的前提是优先检查所属的进程,有无启动,没有启动的话,会先启动所属进程,之后才会启动Activity。
启动方式:显示启动与隐式启动
显示启动:即指定启动的Activity 对象。 要求必须为同进程对象(所属进程无法拿到别的进程Activity的字节码)
隐式启动:通过Intent Filter过滤器筛选,适合跨进程拉起。
实际操作
Activity的启动,是由所在应用进程端进程与系统SystemServer服务进程互相配合完成。
2. 主要API 介绍
-
Instrumentation
可通过AndroidManifest.xml 的<Instrumentation>描述该类的实现。
负责创建Activity的具体生命周期。 -
ActivityManager
该类提供与Activity、Service、Process交互的方法。可看作是ActivityManagerService的代理类 -
ActivityManagerService
Android中核心类之一,负责四大组件的启动,切换,调度及应用程序的管理及调度等。 -
ActivityThread
管理主线程,根据Activity管理者的请求调度和执行activities、Provider,Service,Process,broadcasts及其相关的操作。
其中H (Handler)变量,定义了大量的与Service,Provider等相关的消息类型。 -
ActivityStack
负责单个Activity栈的状态和管理。 -
ActivityStackSupervisor
负责所有Activity栈的管理。内部管理了mHomeStack、mFocusedStack和mLastFocusedStack三个Activity栈。其中,mHomeStack管理的是Launcher相关的Activity栈;mFocusedStack管理的是当前显示在前台Activity的Activity栈;mLastFocusedStack管理的是上一次显示在前台Activity的Activity栈。
android/app/Activity.java
1.启动 为简单起见,从 Activity 的startActivity() 方法 开始分析
@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);
}
}
最终回调用至startActivityForResult 方法
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) {
// 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;
}
cancelInputsAndStartExitTransition(options);
// TODO Consider clearing/flushing other event sources and events for child windows.
} else {
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 (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;
}
再看看方法注释
* @param requestCode If >= 0, this code will be returned in
* onActivityResult() when the activity exits.
说明如果requestCode 设置的是<0的值,是不会有onActivityResult返回的。
轮到Instrument 上场了,android/app/Instrumentation.java。
这个类是Activity 应用进程端的核心控制类。
@UnsupportedAppUsage
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
Uri referrer = target != null ? target.onProvideReferrer() : null;
if (referrer != null) {
intent.putExtra(Intent.EXTRA_REFERRER, referrer);
}
if (mActivityMonitors != null) {
synchronized (mSync) {
final int N = mActivityMonitors.size();
for (int i=0; i<N; i++) {
final ActivityMonitor am = mActivityMonitors.get(i);
ActivityResult result = null;
if (am.ignoreMatchingSpecificIntents()) {
result = am.onStartActivity(intent);
}
if (result != null) {
am.mHits++;
return result;
} else if (am.match(who, null, intent)) {
am.mHits++;
if (am.isBlocking()) {
return requestCode >= 0 ? am.getResult() : null;
}
break;
}
}
}
}
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
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;
}
看下这个函数的入参
* @param who The Context from which the activity is being started.
* @param contextThread The main thread of the Context from which the activity is being started.
* @param token Internal token identifying to the system who is starting
* the activity; may be null.
* @param target Which activity is performing the start (and thus receiving
* any result); may be null if this call is not being made
* from an activity.
* @param intent The actual Intent to start.
* @param requestCode Identifier for this request's result; less than zero
* if the caller is not expecting a result.
* @param options Addition options.
contextThread Binder对象,是主进程的context对象;
token Binder对象,指向了服务端;
这里的ActivityTaskManager.getService(),10.0 开始变成ActivityTaskManagerService,调用startActivity方法,辗转跳转至startActivityAsUser。
这里与Android 9.0 是不同的,9.0 是通过
ActivityManagerNative.getDefault().startActivity() 方式,Binder形式进行应用进程端与系统服务进程之间的交互。
这里小结下:
@Override
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) {
return mActivityTaskManager.startActivityAsUser(caller, callingPackage, intent,
resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo,
bOptions, userId);
}
ActivityTaskManagerService,会调用startActivityAsUser方法
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("startActivityAsUser");
userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
// 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.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.realCallingPid, mRequest.realCallingUid,
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,
mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
} else {
return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,
mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
mRequest.outActivity, mRequest.inTask, mRequest.reason,
mRequest.allowPendingRemoteAnimationRegistryLookup,
mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
}
} finally {
onExecutionComplete();
}
}
ActivityStarter.startActivityMayWait方法中调用多个startActivity方法后会调用到一个比较重要的方法startActivityUnchecked。会根据启动标志位和Activity启动模式来决定如何启动一个Activity以及是否要调用deliverNewIntent方法通知Activity有一个Intent试图重新启动它。
/**
* Decide whether the new activity should be inserted into an existing task. Returns null
* if not or an ActivityRecord with the task into which the new activity should be added.
*/
private ActivityRecord getReusableIntentActivity() {
Decide whether the new activity should be inserted into an existing task
根据启动模式,确定是否将Activity 加入一个已存在的task中。
最终调用方法
mRootActivityContainer.resumeFocusedStacksTopActivities(
mTargetStack, mStartActivity, mOptions);
这里与9.0 也是不同的。9.0 是直接通过ActivityStackSupervisor,10.0 是先通过RootActivityContainer。resumeFocusedStacksTopActivities 最终会调用ActivityStack的resumeTopActivityUncheckedLocked方法。
@GuardedBy("mService")
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
if (mInResumeTopActivity) {
// Don't even start recursing.
return false;
}
boolean result = false;
try {
// Protect against recursion.
mInResumeTopActivity = true;
result = resumeTopActivityInnerLocked(prev, options);
// When resuming the top activity, it may be necessary to pause the top activity (for
// example, returning to the lock screen. We suppress the normal pause logic in
// {@link #resumeTopActivityUncheckedLocked}, since the top activity is resumed at the
// end. We call the {@link ActivityStackSupervisor#checkReadyForSleepLocked} again here
// to ensure any necessary pause logic occurs. In the case where the Activity will be
// shown regardless of the lock screen, the call to
// {@link ActivityStackSupervisor#checkReadyForSleepLocked} is skipped.
final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
if (next == null || !next.canTurnScreenOn()) {
checkReadyForSleep();
}
} finally {
mInResumeTopActivity = false;
}
return result;
}
注意看这里面的注释。
在ActivityStack.resumeTopActivityInnerLocked方法中会去判断是否有Activity处于Resume状态,如果有的话会先让这个Activity执行Pausing过程,然后再执行startSpecificActivityLocked方法启动要启动Activity。
后续 先执行onpause方法退出。层层转发,实际调用的是PauseActivityItem.execute方法。
在PauseActivityItem.execute方法中调用ActivityThread.handlePauseActivity方法,经过一步步调用来到performPauseActivity方法,在这个方法中会先去判断是否需要调用callActivityOnSaveInstanceState方法来保存临时数据,然后执行Instrumentation.callActivityOnPause方法继续执行pasue流程。
@Override
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
client.handlePauseActivity(token, mFinished, mUserLeaving, mConfigChanges, pendingActions,
"PAUSE_ACTIVITY_ITEM");
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
Instrumentation.callActivityOnPause方法中直接调用Activity.performPause,至此栈顶Activity的Pausing流程全部完毕。
frameworks/base/core/java/android/app/Instrumentation.java
public void callActivityOnPause(Activity activity) {
activity.performPause();
}
frameworks/base/core/java/android/app/Activity.java
final void performPause() {
...
onPause();
...
}
至此,基本的链路已经建立。 真正调起Activity oncreate() 的流程类似
完全冷启动流程较为繁琐,将会新增专题记录。
Activity启动流程:
1、应用通过startActivity或是startActivityForResult方法向ActivityManagerService发出启动请求。
2、ActivityManagerService接收到启动请求后会进行必要的初始化以及状态的刷新,然后解析Activity的启动模式,为启动Activity做一系列的准备工作。
ActivityStarter 等所在包,com.android.server. ,为服务端进程,ActivityThread等所在包为android.app包下,为客户端进程。
3、做完上述准备工作后,会去判断栈顶是否为空,如果不为空即当前有Activity显示在前台,则会先进行栈顶Activity的onPause流程退出。
4、栈顶Activity执行完onPause流程退出后开始启动Activity。如果Activity被启动过则直接执行onRestart->onStart->onResume过程直接启动Activity(热启动过程)。否则执行Activity所在应用的冷启动过程。
5、冷启动过程首先会通过Zygote进程fork出一个新的进程,然后根据传递的”android.app.ActivityThread”字符串,反射出该对象并执行ActivityThread的main方法进行主线程的初始化。
6、Activity所在应用的进程和主线程完成初始化之后开始启动Activity,首先对Activity的ComponentName、ContextImpl、Activity以及Application对象进行了初始化并相互关联,然后设置Activity主题,最后执行onCreate->onStart->onResume方法完成Activity的启动。
7、上述流程都执行完毕后,会去执行栈顶Activity的onStop过程。
至此,完整的Activity启动流程全部执行完毕。
无图无真相,简单粗暴(非科学)的展示下。

来张终极版

补一张 桌面图标点击后的启动流程图

网友评论