上篇文章讲述了app从启动创建Activity调用onCreate,onStart, onResume方法,这篇文章讲述一下Activity启动的另一个切入点:startActivity方法,启动Activity。
Android进阶3:Activity源码分析(1) —— Activity启动流程(8.0)
通过上一篇文章,我们总结一下:
1:ActivityThread是通过Instrumentation调度Activity的生命周期的
2:ApplicationThread继承自IApplicationThread.Stub,本身就是一个Binder对象。AMS给ActivityThread传递信息,就是通过Binder机制,也就是ApplicationThread传递的。
3:Instrumentation内部提供了创建Activity,调用Activity的方法,创建Application,调用Application的方法,至少从我们上一篇文章得到的结论是:Instrumentation好比一个管家,管理着Activity和Application的生命周期。
接下来是一些小知识点:
1:我们之前说的UI主线程初始化Looper是在ActivityThread中的main方法中,这就是为什么我们可以在UI层直接发送使用Handler机制。
2:项目开发中总是在Application的onCreate中,做一些初始化操作,因为Application的创建的比Activity创建更早,并且Application 的onCreate方法调用的更早。
好了,开始分析另一个切入点:Activity的startActivity(…)
先看下Activity的startActivity源码:
@Override
public void startActivity(Intent intent) {
this.startActivity(intent, null);
}
//Bundle : 传递的数据
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
//不需要返回数据,requestCode默认:-1
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);
}
}
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode) {
startActivityForResult(intent, requestCode, null);
}
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
if (mParent == null) {
//requestCode = -1
options = transferSpringboardActivityOptions(options);
//调用Instrumentation的execStartActivity方法;
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
......
}
通过上述代码可以看到:startActivity其实最终调用的都是startActivityForResult,如果不需要返回值,requestCode传递-1, 此时调用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);
/*
ActivityManager.getService().startActivity()就是IActivityManager的代理对象调用了startActivity方法,通过binder机制,
从而调用ActivityManagerService的startActivity方法。
*/
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;
}
再调用AMS的startActivity方法,Binder机制
@Override
public int startActivity(IBinder whoThread, String callingPackage,
Intent intent, String resolvedType, Bundle bOptions) {
.......
return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
resolvedType, null, null, null, null, 0, 0, null, null,
null, bOptions, false, callingUser, null, tr, "AppTaskImpl");
}
进入:startActivityMayWait
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,
IActivityContainer iContainer, TaskRecord inTask, String reason) {
.......
final ActivityRecord[] outRecord = new ActivityRecord[1];
int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
aInfo, rInfo, voiceSession, voiceInteractor,
resultTo, resultWho, requestCode, callingPid,
callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
options, ignoreTargetSecurity, componentSpecified, outRecord, container,
inTask, reason);
........
}
进入:startActivityLocked
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, ActivityStackSupervisor.ActivityContainer container,
TaskRecord inTask, String reason) {
.........
mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
container, inTask);
.........
}
进入:startActivity
/** DO NOT call this method directly. Use {@link #startActivityLocked} instead. */
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, ActivityStackSupervisor.ActivityContainer container,
TaskRecord inTask) {
........
doPendingActivityLaunchesLocked(false);
return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true,
options, inTask, outActivity);
}
进入:doPendingActivityLaunchesLocked
final void doPendingActivityLaunchesLocked(boolean doResume) {
while (!mPendingActivityLaunches.isEmpty()) {
final PendingActivityLaunch pal = mPendingActivityLaunches.remove(0);
final boolean resume = doResume && mPendingActivityLaunches.isEmpty();
try {
startActivity(pal.r, pal.sourceRecord, null, null, pal.startFlags, resume, null,
null, null /*outRecords*/);
} catch (Exception e) {
Slog.e(TAG, "Exception during pending activity launch pal=" + pal, e);
pal.sendErrorResult(e.getMessage());
}
}
}
进入:startActivity
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);
}
......
}
进入startActivityUnchecked
// Note: This method should only be called from {@link startActivity}.
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
ActivityRecord[] outActivity) {
.......
if (mDoResume) {
mSupervisor.resumeFocusedStackTopActivityLocked();
}
.......
}
进入:resumeFocusedStackTopActivityLocked
boolean resumeFocusedStackTopActivityLocked() {
return resumeFocusedStackTopActivityLocked(null, null, null);
}
boolean resumeFocusedStackTopActivityLocked(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
.......
if (r == null || r.state != RESUMED) {
mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
} else if (r.state == RESUMED) {
// Kick off any lingering app transitions form the MoveTaskToFront operation.
mFocusedStack.executeAppTransition(targetOptions);
}
return false;
}
进入resumeTopActivityUncheckedLocked:
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
........
result = resumeTopActivityInnerLocked(prev, options);
......
}
进入resumeTopActivityInnerLocked:
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
......
mStackSupervisor.startSpecificActivityLocked(next, true, true);
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
return true;
}
进入startSpecificActivityLocked:
void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
// Is this activity's application already running?
ProcessRecord app = mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid, true);
r.getStack().setLaunchTime(r);
if (app != null && app.thread != null) {
....
realStartActivityLocked(r, app, andResume, checkConfig);
......
}
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
}
进入:realStartActivityLocked
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
boolean andResume, boolean checkConfig) throws RemoteException {
.......
/*
通过binder机制,通过代理调用ApplicationThread的scheduleLaunchActivity方法。将启动Activity的操作交给ApplicationThread类
*/
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
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, app.repProcState, r.icicle,
r.persistentState, results, newIntents, !andResume,
mService.isNextTransitionForward(), profilerInfo);
......
}
app.thread也就是ApplicationThread,交给UI层处理,进入scheduleLaunchActivity:
// we use token to identify this activity without having to send the
// activity itself back to the activity manager. (matters more with ipc)
@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 pendingResults, List pendingNewIntents,
boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {
updateProcessState(procState, false);
//用于封装启动Activity一些参数值
ActivityClientRecord r = new ActivityClientRecord();
......
sendMessage(H.LAUNCH_ACTIVITY, r);
}
发送消息:
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
.....
//启动Activity
Activity a = performLaunchActivity(r, customIntent);
.....
}
接下来就跟上一篇文章分析走的流程一样的:
performLaunchActivity ——》 Instrumentation & callActivityOnCreate ——》Activity & performCreate ——》Activity & onCreate
至此Activity就创建完毕了。通过上述流程分析,我们再一次大致了解了流程:
Activity通过Binder机制调用Instrumentation, Instrumentation在通过Binder机制调用AMS的方法,AMS经过一系列操作,然后再通过Binder机制返回给主线程的ApplicationThread, 此时发送消息交给ActivityThread处理,再通过Binder机制,让Instrumentation统一处理Activity的生命周期,调用onCreate方法。
接下来再说一下finish的关闭流程吧
调用finish方法最终都会调用以下方法:
private void finish(int finishTask) {
if (mParent == null) {
int resultCode;
Intent resultData;
synchronized (this) {
resultCode = mResultCode;
resultData = mResultData;
}
if (false) Log.v(TAG, "Finishing self: token=" + mToken);
try {
if (resultData != null) {
resultData.prepareToLeaveProcess(this);
}
if (ActivityManager.getService()
.finishActivity(mToken, resultCode, resultData, finishTask)) {
mFinished = true;
}
} catch (RemoteException e) {
// Empty
}
} else {
mParent.finishFromChild(this);
}
}
调用AMS的finishActivity方法:
@Override
public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
int finishTask) {
.....
res = tr.getStack().requestFinishActivityLocked(token, resultCode,
resultData, "app-request", true);
.......
}
进入ActivityStack的requestFinishActivityLocked方法:
/**
* @return Returns true if the activity is being finished, false if for
* some reason it is being left as-is.
*/
final boolean requestFinishActivityLocked(IBinder token, int resultCode,
Intent resultData, String reason, boolean oomAdj) {
ActivityRecord r = isInStackLocked(token);
if (DEBUG_RESULTS || DEBUG_STATES) Slog.v(TAG_STATES,
"Finishing activity token=" + token + " r="
+ ", result=" + resultCode + ", data=" + resultData
+ ", reason=" + reason);
if (r == null) {
return false;
}
finishActivityLocked(r, resultCode, resultData, reason, oomAdj);
return true;
}
进入:finishActivityLocked
final boolean finishActivityLocked(ActivityRecord r, int resultCode, Intent resultData,
String reason, boolean oomAdj) {
return finishActivityLocked(r, resultCode, resultData, reason, oomAdj, !PAUSE_IMMEDIATELY);
}
/**
* @return Returns true if this activity has been removed from the history
* list, or false if it is still in the list and will be removed later.
*/
final boolean finishActivityLocked(ActivityRecord r, int resultCode, Intent resultData,
String reason, boolean oomAdj, boolean pauseImmediately) {
......
final boolean removedActivity = finishCurrentActivityLocked(r, finishMode, oomAdj)
== null;
.......
}
进入:finishCurrentActivityLocked
final ActivityRecord finishCurrentActivityLocked(ActivityRecord r, int mode, boolean oomAdj) {
.......
boolean activityRemoved = destroyActivityLocked(r, true, "finish-imm");
.......
}
进入:destroyActivityLocked
final boolean destroyActivityLocked(ActivityRecord r, boolean removeFromApp, String reason) {
........
r.app.thread.scheduleDestroyActivity(r.appToken, r.finishing,
r.configChangeFlags);
........
}
进入ApplicationThread的scheduleDestroyActivity方法内,发送消息,进入到ActivityThread的handleDestroyActivity方法:
private void handleDestroyActivity(IBinder token, boolean finishing,
int configChanges, boolean getNonConfigInstance) {
ActivityClientRecord r = performDestroyActivity(token, finishing,
configChanges, getNonConfigInstance);
......
}
进入performDestroyActivity方法:
private ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing,
int configChanges, boolean getNonConfigInstance) {
ActivityClientRecord r = mActivities.get(token);
Class extends Activity> activityClass = null;
if (localLOGV) Slog.v(TAG, "Performing finish of " + r);
if (r != null) {
activityClass = r.activity.getClass();
r.activity.mConfigChangeFlags |= configChanges;
if (finishing) {
r.activity.mFinished = true;
}
//步骤1:pause Activity
performPauseActivityIfNeeded(r, "destroy");
if (!r.stopped) {
try {
//步骤2:stop Activity
r.activity.performStop(r.mPreserveWindow);
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
if (!mInstrumentation.onException(r.activity, e)) {
throw new RuntimeException(
"Unable to stop activity "
+ safeToComponentShortString(r.intent)
+ ": " + e.toString(), e);
}
}
r.stopped = true;
EventLog.writeEvent(LOG_AM_ON_STOP_CALLED, UserHandle.myUserId(),
r.activity.getComponentName().getClassName(), "destroy");
}
if (getNonConfigInstance) {
try {
r.lastNonConfigurationInstances
= r.activity.retainNonConfigurationInstances();
} catch (Exception e) {
if (!mInstrumentation.onException(r.activity, e)) {
throw new RuntimeException(
"Unable to retain activity "
+ r.intent.getComponent().toShortString()
+ ": " + e.toString(), e);
}
}
}
try {
r.activity.mCalled = false;
//步骤3:destroy Activity
mInstrumentation.callActivityOnDestroy(r.activity);
.......
}
先看步骤1: 进入performPauseActivityIfNeeded:
private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
.......
mInstrumentation.callActivityOnPause(r.activity);
.......
}
调用了Instrumentation的callActivityOnPause方法,方法内调用Activity的performPause方法,内部调用onPause方法,
所以finish Activity时,onPause最先触发。
接下来看下步骤2:performStop:
final void performStop(boolean preserveWindow) {
.......
mInstrumentation.callActivityOnStop(this);
.......
}
调用了Instrumentation的callActivityOnStop方法,然后方法内有调用了Activity的onStop方法。
接下来看步骤3:调用了Instrumentation的callActivityOnDestroy方法:
public void callActivityOnDestroy(Activity activity) {
activity.performDestroy();
}
调用了Activity的performDestroy方法:
final void performDestroy() {
mDestroyed = true;
mWindow.destroy();
mFragments.dispatchDestroy();
//我们最终想看到的方法
onDestroy();
mFragments.doLoaderDestroy();
if (mVoiceInteractor != null) {
mVoiceInteractor.detachActivity();
}
}
至此finish Activity的流程就算走完了
finish Activity的方法回调是:onPause ——》onStop ——》onDestroy
AMS交互的大致流程就是:finish调用AMS的方法,经过一系列操作,然后返回给主线程的ApplicationThread处理,发送消息,交给ActivityThread处理,然后Activity的生命周期的方法,有Instrumentation统一管理调度。
上述分析如果有错误,感觉指正O(∩_∩)O!
Android学习交流: