APP&Activity 啟動流程(基于Android10)

Activity 啟動流程聽起來非常復(fù)雜赁濒,但實際上很多東西我們沒必要完全掌握真仲,只需要去大概理解原理和流程就行偿洁。

名詞解釋
zygote 意思為受精卵 為所有進(jìn)程的父進(jìn)程

1. 流程的發(fā)起

從startActivity開始看起

@Override
    public void startActivity(Intent intent, @Nullable Bundle options) {
        if (options != null) {
            startActivityForResult(intent, -1, options);
        } else {
            // Note we want to go through this call for compatibility with
            // applications that may have overridden the method.
            startActivityForResult(intent, -1);
        }
    }

最終調(diào)用的是 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());
            }
          ...
        }
    }

在這個方法里看到了久仰大名的Instrumentation 這個類是Application和Activity生命周期的關(guān)鍵坎穿,然后去看 execStartActivity

int result = ActivityTaskManager.getService()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);

只挑了里面的關(guān)鍵部分湘今,又看到了不得了的東西 ActivityTaskManager.getService(),看著好像另一個大名鼎鼎的ActivityManagerService 啊唉窃,看一下getService方法

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

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

但是這里拿到的不是ActivityManagerService
而是**ActivityTaskManagerService **耙饰,然后再去調(diào)用它的 startActivityAsUser

  private int startActivityAsUser(IApplicationThread caller, String callingPackage,
            @Nullable String callingFeatureId, Intent intent, String resolvedType,
            IBinder resultTo, String resultWho, int requestCode, int startFlags,
            ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
        assertPackageMatchesCallingUid(callingPackage);
        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)
                .setCallingFeatureId(callingFeatureId)
                .setResolvedType(resolvedType)
                .setResultTo(resultTo)
                .setResultWho(resultWho)
                .setRequestCode(requestCode)
                .setStartFlags(startFlags)
                .setProfilerInfo(profilerInfo)
                .setActivityOptions(bOptions)
                .setUserId(userId)
                .execute();

    }

到了這一層感覺就看不懂了,不知道的東西太多纹份,就不深入探究了

這就是第一步過程苟跪,應(yīng)用進(jìn)程調(diào)用ATMS系統(tǒng)進(jìn)程發(fā)起打開Activity的請求,ATMS 是10.0才有的蔓涧,分擔(dān)了一些AMS的工作件已,其內(nèi)部也有很多是調(diào)用AMS完成的。用一張圖表示

image.png

從先在開始啟動流程就進(jìn)入到系統(tǒng)進(jìn)程中了元暴。

2. 系統(tǒng)進(jìn)程對創(chuàng)建Activity的處理

2.1 ATMS 發(fā)起打開Activity或者是創(chuàng)建進(jìn)程的請求

image.png

ActivityTaskManagerService 最終會執(zhí)行 ActivityStarter.execute方法

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

上面這個分叉最終都會走到 startActivity
里面又調(diào)用了startActivityUnchecked方法拨齐,之后調(diào)用RootActivityContainer的resumeFocusedStacksTopActivities方法。RootActivityContainer是Android10新增的類昨寞,分擔(dān)了之前ActivityStackSupervisor的部分功能瞻惋。接著跳轉(zhuǎn)到ActivityStack的resumeTopActivityUncheckedLocked方法然后又調(diào)用resumeTopActivityInnerLocked,中間沒有什么邏輯需要看的援岩,所以就跳過了歼狼,直接看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就發(fā)送ResumeActivityItem事務(wù)給客戶端了享怀,后面會講到
                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 {
            ....
            if (SHOW_APP_STARTING_PREVIEW) {
                    //這里就是 冷啟動時 出現(xiàn)白屏 的原因了:取根activity的主題背景 展示StartingWindow
                    next.showStartingWindow(null , false ,false);
                }
            // 繼續(xù)當(dāng)前Activity羽峰,普通activity的正常啟動 關(guān)注這里即可
            mStackSupervisor.startSpecificActivityLocked(next, true, true);
        }
        return true;
    }

這里先暫停上個Activity,然后再進(jìn)入到 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()不滿足的話添瓷,說明沒有進(jìn)程梅屉,就會取創(chuàng)建進(jìn)程
            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);
        }
    }

這里 會先判斷進(jìn)程有沒創(chuàng)建,創(chuàng)建的話會進(jìn)入 realStartActivityLocked鳞贷,沒開啟的話會調(diào)用 ActivityManagerInternal.startProgress坯汤,下面我們先看進(jìn)程以已經(jīng)創(chuàng)建的情況

2.2 在當(dāng)前進(jìn)程開啟Activity

當(dāng)前進(jìn)程指的是APP進(jìn)程,不是系統(tǒng)進(jìn)程
進(jìn)入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惰聂,其中參數(shù)proc.getThread()是IApplicationThread疆偿,就是前面提到的ApplicationThread在系統(tǒng)進(jìn)程的代理。

ClientTransaction是包含一系列的待客戶端處理的事務(wù)的容器搓幌,客戶端接收后取出事務(wù)并執(zhí)行杆故。

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

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

LaunchActivityItem看名字就像是啟動Activity的溉愁,走到這里只是把
LaunchActivityItem保存了起來处铛,那再回到realStartActivityLocked 中,接著調(diào)用了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);
    }

這個Client 就是ApplicationThread 下面啟動進(jìn)程的時候會講到這個東西就是系統(tǒng)進(jìn)程給APP進(jìn)程通信的媒介投队,所以這一步就又回到APP進(jìn)程了。

2.3 回到APP進(jìn)程 進(jìn)行創(chuàng)建Activity的后續(xù)操作

ApplicationThread 的scheduleTransaction 調(diào)用的是ActivityThread 的scheduleTransaction爵川,是在它的父類ClientTransactionHandler中實現(xiàn)的:

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

這里發(fā)送了一個消息敷鸦,最終由ActivityThread的H(一個Handler)處理,為什么要使用Handler呢寝贡,因為scheduleTransaction方法是被系統(tǒng)進(jìn)程調(diào)用的扒披,跨進(jìn)程的方法調(diào)用都發(fā)生在Binder的線程池中
所以在這里要發(fā)送到主線程執(zhí)行
最終是這樣執(zhí)行的:

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;

又交給了mTransactionExecutor這個對象處理,但是最終還是交給了ActivityThread 的 handleLaunchActivity圃泡。

下面就進(jìn)入到另一個核心部分碟案,創(chuàng)建Activity和Activity生命周期的管理

2.4 創(chuàng)建Activity以及Activity生命周期的管理

進(jìn)入handleLaunchActivity

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

繼續(xù)跟performLaunchActivity方法,這里就是activity 啟動的核心實現(xiàn)了:

    /**  activity 啟動的核心實現(xiàn). */
    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);
        }
        //創(chuàng)建ContextImpl對象
        ContextImpl appContext = createBaseContextForActivity(r);
        Activity activity = null;
        try {
            //2价说、創(chuàng)建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、創(chuàng)建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關(guān)聯(lián)上下文環(huán)境
                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鳖目、調(diào)用生命周期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主要完成以下事情:

從ActivityClientRecord獲取待啟動的Activity的組件信息
通過mInstrumentation.newActivity方法使用類加載器創(chuàng)建activity實例
通過LoadedApk的makeApplication方法創(chuàng)建Application對象,內(nèi)部也是通過mInstrumentation使用類加載器缤弦,創(chuàng)建后就調(diào)用了instrumentation.callApplicationOnCreate方法领迈,也就是Application的onCreate方法。
創(chuàng)建ContextImpl對象并通過activity.attach方法對重要數(shù)據(jù)初始化碍沐,關(guān)聯(lián)了Context的具體實現(xiàn)ContextImpl狸捅,attach方法內(nèi)部還完成了window創(chuàng)建,這樣Window接收到外部事件后就能傳遞給Activity了累提。
調(diào)用Activity的onCreate方法尘喝,是通過 mInstrumentation.callActivityOnCreate方法完成,Activity就創(chuàng)建完成了斋陪。
那onStart 和 onResume是什么時候調(diào)用的呢
我們再來重新看看在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;
    }

可以看到里面有一個 ResumeActivityItem 然后調(diào)用了mService.getLifecycleManager().scheduleTransaction瞧省,這個剛才說了會調(diào)用到ActivityThread里的方法扯夭,其實最后調(diào)用了ActivityThread的handleResumeActivity方法:

    @Override
    public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
            String reason) {
        ...
        // performResumeActivity內(nèi)部會走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鞍匾、設(shè)置可見
                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. 調(diào)用生命周期:通過performResumeActivity方法交洗,內(nèi)部調(diào)用生命周期onStart、onResume方法
  2. 設(shè)置視圖可見:通過activity.makeVisible方法橡淑,添加window构拳、設(shè)置可見。(所以視圖的真正可見是在onResume方法之后)

到這里一個Activity就真正顯示出來了

3 創(chuàng)建進(jìn)程

下面開始看進(jìn)程不存在的情況梁棠,會調(diào)用ActivityManagerInternal::startProcess ActivityManagerInternal 是一個抽象類置森,具體的實現(xiàn)類時 AMS 中的 LocalService,具體代碼就不看了符糊,很復(fù)雜凫海,最后AMS 會通過socket與Zygote進(jìn)行通信去創(chuàng)建APP進(jìn)程**,Zygote會fork一個進(jìn)程出來

為什么這里使用Socket與zygote進(jìn)行通信呢男娄,可以參考這篇文章為什么systemServer進(jìn)程與zygote進(jìn)程的通信是使用socket而不是binder行贪?

APP進(jìn)程創(chuàng)建好之后 就會執(zhí)行ActivityThread的main方,這就是Android 每個進(jìn)程的入口方法

public static void main(String[] args) {
    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
    SamplingProfilerIntegration.start();

    // CloseGuard defaults to true and can be quite spammy.  We
    // disable it here, but selectively enable it later (via
    // StrictMode) on debug builds, but using DropBox, not logs.
    CloseGuard.setEnabled(false);

    Environment.initForCurrentUser();

    // Set the reporter for event logging in libcore
    EventLogger.setReporter(new EventLoggingReporter());

    // Make sure TrustedCertificateStore looks in the right place for CA certificates
    final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
    TrustedCertificateStore.setDefaultUserDirectory(configDir);

    Process.setArgV0("<pre-initialized>");

    Looper.prepareMainLooper();

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

    if (sMainThreadHandler == null) {
        sMainThreadHandler = thread.getHandler();
    }

    if (false) {
        Looper.myLooper().setMessageLogging(new
                LogPrinter(Log.DEBUG, "ActivityThread"));
    }

    // End of event ActivityThreadMain.
    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    Looper.loop();

    throw new RuntimeException("Main thread loop unexpectedly exited");
}

這里面有很多內(nèi)容模闲,最重要的兩個是:
1. 執(zhí)行了Looper.prepareMainLooper()建瘫,這會在主線程中創(chuàng)建一個Looper,然后調(diào)用Looper.loop 開啟無限循環(huán)尸折,這就是Android 中消息機(jī)制的核心
2. 創(chuàng)建了一個ActivityThread啰脚,并調(diào)用attach方法

里面又創(chuàng)建了一個ActivityThread對象,因為main方法是static的实夹,所以在調(diào)用的時候是不存在ActivityThread對象的橄浓,之前包括之后使用的所有ActivityThread都是在這創(chuàng)建出來的。然后調(diào)用了它的attach:

image.png

這個方法的主要目的是將APP進(jìn)程中的 ApplicationThread 傳遞給AMS亮航,之后AMS進(jìn)程與APP進(jìn)程的通信就靠它了贮配。

下面是ActivityManagerService的attachApplicationLocked:

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

            ...
                //1、IPC操作塞赂,創(chuàng)建綁定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方法主要三件事:

  1. 調(diào)用IApplicationThread的bindApplication方法宴猾,IPC操作圆存,創(chuàng)建綁定Application;
  2. 通過makeActive方法賦值IApplicationThread
  3. 通過ATMS啟動 根activity

先看一下第一個ApplicationThread.bindApplication:


image.png
image.png

初始化了一大堆東西仇哆,最后發(fā)送了一條消息


image.png

ActivityThread 內(nèi)部的Handler在收到這條消息之后調(diào)用了handleBindApplication方法創(chuàng)建了Instrumentation


image.png

然后又創(chuàng)建了Application


image.png

Application 最終還是在 Instrumentation中創(chuàng)建的

 public Application newApplication(ClassLoader cl, String className, Context context)
            throws InstantiationException, IllegalAccessException, 
            ClassNotFoundException {
        Application app = getFactory(context.getPackageName())
                .instantiateApplication(cl, className);
        app.attach(context);
        return app;
    }

創(chuàng)建完Application 會將外部創(chuàng)建的 ContextImpl 作為baseContext傳遞給Application沦辙,然后又通過Instrumentation 調(diào)用了 callApplicationOnCreate


image.png

第二件事就是將APP進(jìn)程內(nèi)的ApplicationThread保存下來

再來看 根activity 的啟動,回到上面AMS的attachApplicationLocked方法讹剔,調(diào)用了mAtmInternal.attachApplication方法油讯,mAtmInternal是ActivityTaskManagerInternal實例详民,具體實現(xiàn)是在ActivityTaskManagerService的內(nèi)部類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;
    }

眼神好的人看到了realStartActivityLocked沈跨,這不又回到了2.2小節(jié)了嗎,后面的流程就一樣了兔综。
至此Activity啟動流程就完成了

總結(jié)

Activity的啟動總體是職責(zé)與操作系統(tǒng)中的進(jìn)程管理和調(diào)度模塊相類似饿凛,因此它在Android中非常一波三折,流程還是很長的

先解釋一下幾個比較重要的類:

  1. **Instrumentation **負(fù)責(zé) Application 和 四大組件生命周期調(diào)用
  2. ActivityTaskManagerService & ActivityMangerService 也就是常說的 ATMS 和 AMS软驰, 是在系統(tǒng)進(jìn)程中的實例涧窒,Android中最核心的服務(wù)之一,負(fù)責(zé)系統(tǒng)中四大組件的啟動锭亏、切換纠吴、調(diào)度及應(yīng)用進(jìn)程的管理和調(diào)度等工作,其重要慧瘤,它本身也是一個Binder的實現(xiàn)類戴已。
  3. ApplicationThread 是ActivityThread的內(nèi)部類,繼承IApplicationThread.Stub碑隆,是一個IBinder恭陡,是ActiivtyThread和AMS通信的橋梁蹬音,AMS則通過代理調(diào)用此App進(jìn)程的本地方法上煤,運(yùn)行在Binder線程池
  4. ActivityThread 應(yīng)用的入口類,系統(tǒng)通過調(diào)用main函數(shù)著淆,開啟消息循環(huán)隊列劫狠。ActivityThread所在線程被稱為應(yīng)用的主線程(UI線程)

整個流程可以分為下面幾部

  1. Activity調(diào)用startActivity 走到了 Instrumentation,然后Instrumentation 拿到ATMS 調(diào)用ATMS 的startActivity 進(jìn)入了系統(tǒng)進(jìn)程內(nèi)
  2. 然后ATMS 和 AMS 一連串的調(diào)用到了ActivityStackSupervisor 的
    startSpecificActivityLocked永部,在這里先判斷Activity所在的進(jìn)程有沒有被創(chuàng)建独泞,如果沒創(chuàng)建就走到 LocalService.startProgress 創(chuàng)建進(jìn)程,如果已經(jīng)創(chuàng)建了進(jìn)程就直接到第6步
  3. 創(chuàng)建完進(jìn)程之后 會通過反射調(diào)用ActivityThread的main方法進(jìn)入Android的主線程 創(chuàng)建無限循環(huán)的Looper苔埋,然后創(chuàng)建一個ActivityThread 實例懦砂,調(diào)用attach方法,里面又調(diào)用了AMS的 attachApplicationLocked组橄,將APP進(jìn)程中的ApplicationThread傳遞給AMS 用于兩個進(jìn)程綁定荞膘,從這開始又進(jìn)入了系統(tǒng)進(jìn)程(這一步才開始APP進(jìn)程與系統(tǒng)進(jìn)程的交互,前面的都是啟動Activity的那個進(jìn)程和系統(tǒng)進(jìn)程的交互)
  4. AMS 進(jìn)行了一系列準(zhǔn)備工作 然后又調(diào)用了ActivityThread 的 bindApplication方法玉工,這個方法里會調(diào)用Instrumentation創(chuàng)建Application羽资,調(diào)用Application的attachBaseContext和onCreate方法,Application就創(chuàng)建完畢了
  5. 再調(diào)用ActivityThread .bindApplication創(chuàng)建完APP進(jìn)程的Application之后遵班,調(diào)用了AMS中的attachApplication屠升,里面又調(diào)用了ActivityStackSupervisor.realStartActivityLocked 方法
    6.從 realStartActivityLocked 開始真正的開啟Activity啟動潮改,在這之前會先pause上一個Activity,然后創(chuàng)建LacunchActivityItem和 ResumeLauncherActivity,然后將LacunchActivityItem通ApplicationThread發(fā)送給APP進(jìn)程的ActivityThread
  6. 這一步開始又回到了APP進(jìn)程腹暖,ActivityThread通過Handler來處理事件汇在,最后調(diào)用到了自己的performLaunchActivity方法,然后通過Instrumentation的newActivity方法反射創(chuàng)建了Activity實例微服,然后調(diào)用activity.attach進(jìn)行方法關(guān)聯(lián)Context 初始化window等方法趾疚,然后調(diào)用Activity的onCreate方法,到這一步Activity就創(chuàng)建完畢了
    8.在第6步中創(chuàng)建了ResumeActivityItem以蕴,同樣的也會調(diào)用到APP進(jìn)程中的ActivityThread 中的方法糙麦,這次調(diào)用的是 handleResumeActivity,調(diào)用performResumeActivity里面主要是通過Instrumentation調(diào)用了onStart和onResume方法丛肮,performResumeActivity調(diào)用完畢后才將dcorview 添加到window上赡磅,所以view真正是的可見是在onResume之后的。對Activity來說宝与,在onResume之前 只是創(chuàng)建了Window并把Window顯示出來了焚廊,但是并沒有添加實質(zhì)性的可以看到的View。所以就不明白官方對生命周期的描述 onStart代表Activity可見习劫,onResume代表Activity已經(jīng)獲取到焦點(diǎn)

題外話

Activity啟動完成了咆瘟,但是View的三大流程什么時候開始的呢?

本文參考了大佬的文章
源碼可以在Code Search查看

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末诽里,一起剝皮案震驚了整個濱河市袒餐,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌谤狡,老刑警劉巖灸眼,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異墓懂,居然都是意外死亡焰宣,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進(jìn)店門捕仔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來匕积,“玉大人,你說我怎么就攤上這事榜跌∩了簦” “怎么了?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵斜做,是天一觀的道長苞氮。 經(jīng)常有香客問我,道長瓤逼,這世上最難降的妖魔是什么笼吟? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任库物,我火速辦了婚禮,結(jié)果婚禮上贷帮,老公的妹妹穿的比我還像新娘戚揭。我一直安慰自己,他們只是感情好撵枢,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布民晒。 她就那樣靜靜地躺著,像睡著了一般锄禽。 火紅的嫁衣襯著肌膚如雪潜必。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天沃但,我揣著相機(jī)與錄音磁滚,去河邊找鬼。 笑死宵晚,一個胖子當(dāng)著我的面吹牛垂攘,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播淤刃,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼晒他,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了逸贾?” 一聲冷哼從身側(cè)響起陨仅,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎耕陷,沒想到半個月后掂名,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體据沈,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡哟沫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了锌介。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嗜诀。...
    茶點(diǎn)故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖孔祸,靈堂內(nèi)的尸體忽然破棺而出隆敢,到底是詐尸還是另有隱情,我是刑警寧澤崔慧,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布拂蝎,位于F島的核電站,受9級特大地震影響惶室,放射性物質(zhì)發(fā)生泄漏温自。R本人自食惡果不足惜玄货,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望悼泌。 院中可真熱鬧松捉,春花似錦、人聲如沸馆里。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鸠踪。三九已至丙者,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間营密,已是汗流浹背蔓钟。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留卵贱,地道東北人滥沫。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像键俱,于是被迫代替她去往敵國和親兰绣。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評論 2 354