【基于Android Q】Activity啟動流程源碼分析【二】

Activity的啟動主要包括以下幾個步驟:

  1. 應用通過startActivity或是startActivityForResult方法向ActivityManagerService發出啟動請求。
  2. ActivityManagerService接收到啟動請求后,解析啟動的Activity信息以及啟動模式,為正式啟動做準備工作。
  3. ActivityManagerService做完準備工作之后,判斷棧頂是否為空,如果不為空,即當前有Activity顯示在前臺,則先會請求對棧頂 Activity進行onPause操作。
  4. 棧頂Activity執行onPause操作。
  5. 棧頂Activity執行onPause操作結束,通知ActivityManagerService onPause完成。
  6. 為啟動Activity創建新進程。
  7. Activity所在應用進程和主線程初始化完成之后創建Application。
  8. 繼續啟動Activity。
時序圖

用戶調用startActivitystartActivityForResult

//frameworks/base/core/java/android/app/Activity.java
5533    @Override
5534    public void startActivity(Intent intent, @Nullable Bundle options) {
5535        if (options != null) {
5536            startActivityForResult(intent, -1, options);
5537        } else {
5538            // Note we want to go through this call for compatibility with
5539            // applications that may have overridden the method.
5540            startActivityForResult(intent, -1);
5541        }
5542    }
//frameworks/base/core/java/android/app/Activity.java
5901    @Override
5902    @UnsupportedAppUsage
5903    public void startActivityForResult(
5904            String who, Intent intent, int requestCode, @Nullable Bundle options) {
5905        Uri referrer = onProvideReferrer();
5906        if (referrer != null) {
5907            intent.putExtra(Intent.EXTRA_REFERRER, referrer);
5908        }
5909        options = transferSpringboardActivityOptions(options);
5910        Instrumentation.ActivityResult ar =
5911            mInstrumentation.execStartActivity(
5912                this, mMainThread.getApplicationThread(), mToken, who,
5913                intent, requestCode, options);
5914        if (ar != null) {
5915            mMainThread.sendActivityResult(
5916                mToken, who, requestCode,
5917                ar.getResultCode(), ar.getResultData());
5918        }
5919        cancelInputsAndStartExitTransition(options);
5920    }

execStartActivity里面我們需要注意兩個參數。mMainThread.getApplicationThread()會返回一個ApplicationThread類型的變量。這個變量我們在上一章已經介紹過了,這里ApplicationThread代表的是發起請求的APP1,后面AMS和APP1就通過它來進行跨進程通信,步驟2 AMS中止APP1,AMS就是根據這個參數找到APP1的。mToken我們在上一章中也介紹過了,它是連接ActivityRecordActivityClientRecordactivity的橋梁,AMS通過它就可以獲取APP1的詳細信息了。

//frameworks/base/core/java/android/app/Instrumentation.java
1677    @UnsupportedAppUsage
1678    public ActivityResult execStartActivity(
1679            Context who, IBinder contextThread, IBinder token, Activity target,
1680            Intent intent, int requestCode, Bundle options) {
        ........
1711            int result = ActivityTaskManager.getService()
1712                .startActivity(whoThread, who.getBasePackageName(), intent,
1713                        intent.resolveTypeIfNeeded(who.getContentResolver()),
1714                        token, target != null ? target.mEmbeddedID : null,
1715                        requestCode, 0, null, options);
        ........

startActivity會進行一次binder調用,ActivityTaskManagerService之前講過是用來分擔ActivityManagerService的一些功能的。這個地方開始就從當前應用APP1跳轉到了AMS,通知AMS要啟動APP2。

//frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
1008    @Override
1009    public final int startActivity(IApplicationThread caller, String callingPackage,
1010            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
1011            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
1012        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
1013                resultWho, requestCode, startFlags, profilerInfo, bOptions,
1014                UserHandle.getCallingUserId());
1015    }

APP1要求啟動APP2,我們需要記錄幾個關鍵的參數,
caller:誰發起了這次啟動請求,
intent:被啟動activity APP2的信息,
resultTo:發起啟動要求的APP1的信息。
這樣誰要求啟動誰這個請求就很清晰的傳遞給了AMS。

//frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
1031    @Override
1032    public int startActivityAsUser(IApplicationThread caller, String callingPackage,
1033            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
1034            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
1035        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
1036                resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
1037                true /*validateIncomingUser*/);
1038    }
1039
1040    int startActivityAsUser(IApplicationThread caller, String callingPackage,
1041            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
1042            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
1043            boolean validateIncomingUser) {
1044        enforceNotIsolatedCaller("startActivityAsUser");
1045
1046        userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
1047                Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
1048
1049        // TODO: Switch to user app stacks here.
1050        return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
1051                .setCaller(caller)
1052                .setCallingPackage(callingPackage)
1053                .setResolvedType(resolvedType)
1054                .setResultTo(resultTo)
1055                .setResultWho(resultWho)
1056                .setRequestCode(requestCode)
1057                .setStartFlags(startFlags)
1058                .setProfilerInfo(profilerInfo)
1059                .setActivityOptions(bOptions)
1060                .setMayWait(userId)
1061                .execute();
1062
1063    }

首先獲取并初始化ActivityStater對象,然后調用它的execute方法。

//frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
511    int execute() {
512        try {
513            // TODO(b/64750076): Look into passing request directly to these methods to allow
514            // for transactional diffs and preprocessing.
515            if (mRequest.mayWait) {
516                return startActivityMayWait(mRequest.caller, mRequest.callingUid,
517                        mRequest.callingPackage, mRequest.realCallingPid, mRequest.realCallingUid,
518                        mRequest.intent, mRequest.resolvedType,
519                        mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
520                        mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
521                        mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
522                        mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
523                        mRequest.inTask, mRequest.reason,
524                        mRequest.allowPendingRemoteAnimationRegistryLookup,
525                        mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
526            } else {
527                return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
528                        mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
529                        mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
530                        mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,
531                        mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
532                        mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
533                        mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
534                        mRequest.outActivity, mRequest.inTask, mRequest.reason,
535                        mRequest.allowPendingRemoteAnimationRegistryLookup,
536                        mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
537            }
538        } finally {
539            onExecutionComplete();
540        }
541    }

接著調用startActivityMayWait

//frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
1144    private int startActivityMayWait(IApplicationThread caller, int callingUid,
1145            String callingPackage, int requestRealCallingPid, int requestRealCallingUid,
1146            Intent intent, String resolvedType, IVoiceInteractionSession voiceSession,
1147            IVoiceInteractor voiceInteractor, IBinder resultTo, String resultWho, int requestCode,
1148            int startFlags, ProfilerInfo profilerInfo, WaitResult outResult,
1149            Configuration globalConfig, SafeActivityOptions options, boolean ignoreTargetSecurity,
1150            int userId, TaskRecord inTask, String reason,
1151            boolean allowPendingRemoteAnimationRegistryLookup,
1152            PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {
        ........  
            //PakageManagerService解析intent(APP2的intent),獲取Activity更多的信息
1194        ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
1195                0 /* matchFlags */,
1196                        computeResolveFilterUid(
1197                                callingUid, realCallingUid, mRequest.filterCallingUid));
        ........
1297            final ActivityRecord[] outRecord = new ActivityRecord[1];
1298            int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,
1299                    voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
1300                    callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
1301                    ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
1302                    allowPendingRemoteAnimationRegistryLookup, originatingPendingIntent,
        ........
//frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
568    private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
569            String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
570            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
571            IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
572            String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
573            SafeActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
574            ActivityRecord[] outActivity, TaskRecord inTask, String reason,
575            boolean allowPendingRemoteAnimationRegistryLookup,
576            PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {
        ........
585        mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
586                aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
587                callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
588                options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
589                inTask, allowPendingRemoteAnimationRegistryLookup, originatingPendingIntent,
590                allowBackgroundActivityStart);
591
592        if (outActivity != null) {
593            // mLastStartActivityRecord[0] is set in the call to startActivity above.
594            outActivity[0] = mLastStartActivityRecord[0];
595        }
596
597        return getExternalResult(mLastStartActivityResult);
598    }
/frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
613    private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
614            String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
615            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
616            IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
617            String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
618            SafeActivityOptions options,
619            boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
620            TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup,
621            PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {
        ........
629        if (caller != null) {
630            callerApp = mService.getProcessController(caller);
631            if (callerApp != null) {
                   //獲取調用者的pid和uid
632                callingPid = callerApp.getPid();
633                callingUid = callerApp.mInfo.uid;
        ........
           //sourceRecord表示發起本次請求的Activity,即父Activity對應的信息
           //resultRecord表示接收處理結果的Activity。一般情況下二者相等
650        ActivityRecord sourceRecord = null;
651        ActivityRecord resultRecord = null;
652        if (resultTo != null) {
653            sourceRecord = mRootActivityContainer.isInAnyStack(resultTo);
654            if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
655                    "Will send result to " + resultTo + " " + sourceRecord);
656            if (sourceRecord != null) {
657                if (requestCode >= 0 && !sourceRecord.finishing) {
658                    resultRecord = sourceRecord;
659                }
660            }
661        }
        ........
           //創建ActivityRecord,ActivityRecord用于保存Activity的信息,現在AMS已經擁有了該Activity的實例,但他還沒有和TaskRecord關聯起來
901        ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
902                callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
903                resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
904                mSupervisor, checkedOptions, sourceRecord);
905        if (outActivity != null) {
906            outActivity[0] = r;
907        }
        .......
935        final int res = startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
936                true /* doResume */, checkedOptions, inTask, outActivity, restrictedBgActivity);
937        mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outActivity[0]);
938        return res;
939    }
//frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
1396    private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
1397                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
1398                int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
1399                ActivityRecord[] outActivity, boolean restrictedBgActivity) {
1400        int result = START_CANCELED;
1401        final ActivityStack startedActivityStack;
1402        try {
1403            mService.mWindowManager.deferSurfaceLayout();
1404            result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
1405                    startFlags, doResume, options, inTask, outActivity, restrictedBgActivity);
        ........

startActivityUnchecked這個函數最重要的工作就是為我們剛剛創建好的ActivityRecord找到它對用的TaskRecordActivityStack

//frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
1474    private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
1475            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
1476            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
1477            ActivityRecord[] outActivity, boolean restrictedBgActivity) {
        ........
1665        // Should this be considered a new task?
1666        int result = START_SUCCESS;
1667        if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
1668                && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
1669            newTask = true;
                //ActivityRecord和TaskRecord,ActivityStack就是在這個函數建立聯系的,詳細過程可以參考上一篇博客
1670            result = setTaskFromReuseOrCreateNewTask(taskToAffiliate);
        ........
1728                mRootActivityContainer.resumeFocusedStacksTopActivities(
1729                        mTargetStack, mStartActivity, mOptions);
1730            }
1731        } else if (mStartActivity != null) {
1732            mSupervisor.mRecentTasks.add(mStartActivity.getTaskRecord());
1733        }
1734        mRootActivityContainer.updateUserStack(mStartActivity.mUserId, mTargetStack);
1735
1736        mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTaskRecord(),
1737                preferredWindowingMode, mPreferredDisplayId, mTargetStack);
1738
1739        return START_SUCCESS;
1740    }
//frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java
1149    boolean resumeFocusedStacksTopActivities(
1150            ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
1151
1152        if (!mStackSupervisor.readyToResume()) {
1153            return false;
1154        }
1155
1156        boolean result = false;
1157        if (targetStack != null && (targetStack.isTopStackOnDisplay()
1158                || getTopDisplayFocusedStack() == targetStack)) {
1159            result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
1160        }
        ........
//frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java
2567    boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
2568        if (mInResumeTopActivity) {
2569            // Don't even start recursing.
2570            return false;
2571        }
2572
2573        boolean result = false;
2574        try {
2575            // Protect against recursion.
2576            mInResumeTopActivity = true;
2577            result = resumeTopActivityInnerLocked(prev, options);
2578
2579            // When resuming the top activity, it may be necessary to pause the top activity (for
2580            // example, returning to the lock screen. We suppress the normal pause logic in
2581            // {@link #resumeTopActivityUncheckedLocked}, since the top activity is resumed at the
2582            // end. We call the {@link ActivityStackSupervisor#checkReadyForSleepLocked} again here
2583            // to ensure any necessary pause logic occurs. In the case where the Activity will be
2584            // shown regardless of the lock screen, the call to
2585            // {@link ActivityStackSupervisor#checkReadyForSleepLocked} is skipped.
2586            final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
2587            if (next == null || !next.canTurnScreenOn()) {
2588                checkReadyForSleep();
2589            }
2590        } finally {
2591            mInResumeTopActivity = false;
2592        }
2593
2594        return result;
2595    }

//frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java
2616    private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
2617        if (!mService.isBooting() && !mService.isBooted()) {
2618            // Not ready yet!
2619            return false;
2620        }
        ........
2747        if (mResumedActivity != null) {
2748            if (DEBUG_STATES) Slog.d(TAG_STATES,
2749                    "resumeTopActivityLocked: Pausing " + mResumedActivity);
                //中止當前activity
2750            pausing |= startPausingLocked(userLeaving, false, next, false);
2751        }
        ........
                //繼續activity的啟動
3039            mStackSupervisor.startSpecificActivityLocked(next, true, true);
3040        }
3041
3042        return true;
3043    }

如果當前界面正在顯示一個Activity,那么在啟動新的Activity之前必須中斷當前的Activity,中斷完成之后繼續調用startSpectificActivityLocked函數繼續啟動activity。步驟1,2主要做的就是根據APP1啟動APP2的請求,為APP1創建ActivityRecord,并為這個ActivityRecord找到找到它所屬的TaskRecordActivityStack,ActivityDisplay

接下來我們看下步驟3,4,`onPause`當前Activity,我們還是先看下這一步驟的時序圖:
//frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java
1653      final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
1654              ActivityRecord resuming, boolean pauseImmediately) {
          ........
//Android 9.0之后引入了ClientLifecycleManager和ClientTransactionHandler來輔助管理Activity的
//生命周期,它會發送EXECUTE_TRANSACTION消息到ActivityThread.H里面繼續執行。這邊我們要注意傳入了
//一個參數PauseActivityItem
1698                  mService.getLifecycleManager().scheduleTransaction(prev.app.getThread(),
1699                          prev.appToken, PauseActivityItem.obtain(prev.finishing, userLeaving,
1700                                  prev.configChangeFlags, pauseImmediately));
          ........
//frameworks/base/services/core/java/com/android/server/wm/ClientLifecycleManager.java
65      void scheduleTransaction(@NonNull IApplicationThread client, @NonNull IBinder activityToken,
66              @NonNull ActivityLifecycleItem stateRequest) throws RemoteException {
67          final ClientTransaction clientTransaction = transactionWithState(client, activityToken,
68                  stateRequest);
69          scheduleTransaction(clientTransaction);
70      }
 
 
45      void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
46          final IApplicationThread client = transaction.getClient();
47          transaction.schedule();
48          if (!(client instanceof Binder)) {
49              // If client is not an instance of Binder - it's a remote call and at this point it is
50              // safe to recycle the object. All objects used for local calls will be recycled after
51              // the transaction is executed on client in ActivityThread.
52              transaction.recycle();
53          }
54      }
 
//frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java
134      public void schedule() throws RemoteException {
135          mClient.scheduleTransaction(this);
136      }
137

Client是一個IApplicationThread類型。ActivityThread的內部類ApplicationThread派生這個接口類并實現對應的方法。所以直接跳轉到ApplicationThread中的scheduleTransaction方法。

//frameworks/base/core/java/android/app/ActivityThread.java
1665          public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
1666              ActivityThread.this.scheduleTransaction(transaction);
1667          }
1668  

接著調用它父類ClientTransactionHandlerscheduleTransaction方法

//frameworks/base/core/java/android/app/ClientTransactionHandler.java
45      void scheduleTransaction(ClientTransaction transaction) {
46          transaction.preExecute(this);
47          sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
48      }
49 

ClientTransactionHandler.scheduleTransaction方法中調用了sendMessage方法,這個方法是一個抽象方法,其實現在ClientTransactionHandler派生類ActivityThread中。ActivityThread.sendMessage方法會把消息發送給內部名字叫HHandler


//frameworks/base/core/java/android/app/ActivityThread.java
3106      void sendMessage(int what, Object obj) {
3107          sendMessage(what, obj, 0, 0, false);
3108      }
3109  
3110      private void sendMessage(int what, Object obj, int arg1) {
3111          sendMessage(what, obj, arg1, 0, false);
3112      }
3113  
3114      private void sendMessage(int what, Object obj, int arg1, int arg2) {
3115          sendMessage(what, obj, arg1, arg2, false);
3116      }
3117  
3118      private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
3119          if (DEBUG_MESSAGES) {
3120              Slog.v(TAG,
3121                      "SCHEDULE " + what + " " + mH.codeToString(what) + ": " + arg1 + " / " + obj);
3122          }
3123          Message msg = Message.obtain();
3124          msg.what = what;
3125          msg.obj = obj;
3126          msg.arg1 = arg1;
3127          msg.arg2 = arg2;
3128          if (async) {
3129              msg.setAsynchronous(true);
3130          }
3131          mH.sendMessage(msg);
3132      }
 
1853          public void handleMessage(Message msg) {
1854              if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
1855              switch (msg.what) {
          ........
2014                  case EXECUTE_TRANSACTION:
2015                      final ClientTransaction transaction = (ClientTransaction) msg.obj;
2016                      mTransactionExecutor.execute(transaction);
2017                      if (isSystem()) {
2018                          // Client transactions inside system process are recycled on the client side
2019                          // instead of ClientLifecycleManager to avoid being cleared before this
2020                          // message is handled.
2021                          transaction.recycle();
2022                      }
2023                      // TODO(lifecycler): Recycle locally scheduled transactions.
2024                      break;
          ........

Handler H的實例接收到EXECUTE_TRANSACTION消息后調用TransactionExecutor.execute切換Activity的狀態。

//frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java
69      public void execute(ClientTransaction transaction) {
70          if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Start resolving transaction");
71  
72          final IBinder token = transaction.getActivityToken();
73          if (token != null) {
74              final Map<IBinder, ClientTransactionItem> activitiesToBeDestroyed =
75                      mTransactionHandler.getActivitiesToBeDestroyed();
76              final ClientTransactionItem destroyItem = activitiesToBeDestroyed.get(token);
77              if (destroyItem != null) {
78                  if (transaction.getLifecycleStateRequest() == destroyItem) {
79                      // It is going to execute the transaction that will destroy activity with the
80                      // token, so the corresponding to-be-destroyed record can be removed.
81                      activitiesToBeDestroyed.remove(token);
82                  }
83                  if (mTransactionHandler.getActivityClient(token) == null) {
84                      // The activity has not been created but has been requested to destroy, so all
85                      // transactions for the token are just like being cancelled.
86                      Slog.w(TAG, tId(transaction) + "Skip pre-destroyed transaction:\n"
87                              + transactionToString(transaction, mTransactionHandler));
88                      return;
89                  }
90              }
91          }
92  
93          if (DEBUG_RESOLVER) Slog.d(TAG, transactionToString(transaction, mTransactionHandler));
94  
95          executeCallbacks(transaction);
96  
97          executeLifecycleState(transaction);
98          mPendingActions.clear();
99          if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "End resolving transaction");
100      }

接下來我們關注executeLifecycleState函數。

//frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java
152      private void executeLifecycleState(ClientTransaction transaction) {
             //我們最開始在ActivityStack.startPausingLocked方法里面scheduleTransaction
             //傳遞的是PauseActivityItem
153          final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
154          if (lifecycleItem == null) {
155              // No lifecycle request, return early.
156              return;
157          }
158  
159          final IBinder token = transaction.getActivityToken();
160          final ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
161          if (DEBUG_RESOLVER) {
162              Slog.d(TAG, tId(transaction) + "Resolving lifecycle state: "
163                      + lifecycleItem + " for activity: "
164                      + getShortActivityName(token, mTransactionHandler));
165          }
166  
167          if (r == null) {
168              // Ignore requests for non-existent client records for now.
169              return;
170          }
171  
172          // Cycle to the state right before the final requested state.
173          cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */, transaction);
174  
175          // Execute the final transition with proper parameters.
176          lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
             //調用PauseActivityItem.execute
177          lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
178      }
//frameworks/base/core/java/android/app/servertransaction/PauseActivityItem.java
43      public void execute(ClientTransactionHandler client, IBinder token,
44              PendingTransactionActions pendingActions) {
45          Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
46          client.handlePauseActivity(token, mFinished, mUserLeaving, mConfigChanges, pendingActions,
47                  "PAUSE_ACTIVITY_ITEM");
48          Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
49      }
50

PauseActivityItem.execute方法中調用Activity.handlePauseActivity方法。

//frameworks/base/core/java/android/app/ActivityThread.java
4397      public void handlePauseActivity(IBinder token, boolean finished, boolean userLeaving,
4398              int configChanges, PendingTransactionActions pendingActions, String reason) {
4399          ActivityClientRecord r = mActivities.get(token);
4400          if (r != null) {
4401              if (userLeaving) {
4402                  performUserLeavingActivity(r);
4403              }
4404  
4405              r.activity.mConfigChangeFlags |= configChanges;
4406              performPauseActivity(r, finished, reason, pendingActions);
4407  
4408              // Make sure any pending writes are now committed.
4409              if (r.isPreHoneycomb()) {
4410                  QueuedWork.waitToFinish();
4411              }
4412              mSomeActivitiesChanged = true;
4413          }
4414      }
 
4430      private Bundle performPauseActivity(ActivityClientRecord r, boolean finished, String reason,
4431              PendingTransactionActions pendingActions) {
4432          if (r.paused) {
4433              if (r.activity.mFinished) {
4434                  // If we are finishing, we won't call onResume() in certain cases.
4435                  // So here we likewise don't want to call onPause() if the activity
4436                  // isn't resumed.
4437                  return null;
4438              }
4439              RuntimeException e = new RuntimeException(
4440                      "Performing pause of activity that is not resumed: "
4441                      + r.intent.getComponent().toShortString());
4442              Slog.e(TAG, e.getMessage(), e);
4443          }
4444          if (finished) {
4445              r.activity.mFinished = true;
4446          }
4447  
4448          // Pre-Honeycomb apps always save their state before pausing
4449          final boolean shouldSaveState = !r.activity.mFinished && r.isPreHoneycomb();
4450          if (shouldSaveState) {
4451              callActivityOnSaveInstanceState(r);
4452          }
4453  
4454          performPauseActivityIfNeeded(r, reason);
          ........
 
4481      private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
4482          if (r.paused) {
4483              // You are already paused silly...
4484              return;
4485          }
4486  
4487          // Always reporting top resumed position loss when pausing an activity. If necessary, it
4488          // will be restored in performResumeActivity().
4489          reportTopResumedActivityChanged(r, false /* onTop */, "pausing");
4490  
4491          try {
4492              r.activity.mCalled = false;
4493              mInstrumentation.callActivityOnPause(r.activity);
4494              if (!r.activity.mCalled) {
4495                  throw new SuperNotCalledException("Activity " + safeToComponentShortString(r.intent)
4496                          + " did not call through to super.onPause()");
4497              }
4498          } catch (SuperNotCalledException e) {
4499              throw e;
4500          } catch (Exception e) {
4501              if (!mInstrumentation.onException(r.activity, e)) {
4502                  throw new RuntimeException("Unable to pause activity "
4503                          + safeToComponentShortString(r.intent) + ": " + e.toString(), e);
4504              }
4505          }
4506          r.setState(ON_PAUSE);
4507      }

繼調用InstrumentationcallActivityOnPause


//frameworks/base/core/java/android/app/Instrumentation.java
1506      public void callActivityOnPause(Activity activity) {
1507          activity.performPause();
1508      }

performPause方法中我們終于看到了熟悉的身影Activity生命周期的onPause方法,至此棧頂Activity的Pause流程全部結束。

//frameworks/base/core/java/android/app/Activity.java
7973      final void performPause() {
7974          dispatchActivityPrePaused();
7975          mDoReportFullyDrawn = false;
7976          mFragments.dispatchPause();
7977          mCalled = false;
7978          onPause();
7979          writeEventLog(LOG_AM_ON_PAUSE_CALLED, "performPause");
7980          mResumed = false;
7981          if (!mCalled && getApplicationInfo().targetSdkVersion
7982                  >= android.os.Build.VERSION_CODES.GINGERBREAD) {
7983              throw new SuperNotCalledException(
7984                      "Activity " + mComponent.toShortString() +
7985                      " did not call through to super.onPause()");
7986          }
7987          dispatchActivityPostPaused();
7988      }

我們繼續流程分析,步驟6為要啟動的APP2創建Process。還是先把時序圖放上來。


//frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
956      void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
957          // Is this activity's application already running?
958          final WindowProcessController wpc =
959                  mService.getProcessController(r.processName, r.info.applicationInfo.uid);
960  
961          boolean knownToBeDead = false;
962          if (wpc != null && wpc.hasThread()) {
963              try {
                     //如果進程和線程存在,則直接調用realStartActivityLocked
964                  realStartActivityLocked(r, wpc, andResume, checkConfig);
965                  return;
966              } catch (RemoteException e) {
967                  Slog.w(TAG, "Exception when starting activity "
968                          + r.intent.getComponent().flattenToShortString(), e);
969              }
970  
971              // If a dead object exception was thrown -- fall through to
972              // restart the application.
973              knownToBeDead = true;
974          }
          ........
990              final Message msg = PooledLambda.obtainMessage(
991                      ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
992                      r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());
993              mService.mH.sendMessage(msg);
994          } finally {
995              Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
996          }
997      }

ActivityManagerInternal的實現類為ActivityManagerService.localService

//frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
18400          public void startProcess(String processName, ApplicationInfo info,
18401                  boolean knownToBeDead, String hostingType, ComponentName hostingName) {
18402              try {
18403                  if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
18404                      Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "startProcess:"
18405                              + processName);
18406                  }
18407                  synchronized (ActivityManagerService.this) {
18408                      startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,
18409                              new HostingRecord(hostingType, hostingName),
18410                              false /* allowWhileBooting */, false /* isolated */,
18411                              true /* keepIfLarge */);
18412                  }
18413              } finally {
18414                  Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
18415              }
18416          }
 
3022      final ProcessRecord startProcessLocked(String processName,
3023              ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3024              HostingRecord hostingRecord, boolean allowWhileBooting,
3025              boolean isolated, boolean keepIfLarge) {
3026          return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
3027                  hostingRecord, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3028                  null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3029                  null /* crashHandler */);
3030      }

startProcessLocked這個方法開始準備創建進程,這個方法調用的是ProcessList的startProcessLocked方法。

1849      final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
1850              boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord,
1851              boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
1852              String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
          ........
1920          if (app == null) {
1921              checkSlow(startTime, "startProcess: creating new process record");
                  //創建ProcessRecord
1922              app = newProcessRecordLocked(info, processName, isolated, isolatedUid, hostingRecord);
          ........
1952          checkSlow(startTime, "startProcess: stepping in to startProcess");
1953          final boolean success = startProcessLocked(app, hostingRecord, abiOverride);
1954          checkSlow(startTime, "startProcess: done starting proc!");
1955          return success ? app : null;
1956      }
 
 
1842      final boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
1843              String abiOverride) {
1844          return startProcessLocked(app, hostingRecord,
1845                  false /* disableHiddenApiChecks */, false /* mountExtStorageFull */, abiOverride);
1846      }
 
1428      boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
1429              boolean disableHiddenApiChecks, boolean mountExtStorageFull,
1430              String abiOverride) {
          ........
1621              return startProcessLocked(hostingRecord, entryPoint, app, uid, gids,
1622                      runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
1623                      startTime);
1624          } catch (RuntimeException e) {
1625              Slog.e(ActivityManagerService.TAG, "Failure starting process " + app.processName, e);
1626  
1627              // Something went very wrong while trying to start this process; one
1628              // common case is when the package is frozen due to an active
1629              // upgrade. To recover, clean up any active bookkeeping related to
1630              // starting this process. (We already invoked this method once when
1631              // the package was initially frozen through KILL_APPLICATION_MSG, so
1632              // it doesn't hurt to use it again.)
1633              mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
1634                      false, false, true, false, false, app.userId, "start failure");
1635              return false;
1636          }
1637      }
 
 
1640      boolean startProcessLocked(HostingRecord hostingRecord,
1641              String entryPoint,
1642              ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
1643              String seInfo, String requiredAbi, String instructionSet, String invokeWith,
1644              long startTime) {
          ........
1667                  try {
                          //注意這個參數final String entryPoint = "android.app.ActivityThread";
1668                      final Process.ProcessStartResult startResult = startProcess(app.hostingRecord,
1669                              entryPoint, app, app.startUid, gids, runtimeFlags, mountExternal,
1670                              app.seInfo, requiredAbi, instructionSet, invokeWith, app.startTime);
1671                      synchronized (mService) {
1672                          handleProcessStartedLocked(app, startResult, startSeq);
1673                      }
          ........

內部經過一系列startProcessLocked的調用會來到startProcess函數。我們需要注意其中

final String entryPoint = "android.app.ActivityThread";這個參數,這個參數會一路從Process傳遞到ZygoteProcess,并在ZygoteProcess中調用startViaZygote方法,fork出一個新的進程。并根據傳遞的"android.app.ActivityThread"反射出該對象,于是進程創建進入到ActivityThreadmain方法中。這一部分的具體流程我們會單獨在后面的博客中進行講解。

至此我們已經創建好了進程。當Zygote創建完一個應用進程之后,得到的僅僅是一個可以運行的載體,它還沒有和Android系統建立聯系,我們需要為它創建一個運行環境Context,然后在裝載Provider信息,再將新創建的進程綁定到AMS中,這才是一個完整的Android進程。這就是我們步驟7需要完成的操作。
//frameworks/base/core/java/android/app/ActivityThread.java
7310      public static void main(String[] args) {
7311          Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
7312  
7313          // Install selective syscall interception
7314          AndroidOs.install();
7315  
7316          // CloseGuard defaults to true and can be quite spammy.  We
7317          // disable it here, but selectively enable it later (via
7318          // StrictMode) on debug builds, but using DropBox, not logs.
7319          CloseGuard.setEnabled(false);
7320  
7321          Environment.initForCurrentUser();
7322  
7323          // Make sure TrustedCertificateStore looks in the right place for CA certificates
7324          final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
7325          TrustedCertificateStore.setDefaultUserDirectory(configDir);
7326  
7327          Process.setArgV0("<pre-initialized>");
7328  
              //創建了主線程的Looper對象,并調用Looper.loop()方法啟動Loop
7329          Looper.prepareMainLooper();
          ........
7342          ActivityThread thread = new ActivityThread();
7343          thread.attach(false, startSeq);
7344  
7345          if (sMainThreadHandler == null) {
7346              sMainThreadHandler = thread.getHandler();
7347          }
7348  
7349          if (false) {
7350              Looper.myLooper().setMessageLogging(new
7351                      LogPrinter(Log.DEBUG, "ActivityThread"));
7352          }
7353  
7354          // End of event ActivityThreadMain.
7355          Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7356          Looper.loop();
7357  
7358          throw new RuntimeException("Main thread loop unexpectedly exited");
7359      }
 
7071      private void attach(boolean system, long startSeq) {
7072          sCurrentActivityThread = this;
7073          mSystemThread = system;
7074          if (!system) {
7075              android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
7076                                                      UserHandle.myUserId());
7077              RuntimeInit.setApplicationObject(mAppThread.asBinder());
7078              final IActivityManager mgr = ActivityManager.getService();
7079              try {
                      //這又是一個binder調用,它通過binder將ActivityThread中的IApplicationThread的實例傳遞給AMS,
                      //然后AMS就可以通過它與應用程序進行通信
7080                  mgr.attachApplication(mAppThread, startSeq);
          ........
//frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
5175      public final void attachApplication(IApplicationThread thread, long startSeq) {
5176          synchronized (this) {
5177              int callingPid = Binder.getCallingPid();
5178              final int callingUid = Binder.getCallingUid();
5179              final long origId = Binder.clearCallingIdentity();
5180              attachApplicationLocked(thread, callingPid, callingUid, startSeq);
5181              Binder.restoreCallingIdentity(origId);
5182          }
5183      }
 
4762      private final boolean attachApplicationLocked(IApplicationThread thread,
4763              int pid, int callingUid, long startSeq) {
          ........
5058                  thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
5059                          null, null, null, testMode,
5060                          mBinderTransactionTrackingEnabled, enableTrackAllocation,
5061                          isRestrictedBackupMode || !normalMode, app.isPersistent(),
5062                          new Configuration(app.getWindowProcessController().getConfiguration()),
5063                          app.compat, getCommonServicesLocked(app.isolated),
5064                          mCoreSettingsObserver.getCoreSettingsLocked(),
5065                          buildSerial, autofillOptions, contentCaptureOptions);
          ........
                  //將thread傳給ProcessRecord.thread,可以理解為將應用進程與AMS建立起了綁定
5074              app.makeActive(thread, mProcessStats);

我們從應用程序調用到AMS中又通過bindApplication調回到應用程序,它在AMS中最重要的事就是建立了應用程序與AMS的聯系。之前我們Zygote fork的進程并沒有包含任何與Activity相關的 信息,甚至連進程名都沒有真正命名。此處的bindApplication就是初始化這個新進程并創建對應的Android環境。

//frameworks/base/core/java/android/app/ActivityThread.java
996          public final void bindApplication(String processName, ApplicationInfo appInfo,
997                  List<ProviderInfo> providers, ComponentName instrumentationName,
998                  ProfilerInfo profilerInfo, Bundle instrumentationArgs,
999                  IInstrumentationWatcher instrumentationWatcher,
1000                  IUiAutomationConnection instrumentationUiConnection, int debugMode,
1001                  boolean enableBinderTracking, boolean trackAllocation,
1002                  boolean isRestrictedBackupMode, boolean persistent, Configuration config,
1003                  CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
1004                  String buildSerial, AutofillOptions autofillOptions,
1005                  ContentCaptureOptions contentCaptureOptions) {
          ........
1034              AppBindData data = new AppBindData();
1035              data.processName = processName;
1036              data.appInfo = appInfo;
1037              data.providers = providers;
1038              data.instrumentationName = instrumentationName;
1039              data.instrumentationArgs = instrumentationArgs;
1040              data.instrumentationWatcher = instrumentationWatcher;
1041              data.instrumentationUiAutomationConnection = instrumentationUiConnection;
1042              data.debugMode = debugMode;
1043              data.enableBinderTracking = enableBinderTracking;
1044              data.trackAllocation = trackAllocation;
1045              data.restrictedBackupMode = isRestrictedBackupMode;
1046              data.persistent = persistent;
1047              data.config = config;
1048              data.compatInfo = compatInfo;
1049              data.initProfilerInfo = profilerInfo;
1050              data.buildSerial = buildSerial;
1051              data.autofillOptions = autofillOptions;
1052              data.contentCaptureOptions = contentCaptureOptions;
1053              sendMessage(H.BIND_APPLICATION, data);
1054          }

ActivityThread的接口被AMS調用后,會將參數保存到AppBindData對象中,然后發送消息BIND_APPLICATIONActivityThread的主線程處理。

6122      private void handleBindApplication(AppBindData data) {
          ........
6154          // send up app name; do this *before* waiting for debugger
              //設置進程名
6155          Process.setArgV0(data.processName);
          ........
6428          try {
6429              // If the app is being launched for full backup or restore, bring it up in
6430              // a restricted environment with the base application class.
6431              app = data.info.makeApplication(data.restrictedBackupMode, null);
          ........
//frameworks/base/core/java/android/app/LoadedApk.java
1194      public Application makeApplication(boolean forceDefaultAppClass,
1195              Instrumentation instrumentation) {
          ........
1217              ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
1218              app = mActivityThread.mInstrumentation.newApplication(
1219                      cl, appClass, appContext);
          ........
1232          if (instrumentation != null) {
1233              try {
1234                  instrumentation.callApplicationOnCreate(app);
1235              } catch (Exception e) {
1236                  if (!instrumentation.onException(app, e)) {
1237                      Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1238                      throw new RuntimeException(
1239                          "Unable to create application " + app.getClass().getName()
1240                          + ": " + e.toString(), e);
1241                  }
1242              }
1243          }
          ........

data.info.makeApplication方法,在創建Application的過程中,接著調用InstrumentationnewApplication方法。

//frameworks/base/core/java/android/app/Instrumentation.java
1151      public Application newApplication(ClassLoader cl, String className, Context context)
1152              throws InstantiationException, IllegalAccessException,
1153              ClassNotFoundException {
1154          Application app = getFactory(context.getPackageName())
1155                  .instantiateApplication(cl, className);
1156          app.attach(context);
1157          return app;
1158      }

newApplication方法通過反射的方法創建Application。因為app安裝的時候會去解析manifest中的內容,因此查詢系統可以知道要啟動的application的具體類名,然后通過類名反射創建application。至此application創建完成。

創建application之后,通過InstrumentationcallApplicationOnCreate方法調用了創建Application對象的onCreate方法。

//frameworks/base/core/java/android/app/Instrumentation.java
1188      public void callApplicationOnCreate(Application app) {
1189          app.onCreate();
1190      }

終于走到應用的ApplicationonCreate方法,這一步驟結束。

application創建完成之后,繼續回到AMS中的attachApplicationLocked方法,接著啟動Activity的流程。

//frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
4762      private final boolean attachApplicationLocked(IApplicationThread thread,
4763              int pid, int callingUid, long startSeq) {
          ........
5101          if (normalMode) {
5102              try {
5103                  didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
5104              } catch (Exception e) {
5105                  Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
5106                  badApp = true;
5107              }
5108          }
          ........

mAtmInternalActivityTaskManagerService的內部類LocalService。在localServiceattachApplication方法中調用了RootActivityContainerattachApplication方法。

//frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
6867          public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
6868              synchronized (mGlobalLockWithoutBoost) {
6869                  return mRootActivityContainer.attachApplication(wpc);
6870              }
6871          }
 
//frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java
768      boolean attachApplication(WindowProcessController app) throws RemoteException {
          ........
if (activity.app == null && app.mUid == activity.info.applicationInfo.uid
781                              && processName.equals(activity.processName)) {
782                          try {
783                              if (mStackSupervisor.realStartActivityLocked(activity, app,
784                                      top == activity /* andResume */, true /* checkConfig */)) {
785                                  didSomething = true;
786                              }
787                          } catch (RemoteException e) {
788                              Slog.w(TAG, "Exception in new application when starting activity "
789                                      + top.intent.getComponent().flattenToShortString(), e);
790                              throw e;
791                          }
792                      }
          ........

在這我們看到了realStartActivityLocked,這個方法之前在startSpecificActivityLocked方法中見到過,只是當時我們還沒有創建好進程所以沒有執行。

//frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
705      boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
706              boolean andResume, boolean checkConfig) throws RemoteException {
          ........
827                  // Create activity launch transaction.
828                  final ClientTransaction clientTransaction = ClientTransaction.obtain(
829                          proc.getThread(), r.appToken);
830  
831                  final DisplayContent dc = r.getDisplay().mDisplayContent;
832                  clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
833                          System.identityHashCode(r), r.info,
834                          // TODO: Have this take the merged configuration instead of separate global
835                          // and override configs.
836                          mergedConfiguration.getGlobalConfiguration(),
837                          mergedConfiguration.getOverrideConfiguration(), r.compat,
838                          r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
839                          r.icicle, r.persistentState, results, newIntents,
840                          dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
841                                  r.assistToken));
842  
843                  // Set desired final state.
844                  final ActivityLifecycleItem lifecycleItem;
845                  if (andResume) {
846                      lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
847                  } else {
848                      lifecycleItem = PauseActivityItem.obtain();
849                  }
850                  clientTransaction.setLifecycleStateRequest(lifecycleItem);
851  
852                  // Schedule transaction.
853                  mService.getLifecycleManager().scheduleTransaction(clientTransaction);
          ........

新建了一個ClientTransaction對象后,設置LaunchActivityItemcallback,然后調用mServicegetLifecycleManager獲取到ClientLifecycleManager,在通過scheduleTransaction發送請求。這和pause Activity的流程類似,就是改變activity的生命周期。

//frameworks/base/services/core/java/com/android/server/wm/ClientLifecycleManager.java
45      void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
46          final IApplicationThread client = transaction.getClient();
47          transaction.schedule();
48          if (!(client instanceof Binder)) {
49              // If client is not an instance of Binder - it's a remote call and at this point it is
50              // safe to recycle the object. All objects used for local calls will be recycled after
51              // the transaction is executed on client in ActivityThread.
52              transaction.recycle();
53          }
54      }
 
//frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java
134      public void schedule() throws RemoteException {
135          mClient.scheduleTransaction(this);
136      }
 
//frameworks/base/core/java/android/app/ActivityThread.java
1665          public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
1666              ActivityThread.this.scheduleTransaction(transaction);
1667          }
 
//frameworks/base/core/java/android/app/ClientTransactionHandler.java
45      void scheduleTransaction(ClientTransaction transaction) {
46          transaction.preExecute(this);
47          sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
48      }

這邊經過了一圈調用就是向ActivityThread發送一個EXECUTE_TRANSACTION

//frameworks/base/core/java/android/app/ActivityThread.java
1853          public void handleMessage(Message msg) {
          ........
2014                  case EXECUTE_TRANSACTION:
2015                      final ClientTransaction transaction = (ClientTransaction) msg.obj;
2016                      mTransactionExecutor.execute(transaction);
2017                      if (isSystem()) {
2018                          // Client transactions inside system process are recycled on the client side
2019                          // instead of ClientLifecycleManager to avoid being cleared before this
2020                          // message is handled.
2021                          transaction.recycle();
2022                      }
2023                      // TODO(lifecycler): Recycle locally scheduled transactions.
2024                      break;
          ........

和之前pause時候類似,ClientTransactionexecute會調用LaunchActivityItemexecute

//frameworks/base/core/java/android/app/servertransaction/LaunchActivityItem.java
76      public void execute(ClientTransactionHandler client, IBinder token,
77              PendingTransactionActions pendingActions) {
78          Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
79          ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
80                  mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
81                  mPendingResults, mPendingNewIntents, mIsForward,
82                  mProfilerInfo, client, mAssistToken);
83          client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
84          Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
85      }

此處的client是一個ActivityThread對象,因此這里調用的ActivityThreadhandleLaunchActivity

//frameworks/base/core/java/android/app/ActivityThread.java
3381      public Activity handleLaunchActivity(ActivityClientRecord r,
3382              PendingTransactionActions pendingActions, Intent customIntent) {
          ........
3409          final Activity a = performLaunchActivity(r, customIntent);
          ........
 
3159      private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
          ........
3178          ContextImpl appContext = createBaseContextForActivity(r);
3179          Activity activity = null;
3180          try {
3181              java.lang.ClassLoader cl = appContext.getClassLoader();
3182              activity = mInstrumentation.newActivity(
3183                      cl, component.getClassName(), r.intent);
3184              StrictMode.incrementExpectedActivityCount(activity.getClass());
3185              r.intent.setExtrasClassLoader(cl);
3186              r.intent.prepareToEnterProcess();
3187              if (r.state != null) {
3188                  r.state.setClassLoader(cl);
3189              }
          ........
3224                  activity.attach(appContext, this, getInstrumentation(), r.token,
3225                          r.ident, app, r.intent, r.activityInfo, title, r.parent,
3226                          r.embeddedID, r.lastNonConfigurationInstances, config,
3227                          r.referrer, r.voiceInteractor, window, r.configCallback,
3228                          r.assistToken);
          ........
3242                  if (r.isPersistable()) {
3243                      mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
3244                  } else {
3245                      mInstrumentation.callActivityOnCreate(activity, r.state);
3246                  }
          ........

performLaunchActivity中通過mInstrumentationnewActivity方法創建了一個activityactivity就保存了上下文信息。然后通過attachactivityActivityThreadInstrumentationApplication等重要的類聯系起來。這一方法對ActivityComponentNameContextImplActivity以及Application對象進行了初始化并相互關聯。最后調用callActivityOnCreate

//frameworks/base/core/java/android/app/Instrumentation.java
1304      public void callActivityOnCreate(Activity activity, Bundle icicle) {
1305          prePerformCreate(activity);
1306          activity.performCreate(icicle);
1307          postPerformCreate(activity);
1308      }
1309  
 
 
//frameworks/base/core/java/android/app/Activity.java
 
7794      @UnsupportedAppUsage
7795      final void performCreate(Bundle icicle, PersistableBundle persistentState) {
7796          dispatchActivityPreCreated(icicle);
7797          mCanEnterPictureInPicture = true;
7798          restoreHasCurrentPermissionRequest(icicle);
7799          if (persistentState != null) {
7800              onCreate(icicle, persistentState);
7801          } else {
7802              onCreate(icicle);
7803          }
7804          writeEventLog(LOG_AM_ON_CREATE_CALLED, "performCreate");
7805          mActivityTransitionState.readState(icicle);
7806  
7807          mVisibleFromClient = !mWindow.getWindowStyle().getBoolean(
7808                  com.android.internal.R.styleable.Window_windowNoDisplay, false);
7809          mFragments.dispatchActivityCreated();
7810          mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
7811          dispatchActivityPostCreated(icicle);
7812      }

performCreate中調用了activityonCreateActivity創建完成。在Activity對象構建成功,并成功走完onCreateonStart兩個生命周期函數之后,便要進入onResume這個生命周期函數,至此完成Activity全部的啟動操作。Activity的啟動流程太過復雜,所以本篇博客只是總結了啟動的大致流程,其中有很多細節并沒有深入描寫。其中一些重要的細節,會在后續的博客中詳細分析。

基于Android Q的版本

  • Activity.startActivity(有幾個重載方法)
  • Activity.startActivityForResult
  • Instrumentation.execStartActivity
  • ActivityTaskManager.getService().startActivity
    即 IActivityTaskManagerSingleton.get().startActivity
    即 IActivityTaskManager.startActivity
    (aidl實現binder跨進程通訊,通訊的客戶端,以上部分在應用進程)
  • ActivityTaskManagerService.startActivity
    (ActivityTaskManagerService 繼承 IActivityTaskManager.Stub,實現了中的startActivity startActivities startActivityAsUser等方法,是跨進程通訊的服務端,這部分在系統進程)
  • ActivityTaskManagerService.startActivityAsUser
  • ActivityStarter.execute
  • ActivityStarter.startActivityMayWait
  • ActivityStarter.startActivity(有幾個重載方法)
  • ActivityStarter.startActivityUnchecked
  • ActivityStack.ensureActivitiesVisibleLocked(有幾個重載方法)
  • ActivityRecord.makeClientVisible
  • ActivityRecord.makeActiveIfNeeded
  • ActivityStack.resumeTopActivityUncheckedLocked
  • ActivityStack.resumeTopActivityInnerLocked
  • ActivityStackSupervisor.startSpecificActivityLocked
  • ActivityStackSupervisor.realStartActivityLocked
  • mService.getLifecycleManager().scheduleTransaction(clientTransaction)
    即 ClientLifecycleManager.scheduleTransaction
  • ClientTransaction.schedule
    (ClientTransaction中的mActivityCallbacks就是LaunchActivityItem)
  • mClient.scheduleTransaction()
    即 IApplicationThread.scheduleTransaction
    (這里也是使用aidl通過binder通訊,這是通訊的客戶端,這部分在系統進程)
  • ApplicationThread.scheduleTransaction
    (注:1.ApplicationThread是ActivityThread的內部類)
    (注:2.ApplicationThread 繼承了 IApplicationThread.Stub,實現了scheduleTransaction等方法,跨進程通訊的服務端,這部分在應用進程)
  • ActivityThread.scheduleTransaction
  • ClientTransactionHandler.scheduleTransaction
    (ActivityThread 繼承了 ClientTransactionHandler,此處調用父類方法)
  • ActivityThread.sendMessage (what = EXECUTE_TRANSACTION)
  • ActivityThread$H.handleMessage
    (使用ActivityThread內部Handler類H的handleMessage方法接收)
  • TransactionExecutor.execute
  • TransactionExecutor.executeCallbacks
  • ClientTransactionItem.execute
    (ClientTransactionItem 就是 LaunchActivityItem 的父類)
  • ClientTransactionHandler.handleLaunchActivity
    (ClientTransactionHandler 是 ActivityThread 的父類)
  • ActivityThread.performLaunchActivity
    {Instrumentation.newActivity創建activity實例 -> activity.attach -> activity.mIntent = customIntent -> activity.setTheme}
  • Instrumentation.callActivityOnCreate
  • Activity.performCreate
  • Activity.onCreate
    到這里activity就被啟動起來了。

總體來說,不管是哪個版本都是:

  • 首先startActivity
  • 通過Instrumentation調用ActivityManagerService(簡稱AMS)通過跨進程通訊,從應用進程調用到系統進程,并在系統進程中進行一些列操作
  • 在系統進程處理完成后,通過IApplicationThread也進行跨進程通訊,從系統進程回到應用進程,通過ActivityThread中的Handler處理消息
  • 最后又通過Instrumentation創建要啟動的Activity,并調用創建的activity的onCreate方法
    也就是說啟動Activity其實是經過了兩次跨進程通訊才將Activity啟動起來的。

感謝
https://blog.csdn.net/nanyou519/article/details/104735722

http://www.lxweimin.com/p/d94a40e0e5ec

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,825評論 6 546
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,814評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,980評論 0 384
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 64,064評論 1 319
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,779評論 6 414
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,109評論 1 330
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,099評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,287評論 0 291
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,799評論 1 338
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,515評論 3 361
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,750評論 1 375
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,221評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,933評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,327評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,667評論 1 296
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,492評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,703評論 2 380

推薦閱讀更多精彩內容