概述
本文的內容緊接著上一篇文章Android源碼探究:Activity啟動流程完全解析(上),繼續介紹Activity的啟動流程。
主流程分析
8-1、ActivityManagerService#activityPaused(token)
經過客戶端的跨進程調用,AMS的activityPaused(token)被調用了。
@Override
public final void activityPaused(IBinder token) {
final long origId = Binder.clearCallingIdentity();
synchronized(this) {
ActivityStack stack = ActivityRecord.getStackLocked(token);
if (stack != null) {
stack.activityPausedLocked(token, false);
}
}
Binder.restoreCallingIdentity(origId);
}
根據token來獲取Activity所在的ActivityStack,進一步調用activityPausedLocked(params..)
8-2、ActivityStack#activityPausedLocked(params..)
final void activityPausedLocked(IBinder token, boolean timeout) {
//先從ActivityStack根據token取出對應的ActivityRecord
final ActivityRecord r = isInStackLocked(token);
if (r != null) {
mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
//如果二者相等,表示記錄的需要暫停的Activity已經暫停完畢
if (mPausingActivity == r) {
mService.mWindowManager.deferSurfaceLayout();
try {
completePauseLocked(true /* resumeNext */, null /* resumingActivity */);
} finally {
mService.mWindowManager.continueSurfaceLayout();
}
return;
} else {
//省略...
}
}
mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
}
這里沒什么好說的,我們繼續看completePauseLocked(params..)
。
8-3、ActivityStack#completePauseLocked(params..)
private void completePauseLocked(boolean resumeNext, ActivityRecord resuming) {
ActivityRecord prev = mPausingActivity;
//省略大部分的代碼...
if (resumeNext) {
final ActivityStack topStack = mStackSupervisor.getFocusedStack();
if (!topStack.shouldSleepOrShutDownActivities()) {
mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev, null);
} else {
//...
}
}
}
當代碼執行到這里的時候,讀者應該對這個方法resumeFocusedStackTopActivityLocked(params..)
有點眼熟吧?上面已經執行過該方法了,接下來的調用鏈都是一樣的了,最終會執行到ActivityStackSupervisor#startSpecificActivityLocked(params..)
這個方法,進行Activity的真正啟動過程。
8-4、ActivityStackSupervisor#startSpecificActivityLocked(params..)
void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
//獲取Activity所對應的進程記錄
ProcessRecord app = mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid, true);
getLaunchTimeTracker().setLaunchTime(r);
//如果該進程已經啟動了,那么直接開始啟動Activity
if (app != null && app.thread != null) {
try {
//若該Activity的flag不包含多進程標志位 或 不是安卓框架的組件
if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
|| !"android".equals(r.info.packageName)) {
// Don't add this if it is a platform component that is marked
// to run in multiple processes, because this is actually
// part of the framework so doesn't make sense to track as a
// separate apk in the process.
// 如果它是一個標記為多進程運行的平臺組件,則不要添加該項,
// 因為這實際上是安卓框架的一部分,因此在進程中作為單獨的apk進行跟蹤是沒有意義的。
app.addPackage(r.info.packageName, r.info.applicationInfo.longVersionCode,
mService.mProcessStats);
}
//真正地啟動一個Activity
realStartActivityLocked(r, app, andResume, checkConfig);
return;
} catch (RemoteException e) {
//...
}
// If a dead object exception was thrown -- fall through to
// restart the application.
}
//代碼9-1:否則,先啟動一個新的進程,然后再啟動Activity
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
}
代碼的邏輯很清晰明了,主要是先判斷Activity所對應的進程是否已經存在,如果存在了那就直接去執行真正的啟動Activity過程;如果該進程還不存在,那么就要去啟動一個進程。接下來的分析有兩條路可以走,一是沿著Activity啟動進行分析;二是沿著進程的啟動進行分析。實際上進程的啟動完畢之后也還是要進行Activity的啟動的。也就是說調用了mService.startProcessLocked(params)
后,會啟動新的進程,然后ActivityStackSupervisor再次調用realStartActivityLocked(params..)
在進程內啟動Activity。
其實,這個調用順序符合這一種情況:在進程A的ActivityA內啟動了進程B的ActivityB,此時先暫停進程A的ActivityA,然后進程B還沒有啟動,那么先啟動進程B,然后再啟動ActivityB。
因此,接下來我們先來看怎樣啟動一個新的進程。
9-1、ActivityManagerService#startProcessLocked(params..)
final ProcessRecord startProcessLocked(String processName,
ApplicationInfo info, boolean knownToBeDead, int intentFlags,
String hostingType, ComponentName hostingName, boolean allowWhileBooting,
boolean isolated, boolean keepIfLarge) {
return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
null /* crashHandler */);
}
private final boolean startProcessLocked(ProcessRecord app, String hostingType,
String hostingNameStr, boolean disableHiddenApiChecks, String abiOverride) {
//省略大部分代碼...
final String entryPoint = "android.app.ActivityThread";
return startProcessLocked(hostingType, hostingNameStr, entryPoint, app, uid, gids,
runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
startTime);
}
}
//一系列startProcessLocked(params..)重載方法的調用
//最終會調用下面的startProcess(params..)方法
private ProcessStartResult startProcess(String hostingType, String entryPoint,
ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
String seInfo, String requiredAbi, String instructionSet, String invokeWith,
long startTime) {
try {
final ProcessStartResult startResult;
if (hostingType.equals("webview_service")) {
startResult = startWebView(entryPoint,
app.processName, uid, uid, gids, runtimeFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, null,
new String[] {PROC_START_SEQ_IDENT + app.startSeq});
} else {
startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, runtimeFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, invokeWith,
new String[] {PROC_START_SEQ_IDENT + app.startSeq});
}
return startResult;
}
}
中間省略了大部分的重載方法的調用,最后來到了Process.start(params..)
,把一系列進程有關的信息都傳遞了進去,根據這些信息來創建一個進程。
9-2、Process#start(params..)
這個類的源碼在Android SDK內可以找到,我們直接看它的代碼:
public static final ProcessStartResult start(final String processClass,
final String niceName,
int uid, int gid, int[] gids,
int runtimeFlags, int mountExternal,
int targetSdkVersion,
String seInfo,
String abi,
String instructionSet,
String appDataDir,
String invokeWith,
String[] zygoteArgs) {
return zygoteProcess.start(processClass, niceName, uid, gid, gids,
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
}
這里我們需要關注一個參數processClass
,當一個進程被啟動后,以processClass
為類名的類的main(args)
函數會被調用。而這里的processClass
是代碼9-1中傳遞進來的“android.app.ActivityThread”。那么也就是說,一個新的進程啟動后,它的ActivityThread的main()函數會最先得到執行。所以,ActivityThread#main()是整個應用程序的入口。
9-3、zygoteProcess#start(params..)
代碼執行到了zygoteProcess的start(params..)方法,我們先來看一下代碼的執行:
public final Process.ProcessStartResult start(final String processClass,
final String niceName,int uid, int gid, int[] gids,
int runtimeFlags, int mountExternal,int targetSdkVersion,
String seInfo,String abi,String instructionSet,String appDataDir,
String invokeWith,String[] zygoteArgs) {
try {
return startViaZygote(processClass, niceName, uid, gid, gids,
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith, false /* startChildZygote */,
zygoteArgs);
} catch{
//...
}
}
private Process.ProcessStartResult startViaZygote(params...)throws ZygoteStartFailedEx {
ArrayList<String> argsForZygote = new ArrayList<String>();
//為zygote進程添加各種參數...
argsForZygote.add("--runtime-args");
argsForZygote.add("--setuid=" + uid);
argsForZygote.add("--setgid=" + gid);
//省略...
//這里加了鎖,同一時間內只允許一條線程執行創建進程的操作
synchronized(mLock) {
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
}
}
/**
* 把新進程的參數發給zygote進程,它會創建一個子進程,并返回子進程的pid
*
*/
@GuardedBy("mLock")
private static Process.ProcessStartResult zygoteSendArgsAndGetResult(
ZygoteState zygoteState, ArrayList<String> args)
throws ZygoteStartFailedEx {
try {
//這里的跨進程通信,使用的是socket通信機制
//由于這里都是在鎖的機制下執行,所以不會出現并發錯誤
final BufferedWriter writer = zygoteState.writer;
final DataInputStream inputStream = zygoteState.inputStream;
//把所有新進程的參數都寫入緩沖區
writer.write(Integer.toString(args.size()));
writer.newLine();
for (int i = 0; i < sz; i++) {
String arg = args.get(i);
writer.write(arg);
writer.newLine();
}
writer.flush();
// Should there be a timeout on this?
Process.ProcessStartResult result = new Process.ProcessStartResult();
//讀取zygote進程返回的值,這就是新進程的pid
result.pid = inputStream.readInt();
result.usingWrapper = inputStream.readBoolean();
if (result.pid < 0) {
throw new ZygoteStartFailedEx("fork() failed");
}
return result;
}
}
zygote
到底是何方神圣呢?其實在安卓系統啟動的過程中,zygote進程就會被啟動,它負責了整個frameworks層和application層的所有進程的創建和啟動工作。也就是說,所有的進程都是它孕育出來的,都是它的子進程。同時,zygote
的中文意思受精卵
剛好與它的行為相符合。
需要注意的是,上面的代碼都是運行在AMS內,只不過最后通過socket跨進程通信的方式通知了zygote進程來fork一個子進程,并且獲取到了子進程的pid。該子進程創建、啟動完畢之后,ActivityThread#main()
方法就得到了調用。
10-1、ActivityThread#main()
ActivityThread的main()方法可以說是我們應用程序的開端,它運行在一個新的進程空間內。當一個新的進程啟動完畢開始運行后,它首先要做的是通知AMS它被啟動了,因為此時AMS還等著它去執行啟動Activity的后續流程呢。我們來看看main()方法做了什么工作:
public static void main(String[] args) {
//初始化環境
Environment.initForCurrentUser();
// Set the reporter for event logging in libcore
EventLogger.setReporter(new EventLoggingReporter());
// Make sure TrustedCertificateStore looks in the right place for CA certificates
final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
TrustedCertificateStore.setDefaultUserDirectory(configDir);
Process.setArgV0("<pre-initialized>");
//為主線程準備Looper
Looper.prepareMainLooper();
//從命令行參數中獲取序列號
long startSeq = 0;
if (args != null) {
for (int i = args.length - 1; i >= 0; --i) {
if (args[i] != null && args[i].startsWith(PROC_START_SEQ_IDENT)) {
startSeq = Long.parseLong(
args[i].substring(PROC_START_SEQ_IDENT.length()));
}
}
}
//創建ActivityThread的實例
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq); //通知AMS進行綁定操作
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
Looper.loop(); //開啟主線程的消息循環
throw new RuntimeException("Main thread loop unexpectedly exited");
}
代碼的邏輯很清晰,關鍵的地方上面也有注釋。可以看出,在main()
函數的最后,開啟了主線程的消息循環,通過Handler和Looper的組合,可以不斷地處理AMS、WMS發過來的消息請求等,有關主線程消息循環的內容,有興趣的可以自行查閱相關的信息,這里不做展開講述。我們的關注點放在thread.attach(false,startSeq)
這行代碼內,我們看看它做了什么工作吧。
10-2、ActivityThread#attach(params..)
private void attach(boolean system, long startSeq) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
//獲取AMS在客戶端的代理對象
final IActivityManager mgr = ActivityManager.getService();
try {
//進行跨進程通信,通知AMS進行綁定操作
//這里的mAppThread就是ApplicationThread,在ActivityThread
//被實例化的時候,它也被實例化了。
mgr.attachApplication(mAppThread, startSeq);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
} else {
//...
}
//...
}
上面的代碼出現了ApplicationThread
對象,它在前面已經出現過很多次了,它是一個Binder對象,用于AMS來跨進程與APP進行消息通信。這里通過Binder跨進程通信,調用了AMS的attachApplication(params..)方法。我們再次打開AMS的代碼,找到該方法。(需要注意的是:應用程序的主線程執行完該方法之后,繼續進行消息循環,以等待下一次AMS的消息。)
10-3、ActivityManagerService#attachApplication(params..)
@Override
public final void attachApplication(IApplicationThread thread, long startSeq) {
synchronized (this) {
//..
attachApplicationLocked(thread, callingPid, callingUid, startSeq);
}
}
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid, int callingUid, long startSeq) {
ProcessRecord app;
long startTime = SystemClock.uptimeMillis();
//根據pid來獲取進程記錄
if (pid != MY_PID && pid >= 0) {
synchronized (mPidsSelfLocked) {
app = mPidsSelfLocked.get(pid);
}
} else {
app = null;
}
//ProcessRecord保存了當前的IApplicationThread,即保存了客戶端的一個代理對象
//AMS能根據該Binder對象快速找到所指的應用
app.makeActive(thread, mProcessStats);
//省略大部分代碼...
if (app.isolatedEntryPoint != null) {
//...
} else if (app.instr != null) {
//代碼11-1、跨進程調用ApplicationThread的方法,告訴APP端有關該進程的信息
thread.bindApplication(processName, appInfo, providers,
app.instr.mClass,
profilerInfo, app.instr.mArguments,
app.instr.mWatcher,
app.instr.mUiAutomationConnection, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(getGlobalConfiguration()), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial, isAutofillCompatEnabled);
} else {
//...
}
}
// See if the top visible activity is waiting to run in this process...
if (normalMode) {
try {
//代碼12-1、告訴ActivityStackSupervisor,該app已經完成了綁定操作,可以啟動一個Activity了
if (mStackSupervisor.attachApplicationLocked(app)) {
didSomething = true;
}
}
}
return true;
}
上面已經省略了大部分的代碼,很多都是異常狀態的處理以及初始化等邏輯,核心在于thread.bindApplication(params..)
和mStackSupervisor.attachApplicationLocked(app)
這兩個方法的調用上。前一行代碼通過IApplicationThread
跨進程通信,調用了APP端的相應方法,把有關進程的重要信息傳遞了過去。這樣便完成從客戶端到服務端的綁定操作。后一行代碼,通過ActivityStackSupervisor
來找到對應的ActivityStack
,然后進行綁定,這樣便完成了從服務端到客戶端的綁定操作。通過這兩個操作,客戶端的應用程序知道了自己的應用信息、進程信息等;而服務端則知道了客戶端的Binder代理對象,方便之后的跨進程操作。
11-1、ApplicationThread#bindApplication(params..)
我們先來看該方法的調用,我們又從AMS進程回到了應用進程:
public final void bindApplication(params..) {
if (services != null) {
// Setup the service cache in the ServiceManager
ServiceManager.initServiceCache(services);
}
setCoreSettings(coreSettings);
AppBindData data = new AppBindData();
data.processName = processName;
data.appInfo = appInfo;
data.providers = providers;
//省略賦值代碼..
//通過Handler發送消息
sendMessage(H.BIND_APPLICATION, data);
}
由此可見,App的有關信息從AMS傳遞了過來,并保存在了AppBindData
這個對象內。接著,就是我們熟悉的發送消息過程,通過Handler切換到主線程,在主線程內處理這個消息。代碼如下:
public void handleMessage(Message msg) {
switch (msg.what) {
case BIND_APPLICATION:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
AppBindData data = (AppBindData)msg.obj;
handleBindApplication(data);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
}
Object obj = msg.obj;
if (obj instanceof SomeArgs) {
((SomeArgs) obj).recycle();
}
}
得益于主線程的消息循環,當H
接受到BIND_APPLICATION
的消息時,就能馬上開始處理這個消息,處理完畢后繼續消息循環。
11-2、ActivityThread#handleBindApplication(data)
private void handleBindApplication(AppBindData data) {
//省略大部分代碼...
//創建上下文環境context
final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
Application app;
try {
app = data.info.makeApplication(data.restrictedBackupMode, null);
//....
try {
mInstrumentation.callApplicationOnCreate(app);
}
}
}
以上省略了絕大部分的代碼,很多都是初始化代碼,比如加載各種庫等。當Application初始化完畢之后,調用了mInstrumentation.callApplicationOnCreate(app)
。
11-3、Instrumentation#callApplicationOnCreate(app)
public void callApplicationOnCreate(Application app) {
app.onCreate();
}
很簡單,調用了Application#onCreate()
方法,也就是我們業務層常重寫的方法之一,代碼執行到這里,應用程序的初始化已經完成了。下面就是在應用程序的基礎上啟動一個Activity了。
12-1、ActivityStackSupervisor#attachApplicationLocked(app)
回到10-3的代碼,繼續往下執行,接著AMS就會調用mStackSupervisor.attachApplicationLocked(app)
方法,可想而知,在方法的內部,應該是要啟動一個Activity了。因為一切的準備工作都已經完成了。
boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
final String processName = app.processName;
boolean didSomething = false;
for (...) {
for (...) {
for (int i = 0; i < size; i++) {
final ActivityRecord activity = mTmpActivityList.get(i);
//如果該ActivityRecord的進程字段為空 并且進程uid與Activity的進程id相同
//并且 進程名字與Activity的進程名字相同
if (activity.app == null && app.uid == activity.info.applicationInfo.uid
&& processName.equals(activity.processName)) {
try {
//啟動該Activity
if (realStartActivityLocked(activity, app,
top == activity /* andResume */, true /* checkConfig */)) {
didSomething = true;
}
}
}
}
}
}
return didSomething;
}
上面代碼的邏輯主要是遍歷所有的任務棧,找到活躍的任務棧后,再在其中找到需要啟動的Activity,將它啟動。啟動的邏輯放在了realStartActivityLocked(params..)
,終于,我們又看到了這個方法,殊途同歸。
12-2、ActivityStackSupervisor#realStartActivityLocked(params..)
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
boolean andResume, boolean checkConfig) throws RemoteException {
//這里進行了判斷,如果有Activity處于未暫停的狀態,則不能啟動一個新的Activity
//由于我們是從客戶端通知server來啟動一個Activity的,因此已經不存在未暫停的Activity了
if (!allPausedActivitiesComplete()) {
return false;
}
final TaskRecord task = r.getTask();
final ActivityStack stack = task.getStack();
try {
//創建一個客戶端的事務
final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
r.appToken);
//添加callback,留意這里的添加了LaunchActivityItem
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
System.identityHashCode(r), r.info,
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
r.persistentState, results, newIntents, mService.isNextTransitionForward(),
profilerInfo));
//為該事務的目標設置為ResumeActivityItem,即啟動一個Activity,并改變它
//的生命周期到Resumed狀態
final ActivityLifecycleItem lifecycleItem;
if (andResume) {
lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());
}
clientTransaction.setLifecycleStateRequest(lifecycleItem);
//通過事務管理器執行一個事務
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
}
return true;
}
可以看到,我們再次遇到了熟悉的ClientTransaction
,前面解析暫停Activity時也遇到它,那么接下來的邏輯應該就是與暫停的邏輯差不多了,只不過現在的ActivityLifecycleItem
變成了ResumeActivityItem
,即Activity的目標狀態是resumed。接下來的調用鏈與前面見過的是一致的,即:ClientLifecycleManager#scheduleTransaction(clientTransaction)
——>ClientTransaction.schedule()
——>IApplicationThread.scheduleTransaction(this)
——>ActivityThread#scheduleTransaction(transaction)
——>H#handleMessage(msg)
——>TransactionExecutor#execute(transaction)
其中,通過IApplicationThread這個Binder對象進行了跨進程調用,調用了APP端的方法,此時從AMS進程切換到了我們的應用進程。緊接著,通過Handler機制切換到了主線程,并在主線程處理EXECUTE_TRANSACTION
這個消息,接著進一步交給TransactionExecutor
來處理這個事務。
13-1、TransactionExecutor#execute(transaction)
在代碼7-1已經介紹過這個方法了,我們再來簡單看一下就行:
public void execute(ClientTransaction transaction) {
final IBinder token = transaction.getActivityToken();
log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token);
executeCallbacks(transaction);
executeLifecycleState(transaction);
mPendingActions.clear();
log("End resolving transaction");
}
在代碼12-2中,我們有留意到初始化clientTransaction
時,為它添加了一個callback
,即LaunchActivityItem
,那么這里首先會執行executeCallbacks(transaction)
方法。
13-2、TransactionExecutor#executeCallbacks(transaction)
public void executeCallbacks(ClientTransaction transaction) {
final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
if (callbacks == null) {
// No callbacks to execute, return early.
return;
}
log("Resolving callbacks");
final IBinder token = transaction.getActivityToken();
ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
//根據前面的代碼,這里的size為1
final int size = callbacks.size();
for (int i = 0; i < size; ++i) {
final ClientTransactionItem item = callbacks.get(i);
log("Resolving callback: " + item);
//這里的Item實際上就是LaunchActivityItem.
item.execute(mTransactionHandler, token, mPendingActions);
item.postExecute(mTransactionHandler, token, mPendingActions);
//...
}
}
在方法內部調用了LaunchActivityItem
的相關方法,其中關鍵是LaunchActivityItem#execute(params..)
13-3、LaunchActivityItem#execute(params..)
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
//實例化一個ActivityClientRecord
ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
mPendingResults, mPendingNewIntents, mIsForward,
mProfilerInfo, client);
//實際上調用的是ActivityThread的handleLaunchActivity方法
client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
這里的ClientTransactionHandler
是ActivityThread
的父類,而ActivityThread
重寫了該方法,因此我們到ActivityThread
尋找該方法。
13-4、ActivityThread#handleLaunchActivity(params..)
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent) {
//....
final Activity a = performLaunchActivity(r, customIntent);
//...
return a;
}
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
//省略部分代碼..
ActivityInfo aInfo = r.activityInfo;
ContextImpl appContext = createBaseContextForActivity(r); //創建Context
Activity activity = null;
try {
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent); //創建一個新的Activity
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess();
if (r.state != null) {
r.state.setClassLoader(cl);
}
}
try {
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
if (activity != null) {
appContext.setOuterContext(activity);
//activity綁定application
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);
if (r.isPersistable()) {
//前面創建了Activity,接下來觸發它的生命周期方法
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
r.activity = activity;
}
r.setState(ON_CREATE); //設置Activity此時的狀態為onCreate
mActivities.put(r.token, r);
return activity;
}
經過一系列的創建、初始化過程,終于到了Instrumentation#callActivityOnCreate(params..)
,顯然,這里就是觸發Activity生命周期方法的地方了。
13-5、Instrumentation#callActivityOnCreate(params..)
public void callActivityOnCreate(Activity activity, Bundle icicle) {
prePerformCreate(activity);
activity.performCreate(icicle);
postPerformCreate(activity);
}
沒什么好說的,下一步就是Activity#performCreate(bundle)
:
final void performCreate(Bundle icicle) {
performCreate(icicle, null);
}
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
mCanEnterPictureInPicture = true;
restoreHasCurrentPermissionRequest(icicle);
if (persistentState != null) {
onCreate(icicle, persistentState);
} else {
onCreate(icicle); //onCreate()生命周期方法調用
}
writeEventLog(LOG_AM_ON_CREATE_CALLED, "performCreate");
mActivityTransitionState.readState(icicle);
mVisibleFromClient = !mWindow.getWindowStyle().getBoolean(
com.android.internal.R.styleable.Window_windowNoDisplay, false);
mFragments.dispatchActivityCreated(); //告訴Fragment分發create事件
mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
}
最后,終于來到了Activity#onCreate()
方法,也這就是我們應用Activity默認重寫的一個方法。到了這一步,一個Activity終于真正地創建、啟動成功了。但還沒有完成,因為我們的目標狀態是resumed,所以我們還要把Activity的狀態逐步切換到onResume
狀態。
讓我們回到代碼13-1的executeLifecycleState(transaction)
,這個方法讀者應該也是熟悉的了,因為在處理pause
狀態時也曾經遇到過了。那么接下來的邏輯就顯而易見了,具體的邏輯就在代碼7-2處,只不過現在的狀態路徑變成了:onStart和onResume,也就是會分別調用ActivityThread#handleStartActivity
和ActivityThread#handleResumeActivity
;接著進一步調用到Activity#performStart()
和Activity#performResume()
。最后,我們熟悉的生命周期方法onStart()
和onResume()
都會得到調用。
本文到這里就告一段落了,整篇文章很長,為耐心看到這里的你點贊~希望這篇文章能對您有所裨益,謝謝閱讀!