庖丁解牛 Activity 啟動流程

来源:https://www.cnblogs.com/bingxinshuo/archive/2019/12/03/11980287.html
-Advertisement-
Play Games

前言 這是 "Android 9.0 AOSP 系列" 的第五篇了,先來回顧一下前面幾篇的大致內容。 "Java 世界的盤古和女媧 —— Zygote" 主要介紹了 Android 世界的第一個 Java 進程 的啟動過程。 註冊服務端 socket,用於響應客戶端請求 各種預載入操作,類,資源,共 ...


前言

這是 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.so

  • createSystemContext(),初始化系統上下文

  • 創建系統服務管理者 SystemServiceManager

  • startBootstrapServices,啟動系統引導服務

  • 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 值

  • 安裝系統 Provider

  • systemReady(),最終會啟動桌面 Home Activity

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

啟動流程分析

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

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

> ActivityManagerService.java

boolean 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;
}

調用 ActivityStartControllerstartHomeActivity() 方法:

> ActivityStartController.java

void 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);
            }
        }
    }

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

> Instrumentation.java

public 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.java

public static IActivityManager getService() {
    return IActivityManagerSingleton.get();
}

private static final Singleton<IActivityManager> IActivityManagerSingleton =
        new Singleton<IActivityManager>() {
            @Override
            protected IActivityManager create() {
                final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                final IActivityManager am = IActivityManager.Stub.asInterface(b);
                return am;
            }
        };

接著就進入到 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.java

private 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 ,要啟動的任務棧等。這一塊源碼很長,上面作了大量刪減,僅保留了基本的調用鏈。感興趣的同學可以自行查看源文件。接下來 調用了 ActivityStackSupervisorresumeFocusedStackTopActivityLocked() 方法。

> 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.java

boolean 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.java

private 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.java

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

跟進 schedule() 方法。

> ClientTransaction.java

public void schedule() throws RemoteException {
    mClient.scheduleTransaction(this);
}

這裡的 mClient 是 IApplicationThread 類型,它是 ApplicationThread 的 Binder 代理對象,所以這裡會跨進程調用到 ApplicationThread.scheduleTransaction()方法 。 ApplicationThreadActivityThread 的內部類,但不論是 ApplicationThread 還是 ActivityThread 其實都沒有 scheduleTransaction() 方法,所以調用的是其父類 ClientTransactionHandler 的方法。

> ClientTransactionHandler.java

public 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.java

private 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.java

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

調用了 TransactionExecutorexecute() 方法。

> 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

@VisibleForTesting
public 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), ......);

也就是說會執行 LaunchActivityItemexecute() 方法。

> LaunchActivityItem.java

@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);
    // 調用 ActivityThread.handleLaunchActivity()
    client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
    Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}

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

> ActivityThread.java

@Override
public Activity handleLaunchActivity(ActivityClientRecord r,
        PendingTransactionActions pendingActions, Intent customIntent) {

    ......

    final Activity a = performLaunchActivity(r, customIntent);

    ......

    return a;
}
> ActivityThread.java

private 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.java

public 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.java

public void callActivityOnCreate(Activity activity, Bundle icicle) {
    prePerformCreate(activity);
    activity.performCreate(icicle);
    postPerformCreate(activity);
}
> Activity.java

final 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 的嗎?是 TransactionExecutorexecute() 方法。

> 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.java

private 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

@Override
public 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() 。不過這裡有一點比較特殊,還是得拎出來說一下。

文章首發微信公眾號: 秉心說 , 專註 Java 、 Android 原創知識分享,LeetCode 題解。

更多最新原創文章,掃碼關註我吧!

> ActivityThread.java

public 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.java

void 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 相關了。敬請期待!

文章首發微信公眾號: 秉心說 , 專註 Java 、 Android 原創知識分享,LeetCode 題解。

更多最新原創文章,掃碼關註我吧!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 需求 SQL Server的作業歷史(Job)記錄是保存在msdb庫中的,很方便就查詢相關的Job定義,計劃和歷史記錄,而MySQL的event卻沒有歷史記錄。為方便查看event是否正常執行以及執行結果,通過以下兩個步驟來實現類似的功能。 實現 1. 在mysql庫創建event執行的歷史記錄表 ...
  • 問題描述:情形是當主庫真正出現異常之後,才會執行的操作,那麼我們執行過failover 之後,如何在重新構建DG,這裡我們利用flashback database來重構。模擬前主庫要開啟閃回區,否則要重新搭建DG了 1.由於主庫已經不可訪問,下麵所有的操作都在備庫完成,先取消實時同步 SQL> al ...
  • 有時會發現資料庫system表空間增長很快,使用以下語句查看system表空間使用量。也可以使用toad直接看。 執行以下語句查看是哪個對象占用較大 一般發現都是發現是AUD$審計表占用資源量大。 直接登錄資料庫,清理掉SYS.AUD$表。 如果想關閉資料庫審計,可以參考以下鏈接 https://w ...
  • spark 各個版本的application 調度演算法還是有這明顯的不同之處的。從spark1.3.0 到 spark 1.6.1、spark2.x 到 現在最新的spark 3.x ,調度演算法有了一定的修改。下麵大家一起學習一下,最新的spark 版本spark-3.0的Application 調 ...
  • 說明: 1)該實驗所有過程均是本人親自敲命令完成,所有代碼運行正確 2)安裝過程使用的是suse11 sp3操作系統,後續的實驗過程換成了麒麟中標,因此部分路徑可能存在差異 3)安裝過程使用了命令行安裝,圖形界面簡單,因此本文沒有介紹 4)job部分命令行操作太繁瑣,建議使用圖形界面操作,因此本文也 ...
  • sqlServer2012(936 簡體中文GBK )為例: 例如: varchar(10),只能存儲10個英文字元或數字,也只能存儲5個漢字; char(10),只能存儲10個英文字元或數字,也只能存儲5個漢字; nvarchar(10),即存儲10個英文字元或數字,也能存儲10個漢字; ncha ...
  • 知識點 △用資料庫的原因 1文件操作的複雜度 2同步 3併發處理 4安全 △資料庫系統(DBS) 資料庫(DB) + 資料庫管理系統 (DBS)+ 資料庫應用程式 + 資料庫管理員 (BDA)+ 最終用戶 △資料庫管理系統 DBM 網路應用服務端 我們要使用服務端的數據 需要有一個客戶端 客戶端可以 ...
  • 常見的SQL優化方式 1. 對查詢進行優化,應儘量避免全表掃描,首先應考慮在 where及order by 涉及的列上建立索引 。 2. 應儘量 避免 在 where 子句中對欄位進行null 值判斷,否則將導致引擎放棄使用索引而進行全表掃描,如: 可以在num上設置預設值0,確保表中num列是否存 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...