Activity的啓動過程詳解(基於10.0源碼) 二、流程分析 三、根Activity的啓動—應用進程啓動 總結

、Service、BroadcastReceiver、ContentProvider。我們最常接觸也是用戶直接感受到的就是Activity了,今天來就說說Android啓動的執行過程和工作原理。

Activity是一種 展示型組件,用於展示給用戶一個可以交互的頁面。Activity是Android中最重要的組件,對用戶來說,所有的Activity就是一個App的全部,而其他組件用戶是不能直接感知的。在開發層面,要啓動一個Activity可以使用Intent,分顯式和隱式,並且還可以設置Activity的啓動模式

Android系統對四大組件都做了很大程度的封裝,這樣我們可以快速使用組件。Activity的啓動在系統封裝後,變的極爲簡單,顯示啓動activity代碼如下:

Intent intent = new Intent(this, TestActivity.class);
this.startActivity(intent);

這樣就可以啓動TestActivity了,那麼問題來了,

  • 這個代碼是如何啓動一個Activity的?
  • 裏面做了哪些事情?
  • onCreate這些生命週期是何時執行的?
  • Activity對象何時創建的?
  • 視圖是怎麼處理以及何時可見的?

那麼爲啥需要了解這些問題呢?不瞭解 ,平時開發好像也沒啥問題啊。其實不然,解決這些問題後,你會對Android系統有更深層次的理解,也會學習到系統源碼優秀的設計。並且對解決一些高級問題和深入的性能優化問題有很大幫助,是技術進階的必要階段。這就需要我們通過閱讀源碼來梳理這些問題,但另一方面,系統源碼是很龐大繁雜的,我們需要帶着問題抓住主流程,不能陷入代碼細節——這是閱讀系統源碼以及其他第三方庫源碼的正確姿勢。

二、流程分析

本部分流程分析涉及技術知識點較多, 建議先對 IPCHandler等相關知識有一定掌握。

2.1 Activity啓動的發起

下面我們就來對Activity的工作流程進行梳理,達到對Activity整體流程的掌握。從startActivity方法開始,會走到startActivityForResult方法:

    public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
        if (mParent == null) {
            options = transferSpringboardActivityOptions(options);
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
            if (ar != null) {
                mMainThread.sendActivityResult(
                    mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                    ar.getResultData());
            }
            if (requestCode >= 0) {
                mStartedActivity = true;
            }

            cancelInputsAndStartExitTransition(options);
        } else {
            ...
        }
    }

看到裏面調用了mInstrumentation.execStartActivity方法,其中一個參數mMainThread.getApplicationThread(),它的類型是ApplicationThread,ApplicationThread是ActivityThread的內部類,繼承IApplicationThread.Stub,也是個Binder對象,在Activity工作流程中有重要作用。而Instrumentation具有跟蹤application及activity生命週期的功能,用於android 應用測試框架中代碼檢測。接着看下mInstrumentation.execStartActivity方法:

    public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        IApplicationThread whoThread = (IApplicationThread) contextThread;
        Uri referrer = target != null ? target.onProvideReferrer() : null;
        if (referrer != null) {
            intent.putExtra(Intent.EXTRA_REFERRER, referrer);
        }
        ...

        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);
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }

這裏看到Activity的啓動又交給了ActivityTaskManager.getService(),這是啥?跟進去看看:

//ActivityTaskManager
    public static IActivityTaskManager getService() {
        return IActivityTaskManagerSingleton.get();
    }
    
    private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
            new Singleton<IActivityTaskManager>() {
                @Override
                protected IActivityTaskManager create() {
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);
                    return IActivityTaskManager.Stub.asInterface(b);
                }
            };

看到IBinder這個標誌,這裏你應該明白了:這裏是獲取一個跨進程的服務。獲取的什麼服務呢?是ActivityTaskManagerService(ATMS),它繼承於IActivityTaskManager.Stub,是個Binder對象,並且是通過單例提供服務的。 ATMS是用於管理Activity及其容器(任務、堆棧、顯示等)的系統服務,運行在系統服務進程(system_server)之中。

值得說明的是,ATMS是在Android10中新增的,分擔了之前ActivityManagerService(AMS)的一部分功能(activity task相關)。
在Android10 之前 ,這個地方獲取的是服務是AMS。查看Android10的AMS,你會發現startActivity方法內也是調用了ATMS的startActivity方法。所以在理解上,ATMS就隸屬於AMS。

接着看,ActivityTaskManager.getService().startActivity有個返回值result,且調用了checkStartActivityResult(result, intent):

    public static void checkStartActivityResult(int res, Object intent) {
        if (!ActivityManager.isStartResultFatalError(res)) {
            return;
        }

        switch (res) {
            case ActivityManager.START_INTENT_NOT_RESOLVED:
            case ActivityManager.START_CLASS_NOT_FOUND:
                if (intent instanceof Intent && ((Intent)intent).getComponent() != null)
                    throw new ActivityNotFoundException(
                            "Unable to find explicit activity class "
                            + ((Intent)intent).getComponent().toShortString()
                            + "; have you declared this activity in your AndroidManifest.xml?");
                throw new ActivityNotFoundException(
                        "No Activity found to handle " + intent);
            case ActivityManager.START_PERMISSION_DENIED:
                throw new SecurityException("Not allowed to start activity "
                        + intent);
            ...
            
            case ActivityManager.START_CANCELED:
                throw new AndroidRuntimeException("Activity could not be started for "
                        + intent);
            default:
                throw new AndroidRuntimeException("Unknown error code "
                        + res + " when starting " + intent);
        }
    }

這是用來檢查Activity啓動的結果,如果發生致命錯誤,就會拋出對應的異常。看到第一個case中就拋出了 have you declared this activity in your AndroidManifest.xml?——如果Activity沒在Manifest中註冊就會有這個錯誤。

2.2 Activity的管理——ATMS

好了,到這裏,Activity的啓動就跨進程(IPC)的轉移到系統進程提供的服務ATMS中了,接着看ATMS的startActivity:

//ActivityTaskManagerService
    @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());
    }
    
    @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*/);
    }

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

    }

跟到startActivityAsUser中,通過getActivityStartController().obtainStarter方法獲取ActivityStarter實例 然後調用一系列方法,最後的execute()方法是開始啓動activity:

    int execute() {
        try {
            // TODO(b/64750076): Look into passing request directly to these methods to allow
            // for transactional diffs and preprocessing.
            if (mRequest.mayWait) {
                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);
            } else {
                return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
                        mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
                        mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
                        mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,
                        mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
                        mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
                        mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
                        mRequest.outActivity, mRequest.inTask, mRequest.reason,
                        mRequest.allowPendingRemoteAnimationRegistryLookup,
                        mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
            }
        } finally {
            onExecutionComplete();
        }
    }

分了兩種情況,不過 不論startActivityMayWait還是startActivity最終都是走到下面這個startActivity方法:

    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);
        } finally {
            final ActivityStack currentStack = r.getActivityStack();
            startedActivityStack = currentStack != null ? currentStack : mTargetStack;

           ...
        }

        postStartActivityProcessing(r, result, startedActivityStack);
        return result;
    }

裏面有調用了startActivityUnchecked方法,之後調用RootActivityContainer的resumeFocusedStacksTopActivities方法。RootActivityContainer是Android10新增的類,分擔了之前ActivityStackSupervisor的部分功能。接着跳轉到ActivityStack的resumeTopActivityUncheckedLocked方法:

//ActivityStack
    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);

            final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
            if (next == null || !next.canTurnScreenOn()) {
                checkReadyForSleep();
            }
        } finally {
            mInResumeTopActivity = false;
        }

        return result;
    }

跟進resumeTopActivityInnerLocked方法:

    private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
        ...
        boolean pausing = getDisplay().pauseBackStacks(userLeaving, next, false);
        if (mResumedActivity != null) {
            if (DEBUG_STATES) Slog.d(TAG_STATES,
                    "resumeTopActivityLocked: Pausing " + mResumedActivity);
             // 暫停上一個Activity
            pausing |= startPausingLocked(userLeaving, false, next, false);
        }
        ...
        //這裏next.attachedToProcess(),只有啓動了的Activity纔會返回true
        if (next.attachedToProcess()) {
            ...
            
            try {
                final ClientTransaction transaction =
                        ClientTransaction.obtain(next.app.getThread(), next.appToken);
                ...
                //啓動了的Activity就發送ResumeActivityItem事務給客戶端了,後面會講到
                transaction.setLifecycleStateRequest(
                        ResumeActivityItem.obtain(next.app.getReportedProcState(),
                                getDisplay().mDisplayContent.isNextTransitionForward()));
                mService.getLifecycleManager().scheduleTransaction(transaction);
               ....
            } catch (Exception e) {
                ....
                mStackSupervisor.startSpecificActivityLocked(next, true, false);
                return true;
            }
            ....
        } else {
            ....
            // 繼續當前Activity,普通activity的正常啓動 關注這裏即可
            mStackSupervisor.startSpecificActivityLocked(next, true, true);
        }
        return true;
    }

先對上一個Activity執行pause操作,再執行當前創建操作,代碼最終進入到了ActivityStackSupervisor.startSpecificActivityLocked方法中:

    void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
        // Is this activity's application already running?
        final WindowProcessController wpc =
                mService.getProcessController(r.processName, r.info.applicationInfo.uid);

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

        ...
        
        try {
            if (Trace.isTagEnabled(TRACE_TAG_ACTIVITY_MANAGER)) {
                Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "dispatchingStartProcess:"
                        + r.processName);
            }
            // 上面的wpc != null && wpc.hasThread()不滿足的話,說明沒有進程,就會取創建進程
            final Message msg = PooledLambda.obtainMessage(
                    ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
                    r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());
            mService.mH.sendMessage(msg);
        } finally {
            Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
        }
    }

有個判斷條件if (wpc != null && wpc.hasThread()),意思是是否啓動了應用進程,內部是通過IApplicationThread是否爲空來判斷。這裏我們只看已啓動應用進程的情況,及調用了realStartActivityLocked方法,,:

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

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

                // 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);

                ...

        return true;
    }

中間有段代碼如上,通過 ClientTransaction.obtain( proc.getThread(), r.appToken)獲取了clientTransaction,其中參數proc.getThread()是IApplicationThread,就是前面提到的ApplicationThread在系統進程的代理。

ClientTransaction是包含一系列的待客戶端處理的事務的容器,客戶端接收後取出事務並執行。

接着看,使用clientTransaction.addCallback添加了LaunchActivityItem實例:

    //都是用來發送到客戶端的
    private List<ClientTransactionItem> mActivityCallbacks;
    
    public void addCallback(ClientTransactionItem activityCallback) {
        if (mActivityCallbacks == null) {
            mActivityCallbacks = new ArrayList<>();
        }
        mActivityCallbacks.add(activityCallback);
    }

看下LaunchActivityItem實例的獲取:

    /** Obtain an instance initialized with provided params. */
    public static LaunchActivityItem obtain(Intent intent, int ident, ActivityInfo info,
            Configuration curConfig, Configuration overrideConfig, CompatibilityInfo compatInfo,
            String referrer, IVoiceInteractor voiceInteractor, int procState, Bundle state,
            PersistableBundle persistentState, List<ResultInfo> pendingResults,
            List<ReferrerIntent> pendingNewIntents, boolean isForward, ProfilerInfo profilerInfo,
            IBinder assistToken) {
        LaunchActivityItem instance = ObjectPool.obtain(LaunchActivityItem.class);
        if (instance == null) {
            instance = new LaunchActivityItem();
        }
        setValues(instance, intent, ident, info, curConfig, overrideConfig, compatInfo, referrer,
                voiceInteractor, procState, state, persistentState, pendingResults,
                pendingNewIntents, isForward, profilerInfo, assistToken);

        return instance;
    }

new了一個LaunchActivityItem然後設置各種值。我們從名字就能看出,它就是用來啓動activity的。它是怎麼發揮作用的呢?接着看:

回到realStartActivityLocked方法,接着調用了mService.getLifecycleManager().scheduleTransaction(clientTransaction),mService是ActivityTaskManagerService,getLifecycleManager()方法獲取的是ClientLifecycleManager實例,它的scheduleTransaction方法如下:

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

就是調用ClientTransaction的schedule方法,那就看看:

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

很簡單,就是調用IApplicationThread的scheduleTransaction方法。由於IApplicationThread是ApplicationThread在系統進程的代理,所以真正執行的地方就是 客戶端的ApplicationThread中了。也就是說,Activity啓動的操作又跨進程的還給了客戶端

好了,到這裏我們稍稍梳理下:啓動Activity的操作從客戶端 跨進程 轉移到 ATMS,ATMS通過ActivityStarter、ActivityStack、ActivityStackSupervisor 對 Activity任務、activity棧、Activity記錄 管理後,又用過跨進程把正在啓動過程又轉移到了客戶端。

2.3 線程切換及消息處理——mH

接着上面的分析,我們找到ApplicationThread的scheduleTransaction方法:

        @Override
        public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
            ActivityThread.this.scheduleTransaction(transaction);
        }

那就再看ActivityThread的scheduleTransaction方法,實際在其父類ClientTransactionHandler中:

    void scheduleTransaction(ClientTransaction transaction) {
        transaction.preExecute(this);
        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
    }

使用sendMessage發送消息,參數是ActivityThread.H.EXECUTE_TRANSACTION和transaction,接着看:

    void sendMessage(int what, Object obj) {
        sendMessage(what, obj, 0, 0, false);
    }
    private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
        if (DEBUG_MESSAGES) {
            Slog.v(TAG,
                    "SCHEDULE " + what + " " + mH.codeToString(what) + ": " + arg1 + " / " + obj);
        }
        Message msg = Message.obtain();
        msg.what = what;
        msg.obj = obj;
        msg.arg1 = arg1;
        msg.arg2 = arg2;
        if (async) {
            msg.setAsynchronous(true);
        }
        mH.sendMessage(msg);
    }

最後調用了mH.sendMessage(msg),mH是個啥?我們看看:

//ActivityThread
final H mH = new H();

    class H extends Handler {
        public static final int BIND_APPLICATION        = 110;
        @UnsupportedAppUsage
        public static final int EXIT_APPLICATION        = 111;
        @UnsupportedAppUsage
        public static final int RECEIVER                = 113;
        @UnsupportedAppUsage
        public static final int CREATE_SERVICE          = 114;
        @UnsupportedAppUsage
        public static final int SERVICE_ARGS            = 115;
        ...
        public static final int EXECUTE_TRANSACTION = 159;
        public static final int RELAUNCH_ACTIVITY = 160;
        ...
        public void handleMessage(Message msg) {
            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
            switch (msg.what) {
                case BIND_APPLICATION:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
                    AppBindData data = (AppBindData)msg.obj;
                    handleBindApplication(data);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
                case EXIT_APPLICATION:
                    if (mInitialApplication != null) {
                        mInitialApplication.onTerminate();
                    }
                    Looper.myLooper().quit();
                    break;
                case RECEIVER:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveComp");
                    handleReceiver((ReceiverData)msg.obj);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
                case CREATE_SERVICE:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate: " + String.valueOf(msg.obj)));
                    handleCreateService((CreateServiceData)msg.obj);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
                case BIND_SERVICE:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");
                    handleBindService((BindServiceData)msg.obj);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
                ...
                
                case EXECUTE_TRANSACTION:
                    final ClientTransaction transaction = (ClientTransaction) msg.obj;
                    mTransactionExecutor.execute(transaction);
                    if (isSystem()) {
                        // Client transactions inside system process are recycled on the client side
                        // instead of ClientLifecycleManager to avoid being cleared before this
                        // message is handled.
                        transaction.recycle();
                    }
                    break;
                case RELAUNCH_ACTIVITY:
                    handleRelaunchActivityLocally((IBinder) msg.obj);
                    break;
                ...
            }
            Object obj = msg.obj;
            if (obj instanceof SomeArgs) {
                ((SomeArgs) obj).recycle();
            }
            if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what));
        }
    }

mH是在創建ActivityThread實例時賦值的,是自定義Handler子類H的實例,也就是在ActivityThread的main方法中,並且初始化是已經主線程已經有了mainLooper,所以,使用這個mH來sendMessage就把消息發送到了主線程

那麼是從哪個線程發送的呢?那就要看看ApplicationThread的scheduleTransaction方法是執行在哪個線程了。根據IPC知識,我們知道,服務器的Binder方法運行在Binder的線程池中,也就是說系統進行跨進程調用ApplicationThread的scheduleTransaction就是執行在Binder的線程池中的了。

到這裏,消息就在主線程處理了,那麼是怎麼處理Activity的啓動的呢?接着看。我們找到ActivityThread.H.EXECUTE_TRANSACTION這個消息的處理,就在handleMessage方法的倒數第三個case(就在上面代碼):取出ClientTransaction實例,調用TransactionExecutor的execute方法,那就看看:

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

        final IBinder token = transaction.getActivityToken();
        ...
        executeCallbacks(transaction);

        executeLifecycleState(transaction);
        ...
    }

繼續跟進executeCallbacks方法:

    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);
            ...
            item.execute(mTransactionHandler, token, mPendingActions);
            item.postExecute(mTransactionHandler, token, mPendingActions);
            ...
        }
    }

遍歷callbacks,調用ClientTransactionItem的execute方法,而我們這裏要關注的是ClientTransactionItem的子類LaunchActivityItem,看下它的execute方法:

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

裏面調用了client.handleLaunchActivity方法,client是ClientTransactionHandler的實例,是在TransactionExecutor構造方法傳入的,TransactionExecutor創建是在ActivityThread中:

//ActivityThread
private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this);

所以,client.handleLaunchActivity方法就是ActivityThread的handleLaunchActivity方法。

好了,到這裏 ApplicationThread把啓動Activity的操作,通過mH切到了主線程,走到了ActivityThread的handleLaunchActivity方法

2.4 Activity啓動核心實現——初始化及生命週期

那就接着看:

    public Activity handleLaunchActivity(ActivityClientRecord r,
            PendingTransactionActions pendingActions, Intent customIntent) {
        ...
        final Activity a = performLaunchActivity(r, customIntent);
        ...
        return a;
    }

繼續跟performLaunchActivity方法,這裏就是activity 啓動的核心實現了:

    /**  activity 啓動的核心實現. */
    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        //1、從ActivityClientRecord獲取待啓動的Activity的組件信息
        ActivityInfo aInfo = r.activityInfo;
        if (r.packageInfo == null) {
            r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                    Context.CONTEXT_INCLUDE_CODE);
        }

        ComponentName component = r.intent.getComponent();
        if (component == null) {
            component = r.intent.resolveActivity(
                mInitialApplication.getPackageManager());
            r.intent.setComponent(component);
        }

        if (r.activityInfo.targetActivity != null) {
            component = new ComponentName(r.activityInfo.packageName,
                    r.activityInfo.targetActivity);
        }
        //創建ContextImpl對象
        ContextImpl appContext = createBaseContextForActivity(r);
        Activity activity = null;
        try {
            //2、創建activity實例
            java.lang.ClassLoader cl = appContext.getClassLoader();
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            StrictMode.incrementExpectedActivityCount(activity.getClass());
            r.intent.setExtrasClassLoader(cl);
            r.intent.prepareToEnterProcess();
            if (r.state != null) {
                r.state.setClassLoader(cl);
            }
        } catch (Exception e) {
            ..
        }
        try {
            //3、創建Application對象(如果沒有的話)
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);
            ...
            if (activity != null) {
                CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
                Configuration config = new Configuration(mCompatConfiguration);
                if (r.overrideConfig != null) {
                    config.updateFrom(r.overrideConfig);
                }
              
                Window window = null;
                if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
                    window = r.mPendingRemoveWindow;
                    r.mPendingRemoveWindow = null;
                    r.mPendingRemoveWindowManager = null;
                }
                appContext.setOuterContext(activity);
                
                //4、attach方法爲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);

                if (customIntent != null) {
                    activity.mIntent = customIntent;
                }
                r.lastNonConfigurationInstances = null;
                checkAndBlockForNetworkAccess();
                activity.mStartedActivity = false;
                int theme = r.activityInfo.getThemeResource();
                if (theme != 0) {
                    activity.setTheme(theme);
                }

                activity.mCalled = false;
                
                //5、調用生命週期onCreate
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
                if (!activity.mCalled) {
                    throw new SuperNotCalledException(
                        "Activity " + r.intent.getComponent().toShortString() +
                        " did not call through to super.onCreate()");
                }
                r.activity = activity;
            }
            r.setState(ON_CREATE);
            
            synchronized (mResourcesManager) {
                mActivities.put(r.token, r);
            }

        } 
        ...

        return activity;
    }

performLaunchActivity主要完成以下事情:

  1. 從ActivityClientRecord獲取待啓動的Activity的組件信息
  2. 通過mInstrumentation.newActivity方法使用類加載器創建activity實例
  3. 通過LoadedApk的makeApplication方法創建Application對象,內部也是通過mInstrumentation使用類加載器,創建後就調用了instrumentation.callApplicationOnCreate方法,也就是Application的onCreate方法。
  4. 創建ContextImpl對象並通過activity.attach方法對重要數據初始化,關聯了Context的具體實現ContextImpl,attach方法內部還完成了window創建,這樣Window接收到外部事件後就能傳遞給Activity了。
  5. 調用Activity的onCreate方法,是通過 mInstrumentation.callActivityOnCreate方法完成。

到這裏Activity的onCreate方法執行完,那麼onStart、onResume呢?

上面看到LaunchActivityItem,是用來啓動Activity的,也就是走到Activity的onCreate,那麼是不是有 "XXXActivityItem"呢? 有的:

  • LaunchActivityItem 遠程App端的onCreate生命週期事務
  • ResumeActivityItem 遠程App端的onResume生命週期事務
  • PauseActivityItem 遠程App端的onPause生命週期事務
  • StopActivityItem 遠程App端的onStop生命週期事務
  • DestroyActivityItem 遠程App端onDestroy生命週期事務

另外梳理過程中涉及的幾個類:

  • ClientTransaction 客戶端事務控制者
  • ClientLifecycleManager 客戶端的生命週期事務控制者
  • TransactionExecutor 遠程通信事務執行者

那麼我們再來看看ResumeActivityItem吧。

我們再來重新看看在ActivityStackSupervisor的realStartActivityLocked方法:

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

                final DisplayContent dc = r.getDisplay().mDisplayContent;
                clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                        System.identityHashCode(r), r.info,
                        mergedConfiguration.getGlobalConfiguration(),
                        mergedConfiguration.getOverrideConfiguration(), r.compat,
                        r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
                        r.icicle, r.persistentState, results, newIntents,
                        dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
                                r.assistToken));

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

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

                ...

        return true;
    }

前面只說了通過clientTransaction.addCallback添加LaunchActivityItem實例,在注意下面接着調用了clientTransaction.setLifecycleStateRequest(lifecycleItem)方法,lifecycleItem是ResumeActivityItem或PauseActivityItem實例,這裏我們關注ResumeActivityItem,先看下setLifecycleStateRequest方法:

    /**
     * Final lifecycle state in which the client activity should be after the transaction is
     * executed.
     */
    private ActivityLifecycleItem mLifecycleStateRequest;
    
    public void setLifecycleStateRequest(ActivityLifecycleItem stateRequest) {
        mLifecycleStateRequest = stateRequest;
    }

mLifecycleStateRequest表示執行transaction後的最終的生命週期狀態。

繼續看處理ActivityThread.H.EXECUTE_TRANSACTION這個消息的處理,即TransactionExecutor的execute方法:

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

        final IBinder token = transaction.getActivityToken();
        ...
        executeCallbacks(transaction);

        executeLifecycleState(transaction);
        ...
    }

前面我們關注的是executeCallbacks方法,現在看看executeLifecycleState方法:

    /** Transition to the final state if requested by the transaction. */
    private void executeLifecycleState(ClientTransaction transaction) {
        final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
        if (lifecycleItem == null) {
            // No lifecycle request, return early.
            return;
        }

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

        // Execute the final transition with proper parameters.
        lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
        lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
    }

這裏取出了ActivityLifecycleItem並且調用了它的execute方法,實際就是ResumeActivityItem的方法:

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

經過上面分析實際是走到ActivityThread的handleResumeActivity方法:

    @Override
    public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
            String reason) {
        ...
        // performResumeActivity內部會走onStart、onResume
        final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
        if (r == null) {
            // We didn't actually resume the activity, so skipping any follow-up actions.
            return;
        }
        ...
        
        if (r.window == null && !a.mFinished && willBeVisible) {
            r.window = r.activity.getWindow();
            View decor = r.window.getDecorView();
            decor.setVisibility(View.INVISIBLE);
            ViewManager wm = a.getWindowManager();
            WindowManager.LayoutParams l = r.window.getAttributes();
            a.mDecor = decor;
            l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
            l.softInputMode |= forwardBit;
            if (r.mPreserveWindow) {
                a.mWindowAdded = true;
                r.mPreserveWindow = false;
                
                ViewRootImpl impl = decor.getViewRootImpl();
                if (impl != null) {
                    impl.notifyChildRebuilt();
                }
            }
            ...
            
        if (!r.activity.mFinished && willBeVisible && r.activity.mDecor != null && !r.hideForNow) {
            if (r.newConfig != null) {
                performConfigurationChangedForActivity(r, r.newConfig);
                if (DEBUG_CONFIGURATION) {
                    Slog.v(TAG, "Resuming activity " + r.activityInfo.name + " with newConfig "
                            + r.activity.mCurrentConfig);
                }
                r.newConfig = null;
            }
            if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward=" + isForward);
            WindowManager.LayoutParams l = r.window.getAttributes();
            if ((l.softInputMode
                    & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)
                    != forwardBit) {
                l.softInputMode = (l.softInputMode
                        & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))
                        | forwardBit;
                if (r.activity.mVisibleFromClient) {
                    ViewManager wm = a.getWindowManager();
                    View decor = r.window.getDecorView();
                    wm.updateViewLayout(decor, l);
                }
            }

            r.activity.mVisibleFromServer = true;
            mNumVisibleActivities++;
            if (r.activity.mVisibleFromClient) {
                //添加window、設置可見
                r.activity.makeVisible();
            }
        }

        r.nextIdle = mNewActivities;
        mNewActivities = r;
        if (localLOGV) Slog.v(TAG, "Scheduling idle handler for " + r);
        Looper.myQueue().addIdleHandler(new Idler());
    }

handleResumeActivity主要做了以下事情:

  1. 調用生命週期:通過performResumeActivity方法,內部調用生命週期onStart、onResume方法
  2. 設置視圖可見:通過activity.makeVisible方法,添加window、設置可見。(所以視圖的真正可見是在onResume方法之後)

先來看第一點,生命週期的調用。即performResumeActivity方法:

    public ActivityClientRecord performResumeActivity(IBinder token, boolean finalStateRequest,
            String reason) {
        final ActivityClientRecord r = mActivities.get(token);
        ...
        try {
            ...
            r.activity.performResume(r.startsNotResumed, reason);
            ...
        } 
        ...
        return r;
    }

調用了activity.performResume方法:

    final void performResume(boolean followedByPause, String reason) {
        dispatchActivityPreResumed();
        //內部會走onStart
        performRestart(true /* start */, reason);
        ...
        // 走onResume
        mInstrumentation.callActivityOnResume(this);
        ...
        //這裏是走fragment的onResume
        mFragments.dispatchResume();
        mFragments.execPendingActions();

        ...
    }

  

先調用了performRestart(),performRestart()又會調用performStart(),performStart()內部調用了mInstrumentation.callActivityOnStart(this),也就是Activity的onStart()方法了。

然後是mInstrumentation.callActivityOnResume,也就是Activity的onResume()方法了。到這裏啓動後的生命週期走完了。

再看第二點,設置視圖可見。即activity.makeVisible()方法:

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

這裏把activity的頂級佈局mDecor通過windowManager.addView()方法,把視圖添加到window,並設置mDecor可見。到這裏視圖是真正可見了。值得注意的是,視圖的真正可見是在onResume方法之後的。

好了,到這裏就是真正創建完成並且可見了。

梳理成關係圖如下:



涉及的類梳理如下:

類名 作用
ActivityThread 應用的入口類,系統通過調用main函數,開啓消息循環隊列。ActivityThread所在線程被稱爲應用的主線程(UI線程)
ApplicationThread 是ActivityThread的內部類,繼承IApplicationThread.Stub,是一個IBinder,是ActiivtyThread和AMS通信的橋樑,AMS則通過代理調用此App進程的本地方法,運行在Binder線程池
H 繼承Handler,在ActivityThread中初始化,即主線程Handler,用於主線程所有消息的處理。本片中主要用於把消息從Binder線程池切換到主線程
Intrumentation 具有跟蹤application及activity生命週期的功能,用於監控app和系統的交互
ActivityManagerService Android中最核心的服務之一,負責系統中四大組件的啓動、切換、調度及應用進程的管理和調度等工作,其職責與操作系統中的進程管理和調度模塊相類似,因此它在Android中非常重要,它本身也是一個Binder的實現類。
ActivityTaskManagerService 管理activity及其容器(task, stacks, displays)的系統服務(Android10中新增,分擔了AMS的部分職責)
ActivityStarter 用於解釋如何啓動活動。該類收集所有邏輯,用於確定Intent和flag應如何轉換爲活動以及相關的任務和堆棧
ActivityStack 用來管理系統所有的Activity,內部維護了Activity的所有狀態和Activity相關的列表等數據
ActivityStackSupervisor 負責所有Activity棧的管理。AMS的stack管理主要有三個類,ActivityStackSupervisor,ActivityStack和TaskRecord
ClientLifecycleManager 客戶端生命週期執行請求管理
ClientTransaction 是包含一系列的 待客戶端處理的事務 的容器,客戶端接收後取出事務並執行
LaunchActivityItem、ResumeActivityItem 繼承ClientTransactionItem,客戶端要執行的事務信息,啓動activity

以上就是一個 普通Activity 啓動的完整流程。

爲啥我說 “普通Activity” 呢?因爲你會發現,整個流程是從startActivity這個方法開始的,是我們在一個Activity裏面啓動另一個Activity的情況。那麼第一個Activity,即 根Activity 是如何啓動的呢?

另外還注意到,在ActivityStackSupervisor的startSpecificActivityLocked方法中,上面分析有提到,有個判斷條件if (wpc != null && wpc.hasThread()),意思是 是否啓動了應用進程,而我們只分析了已啓動應用進程的情況。那麼未啓動應用進程的情況就是根Activity的啓動了。下面就來了解根Activity的啓動,也可以理解爲應用程序的啓動過程。

三、根Activity的啓動—應用進程啓動

我們知道,想要啓動一個應用程序(App),需要點擊手機桌面的應用圖標。Android系統的桌面叫做Launcher,有以下作用:

  • 作爲Android系統的啓動器,用於啓動應用程序。
  • 作爲Android系統的桌面,用於顯示和管理應用程序的快捷圖標和其他桌面組件。

Launcher本身也是一個應用程序,它在啓動過程中會請求PackageManageService(系統的包管理服務)返回系統中已經安裝的app的信息,並將其用快捷圖標展示在桌面屏幕上,用戶可以點擊圖標啓動app。例如華爲手機的Launcher就是 “華爲桌面” 這個系統app。

3.1 應用進程的創建

當點擊app圖標後,Launcher會在桌面activity(此activity就叫Launcher)內調用startActivitySafely方法,startActivitySafely方法會調用startActivity方法。接下來的部分就和上面分析的 Activity啓動的發起 過程一致了,即通過IPC走到了ATMS,直到ActivityStackSupervisor的startSpecificActivityLocked方法中對應用進程是否存在的判斷。我們再次瞅瞅:

    void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
        // Is this activity's application already running?
        final WindowProcessController wpc =
                mService.getProcessController(r.processName, r.info.applicationInfo.uid);

        boolean knownToBeDead = false;
        if (wpc != null && wpc.hasThread()) {
            try {
                //有應用進程就啓動activity
                realStartActivityLocked(r, wpc, andResume, checkConfig);
                return;
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception when starting activity "
                        + r.intent.getComponent().flattenToShortString(), e);
            }
            knownToBeDead = true;
        }

        ...
        
        try {
            if (Trace.isTagEnabled(TRACE_TAG_ACTIVITY_MANAGER)) {
                Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "dispatchingStartProcess:"
                        + r.processName);
            }
            // Post message to start process to avoid possible deadlock of calling into AMS with the
            // ATMS lock held.
            // 上面的wpc != null && wpc.hasThread()不滿足的話,說明沒有進程,就會去創建進程
            final Message msg = PooledLambda.obtainMessage(
                    ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
                    r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());
            mService.mH.sendMessage(msg);
        } finally {
            Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
        }
    }

邏輯很清晰:有應用進程就啓動activity(普通activity),沒有就去創建進程(然後再啓動根activity)。

應用進程存在的判斷條件是:wpc != null && wpc.hasThread(),看下WindowProcessController的hasThread方法:

    // The actual proc...  may be null only if 'persistent' is true (in which case we are in the
    // process of launching the app)
    private IApplicationThread mThread;
    
    boolean hasThread() {
        return mThread != null;
    }

前面已有說明,IApplicationThread是ApplicationThread在客戶端(app)在服務端(系統進程)的代理,這裏判斷 IApplicationThread不爲空 就代表進程已存在,爲啥這麼判斷呢?這裏先猜測,進程創建後,一定會有給IApplicationThread賦值的操作,這樣就符合這個邏輯了。我們繼續看,瞅瞅進程是如何創建的,以及創建後是否有給IApplicationThread賦值的操作。

使用ActivityTaskManagerService的mH(繼承handler)發送了一個消息,消息中第一個參數是ActivityManagerInternal::startProcess,ActivityManagerInternal的實現是AMS的內部類LocalService,LocalService的startProcess方法調用了AMS的startProcessLocked方法,那麼我們就看看AMS 的startProcessLocked方法,這裏應該就是創建進程了:

    final ProcessRecord startProcessLocked(String processName,
            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
            HostingRecord hostingRecord, boolean allowWhileBooting,
            boolean isolated, boolean keepIfLarge) {
        return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
                hostingRecord, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
                null /* crashHandler */);
    }

這裏調用了ProcessList.startProcessLocked方法,內部又多次調用了startProcessLocked不同的重載方法,最後走到startProcess方法:

    private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,
            ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
            String seInfo, String requiredAbi, String instructionSet, String invokeWith,
            long startTime) {
        try {
        
        ...
        
               startResult = Process.start(entryPoint,
                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                        app.info.dataDir, invokeWith, app.info.packageName,
                        new String[] {PROC_START_SEQ_IDENT + app.startSeq});
            }
            checkSlow(startTime, "startProcess: returned from zygote!");
            return startResult;
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        }
    }

調用了Process.start方法,跟進看下:

    public static ProcessStartResult start(@NonNull final String processClass,
                                           @Nullable final String niceName,
                                           int uid, int gid, @Nullable int[] gids,
                                           int runtimeFlags,
                                           int mountExternal,
                                           int targetSdkVersion,
                                           @Nullable String seInfo,
                                           @NonNull String abi,
                                           @Nullable String instructionSet,
                                           @Nullable String appDataDir,
                                           @Nullable String invokeWith,
                                           @Nullable String packageName,
                                           @Nullable String[] zygoteArgs) {
        return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids,
                    runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                    abi, instructionSet, appDataDir, invokeWith, packageName,
                    /*useUsapPool=*/ true, zygoteArgs);
    }

ZYGOTE_PROCESS是用於保持與Zygote進程的通信狀態,發送socket請求與Zygote進程通信。Zygote進程進程孵化器,用於創建進程。ZYGOTE_PROCESS的start就不再跟進去了,關於這塊知識可以參考《Android進階解密》第二章、第三章。我們只需要知道其內部:

  • Zygote通過fork創建了一個進程
  • 在新建的進程中創建Binder線程池(此進程就支持了Binder IPC)
  • 最終是通過反射獲取到了ActivityThread類並執行了main方法

3.2 根Activity的啓動

在之前文章 Handler:Android消息機制--《Android開發藝術探索》閱讀筆記——第十章 中介紹主線程的消息機制時就介紹過ActivityThread的main方法,主要就是開啓了主線程的消息循環。

    final H mH = new H();
    
    public static void main(String[] args) {
        ...
        //1、準備主線程的Looper
        Looper.prepareMainLooper();

        long startSeq = 0;
        if (args != null) {
            for (int i = args.length - 1; i >= 0; --i) {
                if (args[i] != null && args[i].startsWith(PROC_START_SEQ_IDENT)) {
                    startSeq = Long.parseLong(
                            args[i].substring(PROC_START_SEQ_IDENT.length()));
                }
            }
        }
        //這裏實例化ActivityThread,也就實例化了上面的mH,就是handler。
        ActivityThread thread = new ActivityThread();
        thread.attach(false, startSeq);

        //獲取handler
        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }

        ...
        //主線程looper開啓
        Looper.loop();
        //因爲主線程的Looper是不能退出的,退出就無法接受事件了。一旦意外退出,會拋出異常
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

在這理,我們關注 這兩這行代碼:

        ActivityThread thread = new ActivityThread();
        thread.attach(false, startSeq);

創建ActivityThread實例,同時會創建ApplicationThread實例,ApplicationThread實例是ActivityThread實例的屬性。然後調用了attach方法:

    private void attach(boolean system, long startSeq) {
        sCurrentActivityThread = this;
        mSystemThread = system;
        if (!system) {
            android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
                                                    UserHandle.myUserId());
            RuntimeInit.setApplicationObject(mAppThread.asBinder());
            final IActivityManager mgr = ActivityManager.getService();
            try {
                //把ApplicationThread實例關聯到AMS中
                mgr.attachApplication(mAppThread, startSeq);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
            ...
        } 
        ...
    }

前面提到過這裏mgr就是AMS在客戶端的代理,所以mgr的attachApplication方法,就是IPC的走到AMS的attachApplication方法了:

    public final void attachApplication(IApplicationThread thread, long startSeq) {
        synchronized (this) {
            int callingPid = Binder.getCallingPid();
            final int callingUid = Binder.getCallingUid();
            final long origId = Binder.clearCallingIdentity();
            attachApplicationLocked(thread, callingPid, callingUid, startSeq);
            Binder.restoreCallingIdentity(origId);
        }
    }

attachApplicationLocked方法很長,這裏保留重要的幾點:

private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid, int callingUid, long startSeq) {

            ...
                //1、IPC操作,創建綁定Application
                thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
                        null, null, null, testMode,
                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
                        isRestrictedBackupMode || !normalMode, app.isPersistent(),
                        new Configuration(app.getWindowProcessController().getConfiguration()),
                        app.compat, getCommonServicesLocked(app.isolated),
                        mCoreSettingsObserver.getCoreSettingsLocked(),
                        buildSerial, autofillOptions, contentCaptureOptions);
            ...
            // 2、賦值IApplicationThread
            app.makeActive(thread, mProcessStats);
            ...
            
        // See if the top visible activity is waiting to run in this process...
        if (normalMode) {
            try {
                //3、通過ATMS啓動 根activity
                didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
            } catch (Exception e) {
                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
                badApp = true;
            }
        }
        ...
}

AMS的attachApplicationLocked方法主要三件事:

  • 調用IApplicationThread的bindApplication方法,IPC操作,創建綁定Application;
  • 通過makeActive方法賦值IApplicationThread,即驗證了上面的猜測(創建進程後賦值);
  • 通過ATMS啓動 根activity

先看makeActive方法:

    public void makeActive(IApplicationThread _thread, ProcessStatsService tracker) {
        ...
        thread = _thread;
        mWindowProcessController.setThread(thread);
    }

看到使用mWindowProcessController.setThread(thread)確實完成了IApplicationThread的賦值。這樣就可以依據IApplicationThread是否爲空判斷進程是否存在了。

再看創建綁定Application的過程:IApplicationThread的bindApplication方法實現是客戶端的ApplicationThread的bindApplication方法,它又使用H轉移到了ActivityThread的handleBindApplication方法(從Binder線程池轉移到主線程),看下handleBindApplication方法:

private void handleBindApplication(AppBindData data) {
    ...
                final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
                    appContext.getClassLoader(), false, true, false);

          
            final ContextImpl instrContext = ContextImpl.createAppContext(this, pi,
                    appContext.getOpPackageName());

            try {
                //創建Instrumentation
                final ClassLoader cl = instrContext.getClassLoader();
                mInstrumentation = (Instrumentation)
                    cl.loadClass(data.instrumentationName.getClassName()).newInstance();
            } 
            ...
            final ComponentName component = new ComponentName(ii.packageName, ii.name);
            mInstrumentation.init(this, instrContext, appContext, component,
                    data.instrumentationWatcher, data.instrumentationUiAutomationConnection);
    ...
            //創建Application
            app = data.info.makeApplication(data.restrictedBackupMode, null);

    ...
            mInitialApplication = app;
            try {
                mInstrumentation.onCreate(data.instrumentationArgs);
            }
    ...
            try {
                //內部調用Application的onCreate方法
                mInstrumentation.callApplicationOnCreate(app);
            }
    ...
}

主要就是創建Application,並且調用生命週期onCreate方法。你會發現在前面介紹的ActivityThread的performLaunchActivity方法中,也有同樣的操作,只不過會先判斷Application是否已存在。也就是說,正常情況下Application的初始化是在handleBindApplication方法中的,並且是創建進程後調用的。performLaunchActivity中只是做了一個檢測,異常情況Application不存在時纔會創建。

再來看 根activity 的啓動,回到上面AMS的attachApplicationLocked方法,調用了mAtmInternal.attachApplication方法,mAtmInternal是ActivityTaskManagerInternal實例,具體實現是在ActivityTaskManagerService的內部類LocalService,去看看:

//ActivityTaskManagerService#LocalService
        public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
            synchronized (mGlobalLockWithoutBoost) {
                return mRootActivityContainer.attachApplication(wpc);
            }
        }

mRootActivityContainer是RootActivityContainer實例,看下它的attachApplication方法:

    boolean attachApplication(WindowProcessController app) throws RemoteException {
        final String processName = app.mName;
        boolean didSomething = false;
        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
            final ActivityDisplay display = mActivityDisplays.get(displayNdx);
            final ActivityStack stack = display.getFocusedStack();
            if (stack != null) {
                stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList);
                final ActivityRecord top = stack.topRunningActivityLocked();
                final int size = mTmpActivityList.size();
                for (int i = 0; i < size; i++) {
                    final ActivityRecord activity = mTmpActivityList.get(i);
                    if (activity.app == null && app.mUid == activity.info.applicationInfo.uid
                            && processName.equals(activity.processName)) {
                        try {
                            if (mStackSupervisor.realStartActivityLocked(activity, app,
                                    top == activity /* andResume */, true /* checkConfig */)) {
                                didSomething = true;
                            }
                        } 
                        ...
                    }
                }
            }
        }
        if (!didSomething) {
            ensureActivitiesVisible(null, 0, false /* preserve_windows */);
        }
        return didSomething;
    }

遍歷activity棧,此時理論上應該只有一個根activity,然後調用mStackSupervisor.realStartActivityLocked方法,看到這裏我們知道了,這裏就開始走上面分析過的流程了,即使用ClientTransaction會跨進程交給客戶端,然後就是2.3、2.4兩個小節的內容。

嗯,到這裏根activity的啓動流程也分析完了。

我們發現,根activity的啓動前 需要創建應用進程,然後走到ActivityThread的main方法,開啓主線程循環,初始化並綁定Application、賦值IApplicationThread,最後真正的啓動過程和普通Activity是一致的。

上面的流程圖 補充 根activity的邏輯,完整關係如下:

總結

關於 普通Activity 啓動的流程的講解,我們分成了幾個階段:啓動的發起、AMS的管理、線程切換、啓動核心實現,知道了啓動過程經歷了兩次IPC,客戶端到AMS、AMS到客戶端,以及Activity創建和生命週期的執行。 然後又在此基礎上 補充的根activity的啓動:先創建應用進程,再綁定Application,最後真正啓動跟Activity。

本篇內容涉及大量知識點,結合 IPCHandlerWindow等相關知識,這樣可以對Android系統有更加完整的認識。

好了,今天就到這裏,歡迎留言討論~

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