从Activity开始(一)——启动流程
(注:源代码为android-8.1)
启动流程
通过我们常用的方法调用开始逐步向下探索。
通常来说,我们使用的最简单的启动Activity方法是startActivity(Intent intent)
,该方法的实现源码为:
(frameworks/base/core/java/android/app/Activity.java)
@Override
public void startActivity(Intent intent) {
this.startActivity(intent, null);
}
这里调用了同名重载函数startActivity(Intent intent, @Nullable Bundle options)
,该方法的源码实现为:
(frameworks/base/core/java/android/app/Activity.java)
@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);
}
}
从这里我们发现,即使是普通的启动Activity方法,也是调用了startActivityForResult(Intent intent, int requestCode, Bundle options)
方法。其中requestCode < 0
时,不会调用onActivityResult()
方法。
该方法源码实现如下:
(frameworks/base/core/java/android/app/Activity.java)
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) {
mStartedActivity = true;
}
cancelInputsAndStartExitTransition(options);
} else {
if (options != null) {
mParent.startActivityFromChild(this, intent, requestCode, options);
} else {
mParent.startActivityFromChild(this, intent, requestCode);
}
}
}
在这个方法中会通过判断mParent
是否为空分为两支。该变量只有在Acitivity为内置Activity的时候才不为空,例如
。在该方法中,关键的操作为
TabActivitymInstrumentation.execStartActivity
。可以看出,启动Activity
其实是通过Instrumentation
类执行的。
下面我们看一下execStartActivity方法的实现:
(frameworks/base/core/java/android/app/Instrumentation.java)
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;
}
这里我们先追踪一下ActivityManager.getService()
方法。
(frameworks/base/core/java/android/app/ActivityManager.java)
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;
}
};
这里的意思就是获取了IActivityManager
类的一个单例。在创建IActivityManager
单例时,首先获取了名为Context.ACTIVITY_SERVICE
的Service
引用,然后通过asInstance
方法转换成IActivityManager
的对象。
ActivityManagerService
继承了IActivityManager.Stub
,说明了是ActivityManagerService
作为服务端,处理startActivity
方法。
(frameworks/base/core/java/android/server/am/ActivityManagerService.java)
@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
方法。继续向下分析。
(frameworks/base/core/java/android/server/am/ActivityManagerService.java)
@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) {
enforceNotIsolatedCaller("startActivity");
userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
userId, false, ALLOW_FULL_ONLY, "startActivity", null);
// TODO: Switch to user app stacks here.
return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
profilerInfo, null, null, bOptions, false, userId, null, "startActivityAsUser");
}
这里也只是多添加了一些userId
的安全性判断。之后继续调用了mActivityStarter.startActivityMayWait
方法。
(frameworks/base/core/java/android/server/am/ActivityStarter.java)
final int startActivityMayWait(IApplicationThread caller, int callingUid,
String callingPackage, Intent intent, String resolvedType,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
IBinder resultTo, String resultWho, int requestCode, int startFlags,
ProfilerInfo profilerInfo, WaitResult outResult,
Configuration globalConfig, Bundle bOptions, boolean ignoreTargetSecurity, int userId,
TaskRecord inTask, String reason) {
...
synchronized (mService) {
...
int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
aInfo, rInfo, voiceSession, voiceInteractor,
resultTo, resultWho, requestCode, callingPid,
callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
options, ignoreTargetSecurity, componentSpecified, outRecord, inTask,
reason);
...
return res;
}
...
}
ActivityStarter
类是启动Activity
的控制器,它集中了所有确定如何将intent
和falgs
转化为Activity
的逻辑。继续跟踪调用方法startActivityLocked
。
(frameworks/base/core/java/android/server/am/ActivityStarter.java)
int startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
ActivityRecord[] outActivity, TaskRecord inTask, String reason) {
if (TextUtils.isEmpty(reason)) {
throw new IllegalArgumentException("Need to specify a reason.");
}
mLastStartReason = reason;
mLastStartActivityTimeMs = System.currentTimeMillis();
mLastStartActivityRecord[0] = null;
mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
inTask);
if (outActivity != null) {
// mLastStartActivityRecord[0] is set in the call to startActivity above.
outActivity[0] = mLastStartActivityRecord[0];
}
// Aborted results are treated as successes externally, but we must track them internally.
return mLastStartActivityResult != START_ABORTED ? mLastStartActivityResult : START_SUCCESS;
}
这里继续调用了startActivity
方法。
(frameworks/base/core/java/android/server/am/ActivityStarter.java)
private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
ActivityRecord[] outActivity, TaskRecord inTask) {
int err = ActivityManager.START_SUCCESS;
// Pull the optional Ephemeral Installer-only bundle out of the options early.
final Bundle verificationBundle = options != null ? options.popAppVerificationBundle() : null;
ProcessRecord callerApp = null;
if (caller != null) {
callerApp = mService.getRecordForAppLocked(caller);
if (callerApp != null) {
callingPid = callerApp.pid;
callingUid = callerApp.info.uid;
} else {
Slog.w(TAG, "Unable to find app for caller " + caller
+ " (pid=" + callingPid + ") when starting: "
+ intent.toString());
err = ActivityManager.START_PERMISSION_DENIED;
}
}
...
return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true,
options, inTask, outActivity);
}
此处的caller
是跟随一路调用传递而来的参数,指向的是ApplicationThread对象。之后继续调用同名重载函数。
(frameworks/base/core/java/android/server/am/ActivityStarter.java)
private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
ActivityRecord[] outActivity) {
int result = START_CANCELED;
try {
mService.mWindowManager.deferSurfaceLayout();
result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, outActivity);
}
...
return result;
}
这里紧接着调用了startActivityUnchecked
方法。
(frameworks/base/core/java/android/server/am/ActivityStarter.java)
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
ActivityRecord[] outActivity) {
...
if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
// 新任务
newTask = true;
result = setTaskFromReuseOrCreateNewTask(taskToAffiliate, preferredLaunchStackId, topStack);
} else if (mSourceRecord != null) {
result = setTaskFromSourceRecord();
} else if (mInTask != null) {
result = setTaskFromInTask();
} else {
setTaskToCurrentTopOrCreateNewTask();
}
...
mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition, mOptions);
if (mDoResume) {
final ActivityRecord topTaskActivity = mStartActivity.getTask().topRunningActivityLocked();
if (!mTargetStack.isFocusable() || (topTaskActivity != null && topTaskActivity.mTaskOverlay && mStartActivity != topTaskActivity)) {
...
} else {
if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) {
mTargetStack.moveToFront("startActivityUnchecked");
}
mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity, mOptions);
}
} else {
mTargetStack.addRecentActivityLocked(mStartActivity);
}
...
}
startActivityUnchecked
方法里面主要是一些栈管理的相关逻辑。启动根Activity
时,会将Intent
的FLAG
设置为FLAG_ACTIVITY_NEW_TASK
,那么就满足条件调用setTaskFromReuseOrCreateNewTask
方法,该方法会创建一个新的Activity任务栈。之后继续向下调用方法mSupervisor.resumeFocusedStackTopActivityLocked
。
(frameworks/base/core/java/android/server/am/ActivityStackSupervisor.java)
boolean resumeFocusedStackTopActivityLocked(ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
...
if (targetStack != null && isFocusedStack(targetStack)) {
return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
if (r == null || r.state != RESUMED) {
mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
} else if (r.state == RESUMED) {
mFocusedStack.executeAppTransition(targetOptions);
}
return false;
}
首先调用ActivityStack
的topRunningActivityLocked
的获取要启动的Activity
所在栈的栈顶的非停止状态的ActivityRecord
。如果该ActivityRecord
为空或不处于RESUMED
状态,则会调用ActivityStack
的resumeTopActivityUncheckedLocked
方法。对于即将要启动的Activity
来说,此处判断必定满足。下面就继续跟踪调用resumeTopActivityUncheckedLocked
方法。
(frameworks/base/core/java/android/server/am/ActivityStack.java)
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
...
boolean result = false;
try {
mStackSupervisor.inResumeTopActivity = true;
result = resumeTopActivityInnerLocked(prev, options);
} finally {
mStackSupervisor.inResumeTopActivity = false;
}
//
final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
if (next == null || !next.canTurnScreenOn()) {
checkReadyForSleep();
}
return result;
}
该方法是为了确保栈顶Activity
是已恢复的。紧接着跟踪resumeTopActivityInnerLocked
方法。
(frameworks/base/core/java/android/server/am/ActivityStack.java)
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
...
mStackSupervisor.startSpecificActivityLocked(next, true, true);
...
}
该方法内的代码非常多,但最终会执行mStackSupervisor.startSpecificActivityLocked
方法。该方法如下。
(frameworks/base/core/java/android/server/am/ActivityStackSupervisor.java)
void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
ProcessRecord app = mService.getProcessRecordLocked(r.processName, r.info.applicationInfo.uid, true);
r.getStack().setLaunchTime(r);
if (app != null && app.thread != null) {
try {
if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0 || !"android".equals(r.info.packageName)) {
app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode, mService.mProcessStats);
}
realStartActivityLocked(r, app, andResume, checkConfig);
return;
} catch (RemoteException e) {
}
}
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0, "activity", r.intent.getComponent(), false, false, true);
}
首先获取到需要启动的Activity
的应用进程,判断该进程是否运行。如果进程运行,则会执行realStartActivityLocked
方法。
(frameworks/base/core/java/android/server/am/ActivityStackSupervisor.java)
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig) throws RemoteException {
...
app.thread.scheduleLauchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info,
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
r.persistentState, results, newIntents, !andResume,
mService.isNextTransitionForward(), profilerInfo);
...
}
这里的app
表示要启动的Activity
所在的进程。app.thread
是IApplicationThread
类型,是AIDL文件,那么继续寻找,发现AcitvityThread
的内部类ApplicationThread
实现了IApplicationThread.Stub
。
(frameworks/base/core/java/android/app/AcitivtyThread.java)
private class ApplicationThread extends IApplicationThread.Stub {
...
@Override
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
int procState, Bundle state, PersistableBundle persistentState,
List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {
updateProcessState(procState, false);
ActivityClientRecord r = new ActivityClientRecord();
...
sendMessage(H.LAUNCH_ACTIVITY, r);
}
...
}
这里调用了ActivityThread
类内的sendMessage
方法。该方法最终调用了内部Handler
子类H
的handleMessage
方法。
(frameworks/base/core/java/android/app/AcitivtyThread.java)
private class H extends Handler {
...
public void handleMessage(Message msg) {
...
switch (msg.what) {
case LAUNCH_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
r.packageInfo = getPackageInfoNoCheck(r.activityInfo.applicationInfo, r.compatInfo);
handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
...
}
...
}
...
}
这里调用了ActivityThread
的handleLaunchActivity
方法。
(frameworks/base/core/java/android/app/AcitivtyThread.java)
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
...
Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
...
handleResumeActivity(r.token, false, r.isForward, !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
...
}
...
}
该方法内调用了performLaunchActivity
方法,是启动Activity
的核心方法。
(frameworks/base/core/java/android/app/AcitivtyThread.java)
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
...
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
try {
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
...
} catch (Exception e) {
...
}
try {
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
...
if (activity != null) {
...
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor, window, r.configCallback);
...
// 调用Activity的performCreate方法
// 而performCreate方法则会调用onCreate方法
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
...
if (!r.activity.mFinished) {
// 此处经过一系列调用,最终会调用onStart方法
activity.performStart();
r.stopped = false;
}
...
}
...
mActivities.put(r.token, r);
} catch (Exception e) {
...
}
return activity;
}
在第一处注释处,该方法经过Instrumenation
调用了Activity
的onCreate
方法。在第二处注释处,该方法又经过一系列调用,最终调用了Activity
的onStart
方法。到此,我们终于看到了常用的熟悉方法。
总结
将上面一整套流程总结后,我们可以得到如下图所示的调用链。
总的来说,Activity
的启动流程可以分为在两个进程内处理,以及进程之间互相通信完成的。
当然,本篇文章仅仅是讲解了方法的调用链,并简单的说明了一下一些重要方法的作用,讲解的比较粗浅。我会在后续的文章中,更加深入的分析Android源码。