Android啟動流程源碼解析(二)
在之前的Android啟動流程源碼解析(一)源碼分析中洲劣,我們最后遺留下來一個問題。那就是我們的Activity的啟動是啥時候處理的翱问摺囱稽?上萬行的分析,也沒看到我們想要的onCreate啥的二跋。其實就是resumeFocusedStacksTopActivities方法战惊,所以我們這篇文章就從這個方法開始。
resumeFocusedStacksTopActivities
boolean resumeFocusedStacksTopActivities() {
return resumeFocusedStacksTopActivities(null, null, null);
}
boolean resumeFocusedStacksTopActivities(ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
boolean result = false;
if (targetStack != null && (targetStack.isTopStackOnDisplay()|| getTopDisplayFocusedStack() == targetStack)) {
//******重點方法******如果當前的activitystack正好處于屏幕的頂部扎即,那么直接調(diào)用將target設(shè)置到頂部顯示
result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
//標記是否已經(jīng)顯示在屏幕上
boolean resumedOnDisplay = false;
final ActivityDisplay display = mActivityDisplays.get(displayNdx);
for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
final ActivityStack stack = display.getChildAt(stackNdx);
//獲取到當前ActivityStack頂部正在運行的Activity
final ActivityRecord topRunningActivity = stack.topRunningActivityLocked();
if (!stack.isFocusableAndVisible() || topRunningActivity == null) {
continue;
}
if (stack == targetStack) {
//上面已經(jīng)做過resume處理了吞获,所以這里我們就不再做處理了
resumedOnDisplay |= result;
continue;
}
if (display.isTopStack(stack) && topRunningActivity.isState(RESUMED)) {
stack.executeAppTransition(targetOptions);
} else {
resumedOnDisplay |= topRunningActivity.makeActiveIfNeeded(target);
}
}
//如果仍然沒有顯示在屏幕上况凉,那么就獲取到屏幕當前持有焦點的ActivityStack,然后將activity顯示在上面
if (!resumedOnDisplay) {
final ActivityStack focusedStack = display.getFocusedStack();
if (focusedStack != null) {
focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
}
}
return result;
}
這里我們只需要關(guān)注一個方法 resumeTopActivityUncheckedLocked 各拷,這個方法也特別長刁绒,我們就拆分開,只關(guān)注重點方法即可
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
if (mInResumeTopActivity) {
// Don't even start recursing.
return false;
}
boolean result = false;
try {
// Protect against recursion.
mInResumeTopActivity = true;
//***重點關(guān)注******
result = resumeTopActivityInnerLocked(prev, options);
final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
if (next == null || !next.canTurnScreenOn()) {
checkReadyForSleep();
}
} finally {
mInResumeTopActivity = false;
}
return result;
}
這里我們也只關(guān)注resumeTopActivityInnerLocked方法
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
...
if (mResumedActivity != null) {
//****重點方法 ****** 調(diào)用acitivity的pause方法
pausing |= startPausingLocked(userLeaving, false, next, false);
}
...
//進行activity的創(chuàng)建處理
mStackSupervisor.startSpecificActivityLocked(next, true, false);
...
}
代碼也很長烤黍,我們只提取了兩個比較重要的函數(shù)知市,一個是調(diào)用onPause生命周期函數(shù),另一個是調(diào)用onCreate生命周期函數(shù)的蚊荣。
onPause的暫停過程
我們首先來看一下是如何一步步通過調(diào)度來執(zhí)行onPause的生命周期調(diào)度的
//ActivityStack.java
final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, ActivityRecord resuming, boolean pauseImmediately) {
...
//當前正在顯示的Activity
ActivityRecord prev = mResumedActivity;
//當前正在顯示的Activity需要執(zhí)行暫停操作了初狰。
//將其賦值給mPausingActivity成員變量。
mPausingActivity = prev;
mLastPausedActivity = prev;
//Activity綁定了對應(yīng)的APP互例?難道有不綁定的情況么奢入?
if (prev.attachedToProcess()) {
...
//******重點方法****
mService.getLifecycleManager().scheduleTransaction(prev.app.getThread(),prev.appToken, PauseActivityItem.obtain(prev.finishing, userLeaving,prev.configChangeFlags, pauseImmediately));
...
重點方法已經(jīng)標注出來了。我們先看看它的參數(shù)的創(chuàng)建過程媳叨。
PauseActivityItem.obtain
//PauseActivityItem.java
//從池中取出一個PauseActivityItem類
public static PauseActivityItem obtain(boolean finished, boolean userLeaving, int configChanges, boolean dontReport) {
PauseActivityItem instance = ObjectPool.obtain(PauseActivityItem.class);
if (instance == null) {
instance = new PauseActivityItem();
}
instance.mFinished = finished;
instance.mUserLeaving = userLeaving;
instance.mConfigChanges = configChanges;
instance.mDontReport = dontReport;
return instance;
}
//ObjectPool.java
public static <T extends ObjectPoolItem> T obtain(Class<T> itemClass) {
synchronized (sPoolSync) {
@SuppressWarnings("unchecked")
final ArrayList<T> itemPool = (ArrayList<T>) sPoolMap.get(itemClass);
if (itemPool != null && !itemPool.isEmpty()) {
return itemPool.remove(itemPool.size() - 1);
}
return null;
}
}
可以看到腥光,對于PauseActivityItem的獲取,是通過享元模式 來進行處理的糊秆。
回到主干武福。
這的mService是ActivityTaskManagerService,getLifecycleManager方法返回的是ClientLifecycleManager對象痘番。
private final ClientLifecycleManager mLifecycleManager;
mLifecycleManager = new ClientLifecycleManager();
ClientLifecycleManager getLifecycleManager() {
return mLifecycleManager;
}
scheduleTransaction
//ClientLifecycleManager.java
//調(diào)用一次生命周期的調(diào)度請求
void scheduleTransaction(@NonNull IApplicationThread client, @NonNull IBinder activityToken,@NonNull ActivityLifecycleItem stateRequest) throws RemoteException {
final ClientTransaction clientTransaction = transactionWithState(client, activityToken,stateRequest);
scheduleTransaction(clientTransaction);
}
//實際的調(diào)度方法
void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
final IApplicationThread client = transaction.getClient();
transaction.schedule();
if (!(client instanceof Binder)) {
//回收
transaction.recycle();
}
}
//創(chuàng)建一個持有狀態(tài)的事務(wù)類
private static ClientTransaction transactionWithState(@NonNull IApplicationThread client,
@NonNull IBinder activityToken, @NonNull ActivityLifecycleItem stateRequest) {
final ClientTransaction clientTransaction = ClientTransaction.obtain(client, activityToken);
clientTransaction.setLifecycleStateRequest(stateRequest);
return clientTransaction;
}
這里最終會調(diào)用ClientTransaction對象的schedule方法捉片。
//ClientTransaction.java
public void schedule() throws RemoteException {
mClient.scheduleTransaction(this);
}
這里的mClient是一個IApplicationThread,其Server端是ActivityThread#ApplicationThread汞舱。所以最終調(diào)用的是ApplicationThread的scheduleTransaction方法
//ActivityThread.java
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
//會調(diào)用ActivityThread.scheduleTransaction方法->該方法位于ActivityThread的父類中
ActivityThread.this.scheduleTransaction(transaction);
}
//ClientTransactionHandler.java
void scheduleTransaction(ClientTransaction transaction) {
//執(zhí)行預(yù)處理
transaction.preExecute(this);
//通過Handler機制發(fā)送事務(wù)請求
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
Handler消息機制就不貼出來了伍纫,直接看其是怎么處理的。
//ActivityThread.java
private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this);
case EXECUTE_TRANSACTION://執(zhí)行生命周期的調(diào)度工作
final ClientTransaction transaction = (ClientTransaction) msg.obj;
mTransactionExecutor.execute(transaction);
當接收到Handler以后昂芜,會調(diào)用TransactionExecutor的execute()方法莹规。
//TransactionExecutor.java
public void execute(ClientTransaction transaction) {
final IBinder token = transaction.getActivityToken();
...
//循環(huán)遍歷回調(diào)請求的所有狀態(tài),并在適當?shù)臅r間執(zhí)行它們
executeCallbacks(transaction);
//執(zhí)行生命周期的改變
executeLifecycleState(transaction);
}
ClientTransaction存在兩種事務(wù),
- 一種是通過setLifecycleStateRequest設(shè)置一個對象的事務(wù)類型泌神,用于表示事務(wù)執(zhí)行以后良漱,客戶端應(yīng)該處于的生命周期狀態(tài)
- 一種是addCallback,增加對客戶端的事務(wù)類型回調(diào)欢际,對客戶端一系列的回調(diào)母市。
這兩個不同的類型,在這里就會存在不同的處理方法损趋。對于第一種會在executeCallbacks中進行處理窒篱,第二種則會在executeLifecycleState中進行處理。
我們這兒的暫停,是通過第二種來進行設(shè)置的墙杯,所以我們直接看executeLifecycleState這個方法配并。
//TransactionExecutor.java
//如果事務(wù)請求,則轉(zhuǎn)換到最終狀態(tài)
private void executeLifecycleState(ClientTransaction transaction) {
// ActivityStackSupervisor.java中進行了這個設(shè)置
// final ActivityLifecycleItem lifecycleItem;
// if (andResume) {
// lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
// } else {
// lifecycleItem = PauseActivityItem.obtain();
// }
// clientTransaction.setLifecycleStateRequest(lifecycleItem);
//所以這里的lifecycleItem可能是ResumeActivityItem或者PauseActivityItem或者其他的生命周期相關(guān)類
final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
if (lifecycleItem == null) {
//如果不是通過setLifecycleStateRequest設(shè)置的高镐,那么該方法不需要處理溉旋,直接返回即可
return;
}
//使用適當?shù)膮?shù)執(zhí)行最后的轉(zhuǎn)換
lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
}
我們這里的lifecycleItem是我們剛才創(chuàng)建的PauseActivityItem,這里會執(zhí)行其execute方法嫉髓。
//PauseActivityItem.java
@Override
public void execute(ClientTransactionHandler client, IBinder token, PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
//這里的client观腊,是Activity獨享
client.handlePauseActivity(token, mFinished, mUserLeaving, mConfigChanges, pendingActions,"PAUSE_ACTIVITY_ITEM");
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
這里的client對象我們需要回退去跟蹤一下
//ActivityThread.java
private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this);
//TransactionExecutor.java
//在ActivityThread類中中調(diào)用了mTransactionExecutor = new TransactionExecutor(this)這個方法,其中的mTransactionHandler是ActivityThread本身
public TransactionExecutor(ClientTransactionHandler clientTransactionHandler) {
mTransactionHandler = clientTransactionHandler;
}
所以說算行,最終調(diào)用的是ActivityThread的handlePauseActivity方法
//ActivityThread.java
public void handlePauseActivity(IBinder token, boolean finished, boolean userLeaving,int configChanges, PendingTransactionActions pendingActions, String reason) {
//獲取對應(yīng)的ActivityClientRecord對象
ActivityClientRecord r = mActivities.get(token);
if (r != null) {
...
//***重點方法***梧油,執(zhí)行pause方法
performPauseActivity(r, finished, reason, pendingActions);
...
}
}
private Bundle performPauseActivity(ActivityClientRecord r, boolean finished, String reason,
PendingTransactionActions pendingActions) {
...
//****重點方法****
performPauseActivityIfNeeded(r, reason);
...
return shouldSaveState ? r.state : null;
}
private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
...
r.activity.mCalled = false;
//重點方法,通過Instrumentation調(diào)用onPause生命周期
mInstrumentation.callActivityOnPause(r.activity);
...
}
最終會通過Instrumentation調(diào)用callActivityOnPause方法州邢。
//Instrumentation.java
public void callActivityOnPause(Activity activity) {
activity.performPause();
}
//Activity.java
final void performPause() {
dispatchActivityPrePaused();
mDoReportFullyDrawn = false;
//管理的Fragment的處理
mFragments.dispatchPause();
mCalled = false;
//調(diào)用了onPause生命周期方法
onPause();
writeEventLog(LOG_AM_ON_PAUSE_CALLED, "performPause");
//設(shè)置mResumed為false儡陨,表示當前activity沒有展示
mResumed = false;
//調(diào)用一些回調(diào)函數(shù)
dispatchActivityPostPaused();
}
到這里為止,原來在我們面前展示的那個Activity調(diào)用了其onPause方法量淌。
Activity的創(chuàng)建過程
回到主線的resumeTopActivityInnerLocked方法中骗村,當執(zhí)行完startPausingLocked方法后,會調(diào)用mStackSupervisor.startSpecificActivityLocked方法
//ActivityStackSupervisor.java
void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
//根據(jù)uid和pid呀枢,獲取activity對應(yīng)的進行和線程信息
final WindowProcessController wpc =mService.getProcessController(r.processName, r.info.applicationInfo.uid);
boolean knownToBeDead = false;
if (wpc != null && wpc.hasThread()) {
//如果進程和線程都存在胚股,執(zhí)行后面的代碼
try {
realStartActivityLocked(r, wpc, andResume, checkConfig);
return;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting activity "
+ r.intent.getComponent().flattenToShortString(), e);
}
knownToBeDead = true;
}
//通過message進行進程的啟動。
final Message msg = PooledLambda.obtainMessage(
ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());
mService.mH.sendMessage(msg);
} finally {
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
}
如果要啟動的activity所在的進程和線程都存在裙秋,那么直接調(diào)用realStartActivityLocked方法進行啟動琅拌,否則的話,就會調(diào)用Handler機制進行進程的創(chuàng)建摘刑。
realStartActivityLocked
//真正執(zhí)行Activity啟動的方法
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc, boolean andResume, boolean checkConfig) throws RemoteException {
//如果還有activity沒有暫停进宝,這里會直接返回false
if (!mRootActivityContainer.allPausedActivitiesComplete()) {
return false;
}
final TaskRecord task = r.getTaskRecord();
final ActivityStack stack = task.getStack();
//設(shè)置標志位,不再接收其他activity的resume的操作
beginDeferResume();
try {
...
//創(chuàng)建了一個Activity事務(wù)
final ClientTransaction clientTransaction = ClientTransaction.obtain(proc.getThread(), r.appToken);
final DisplayContent dc = r.getDisplay().mDisplayContent;
//增加一個要執(zhí)行的事務(wù)LaunchActivityItem泣侮。
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
System.identityHashCode(r), r.info,
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;
//設(shè)置其生命周期LifecycleStateRequest
if (andResume) {
lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
} else {
lifecycleItem = PauseActivityItem.obtain();
}
clientTransaction.setLifecycleStateRequest(lifecycleItem);
//執(zhí)行事務(wù)的調(diào)度
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
...
proc.onStartActivity(mService.mTopProcessState, r.info);
return true;
}
在這個方法里面即彪,創(chuàng)建了一個事務(wù)紧唱,在事務(wù)中增加了一個callback回調(diào)活尊,然后通過setLifecycleStateRequest設(shè)置了一個生命周期,最后通過scheduleTransaction執(zhí)行了調(diào)度漏益。在前面的onPause中蛹锰,我們梳理了整個調(diào)度的流程,最后會調(diào)用到LaunchActivityItem的execute绰疤,然后會調(diào)用生命周期所對應(yīng)的ResumeActivityItem的execute铜犬。
我們挨個看,先看LaunchActivityItem的調(diào)用
//LaunchActivityItem.java
//一般會在TransactionExecutor中調(diào)用這個方法
//ClientTransactionHandler實際是ActivityThread對象,所以這里會執(zhí)行activitythread類中的handleLaunchActivity方法
@Override
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
mPendingResults, mPendingNewIntents, mIsForward,
mProfilerInfo, client, mAssistToken);
//調(diào)用activitythread類中的handleLaunchActivity方法
client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
其本質(zhì)調(diào)用的是ActivityThread中的handleLaunchActivity方法癣猾。
這部分的功能敛劝,我們在Android布局窗口繪制分析中進行過解析。這里不再往下進行解析了纷宇。
我們直接跳過這部分夸盟,來看看如果啟動的activity所在的進程和線程都存在。會進行進程的創(chuàng)建工作像捶。這部分我們后面專門再進行一篇關(guān)于進程創(chuàng)建的解析工作上陕。
本文由 開了肯 發(fā)布!
同步公眾號[開了肯]