首頁>技術>

前言

這是 Android 9.0 AOSP 系列 的第五篇了,先來回顧一下前面幾篇的大致內容。

Java 世界的盤古和女媧 —— Zygote

主要介紹了 Android 世界的第一個 Java 程序 Zygote 的啟動過程。

註冊服務端 socket,用於響應客戶端請求各種預載入操作,類,資源,共享庫等強制 GC 一次fork SystemServer 程序迴圈等待客戶端發來的 socket 請求(請求 socket 連線和請求 fork 應用程序)

Zygote家的大兒子 —— SystemServer

主要介紹了 Zygote 程序 fork 的第一個程序 SystemServer,它承載了各類系統服務的建立和啟動。

語言、時區、地區等設定虛擬機器記憶體設定指紋資訊,Binder 呼叫設定Looper.prepareMainLooper() ,建立主執行緒 Looper初始化 native 服務,載入 libandroid_servers.socreateSystemContext(),初始化系統上下文建立系統服務管理者 SystemServiceManagerstartBootstrapServices,啟動系統引導服務startCoreServices,啟動系統核心服務startOtherServices,啟動其他服務Looper.loop(),開啟訊息迴圈

在 startOtherServices 的最後會呼叫 AMS 的 onSystemReady() 方法啟動桌面 Activity。

Android 世界中,誰喊醒了 Zygote ?

主要介紹了 AMS 向 Zygote 請求建立應用程序的過程,即向 Zygote 程序進行 socket 通訊,與第一篇呼應。

呼叫 Process.start() 建立應用程序ZygoteProcess 負責和 Zygote 程序建立 socket 連線,並將建立程序需要的引數傳送給 Zygote 的 socket 服務端Zygote 服務端接收到引數之後呼叫 ZygoteConnection.processOneCommand() 處理引數,並 fork 程序最後通過 findStaticMain() 找到 ActivityThread 類的 main() 方法並執行,子程序就啟動了

“無處不在” 的系統核心服務 —— ActivityManagerService 啟動流程解析

主要介紹了 ActivityManagerService (AMS) 的啟動流程,它與四大元件的啟動,切換,排程以及應用程序的管理息息相關。

AMS 初始化,通過 ActivityManagerService.Lifecycle 的建構函式中初始化setSystemProcess(),註冊各種服務,建立 ProcessRecord,更新 oom_adj 值安裝系統 ProvidersystemReady(),最終會啟動桌面 Home Activity

今天要介紹的就是 Activity 的啟動流程了。Activity 的啟動是個大工程,細節十分之多。這篇文章會簡單梳理整個啟動流程,不會過度深入原始碼細節。對其中的關鍵問題,如 launchMode 的處理,生命週期的處理,後續會通過單獨的文章深入剖析。

啟動流程分析

先來一張流程圖,對照著看更方便理解。

接著之前的分析,ActivityManagerService 的 systemReady() 方法中最後會去啟動桌面 Hme Activity,呼叫的方法是 startHomeActivityLocked 。

> ActivityManagerService.javaboolean startHomeActivityLocked(int userId, String reason) { ...... Intent intent = getHomeIntent(); ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); if (aInfo != null) { ...... if (app == null || app.instr == null) { intent.setFlags(intent.getFlags() | FLAG_ACTIVITY_NEW_TASK); final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid); final String myReason = reason + ":" + userId + ":" + resolvedUserId; // 啟動桌面 Activity mActivityStartController.startHomeActivity(intent, aInfo, myReason); } } else { Slog.wtf(TAG, "No home screen found for " + intent, new Throwable()); } return true;}

呼叫 ActivityStartController 的 startHomeActivity() 方法:

> ActivityStartController.javavoid startHomeActivity(Intent intent, ActivityInfo aInfo, String reason) { mSupervisor.moveHomeStackTaskToTop(reason); mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason) .setOutActivity(tmpOutRecord) .setCallingUid(0) .setActivityInfo(aInfo) .execute(); mLastHomeActivityStartRecord = tmpOutRecord[0]; if (mSupervisor.inResumeTopActivity) { mSupervisor.scheduleResumeTopActivities(); } }

obtainStarter() 方法返回的是 ActivityStarter 物件,它負責 Activity 的啟動,一系列 setXXX() 方法傳入啟動所需的各種引數,最後的 execute() 是真正的啟動邏輯。

在繼續看原始碼之前,先思考一下現在處於哪個程序?AMS 是在 system_server 程序中初始化的,所以上面的工作都是在 system_server 程序發生的。而我們通常在開發過程中使用的 startActivity() 方法顯然是在應用程序呼叫的。那麼,普通的 startActivity() 方法又是怎麼樣的呼叫鏈呢?跟進 Activity.startActivity() 方法來看一下。

> Activity.java @Override public void startActivity(Intent intent, @Nullable Bundle options) { if (options != null) { startActivityForResult(intent, -1, options); } else { startActivityForResult(intent, -1); } } public void startActivityForResult(@RequiresPermission Intent intent, int requestCode, @Nullable Bundle options) { if (mParent == null) { options = transferSpringboardActivityOptions(options); // 呼叫 Instrumentation.execStartActivity() 方法 Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity( this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode, options); if (ar != null) { // 回撥 ActivityResult mMainThread.sendActivityResult( mToken, mEmbeddedID, requestCode, ar.getResultCode(), ar.getResultData()); } if (requestCode >= 0) { mStartedActivity = true; } cancelInputsAndStartExitTransition(options); } else { // 最終也是呼叫 Instrumentation.execStartActivity() 方法 if (options != null) { mParent.startActivityFromChild(this, intent, requestCode, options); } else { mParent.startActivityFromChild(this, intent, requestCode); } } }

最終都會呼叫 Instrumentation 的 execStartActivity() 方法。Instrumentation 是個非常重要的類,Activity 的啟動,生命週期的回撥都離不開它。後面會多次遇到這個類。

> Instrumentation.javapublic ActivityResult execStartActivity( Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options) { IApplicationThread whoThread = (IApplicationThread) contextThread; ...... try { intent.migrateExtraStreamToClipData(); intent.prepareToLeaveProcess(who); // Binder 呼叫 AMS 來啟動 Activity 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; }

這裡通過 Binder 呼叫 AMS 的 startActivity() 方法。ActivityManager.getService() 不用多想肯定是獲取 AMS 代理物件的。

> ActivityManager.javapublic 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; } };

接著就進入到 AMS 的 startActivity() 方法。

> 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) {setMayWait return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions, UserHandle.getCallingUserId()); } 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, boolean validateIncomingUser) { enforceNotIsolatedCaller("startActivity"); userId = mActivityStartController.checkTargetUser(userId, validateIncomingUser, Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser"); // TODO: Switch to user app stacks here. return mActivityStartController.obtainStarter(intent, "startActivityAsUser") // 獲取 ActivityStarter 物件 .setCaller(caller) .setCallingPackage(callingPackage) .setResolvedType(resolvedType) .setResultTo(resultTo) .setResultWho(resultWho) .setRequestCode(requestCode) .setStartFlags(startFlags) .setProfilerInfo(profilerInfo) .setActivityOptions(bOptions) .setMayWait(userId) .execute(); }

接下來和之前啟動 Home Activity 比較相似了。獲取 ActivityStarter 物件,提供引數,最後 execute() 。

obtainStarter() 通過工廠模式獲取 ActivityStarter 物件。

 ActivityStarter obtainStarter(Intent intent, String reason) { return mFactory.obtain().setIntent(intent).setReason(reason); }

mFactory 的預設實現是 ActivityStarter.DefaultFactory 。

> ActivityStarter.java static class DefaultFactory implements Factory { /** * The maximum count of starters that should be active at one time: * 1. last ran starter (for logging and post activity processing) * 2. current running starter * 3. starter from re-entry in (2) * * 同時啟用的 starter 最多隻能有三個。 */ private final int MAX_STARTER_COUNT = 3; private ActivityStartController mController; private ActivityManagerService mService; private ActivityStackSupervisor mSupervisor; private ActivityStartInterceptor mInterceptor; private SynchronizedPool<ActivityStarter> mStarterPool = new SynchronizedPool<>(MAX_STARTER_COUNT); DefaultFactory(ActivityManagerService service, ActivityStackSupervisor supervisor, ActivityStartInterceptor interceptor) { mService = service; mSupervisor = supervisor; mInterceptor = interceptor; } @Override public void setController(ActivityStartController controller) { mController = controller; } @Override public ActivityStarter obtain() { // 從同步物件池 SynchronizedPool 中獲取 ActivityStarter starter = mStarterPool.acquire(); if (starter == null) { starter = new ActivityStarter(mController, mService, mSupervisor, mInterceptor); } return starter; } @Override public void recycle(ActivityStarter starter) { starter.reset(true /* clearRequest*/); mStarterPool.release(starter); } }

提供了一個容量為 3 的同步物件快取池來快取 ActivityStarter 物件。setXXX() 方法均為引數配置,注意 setMayWait 方法會將 mayWait 引數置為 true。我們直接看它的實際執行過程,execute() 函式。

> ActivityStarter.java int execute() { try { if (mRequest.mayWait) { // setMayWait() 方法中將 mayWait 置為 true return startActivityMayWait(mRequest.caller, mRequest.callingUid, mRequest.callingPackage, 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); } 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); } } finally { // 回收當前 ActivityStarter 物件 onExecutionComplete(); } }

接著呼叫 startActivityMayWait() 。

> ActivityStarter.javaprivate 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, SafeActivityOptions options, boolean ignoreTargetSecurity, int userId, TaskRecord inTask, String reason, boolean allowPendingRemoteAnimationRegistryLookup, PendingIntentRecord originatingPendingIntent) { ..... // Save a copy in case ephemeral needs it final Intent ephemeralIntent = new Intent(intent); // Don't modify the client's object! // 重新建立,不修改客戶端原來的 intent intent = new Intent(intent); if (componentSpecified && !(Intent.ACTION_VIEW.equals(intent.getAction()) && intent.getData() == null) && !Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE.equals(intent.getAction()) && !Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE.equals(intent.getAction()) && mService.getPackageManagerInternalLocked() .isInstantAppInstallerComponent(intent.getComponent())) { intent.setComponent(null /*component*/); componentSpecified = false; } // 獲取 ResolveInfo ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId, 0 /* matchFlags */, computeResolveFilterUid( callingUid, realCallingUid, mRequest.filterCallingUid)); ...... // Collect information about the target of the Intent. // 獲取目標 Intent 的 ActivityInfo ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo); synchronized (mService) { final ActivityStack stack = mSupervisor.mFocusedStack; stack.mConfigWillChange = globalConfig != null && mService.getGlobalConfiguration().diff(globalConfig) != 0; ...... final ActivityRecord[] outRecord = new ActivityRecord[1]; // 呼叫 startActivity() 方法 int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason, allowPendingRemoteAnimationRegistryLookup, originatingPendingIntent); Binder.restoreCallingIdentity(origId); ...... if (outResult != null) { // 設定啟動結果 outResult.result = res; final ActivityRecord r = outRecord[0]; switch(res) { case START_SUCCESS: { mSupervisor.mWaitingActivityLaunched.add(outResult); do { try { // 等待啟動結果 mService.wait(); } catch (InterruptedException e) { } } while (outResult.result != START_TASK_TO_FRONT && !outResult.timeout && outResult.who == null); if (outResult.result == START_TASK_TO_FRONT) { res = START_TASK_TO_FRONT; } break; } ...... break; } } } return res; } }

調動 startActivity() 方法來啟動 Activity,它有兩個過載方法被依次呼叫。這裡會等待啟動結果。

> 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, SafeActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity, TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup, PendingIntentRecord originatingPendingIntent) { int err = ActivityManager.START_SUCCESS; ProcessRecord callerApp = null; if (caller != null) { // caller 不為空時,通過 AMS 查詢 ProcessRecord callerApp = mService.getRecordForAppLocked(caller); if (callerApp != null) { callingPid = callerApp.pid; callingUid = callerApp.info.uid; } else { err = ActivityManager.START_PERMISSION_DENIED; } } // sourceRecord 用於描述發起本次請求的 Activity // resultRecord 使用者描述接收啟動結果的 Activity // 一般情況下,這兩個 Activity 應該是同一個 ActivityRecord sourceRecord = null; ActivityRecord resultRecord = null; ...... // 獲取啟動標誌 final int launchFlags = intent.getFlags(); ...... if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) { // 未找到可以處理該 intent 的類 err = ActivityManager.START_INTENT_NOT_RESOLVED; } if (err == ActivityManager.START_SUCCESS && aInfo == null) { // 沒有找到 intent 中指定的 Activity 類 err = ActivityManager.START_CLASS_NOT_FOUND; } ...... // 許可權檢查 boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho, requestCode, callingPid, callingUid, callingPackage, ignoreTargetSecurity, inTask != null, callerApp, resultRecord, resultStack); abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid, callingPid, resolvedType, aInfo.applicationInfo); ...... // 構建 ActivityRecord ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid, callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(), resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null, mSupervisor, checkedOptions, sourceRecord); ...... // 獲取當前獲取焦點的 ActivityStack final ActivityStack stack = mSupervisor.mFocusedStack; // 如果啟動一個和當前處於 resume 狀態的 activity 不同 uid 的新 activity,要檢查是否允許 app 切換 if (voiceSession == null && (stack.getResumedActivity() == null || stack.getResumedActivity().info.applicationInfo.uid != realCallingUid)) { if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, realCallingPid, realCallingUid, "Activity start")) { mController.addPendingActivityLaunch(new PendingActivityLaunch(r, sourceRecord, startFlags, stack, callerApp)); ActivityOptions.abort(checkedOptions); // 不允許切換,直接返回 return ActivityManager.START_SWITCHES_CANCELED; } } ...... // 呼叫過載方法 return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask, outActivity); }
> 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(); // 呼叫 startActivityUnchecked() 方法 result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor, startFlags, doResume, options, inTask, outActivity); } finally { final ActivityStack stack = mStartActivity.getStack(); if (!ActivityManager.isStartResultSuccessful(result) && stack != null) { stack.finishActivityLocked(mStartActivity, RESULT_CANCELED, null /* intentResultData */, "startActivity", true /* oomAdj */); } // 恢復佈局 mService.mWindowManager.continueSurfaceLayout(); } postStartActivityProcessing(r, result, mTargetStack); return result; }

接著呼叫 startActivityUnchecked() 。

> ActivityStarter.java private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask, ActivityRecord[] outActivity) { // 設定啟動 Activity 的初始狀態,包括 flag setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession, voiceInteractor); // 計算 mLaunchFlags ,啟動標誌位 computeLaunchingTaskFlags(); // 計算 mSourceStack computeSourceStack(); // 設定啟動標誌位 mIntent.setFlags(mLaunchFlags); // 查詢可複用的 Activity ActivityRecord reusedActivity = getReusableIntentActivity(); ...... // 不等於 null 說明新的 activity 應該插入已存在的任務棧中 if (reusedActivity != null) { if (mService.getLockTaskController().isLockTaskModeViolation(reusedActivity.getTask(), (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))) { Slog.e(TAG, "startActivityUnchecked: Attempt to violate Lock Task Mode"); return START_RETURN_LOCK_TASK_MODE_VIOLATION; } final boolean clearTopAndResetStandardLaunchMode = (mLaunchFlags & (FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED)) == (FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) && mLaunchMode == LAUNCH_MULTIPLE; if (mStartActivity.getTask() == null && !clearTopAndResetStandardLaunchMode) { mStartActivity.setTask(reusedActivity.getTask()); } if (reusedActivity.getTask().intent == null) { reusedActivity.getTask().setIntent(mStartActivity); } if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0 || isDocumentLaunchesIntoExisting(mLaunchFlags) || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) { final TaskRecord task = reusedActivity.getTask(); // 清空任務棧 final ActivityRecord top = task.performClearTaskForReuseLocked(mStartActivity, mLaunchFlags); if (reusedActivity.getTask() == null) { reusedActivity.setTask(task); } if (top != null) { if (top.frontOfTask) { top.getTask().setIntent(mStartActivity); } // 觸發 onNewIntent() deliverNewIntent(top); } } ...... // 是否建立新的 task boolean newTask = false; final TaskRecord taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null) ? mSourceRecord.getTask() : null; ...... // 將要啟動的 Activity 在 Task 中置頂 mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition, mOptions); if (mDoResume) { final ActivityRecord topTaskActivity = mStartActivity.getTask().topRunningActivityLocked(); if (!mTargetStack.isFocusable() || (topTaskActivity != null && topTaskActivity.mTaskOverlay && mStartActivity != topTaskActivity)) { mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); mService.mWindowManager.executeAppTransition(); } else { if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) { mTargetStack.moveToFront("startActivityUnchecked"); } // 呼叫 ActivityStackSupervisor.resumeFocusedStackTopActivityLocked() 方法 mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity, mOptions); } } else if (mStartActivity != null) { mSupervisor.mRecentTasks.add(mStartActivity.getTask()); } mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack); mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTask(), preferredWindowingMode, preferredLaunchDisplayId, mTargetStack); return START_SUCCESS; }

startActivityUnchecked() 方法主要除了處理了啟動標記 flag ,要啟動的任務棧等。這一塊原始碼很長,上面作了大量刪減,僅保留了基本的呼叫鏈。感興趣的同學可以自行檢視原始檔。接下來 呼叫了ActivityStackSupervisor 的 resumeFocusedStackTopActivityLocked()方法。

> ActivityStackSupervisor.java boolean resumeFocusedStackTopActivityLocked( ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) { if (!readyToResume()) { return false; } // 目標 Stack 就是 mFocusedStack if (targetStack != null && isFocusedStack(targetStack)) { return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions); } // 獲取 mFocusedStack 棧頂的 ActivityRecord final ActivityRecord r = mFocusedStack.topRunningActivityLocked(); if (r == null || !r.isState(RESUMED)) { mFocusedStack.resumeTopActivityUncheckedLocked(null, null); } else if (r.isState(RESUMED)) { // Kick off any lingering app transitions form the MoveTaskToFront operation. mFocusedStack.executeAppTransition(targetOptions); } return false; }

獲取待啟動 Activity 的 ActivityStack 之後並呼叫其 resumeTopActivityUncheckedLocked() 方法。

> ActivityStack.javaboolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) { if (mStackSupervisor.inResumeTopActivity) { // 防止遞迴啟動 return false; } boolean result = false; try { mStackSupervisor.inResumeTopActivity = true; // 執行 resumeTopActivityInnerLocked() 方法) result = resumeTopActivityInnerLocked(prev, options); final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */); if (next == null || !next.canTurnScreenOn()) { checkReadyForSleep(); } } finally { mStackSupervisor.inResumeTopActivity = false; } return result; }
> ActivityStack.javaprivate boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) { if (!mService.mBooting && !mService.mBooted) { // AMS 還未啟動完成 return false; } ...... if (!hasRunningActivity) { // 當前 Stack 沒有 activity,就去找下一個 stack。可能會啟動 Home 應用 return resumeTopActivityInNextFocusableStack(prev, options, "noMoreActivities"); } // next 就是目標 Activity,將其從下面幾個佇列移除 mStackSupervisor.mStoppingActivities.remove(next); mStackSupervisor.mGoingToSleepActivities.remove(next); next.sleeping = false; mStackSupervisor.mActivitiesWaitingForVisibleActivity.remove(next); ...... // mResumedActivity 指當前 Activity if (mResumedActivity != null) { // 當有其他 Activity 正處於 onResume(),先暫停它 pausing |= startPausingLocked(userLeaving, false, next, false); } ...... ActivityStack lastStack = mStackSupervisor.getLastStack(); if (next.app != null && next.app.thread != null) { ...... synchronized(mWindowManager.getWindowManagerLock()) { // This activity is now becoming visible. if (!next.visible || next.stopped || lastActivityTranslucent) { next.setVisibility(true); } ...... try { final ClientTransaction transaction = ClientTransaction.obtain(next.app.thread, next.appToken); // Deliver all pending results. ArrayList<ResultInfo> a = next.results; if (a != null) { final int N = a.size(); if (!next.finishing && N > 0) { if (DEBUG_RESULTS) Slog.v(TAG_RESULTS, "Delivering results to " + next + ": " + a); transaction.addCallback(ActivityResultItem.obtain(a)); } } if (next.newIntents != null) { transaction.addCallback(NewIntentItem.obtain(next.newIntents, false /* andPause */)); } next.sleeping = false; mService.getAppWarningsLocked().onResumeActivity(next); mService.showAskCompatModeDialogLocked(next); next.app.pendingUiClean = true; next.app.forceProcessStateUpTo(mService.mTopProcessState); next.clearOptionsLocked(); transaction.setLifecycleStateRequest( ResumeActivityItem.obtain(next.app.repProcState, mService.isNextTransitionForward())); mService.getLifecycleManager().scheduleTransaction(transaction); } catch (Exception e) { next.setState(lastState, "resumeTopActivityInnerLocked"); // lastResumedActivity being non-null implies there is a lastStack present. if (lastResumedActivity != null) { lastResumedActivity.setState(RESUMED, "resumeTopActivityInnerLocked"); } Slog.i(TAG, "Restarting because process died: " + next); if (!next.hasBeenLaunched) { next.hasBeenLaunched = true; } else if (SHOW_APP_STARTING_PREVIEW && lastStack != null && lastStack.isTopStackOnDisplay()) { next.showStartingWindow(null /* prev */, false /* newTask */, false /* taskSwitch */); } // 呼叫 startSpecificActivityLocked() mStackSupervisor.startSpecificActivityLocked(next, true, false); if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked(); return true; } } // From this point on, if something goes wrong there is no way // to recover the activity. try { next.completeResumeLocked(); } catch (Exception e) { ...... } } else { ...... // 呼叫 startSpecificActivityLocked() mStackSupervisor.startSpecificActivityLocked(next, true, true); } if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked(); return true;}

上面省略了 resumeTopActivityInnerLocked() 方法中的絕大部分程式碼,原始碼大概有四百多行。其中需要注意的是 startPausingLocked() 和 startSpecificActivityLocked() 方法。

在啟動 Activity 之前,如果當前 Activity 正處於 onResume 狀態,那麼需要先暫停它,即呼叫它的 onPause。這就是 startPausingLocked() 方法的職責。這裡先不具體分析,後面會單獨寫一篇文章說明 Activity 的宣告週期呼叫。另外多說一句,先要執行當前 Activity 的 onPause 然後才會啟動目標 Activity ,所以我們不能在 onPause 中執行耗時任務,會造成切換 Activity 時卡頓。

另一個方法 startSpecificActivityLocked() 就是啟動指定 Activity 了,我們繼續跟下去。

> ActivityStackSupervisor.java void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) { // 通過 AMS 查詢程序是否已存在 ProcessRecord app = mService.getProcessRecordLocked(r.processName, r.info.applicationInfo.uid, true); // 應用程序已經存在並且已經繫結 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.longVersionCode, mService.mProcessStats); } // 應用程序已存在時呼叫 realStartActivityLocked() realStartActivityLocked(r, app, andResume, checkConfig); return; } catch (RemoteException e) { Slog.w(TAG, "Exception when starting activity " + r.intent.getComponent().flattenToShortString(), e); } // If a dead object exception was thrown -- fall through to // restart the application. } // 應用程序不存在則建立程序 mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0, "activity", r.intent.getComponent(), false, false, true); }

首先通過 AMS 查詢應用程序是否已經存在,如果已經存在並且 attach ,則呼叫 realStartActivityLocked() 直接啟動目標 Activity 。如果應用程序不存在,則先建立應用程序。

在 Android 世界中,誰喊醒了 Zygote ? 已經介紹過了應用程序的建立過程。這裡再簡單說一下,Zygote 程序啟動時開啟了 LocalSocket 服務端,等待客戶端請求。AMS 作為 socket 客戶端向 Zygote 發出請求,Zygote 收到請求之後 fork 出子程序。

今天看到一個很有意思的提問,Android 中的 IPC 通訊大多通過 Binder 機制實現,為什麼 Zygote 通過 socket 跨程序通訊? 說實話,我也不知道,歡迎大家留下你的看法。

接著就是 realStartActivityLocked() ,如其名字一樣,真正的要啟動 Activity 了。

> ActivityStackSupervisor.java final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig) throws RemoteException { if (!allPausedActivitiesComplete()) { // 直到所有的 onPause() 執行結束才會去啟動新的 activity return false; } final TaskRecord task = r.getTask(); final ActivityStack stack = task.getStack(); beginDeferResume(); try { ...... // 更新程序 oom-adj 值 mService.updateLruProcessLocked(app, true, null); mService.updateOomAdjLocked(); try { ...... // 新增 LaunchActivityItem final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread, r.appToken); 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)); // 設定生命週期狀態 final ActivityLifecycleItem lifecycleItem; if (andResume) { lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward()); } else { lifecycleItem = PauseActivityItem.obtain(); } clientTransaction.setLifecycleStateRequest(lifecycleItem); // 重點 // // 呼叫 ClientLifecycleManager.scheduleTransaction() mService.getLifecycleManager().scheduleTransaction(clientTransaction); ...... } catch (RemoteException e) { if (r.launchFailed) { // 第二次啟動失敗,finish activity mService.appDiedLocked(app); stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null, "2nd-crash", false); return false; } // 第一次失敗,重啟程序並重試 r.launchFailed = true; app.activities.remove(r); throw e; } } finally { endDeferResume(); } r.launchFailed = false; ...... return true; }

上面的重點是這句程式碼,mService.getLifecycleManager().scheduleTransaction(clientTransaction); 。

這裡又用到了 ClientTransaction 。還記得上面提到的暫停 Activity 嗎 ,也是通過這個類來實現的。本來準備寫到生命週期的單獨文章再分析,看來還是逃不過。這裡穿插著說一下 ClientTransaction 。

首先 mService.getLifecycleManager() 返回的是 ClientLifecycleManager 物件,這是在 Android 9.0 中新增的類。我們看一下它的 scheduleTransaction() 方法。

> ClientLifecycleManager.javavoid scheduleTransaction(ClientTransaction transaction) throws RemoteException { final IApplicationThread client = transaction.getClient(); // -> ApplicationThread transaction.schedule(); // ClientTransaction if (!(client instanceof Binder)) { transaction.recycle(); }}

跟進 schedule() 方法。

> ClientTransaction.javapublic void schedule() throws RemoteException { mClient.scheduleTransaction(this);}

這裡的 mClient 是 IApplicationThread 型別,它是 ApplicationThread的 Binder 代理物件,所以這裡會跨程序呼叫到 ApplicationThread.scheduleTransaction()方法 。 ApplicationThread是 ActivityThread 的內部類,但不論是 ApplicationThread 還是 ActivityThread 其實都沒有 scheduleTransaction() 方法,所以呼叫的是其父類 ClientTransactionHandler 的方法。

> ClientTransactionHandler.javapublic abstract class ClientTransactionHandler { /** Prepare and schedule transaction for execution. */ void scheduleTransaction(ClientTransaction transaction) { transaction.preExecute(this); // sendMessage() 方法在 ActivityThread類中實現 sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction); } }

在回到 ActivityThread 類中看一下 sendMessage() 方法。

> ActivityThread.javaprivate void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) { Message msg = Message.obtain(); msg.what = what; msg.obj = obj; msg.arg1 = arg1; msg.arg2 = arg2; if (async) { msg.setAsynchronous(true); } mH.sendMessage(msg);}

這裡向 mH 傳送了 EXECUTE_TRANSACTION 訊息,並攜帶了 transaction 。mH 是一個 叫做 H 的 Handler 類。它負責主執行緒訊息處理,定義了大概五十多種事件。查詢一下它是如何處理 EXECUTE_TRANSACTION 訊息的。

> ActivityThread.javacase EXECUTE_TRANSACTION: final ClientTransaction transaction = (ClientTransaction) msg.obj; // 執行 TransactionExecutor.execute() mTransactionExecutor.execute(transaction); if (isSystem()) { transaction.recycle(); }

呼叫了 TransactionExecutor 的 execute() 方法。

> TransactionExecutor.java`public void execute(ClientTransaction transaction) { final IBinder token = transaction.getActivityToken(); log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token); // 執行 callBack executeCallbacks(transaction); // 執行生命週期狀態 executeLifecycleState(transaction); mPendingActions.clear(); log("End resolving transaction");}

先來看看 executeCallbacks() 方法。

> TransactionExecutor.java@VisibleForTestingpublic void executeCallbacks(ClientTransaction transaction) { ...... final int size = callbacks.size(); for (int i = 0; i < size; ++i) { final ClientTransactionItem item = callbacks.get(i); ...... item.execute(mTransactionHandler, token, mPendingActions); item.postExecute(mTransactionHandler, token, mPendingActions); ....}

核心程式碼就這些。執行傳入的 callback 的 execute() 方法和 postExecute() 方法。還記得之前 realStartActivityLocked() 方法中呼叫 addCallback() 傳入的引數嗎?

clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent), ......);

也就是說會執行 LaunchActivityItem 的 execute() 方法。

> LaunchActivityItem.java@Overridepublic 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); // 呼叫 ActivityThread.handleLaunchActivity() client.handleLaunchActivity(r, pendingActions, null /* customIntent */); Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);}

兜兜轉轉,再次回到 ActivityThread ,執行其 handleLaunchActivity()方法。

> ActivityThread.java@Overridepublic Activity handleLaunchActivity(ActivityClientRecord r, PendingTransactionActions pendingActions, Intent customIntent) { ...... final Activity a = performLaunchActivity(r, customIntent); ...... return a;}
> ActivityThread.javaprivate Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { ActivityInfo aInfo = r.activityInfo; if (r.packageInfo == null) { r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo, Context.CONTEXT_INCLUDE_CODE); } // 獲取 ComponentName ComponentName component = r.intent.getComponent(); if (component == null) { component = r.intent.resolveActivity( mInitialApplication.getPackageManager()); r.intent.setComponent(component); } if (r.activityInfo.targetActivity != null) { component = new ComponentName(r.activityInfo.packageName, r.activityInfo.targetActivity); } // 獲取 Context ContextImpl appContext = createBaseContextForActivity(r); Activity activity = null; try { java.lang.ClassLoader cl = appContext.getClassLoader(); // 反射建立 Activity activity = mInstrumentation.newActivity( cl, component.getClassName(), r.intent); StrictMode.incrementExpectedActivityCount(activity.getClass()); r.intent.setExtrasClassLoader(cl); r.intent.prepareToEnterProcess(); if (r.state != null) { r.state.setClassLoader(cl); } } catch (Exception e) { ...... } try { // 獲取 Application Application app = r.packageInfo.makeApplication(false, mInstrumentation); if (activity != null) { CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager()); Configuration config = new Configuration(mCompatConfiguration); if (r.overrideConfig != null) { config.updateFrom(r.overrideConfig); } Window window = null; if (r.mPendingRemoveWindow != null && r.mPreserveWindow) { window = r.mPendingRemoveWindow; r.mPendingRemoveWindow = null; r.mPendingRemoveWindowManager = null; } appContext.setOuterContext(activity); 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 (customIntent != null) { activity.mIntent = customIntent; } r.lastNonConfigurationInstances = null; checkAndBlockForNetworkAccess(); activity.mStartedActivity = false; int theme = r.activityInfo.getThemeResource(); if (theme != 0) { // 設定主題 activity.setTheme(theme); } activity.mCalled = false; // 執行 onCreate() if (r.isPersistable()) { mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState); } else { mInstrumentation.callActivityOnCreate(activity, r.state); } if (!activity.mCalled) { throw new SuperNotCalledException( "Activity " + r.intent.getComponent().toShortString() + " did not call through to super.onCreate()"); } r.activity = activity; } r.setState(ON_CREATE); mActivities.put(r.token, r); } catch (SuperNotCalledException e) { throw e; } catch (Exception e) { ...... } return activity; }

這裡又出現了 Instrumentation 的身影,分別呼叫了 newActivity() 方法和 callActivityOnCreate() 方法。

newActivity() 方法反射建立 Activity ,並呼叫其 attach() 方法。

> Instrumentation.javapublic Activity newActivity(Class<?> clazz, Context context, IBinder token, Application application, Intent intent, ActivityInfo info, CharSequence title, Activity parent, String id, Object lastNonConfigurationInstance) throws InstantiationException, IllegalAccessException { Activity activity = (Activity)clazz.newInstance(); ActivityThread aThread = null; // Activity.attach expects a non-null Application Object. if (application == null) { application = new Application(); } activity.attach(context, aThread, this, token, 0 /* ident */, application, intent, info, title, parent, id, (Activity.NonConfigurationInstances)lastNonConfigurationInstance, new Configuration(), null /* referrer */, null /* voiceInteractor */, null /* window */, null /* activityConfigCallback */); return activity;}

callActivityOnCreate() 方法呼叫 Activity.performCreate() 方法,最終回撥 onCreate() 方法。

> Instrumentation.javapublic void callActivityOnCreate(Activity activity, Bundle icicle) { prePerformCreate(activity); activity.performCreate(icicle); postPerformCreate(activity);}
> Activity.javafinal void performCreate(Bundle icicle) { performCreate(icicle, null);}final void performCreate(Bundle icicle, PersistableBundle persistentState) { mCanEnterPictureInPicture = true; restoreHasCurrentPermissionRequest(icicle); // 回撥 onCreate() if (persistentState != null) { onCreate(icicle, persistentState); } else { onCreate(icicle); } writeEventLog(LOG_AM_ON_CREATE_CALLED, "performCreate"); mActivityTransitionState.readState(icicle); mVisibleFromClient = !mWindow.getWindowStyle().getBoolean( com.android.internal.R.styleable.Window_windowNoDisplay, false); mFragments.dispatchActivityCreated(); mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());}

看到這裡,有一種如釋重負的感覺,終於執行到 onCreate() 方法了。其實 Activity 的每個生命週期回撥都是類似的呼叫鏈。

還記得是從哪個方法一路追蹤到 onCreate 的嗎?是TransactionExecutor 的 execute() 方法。

> TransactionExecutor.java`public void execute(ClientTransaction transaction) { final IBinder token = transaction.getActivityToken(); log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token); // 執行 callBack executeCallbacks(transaction); // 執行生命週期狀態 executeLifecycleState(transaction); mPendingActions.clear(); log("End resolving transaction");}

前面分析 executeCallBack() 一路追蹤到 onCreate() ,接下來就要分析 executeLifecycleState() 方法了。

> TransactionExecutor.javaprivate void executeLifecycleState(ClientTransaction transaction) { final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest(); if (lifecycleItem == null) { // No lifecycle request, return early. return; } final IBinder token = transaction.getActivityToken(); final ActivityClientRecord r = mTransactionHandler.getActivityClient(token); if (r == null) { // Ignore requests for non-existent client records for now. return; } // Cycle to the state right before the final requested state. cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */); // Execute the final transition with proper parameters. lifecycleItem.execute(mTransactionHandler, token, mPendingActions); lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions); }

很熟悉,又看到了 lifecycleItem.execute() 。這裡的 lifecycleItem 還是在 realStartActivityLocked() 方法中賦值的。

 lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());

但在分析 ResumeActivityItem 之前,注意一下 execute() 方法之前的 cycleToPath() 方法。具體原始碼就不去分析了,它的作用時根據上次最後執行到的生命週期狀態,和即將執行的生命週期狀態進行同步。說的不是那麼容易理解,舉個例子,上次已經回調了 onCreate() 方法,這次要執行的是 ResumeActivityItem ,中間還有一個 onStart() 狀態,那麼 cycleToPath() 方法就會去回撥 onStart() ,也就是呼叫 ActivityThread.handleStartActivity() 。和 handleLaunchActivity() 差不多的呼叫鏈。

那麼,再回到 ResumeActivityItem.execute() 。

> ResumeActivityItem.java@Overridepublic void execute(ClientTransactionHandler client, IBinder token, PendingTransactionActions pendingActions) { Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityResume"); client.handleResumeActivity(token, true /* finalStateRequest */, mIsForward, "RESUME_ACTIVITY"); Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);}

依舊是呼叫 ActivityThread.handleResumeActivity() 。不過這裡有一點比較特殊,還是得拎出來說一下。

> ActivityThread.javapublic void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward, String reason) { ...... r.activity.mVisibleFromServer = true; mNumVisibleActivities++; if (r.activity.mVisibleFromClient) { // 頁面可見 r.activity.makeVisible(); } } // 主執行緒空閒時會執行 Idler Looper.myQueue().addIdleHandler(new Idler()); }

makeVisible() 方法讓 DecorView 可見。

> Activity.javavoid makeVisible() { if (!mWindowAdded) { ViewManager wm = getWindowManager(); wm.addView(mDecor, getWindow().getAttributes()); mWindowAdded = true; } mDecor.setVisibility(View.VISIBLE);}

最後要注意的就是 Looper.myQueue().addIdleHandler(new Idler())。由於篇幅原因,這裡先不介紹了,後面單獨寫 Activity 生命週期的時候再做分析。大家可以先去原始碼中找找答案。

總結

一路分析過來,Activity終於展示給使用者了。

文章其實又臭又長,很多人可能會有疑問,看這些真的有用嗎?在我看來,一個程式設計師最重要的兩樣東西就是基本功和內功。良好的基本功可以讓我們輕鬆上手一門技術,而深厚的內功就可以讓我們面對難題迎刃而解。原始碼能帶給你的,正是這些。

最近看了 Jetpack 中一些元件的原始碼,下一篇文章應該就是Jetpack 相關了。敬請期待!

最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • .Net Core智慧化開發平臺,讓開發變得簡單