深入理解Android 之 Activity啓動流程

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

  • Android源碼地址

  • 首先來個腦圖,對於整體模塊在大腦中形成一個整體印象

Launcher到ActivityTaskManagerService

Launcher 調用 Activity

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

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

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

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

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

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

 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時序圖來對上面的步驟進行回顧


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.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) {
        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時序圖來對上面的步驟進行回顧

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的時序圖來對上面的步驟進行回顧


最後

  • 通過本文,基本上將引用程序啓動根的Activity啓動流程走了一遍,但是其中還有一點沒說展開的就是應用程序進程的啓動過程,這一部分內容將通過後續文章繼續探究。。如果文章中有寫得不對的地方,歡迎在留言區留言大家一起討論,共同學習進步。如果覺得我的文章給予你幫助,也請給我一個喜歡和關注。

參考

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章