深刻理解Android 之 Activity啓動流程(Android 10)

在進階Android的路上,瞭解理解一個應用根Activity啓動流程能夠做爲一個切入點,由此展開進階之路。平時咱們開發的應用都是展現在Android系統桌面上,這個系統桌面其實也是一個Android應用,它叫Launcher。因此本文經過源碼層面從Launcher調用ATMS,ATMS調用ApplicationThread,最後ActivityThread啓動Activity三個過程瞭解Activity啓動流程(文中源碼基於Android 10 )。java

  • Android源碼地址android

  • 首先來個腦圖,對於總體模塊在大腦中造成一個總體印象 c++

    Activity啓動流程

Launcher到ActivityTaskManagerService

Launcher 調用 Activity

  • 至於Launcher如何加載展現應用程序到界面這裏先略過(與PMS相關),本文先關注Activity啓動過程。當咱們點擊系統桌面的應用圖標,直接響應的則是Launcher這個應用程序,會調用它的startActivitySafely方法

packages/apps/Launcher3/src/com/android/launcher3/Launcher.javagit

public boolean startActivitySafely(View v, Intent intent, ItemInfo item,
            @Nullable String sourceContainer) {
        .....

        boolean success = super.startActivitySafely(v, intent, item, sourceContainer); // 1
        if (success && v instanceof BubbleTextView) {
            // This is set to the view that launched the activity that navigated the user away
            // from launcher. Since there is no callback for when the activity has finished
            // launching, enable the press state and keep this reference to reset the press
            // state when we return to launcher.
            BubbleTextView btv = (BubbleTextView) v;
            btv.setStayPressed(true);
            addOnResumeCallback(btv);
        }
        return success;
    }
複製代碼
  • 經過以上源碼,在註釋1調用的是父類的startActivitySafely方法,Launcher類自己就是Activity,它的父類爲BaseDraggingActivity,接着看到它的startActivitySafely方法

packages/apps/Launcher3/src/com/android/launcher3/BaseDraggingActivity.javagithub

public boolean startActivitySafely(View v, Intent intent, @Nullable ItemInfo item,
            @Nullable String sourceContainer) {
        .......

        // Prepare intent
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); //1
        if (v != null) {
            intent.setSourceBounds(getViewBounds(v));
        }
        try {
            ......
            if (isShortcut) {
                // Shortcuts need some special checks due to legacy reasons.
                startShortcutIntentSafely(intent, optsBundle, item, sourceContainer);
            } else if (user == null || user.equals(Process.myUserHandle())) {
                // Could be launching some bookkeeping activity
                startActivity(intent, optsBundle);//2
                AppLaunchTracker.INSTANCE.get(this).onStartApp(intent.getComponent(),
                        Process.myUserHandle(), sourceContainer);
            } else {
                .......
            }
            getUserEventDispatcher().logAppLaunch(v, intent);
            getStatsLogManager().logAppLaunch(v, intent);
            return true;
        } catch (NullPointerException|ActivityNotFoundException|SecurityException e) {
            Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
            Log.e(TAG, "Unable to launch. tag=" + item + " intent=" + intent, e);
        }
        return false;
    }
複製代碼
  • 以上源碼看到註釋1,設置啓動Activity的Flag爲FLAG_ACTIVITY_NEW_TASK,設置這個Flag則Activity的啓動就會在新的任務棧中啓動,後面還會遇到它;接着看到註釋2,調用了startActivity的方法,顯然這就是調用了Activity類的startActivity方法。繼續探究Activity類的startActivity方法

frameworks/base/core/java/android/app/Activity.java數組

@Override
    public void startActivity(Intent intent, @Nullable Bundle options) {
        if (options != null) {
            startActivityForResult(intent, -1, options);//1
        } else {
            // Note we want to go through this call for compatibility with
            // applications that may have overridden the method.
            startActivityForResult(intent, -1);
        }
    }
複製代碼
  • 有以上源碼看到註釋1,Activity類的startActivity方法調用的是startActivityForResult方法,這個方法平常開發啓動Activity有參數回調也會使用,這裏參數傳入-1,代表Launcher啓動Activity並無論它成功與否。接着看startActivityForResult方法

frameworks/base/core/java/android/app/Activity.javabash

Activity mParent;

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
        if (mParent == null) { //1
            options = transferSpringboardActivityOptions(options);
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);//2
            ......
        } else {
            ......
        }
    }
複製代碼
  • 經過以上源碼看到註釋1,mParent的聲明類型爲Activity,當前仍是正在起Activity,mParent == null成立,看到註釋2調用了Instrumentation類的execStartActivity方法,Instrumentation容許您監視系統與應用程序之間的全部交互(Instrumentation註釋:allowing you to monitor all of the interaction the system has with the application.),接着看到它的execStartActivity方法

Instrumentation 調用到ATMS

frameworks/base/core/java/android/app/Instrumentation.javamarkdown

@UnsupportedAppUsage
    public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        IApplicationThread whoThread = (IApplicationThread) contextThread;//1
        ......
        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess(who);
            int result = ActivityTaskManager.getService()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options); //2
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }
複製代碼
  • 經過以上源碼看到註釋1,這裏獲取了IApplicationThread,若是你瞭解Binder,第一反應就應該很清晰,目前處於Launcher應用程序進程,要啓動Activity則須要請求系統服務進程(SystemServer),而Android進程間通訊則可使用Binder,而這裏實現方式爲AIDL,它的實現類爲ActivityThread的內部類ApplicationThread,而ApplicationThread做用則爲應用程序進程和系統服務進程通訊的橋樑,後面還會繼續提到;接着看到註釋2,這裏調用ActivityTaskManager.getService則能夠獲取ActivityTaskManagerService的代理對象,看看他的實現

frameworks/base/core/java/android/app/ActivityTaskManager.javaapp

public static IActivityTaskManager getService() {
        return IActivityTaskManagerSingleton.get();
    }

    @UnsupportedAppUsage(trackingBug = 129726065)
    private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
            new Singleton<IActivityTaskManager>() {
                @Override
                protected IActivityTaskManager create() {
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);//1
                    return IActivityTaskManager.Stub.asInterface(b); //2
                }
            };
複製代碼
  • 由以上源碼註釋1,經過ServiceManager來獲取遠程服務ActivityTaskManagerService,ServiceManager底層最終調用的仍是c++層的ServiceManager,它是Binder的守護服務,經過它可以獲取在Android系統啓動時註冊的系統服務,這其中就包含這裏提到的ATMS;接着回到註釋2創建 Launcher與 ATMS的鏈接,這樣回到execStartActivity方法,Launcher就經過調用ATMS的startActivity方法將啓動Activity的數據交給ATMS服務來處理了。

Launcher調用到ActivityTaskManagerService時序圖

  • 爲了更好理解,看看Launcher調用到ActivityTaskManagerService時序圖來對上面的步驟進行回顧

Launcher調用到ActivityTaskManagerService時序圖

ActivityTaskManagerService 調用ApplicationThread

ATMS處理啓動Activity請求

  • 經過上一小節,啓動應用程序Activity已經走到ActivityTaskManagerService中,若是你熟悉前以往版本的Android源碼,你確定會知道ActivityManagerService,而在Android 10 中則將AMS用於管理Activity及其容器(任務,堆棧,顯示等)的系統服務分離出來放到ATMS中,也許是谷歌不想讓AMS的代碼愈來愈膨脹吧(Android 10中AMS代碼有一萬九千行)。好了,接着看到ATMS的startActivity方法

frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.javaide

@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) {
        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
                resultWho, requestCode, startFlags, profilerInfo, bOptions,
                UserHandle.getCallingUserId());//1
    }
複製代碼
  • 由以上代碼,繼續調用了startActivityAsUser方法,該方法多傳入了用戶的ID,接着會判斷是否有權限調用,沒有權限調用則拋出異常,不然獲取用戶id用於後續進程間Binder通訊。接着繼續看startActivityAsUser方法

frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java

@Override
    public int startActivityAsUser(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
                resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
                true /*validateIncomingUser*/);//1
    }

    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("startActivityAsUser");

        userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
                Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");

        // TODO: Switch to user app stacks here.
        return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
                .setCaller(caller)
                .setCallingPackage(callingPackage)
                .setResolvedType(resolvedType)
                .setResultTo(resultTo)
                .setResultWho(resultWho)
                .setRequestCode(requestCode)
                .setStartFlags(startFlags)
                .setProfilerInfo(profilerInfo)
                .setActivityOptions(bOptions)
                .setMayWait(userId)
                .execute();//2

    }
複製代碼
  • 由以上代碼,註釋1調用了ATMS本身實現的startActivityAsUser方法,在註釋而2處構造了ActivityStarter,此類收集了用於肯定將意圖和標誌如何轉換爲活動以及關聯的任務和堆棧的全部邏輯,obtainStarter方法第二個參數表明啓動Activity的意圖,接着調用了execute方法,

frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java

int execute() {
        try {
            // TODO(b/64750076): Look into passing request directly to these methods to allow
            // for transactional diffs and preprocessing.
            if (mRequest.mayWait) { //1
                return startActivityMayWait(mRequest.caller, mRequest.callingUid,
                        mRequest.callingPackage, mRequest.realCallingPid, mRequest.realCallingUid,
                        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, mRequest.allowBackgroundActivityStart);//2
            } 
          ......  
        } 
        .......
    }
複製代碼
  • 由以上代碼看到註釋1,前面構造ActivityStarter已經傳入了用戶id,因此這裏判斷條件成立,則繼續調用startActivityMayWait方法

frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java

private int startActivityMayWait(IApplicationThread caller, int callingUid,
            String callingPackage, int requestRealCallingPid, int requestRealCallingUid,
            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, boolean allowBackgroundActivityStart) {
            ......

            final ActivityRecord[] outRecord = new ActivityRecord[1];//1
            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,
                    allowBackgroundActivityStart);//2
          ......
            return res;
        }
    }
複製代碼
  • 由以上代碼,能夠看到註釋1處建立了一個ActivityRecord數組,ActivityRecord表明一個Activity,接着調用了startActivity方法,

frameworks/base/services/core/java/com/android/server/wm/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, boolean allowBackgroundActivityStart) {
        mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(intent);
        int err = ActivityManager.START_SUCCESS;
        // Pull the optional Ephemeral Installer-only bundle out of the options early.
        final Bundle verificationBundle
                = options != null ? options.popAppVerificationBundle() : null;

        WindowProcessController callerApp = null;
        if (caller != null) {//1
            callerApp = mService.getProcessController(caller);//2
            if (callerApp != null) {
                callingPid = callerApp.getPid();
                callingUid = callerApp.mInfo.uid;
            } else {
                Slog.w(TAG, "Unable to find app for caller " + caller
                        + " (pid=" + callingPid + ") when starting: "
                        + intent.toString());
                err = ActivityManager.START_PERMISSION_DENIED;
            }
        }
       .......

        ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
                callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
                resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
                mSupervisor, checkedOptions, sourceRecord);
        if (outActivity != null) {
            outActivity[0] = r;//3
        }

       ......

        final int res = startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
                true /* doResume */, checkedOptions, inTask, outActivity, restrictedBgActivity);//4
        .....
        return res;
    }
複製代碼
  • 由以上代碼,startActivity裏面有不少的邏輯代碼,這裏只看一些重點的邏輯代碼,主要作了兩個事情: (1)註釋1處判斷IApplicationThread是否爲空,前面第一小節咱們就已經提到過,它表明的就是Launcher進程的ApplicationThread,註釋2經過與即將要啓動的應用程序進程創建聯繫,應用程序進程的是fork到Zyote進程,這裏先不進行展開了,先專一Activity啓動流程。接着註釋3建立ActivityRecord表明即將要啓動的Activity,包含了Activity的全部信息,並賦值給上一步驟中建立的ActivityRecord類型的outActivity,註釋4則繼續調用startActivity方法

frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java

private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
                int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
                ActivityRecord[] outActivity, boolean restrictedBgActivity) {
        int result = START_CANCELED;
        final ActivityStack startedActivityStack;
        try {
            mService.mWindowManager.deferSurfaceLayout();
            result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
                    startFlags, doResume, options, inTask, outActivity, restrictedBgActivity);//1
        } 
        ........

        return result;
    }
複製代碼
  • 由以上代碼,註釋1處startActivity又調用了startActivityUnchecked方法

frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java

// Note: This method should only be called from {@link startActivity}.
    private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity, boolean restrictedBgActivity) {
        ......    
        final TaskRecord taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
                ? mSourceRecord.getTaskRecord() : null;
        // Should this be considered a new task?
        int result = START_SUCCESS;
        if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
                && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) { //1
            newTask = true;
            result = setTaskFromReuseOrCreateNewTask(taskToAffiliate); //2
        } 
        ........
        if (mDoResume) {
            final ActivityRecord topTaskActivity =
                    mStartActivity.getTaskRecord().topRunningActivityLocked();
            if (!mTargetStack.isFocusable()
                    || (topTaskActivity != null && topTaskActivity.mTaskOverlay
                    && mStartActivity != topTaskActivity)) {
                
              mTargetStack.ensureActivitiesVisibleLocked(mStartActivity, 0, !PRESERVE_WINDOWS);
                mTargetStack.getDisplay().mDisplayContent.executeAppTransition();
            } else {
                // If the target stack was not previously focusable (previous top running activity
                // on that stack was not visible) then any prior calls to move the stack to the
                // will not update the focused stack.  If starting the new activity now allows the
                // task stack to be focusable, then ensure that we now update the focused stack
                // accordingly.
                if (mTargetStack.isFocusable()
                        && !mRootActivityContainer.isTopDisplayFocusedStack(mTargetStack)) {
                    mTargetStack.moveToFront("startActivityUnchecked");
                }
                mRootActivityContainer.resumeFocusedStacksTopActivities(
                        mTargetStack, mStartActivity, mOptions);//3
            }
        }
複製代碼
  • 由上代碼註釋1,在前面第一節Launcher部分中有提到過設置了Flag爲FLAG_ACTIVITY_NEW_TASK,因此注意判斷條件成立,則調用setTaskFromReuseOrCreateNewTask,它內部會建立的TaskRecord(表明Activity的任務棧),並將傳入的TaskRecord對象設置給表明啓動的Activity的ActivityRecord,接着在註釋3調用了RootActivityContainer的resumeFocusedStacksTopActivities方法,RootActivityContainer 將一些東西從ActivityStackSupervisor中分離出來。目的是將其與RootWindowContainer合併,做爲統一層次結構的一部分,接着看它的resumeFocusedStacksTopActivities方法

frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java

boolean resumeFocusedStacksTopActivities(
            ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {

        ......

        boolean result = false;
        if (targetStack != null && (targetStack.isTopStackOnDisplay()
                || getTopDisplayFocusedStack() == targetStack)) { 
            result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);//1
        }

        .......

        return result;
    }
複製代碼
  • 由以上代碼註釋1處,又調用了ActivityStack的resumeTopActivityUncheckedLocked方法,ActivityStack應該算是任務棧的描述,它管理者一個應用的全部TaskRecord和他們的狀態,接着看到它的resumeTopActivityUncheckedLocked方法

frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java

//確保棧頂 activity 爲Resume
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
        if (mInResumeTopActivity) {
            // Don't even start recursing. return false; } boolean result = false; try { // 防止遞歸 mInResumeTopActivity = true; result = resumeTopActivityInnerLocked(prev, options); //1 ........ } finally { mInResumeTopActivity = false; } return result; } 複製代碼
  • 由以上代碼,在註釋1處接着又調用ActivityStack的resumeTopActivityInnerLocked方法

frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java

@GuardedBy("mService")
    private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
    
    ....
    // Whoops, need to restart this activity!
            
            ........
       mStackSupervisor.startSpecificActivityLocked(next, true, true);//1
            ........
        
}
複製代碼
  • 由以上代碼看到註釋1,resumeTopActivityInnerLocked方法中邏輯很是多,這裏直接精簡到這一句關鍵代碼,調用了ActivityStackSupervisor的startSpecificActivityLocked方法

ActivityStackSupervisor 啓動Activity

frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java

void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
        // Activity應用程序進程是否已經準備好
        final WindowProcessController wpc =
                mService.getProcessController(r.processName, r.info.applicationInfo.uid);

        boolean knownToBeDead = false;
        if (wpc != null && wpc.hasThread()) { //1
            try {
                realStartActivityLocked(r, wpc, andResume, checkConfig); //2
                return;
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception when starting activity " 
                        + r.intent.getComponent().flattenToShortString(), e);
            }
        .......
        }

        .......
        try {
           .......
            // Post message to start process to avoid possible deadlock of calling into AMS with the
            // ATMS lock held.
            final Message msg = PooledLambda.obtainMessage(
                    ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
                    r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());//3
            mService.mH.sendMessage(msg);
        }
        ........
    }

複製代碼
  • 如上代碼所示註釋1,判斷要啓動的應用程序進程是否已經準備好,hasThread則是肯定應用程序進程的IApplicationThread是否存在,若是存在則調用ActivityStackSupervisor的realStartActivityLocked方法啓動Activity;若是是第一次啓動,則應用程序進程沒有準備好,則會走到註釋3處啓動應用程序進程,本文先跳過,留到下篇文章再探究。接下來繼續看到realStartActivityLocked方法

frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java

boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
            boolean andResume, boolean checkConfig) throws RemoteException {
           .......

                // Create activity launch transaction.
                final ClientTransaction clientTransaction = ClientTransaction.obtain(
                        proc.getThread(), r.appToken);//1

                final DisplayContent dc = r.getDisplay().mDisplayContent;
                clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                        System.identityHashCode(r), r.info,
                        // TODO: Have this take the merged configuration instead of separate global
                        // and override configs.
                        mergedConfiguration.getGlobalConfiguration(),
                        mergedConfiguration.getOverrideConfiguration(), r.compat,
                        r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
                        r.icicle, r.persistentState, results, newIntents,
                        dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
                                r.assistToken));//2

                // Set desired final state.
                final ActivityLifecycleItem lifecycleItem;
                if (andResume) {
                    lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
                } else {
                    lifecycleItem = PauseActivityItem.obtain();
                }
                clientTransaction.setLifecycleStateRequest(lifecycleItem);

                // Schedule transaction.
                mService.getLifecycleManager().scheduleTransaction(clientTransaction);//3

                .......

        return true;
    }
複製代碼
  • 由以上代碼註釋1處,建立了ClientTransaction對象,它是包含一系列消息的容器,能夠將其發送到客戶端,這個客戶端就咱們要啓動的應用程序Activity,註釋2處將前面一路傳遞進來的啓動Activity參數封裝成了LaunchActivityItem請求request對象,接着咱們看到註釋3,這裏調用了ClientLifecycleManager的scheduleTransaction方法,它的初始化在AMTS構造方法中,並傳入了ClientTransaction參數,接着看到ClientLifecycleManager的scheduleTransaction方法

ClientLifecycleManager(ActivityThread)處理ClientTransaction

frameworks/base/services/core/java/com/android/server/wm/ClientLifecycleManager.java

void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
        final IApplicationThread client = transaction.getClient();//1
        transaction.schedule();//2
        if (!(client instanceof Binder)) {
            // If client is not an instance of Binder - it's a remote call and at this point it is // safe to recycle the object. All objects used for local calls will be recycled after // the transaction is executed on client in ActivityThread. transaction.recycle(); } } 複製代碼
  • 到此,基本上已經比較清晰了,註釋1處獲取了要啓動的應用程序進程的IApplicationThread,上一步中建立ClientTransaction對象時已經將其賦值給ClientTransaction的變量mClient,隨後scheduleTransaction判斷是否支持進程間通訊;註釋二處則調用了ClientTransaction的schedule方法,

frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java

/** Target client. */
    private IApplicationThread mClient;
    
     /** Schedule the transaction after it was initialized. It will be send to client and all its
     * individual parts will be applied in the following sequence:
     * 1. The client calls {@link #preExecute(ClientTransactionHandler)}, which triggers all work
     *    that needs to be done before actually scheduling the transaction for callbacks and
     *    lifecycle state request.
     * 2. The transaction message is scheduled.
     * 3. The client calls {@link TransactionExecutor#execute(ClientTransaction)}, which executes
     *    all callbacks and necessary lifecycle transitions.
     */
    public void schedule() throws RemoteException {
        mClient.scheduleTransaction(this); //1 
    }

複製代碼
  • 經過以上代碼,註釋1處mClient則表明要啓動的應用程序進程的IApplicationThread,而當前還處於ATMS服務的進程,也就是SystemServer進程,這時ATMS要與即將啓動的應用程序進程通訊則經過IApplicationThread來執行AIDL,IApplicationThread實現爲ApplicationThread,它是ActivityThread的內部類,因此前面也說過ApplicationThread爲進程間通訊的橋樑,註釋1處則至關因而IApplicationThread.scheduleTransaction,並將包含要啓動Activity信息的ClientTransaction傳遞到了應用程序進程,下一節就從IApplicationThread講起。

AMTS調用到ApplicationThread時序圖

  • 爲了更好理解,看看AMTS調用到ApplicationThread時序圖來對上面的步驟進行回顧

AMTS調用到ApplicationThread時序圖

ActivityThread啓動Activity

ApplicationThread 處理進程間數據通訊

  • 接着上一節的內容,咱們從ApplicationThread的scheduleTransaction方法開始

frameworks/base/core/java/android/app/ActivityThread.java

private class ApplicationThread extends IApplicationThread.Stub {
     @Override
        public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
            ActivityThread.this.scheduleTransaction(transaction);//1
        }
}
複製代碼
  • 由以上代碼,註釋1處調用了ActivityThread的scheduleTransaction方法,ActivityThread繼承了ClientTransactionHandler,scheduleTransaction在裏面實現

frameworks/base/core/java/android/app/ClientTransactionHandler.java

/** Prepare and schedule transaction for execution. */
    void scheduleTransaction(ClientTransaction transaction) {
        transaction.preExecute(this);
        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
    }
複製代碼

ActivityThread.H 線程間消息處理

  • 能夠看到這裏發送了一個Handler消息,而ActivityThread.H則是ActivityThread的內部Handler,它是整個應用程序的主線程Handler,這裏爲何須要切換線程呢?其緣由爲前面ATMS進程間通訊則是運行在Binder線程,而Android更新UI則須要在主線程,接着看到ActivityThread.H的消息處理
class H extends Handler {
 
  public void handleMessage(Message msg) {
            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
            switch (msg.what) {
            case EXECUTE_TRANSACTION:
                    final ClientTransaction transaction = (ClientTransaction) msg.obj;//1
                    mTransactionExecutor.execute(transaction);//2
                    ......
                    break;
                    
             }       
}                    
複製代碼

TransactionExecutor

  • 由以上代碼,看到註釋1處,獲取了由ATMS傳遞過來的啓動Activity進程的數據,註釋2處調用了TransactionExecutor的來處理ClientTransaction的數據,接着看到它的execute方法

frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java

public void execute(ClientTransaction transaction) {
        if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Start resolving transaction");

        .......

        executeCallbacks(transaction); //

        executeLifecycleState(transaction);
        mPendingActions.clear();
        if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "End resolving transaction");
    }
複製代碼
  • 由以上代碼註釋1處接着調用了TransactionExecutor的executeCallbacks方法

frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java

/** Cycle through all states requested by callbacks and execute them at proper times. */
    @VisibleForTesting
    public void executeCallbacks(ClientTransaction transaction) {
        final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
        if (callbacks == null || callbacks.isEmpty()) {
            // No callbacks to execute, return early.
            return;
        }
        if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Resolving callbacks in transaction");

        final IBinder token = transaction.getActivityToken();
        ActivityClientRecord r = mTransactionHandler.getActivityClient(token);

        // In case when post-execution state of the last callback matches the final state requested
        // for the activity in this transaction, we won't do the last transition here and do it when // moving to final state instead (because it may contain additional parameters from server). final ActivityLifecycleItem finalStateRequest = transaction.getLifecycleStateRequest(); final int finalState = finalStateRequest != null ? finalStateRequest.getTargetState() : UNDEFINED; // Index of the last callback that requests some post-execution state. final int lastCallbackRequestingState = lastCallbackRequestingState(transaction); final int size = callbacks.size(); for (int i = 0; i < size; ++i) { final ClientTransactionItem item = callbacks.get(i);//1 if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Resolving callback: " + item); final int postExecutionState = item.getPostExecutionState(); final int closestPreExecutionState = mHelper.getClosestPreExecutionState(r, item.getPostExecutionState()); if (closestPreExecutionState != UNDEFINED) { cycleToPath(r, closestPreExecutionState, transaction); } item.execute(mTransactionHandler, token, mPendingActions);//2 ........ } } 複製代碼

LaunchActivityItem

  • 由以上代碼註釋1處,獲取的ClientTransactionItem則爲第二小節中提到過的LaunchActivityItem對象,它繼承了ClientTransactionItem,並保存這須要啓動的Activity數據,接着看到註釋2 LaunchActivityItem的execute方法。

frameworks/base/core/java/android/app/servertransaction/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, mAssistToken);//1
        client.handleLaunchActivity(r, pendingActions, null /* customIntent */);//2
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }
複製代碼
  • 由以上代碼,註釋1處恢復了要啓動的Activity的數據,ActivityClientRecord是ActivityThread的內部類,這裏的client爲ClientTransactionHandler,而前面已經說過ActivityThread繼承ClientTransactionHandler,因此這裏的註釋2處調用的就是ActivityThread的handleLaunchActivity方法

frameworks/base/core/java/android/app/ActivityThread.java

/**
     * Extended implementation of activity launch. Used when server requests a launch or relaunch.
     */
    @Override
    public Activity handleLaunchActivity(ActivityClientRecord r,
            PendingTransactionActions pendingActions, Intent customIntent) {
        .......

        final Activity a = performLaunchActivity(r, customIntent);//1

        .......

        return a;
    }
複製代碼
  • 由以上代碼註釋1處,繼續調用了ActivityThread的performLaunchActivity方法來啓動Activity,返回的也是Activity實例。因此performLaunchActivity方法纔是啓動Activity實例的核心代碼。

Core Activity Launch

frameworks/base/core/java/android/app/ActivityThread.java

/**  Core implementation of activity launch. */
    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    
        ActivityInfo aInfo = r.activityInfo;//1
        if (r.packageInfo == null) {
            r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                    Context.CONTEXT_INCLUDE_CODE);//2
        }

        ComponentName component = r.intent.getComponent();//3
        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);//4
        Activity activity = null;
        try {
        
            java.lang.ClassLoader cl = appContext.getClassLoader();
            //建立Activity的實例
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);//5
            StrictMode.incrementExpectedActivityCount(activity.getClass());
            r.intent.setExtrasClassLoader(cl);
            r.intent.prepareToEnterProcess();
            if (r.state != null) {
                r.state.setClassLoader(cl);
            }
        } catch (Exception e) {
            if (!mInstrumentation.onException(activity, e)) {
                throw new RuntimeException(
                    "Unable to instantiate activity " + component
                    + ": " + e.toString(), e);
            }
        }

        try {
        
        //應用程序Application的建立
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);//6

           ......

            if (activity != null) {
                CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
                Configuration config = new Configuration(mCompatConfiguration);
                if (r.overrideConfig != null) {
                    config.updateFrom(r.overrideConfig);
                }
                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
                        + r.activityInfo.name + " with config " + config);
                Window window = null;
                if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
                    window = r.mPendingRemoveWindow;
                    r.mPendingRemoveWindow = null;
                    r.mPendingRemoveWindowManager = null;
                }
                appContext.setOuterContext(activity);
                // 經過Activity的 attach 方法將 context等各類數據與Activity綁定,初始化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,
                        r.assistToken); //7

                ......
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);//8
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
                ......
                r.activity = activity;
            }
            r.setState(ON_CREATE);

           .......
        }

        return activity;
    }
複製代碼
  • 由以上代碼,註釋1處獲取了前面保存啓動應用程序信息的ActivityClientRecord中的應用程序信息,包括應用程序在清單文件中註冊了哪些四大組件,啓動的根Activity是什麼,並在註釋2處經過getPackageInfo方法獲取LoadedApk描述對應Apk文件資源,註釋3處的ComponentName類獲取則對應啓動Activity的包名和類名,註釋4處則生成了啓動應用程序的Base上下文環境Context,註釋5處經過註釋3獲取的類名,經過類加載器和Intent對象實例化了Activity對象,註釋6則根據註釋2處獲取Apk描述對象LoadedApk建立了應用程序的Application對象,並在makeApplication方法中調用了它的OnCreate方法,因此應用程序最新啓動的是Application纔到根Activity,註釋7處則前面建立的Context、Application、Window對象與Activity關聯來初始化Activity,最後註釋8處還繼續調用了Instrumentation對象的callActivityOnCreate方法。接着往下看

Activity的 OnCreate方法調用

frameworks/base/core/java/android/app/Instrumentation.java

public void callActivityOnCreate(Activity activity, Bundle icicle,PersistableBundle persistentState) {
        prePerformCreate(activity); 
        activity.performCreate(icicle, persistentState);//1
        postPerformCreate(activity);
    }
複製代碼
  • 由以上代碼,註釋1處又調用了Activity的performCreate方法,繼續往下看

frameworks/base/core/java/android/app/Activity.java

final void performCreate(Bundle icicle, PersistableBundle persistentState) {
        dispatchActivityPreCreated(icicle);
        mCanEnterPictureInPicture = true;
        restoreHasCurrentPermissionRequest(icicle);
        if (persistentState != null) {
            onCreate(icicle, persistentState);//1
        } else {
            onCreate(icicle);
        }
        .......
    }
複製代碼
  • 最終,在已經實例初始化好的Activity調用它的performCreate方法中又掉用了onCreate方法(註釋1)。至此,也就是整個應用程序的Activity啓動過程咱們已經走完了。

ActivityThread啓動Activity的時序圖

  • 爲了更好理解,看看ActivityThread啓動Activity的時序圖來對上面的步驟進行回顧

ActivityThread啓動Activity的時序圖

最後

  • 經過本文,基本上將引用程序啓動根的Activity啓動流程走了一遍,可是其中還有一點沒說展開的就是應用程序進程的啓動過程,這一部份內容將在文章深刻理解Android之應用程序進程啓動流程探究。若是文章中有寫得不對的地方,歡迎在留言區留言你們一塊兒討論,共同窗習進步。若是以爲個人文章給予你幫助,也請給我一個喜歡和關注。

參考

About me

blog:

mail:

相關文章
相關標籤/搜索