App啟動流程

創(chuàng)建Application

Android中有一個ActivityThread類楚昭,這個類代表應(yīng)用程序的主線程;Android在打開APP時會首先調(diào)用ActivityThread中的main方法,也就是APP進程的啟動點辙喂;

public static void main(String[] args) {
        ...
        Looper.prepareMainLooper();//1

        // Find the value for {@link #PROC_START_SEQ_IDENT} if provided on the command line.
        // It will be in the format "seq=114"
        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 thread = new ActivityThread();//2
        thread.attach(false, startSeq);//3

        ...
        Looper.loop();//4

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

在main方法中1和4是與啟動Handler有關(guān)莺奔,這里不再贅述;2處創(chuàng)建了ActivityThread遗淳,緊接著3處調(diào)用了attach方法拍柒,意為連接,具體連接什么洲脂?我們分析下attach方法斤儿;

  @UnsupportedAppUsage
  private void attach(boolean system, long startSeq) {
        ...
        if (!system) {
            ...
            final IActivityManager mgr = ActivityManager.getService();//1
            try {
                mgr.attachApplication(mAppThread, startSeq);//2
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
            ...
        } else {
            ...
        }
        ...
    }

在attach方法中,在注釋1處恐锦,通過AIDL獲取了AMS的代理對象IActivityManager 往果,實現(xiàn)了應(yīng)用進程和系統(tǒng)進程通信;緊接著在注釋2處調(diào)用了IActivityManager 的attachApplication方法一铅,即跨進程調(diào)用了AMS的attachApplication方法陕贮;這里的意思是把Application與AMS連接起來,也就是把APP綁定到系統(tǒng)應(yīng)用潘飘,具體怎么綁定的呢肮之?在ActivityManagerService類中找到attachApplication方法,繼續(xù)分析卜录;

@Override
    public final void attachApplication(IApplicationThread thread, long startSeq) {
        if (thread == null) {
            throw new SecurityException("Invalid application interface");
        }
        synchronized (this) {
            int callingPid = Binder.getCallingPid();//1
            final int callingUid = Binder.getCallingUid();//2
            final long origId = Binder.clearCallingIdentity();
            attachApplicationLocked(thread, callingPid, callingUid, startSeq);//3
            Binder.restoreCallingIdentity(origId);
        }
    }

在注釋1和2處系統(tǒng)分別給應(yīng)用分配了pid和uid戈擒,在注釋3處調(diào)用了叫attachApplicationLocked的方法,傳入了pid和uid艰毒,同時也傳入了ActivityThread的代理類IApplicationThread筐高,繼續(xù)往下看看attachApplicationLocked方法中做了什么?

@GuardedBy("this")
    private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
            int pid, int callingUid, long startSeq) {

        ProcessRecord app;  //1
        long startTime = SystemClock.uptimeMillis();
        if (pid != MY_PID && pid >= 0) {
            synchronized (mPidsSelfLocked) {
                app = mPidsSelfLocked.get(pid);  //2
            }
        } 
        ...
        if (app.instr != null) {  //當前進程是否正在活動
           thread.bindApplication(processName, appInfo, providers, app.instr.mClass,
                    profilerInfo, app.instr.mArguments, app.instr.mWatcher, app.instr.mUiAutomationConnection,
                    testMode, mBinderTransactionTrackingEnabled, enableTrackAllocation,
                    isRestrictedBackupMode || !normalMode, app.persistent, new Configuration(getGlobalConfiguration()),
                    app.compat, getCommonServicesLocked(app.isolated), mCoreSettingsObserver.getCoreSettingsLocked(),
                    buildSerial, isAutofillCompatEnabled);   //3
        } else {
            //Application 綁定到當前線程
            thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
                    null, null, null, testMode, mBinderTransactionTrackingEnabled,
                    enableTrackAllocation, isRestrictedBackupMode || !normalMode, app.persistent,
                    new Configuration(getGlobalConfiguration()), app.compat, getCommonServicesLocked(app.isolated),
                    mCoreSettingsObserver.getCoreSettingsLocked(), buildSerial, isAutofillCompatEnabled);  //4
        }
        ...
        //檢測最可見的Activity是否在運行進程中等待,如果再則創(chuàng)建Activity
        if (mStackSupervisor.attachApplicationLocked(app)) {  //5
            didSomething = true;
        }
        ...
    }

注釋1處的ProcessRecord是個進程記錄類柑土,小伙伴們可以把這個類理解成為一個javabean蜀肘,用來保存當前進程相關(guān)的一些信息(如pid、uip稽屏、ApplicationInfo等)扮宠,在注釋2中,根據(jù)pid獲取到了這個類狐榔。
注釋3和注釋4都是綁定Application坛增,通過AIDL調(diào)用了ActivityThread中的bindApplication方法,在這里可以看到荒叼,在AMS中系統(tǒng)只是給Application提供了基本信息轿偎,并沒有創(chuàng)建Application,由此可以猜測Application創(chuàng)建是在ActivityThread中完成的被廓,具體是不是這樣呢坏晦,我們看看ActivityThread類的bindApplication方法

@Override
        public final void bindApplication(String processName, ApplicationInfo appInfo,
                ProviderInfoList providerList, ComponentName instrumentationName,
                ProfilerInfo profilerInfo, Bundle instrumentationArgs,
                IInstrumentationWatcher instrumentationWatcher,
                IUiAutomationConnection instrumentationUiConnection, int debugMode,
                boolean enableBinderTracking, boolean trackAllocation,
                boolean isRestrictedBackupMode, boolean persistent, Configuration config,
                CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
                String buildSerial, AutofillOptions autofillOptions,
                ContentCaptureOptions contentCaptureOptions, long[] disabledCompatChanges) {
          
            setCoreSettings(coreSettings);

            AppBindData data = new AppBindData();
            data.processName = processName;
            data.appInfo = appInfo;
            data.providers = providerList.getList();
            data.instrumentationName = instrumentationName;
            data.instrumentationArgs = instrumentationArgs;
            data.instrumentationWatcher = instrumentationWatcher;
            data.instrumentationUiAutomationConnection = instrumentationUiConnection;
            data.debugMode = debugMode;
            data.enableBinderTracking = enableBinderTracking;
            data.trackAllocation = trackAllocation;
            data.restrictedBackupMode = isRestrictedBackupMode;
            data.persistent = persistent;
            data.config = config;
            data.compatInfo = compatInfo;
            data.initProfilerInfo = profilerInfo;
            data.buildSerial = buildSerial;
            data.autofillOptions = autofillOptions;
            data.contentCaptureOptions = contentCaptureOptions;
            data.disabledCompatChanges = disabledCompatChanges;

            sendMessage(H.BIND_APPLICATION, data);
        }

bindApplication方法中把攜帶的參數(shù)封裝成一個AppBindData對象data,最后用handler發(fā)送消息嫁乘,并攜帶AppBindData數(shù)據(jù)昆婿;H是ActivityThread中的內(nèi)部類,繼承Handler蜓斧。繼續(xù)找到Handler處理消息的地方

 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);//1
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
                ...
            }
}

注釋1處handleBindApplication方法

##ActivityThread 
private void handleBindApplication(AppBindData data) {
       
        ...
        //創(chuàng)建Application
        app = data.info.makeApplication(data.restrictedBackupMode, null); 
        
        ...
}

handleBindApplication方法中仓蛆,調(diào)用了LoadedApk中的makeApplication方法。我們再來看看makeApplication的具體創(chuàng)建過程

@UnsupportedAppUsage
    public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) {
        if (mApplication != null) {
            return mApplication;
        }

        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "makeApplication");

        Application app = null;

        String appClass = mApplicationInfo.className;
        if (forceDefaultAppClass || (appClass == null)) {
            appClass = "android.app.Application";
        }

        try {
            //獲取加載器
            final java.lang.ClassLoader cl = getClassLoader();
            if (!mPackageName.equals("android")) {
                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
                        "initializeJavaContextClassLoader");
                initializeJavaContextClassLoader();
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            }

           ...
            //獲取上下文
            ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);//1
            
            //反射獲取Application
            app = mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);//2
            appContext.setOuterContext(app);
        } catch (Exception e) {
            if (!mActivityThread.mInstrumentation.onException(app, e)) {
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                throw new RuntimeException(
                    "Unable to instantiate application " + appClass
                    + ": " + e.toString(), e);
            }
        }
        mActivityThread.mAllApplications.add(app);
        mApplication = app;

        if (instrumentation != null) {
            try {
                instrumentation.callApplicationOnCreate(app);//3
            } catch (Exception e) {
                if (!instrumentation.onException(app, e)) {
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    throw new RuntimeException(
                        "Unable to create application " + app.getClass().getName()
                        + ": " + e.toString(), e);
                }
            }
        }

        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

        return app;
    }

注釋1創(chuàng)建了Application的上下文挎春,也就是getApplicationContext()獲取到的上下文看疙,獲取的是一個ContextImpl對象,ContextImpl 是Context的子類直奋。注釋2就是創(chuàng)建Application了能庆,在makeApplication中通過類加載器和反射創(chuàng)建了Application;注釋3調(diào)用了Application的onCreate方法脚线。
Application啟動可分為三步:
第一步搁胆,創(chuàng)建應(yīng)用進程ActivityThread;
第二步邮绿,綁定應(yīng)用程序和系統(tǒng)程序渠旁,也就是通過AIDL跨進程通信讓系統(tǒng)進程分配pid和uid等應(yīng)用信息;
第三步船逮,創(chuàng)建Application顾腊,調(diào)用onCreate方法。

創(chuàng)建Activity

@GuardedBy("this")
    private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
            int pid, int callingUid, long startSeq) {
        ...
        // See if the top visible activity is waiting to run in this process...
        //查看頂部可見活動是否正在等待在此進程中運行
        if (normalMode) {
            try {
                if (mStackSupervisor.attachApplicationLocked(app)) {//1
                    didSomething = true;
                }
            } catch (Exception e) {
                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
                badApp = true;
            }
        }

        // Find any services that should be running in this process...
        //查找此進程中應(yīng)運行的任何服務(wù)
        if (!badApp) {
            try {
                didSomething |= mServices.attachApplicationLocked(app, processName);
                checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
            } catch (Exception e) {
                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
                badApp = true;
            }
        }

        // Check if a next-broadcast receiver is in this process...
        //查看此進程中應(yīng)運行的廣播接受者
        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
            try {
                didSomething |= sendPendingBroadcastsLocked(app);
                checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
            } catch (Exception e) {
                // If the app died trying to launch the receiver we declare it 'bad'
                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
                badApp = true;
            }
        }
        ...
    }

在綁定application后挖胃,AMS會查找此進程中應(yīng)該運行的activity杂靶,服務(wù)已經(jīng)廣播接收者承耿,分別進行創(chuàng)建;注釋1處就是創(chuàng)建activity的起點伪煤。進入StackSupervisor類的attachApplicationLocked方法。

boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
        ...
                            //真正開始解鎖Activity
                            if (realStartActivityLocked(activity, app,
                                    top == activity /* andResume */, true /* checkConfig */)) {
                                didSomething = true;
                            }
       ...
    }

在attachApplicationLocked方法中經(jīng)過一系列的判斷和檢測最終調(diào)到了realStartActivityLocked方法凛辣,意為真正開始解鎖Activity抱既,方法傳入activity信息和application信息;繼續(xù)往下走扁誓;

final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
            boolean andResume, boolean checkConfig) throws RemoteException {
            ...
                // Create activity launch transaction.
                //創(chuàng)建活動啟動事務(wù)
                final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
                        r.appToken);
                //添加第一個創(chuàng)建Activity回調(diào)防泵,也就是LaunchActivityItem
                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, app.repProcState, r.icicle,
                        r.persistentState, results, newIntents, mService.isNextTransitionForward(),
                        profilerInfo));

                // Set desired final state. 設(shè)置所需的最終狀態(tài)
                final ActivityLifecycleItem lifecycleItem;
                if (andResume) {
                    lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());
                } else {
                    lifecycleItem = PauseActivityItem.obtain();
                }
                clientTransaction.setLifecycleStateRequest(lifecycleItem);//把最終生命周期放入Transaction,后面會用到

                // Schedule transaction. 執(zhí)行事務(wù)
                mService.getLifecycleManager().scheduleTransaction(clientTransaction);
                ...
    }

在realStartActivityLocked中開啟了一個activity啟動事務(wù)蝗敢,事務(wù)中添加了LaunchActivityItem以用于后期創(chuàng)建時用捷泞,然后設(shè)置activity最終生命周期,開始執(zhí)行任務(wù)寿谴;

void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
        final IApplicationThread client = transaction.getClient();
        transaction.schedule();//1
        if (!(client instanceof Binder)) {
            // If client is not an instance of Binder - it's a remote call and at this point it is
            // safe to recycle the object. All objects used for local calls will be recycled after
            // the transaction is executed on client in ActivityThread.
            transaction.recycle();
        }
    }

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

mClient是ActivityThread的代理對象锁右,用于跨進程調(diào)用ActivityThread的方法,接下來程序從系統(tǒng)進程走入應(yīng)用進程讶泰;

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

繼續(xù)往下走咏瑟,進入ClientTransactionHandler類中的scheduleTransaction方法;

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

ClientTransactionHandler是ActivityThread的父類痪署,和創(chuàng)建application一樣码泞,scheduleTransaction方法中發(fā)送了一個handler消息,任務(wù)作為消息被傳送了出去狼犯;

            case EXECUTE_TRANSACTION:
                    final ClientTransaction transaction = (ClientTransaction) msg.obj;
                    mTransactionExecutor.execute(transaction);//1
                    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();
                    }
                    // TODO(lifecycler): Recycle locally scheduled transactions.
                    break;

注釋1處繼續(xù)往下走

public void execute(ClientTransaction transaction) {
        final IBinder token = transaction.getActivityToken();
        log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token);

        executeCallbacks(transaction);//1 創(chuàng)建Activity 調(diào)用onCreate

        executeLifecycleState(transaction);//2 其它生命周期的調(diào)用
        mPendingActions.clear();
        log("End resolving transaction");
    }

進入TransactionExecutor類的execute方法余寥,注釋1處執(zhí)行創(chuàng)建Activity,注釋2處為調(diào)用Activity其它生命周期悯森;先來看executeCallbacks方法宋舷;

@VisibleForTesting
    public void executeCallbacks(ClientTransaction transaction) {
        final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
       
        ...
        final int size = callbacks.size();
        for (int i = 0; i < size; ++i) {
            final ClientTransactionItem item = callbacks.get(i);//1
            ...

            item.execute(mTransactionHandler, token, mPendingActions);//2
            item.postExecute(mTransactionHandler, token, mPendingActions);
            ...
        }
    }

注釋1處獲取了ClientTransactionItem,這個item就是前面創(chuàng)建transaction 時傳入的LaunchActivityItem呐馆,注釋2處調(diào)用了LaunchActivityItem的execute方法肥缔,注意傳入的參數(shù)mTransactionHandler其實就是ActivityThread;按照之前的尿性猜測一下汹来,LaunchActivityItem的execute方法中還是不會創(chuàng)建activity续膳,創(chuàng)建的方法應(yīng)該在ActivityThread中,傳入?yún)?shù)mTransactionHandler就是為了方便調(diào)用收班,是不是這樣呢坟岔,繼續(xù)往下看;

@Override
    public void execute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
        ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
                mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
                mPendingResults, mPendingNewIntents, mIsForward,
                mProfilerInfo, client);
        client.handleLaunchActivity(r, pendingActions, null /* customIntent */);//1
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }

注釋1處果然調(diào)用了ActivityThread的handleLaunchActivity方法摔桦,找到這個方法

@Override
    public Activity handleLaunchActivity(ActivityClientRecord r,
            PendingTransactionActions pendingActions, Intent customIntent) {
        ...
        final Activity a = performLaunchActivity(r, customIntent);//創(chuàng)建Activity

        ...

        return a;
    }

終于看到Activity 被創(chuàng)建出來了社付,performLaunchActivity就是創(chuàng)建Activity 的方法承疲,具體怎么創(chuàng)建的,來看看performLaunchActivity方法鸥咖;

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        ...

        ContextImpl appContext = createBaseContextForActivity(r);
        Activity activity = null;
        try {//1
            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) {
            if (!mInstrumentation.onException(activity, e)) {
                throw new RuntimeException(
                    "Unable to instantiate activity " + component
                    + ": " + e.toString(), e);
            }
        }

        try {
            ...

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

            mActivities.put(r.token, r);//4

        } catch (SuperNotCalledException e) {
            throw e;

        } catch (Exception e) {
            if (!mInstrumentation.onException(activity, e)) {
                throw new RuntimeException(
                    "Unable to start activity " + component
                    + ": " + e.toString(), e);
            }
        }

        return activity;
    }

注釋1處可以看到和創(chuàng)建application類似燕鸽,activity也是通過類加載器和反射的方式創(chuàng)建的;注釋2處調(diào)用了activity的onCreate方法啼辣;注釋3處把activity的生命周期狀態(tài)置為ON_CREATE啊研,在后面調(diào)用生命周期的時候還會出現(xiàn);注釋4是把activity加入的activity隊列鸥拧;至此activity創(chuàng)建完成党远,下面我們看看activity生命周期調(diào)用;
回到TransactionExecutor類的execute方法富弦;

public void execute(ClientTransaction transaction) {
        final IBinder token = transaction.getActivityToken();
        log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token);

        executeCallbacks(transaction);//1 創(chuàng)建Activity 調(diào)用onCreate

        executeLifecycleState(transaction);//2 其它生命周期的調(diào)用
        mPendingActions.clear();
        log("End resolving transaction");
    }

注釋2處就是activity其它生命周期的方法沟娱;繼續(xù)往下看

/** Transition to the final state if requested by the transaction. */
    private void executeLifecycleState(ClientTransaction transaction) {
        final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
        ...

        // Cycle to the state right before the final requested state.
        cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */);//1

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

/** Transition the client between states. */
    @VisibleForTesting
    public void cycleToPath(ActivityClientRecord r, int finish) {
        cycleToPath(r, finish, false /* excludeLastState */);
    }

    /**
     * Transition the client between states with an option not to perform the last hop in the
     * sequence. This is used when resolving lifecycle state request, when the last transition must
     * be performed with some specific parameters.
     */
    private void cycleToPath(ActivityClientRecord r, int finish,
            boolean excludeLastState) {
        final int start = r.getLifecycleState();
        log("Cycle from: " + start + " to: " + finish + " excludeLastState:" + excludeLastState);
        final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);//2
        performLifecycleSequence(r, path);//3
    }

這里主要看下注釋1處的cycleToPath方法,經(jīng)過層層調(diào)用走到注釋2處的getLifecyclePath方法腕柜,傳入的start, finish分別是activity的當前狀態(tài)和目標狀態(tài)济似,因為在創(chuàng)建activity的時候已經(jīng)把狀態(tài)設(shè)置成ON_CREATE了,所以start現(xiàn)在的值是ON_CREATE盏缤;來看一下getLifecyclePath方法碱屁;

@VisibleForTesting
    public IntArray getLifecyclePath(int start, int finish, boolean excludeLastState) {
        if (start == UNDEFINED || finish == UNDEFINED) {
            throw new IllegalArgumentException("Can't resolve lifecycle path for undefined state");
        }
        if (start == ON_RESTART || finish == ON_RESTART) {
            throw new IllegalArgumentException(
                    "Can't start or finish in intermittent RESTART state");
        }
        if (finish == PRE_ON_CREATE && start != finish) {
            throw new IllegalArgumentException("Can only start in pre-onCreate state");
        }

        mLifecycleSequence.clear();
        if (finish >= start) {
            // just go there
            for (int i = start + 1; i <= finish; i++) {
                mLifecycleSequence.add(i);
            }
        } else { // finish < start, can't just cycle down
            if (start == ON_PAUSE && finish == ON_RESUME) {
                // Special case when we can just directly go to resumed state.
                mLifecycleSequence.add(ON_RESUME);
            } else if (start <= ON_STOP && finish >= ON_START) {
                // Restart and go to required state.

                // Go to stopped state first.
                for (int i = start + 1; i <= ON_STOP; i++) {
                    mLifecycleSequence.add(i);
                }
                // Restart
                mLifecycleSequence.add(ON_RESTART);
                // Go to required state
                for (int i = ON_START; i <= finish; i++) {
                    mLifecycleSequence.add(i);
                }
            } else {
                // Relaunch and go to required state

                // Go to destroyed state first.
                for (int i = start + 1; i <= ON_DESTROY; i++) {
                    mLifecycleSequence.add(i);
                }
                // Go to required state
                for (int i = ON_CREATE; i <= finish; i++) {
                    mLifecycleSequence.add(i);
                }
            }
        }

        // Remove last transition in case we want to perform it with some specific params.
        if (excludeLastState && mLifecycleSequence.size() != 0) {
            mLifecycleSequence.remove(mLifecycleSequence.size() - 1);
        }

        return mLifecycleSequence;
    }

上面說到start值是在創(chuàng)建activity的時候設(shè)置的,那finish是在哪里設(shè)置的呢蛾找?還記得在創(chuàng)建啟動activity任務(wù)時也給任務(wù)設(shè)置了ActivityLifecycleItem吧

final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
            boolean andResume, boolean checkConfig) throws RemoteException {
            ...
                // Set desired final state. 設(shè)置所需的最終狀態(tài)
                final ActivityLifecycleItem lifecycleItem;
                if (andResume) {
                    lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());
                } else {
                    lifecycleItem = PauseActivityItem.obtain();
                }
            ...
    }

finish的值就是在這時候確定的娩脾,此時的值應(yīng)該是ON_RESUME,getLifecyclePath其實就是篩選出當前狀態(tài)后一個狀態(tài)打毛,然后存入IntArray 返回柿赊;
回到cycleToPath方法,在得到activity下一個周期后幻枉,調(diào)用了performLifecycleSequence方法碰声,activity生命周期方法就是在這里調(diào)用的,來看代碼

/** Transition the client through previously initialized state sequence. */
    private void performLifecycleSequence(ActivityClientRecord r, IntArray path) {
        final int size = path.size();
        for (int i = 0, state; i < size; i++) {
            state = path.get(i);
            log("Transitioning to state: " + state);
            switch (state) {
                case ON_CREATE:
                    mTransactionHandler.handleLaunchActivity(r, mPendingActions,
                            null /* customIntent */);
                    break;
                case ON_START:
                    mTransactionHandler.handleStartActivity(r, mPendingActions);
                    break;
                case ON_RESUME:
                    mTransactionHandler.handleResumeActivity(r.token, false /* finalStateRequest */,
                            r.isForward, "LIFECYCLER_RESUME_ACTIVITY");
                    break;
                case ON_PAUSE:
                    mTransactionHandler.handlePauseActivity(r.token, false /* finished */,
                            false /* userLeaving */, 0 /* configChanges */, mPendingActions,
                            "LIFECYCLER_PAUSE_ACTIVITY");
                    break;
                case ON_STOP:
                    mTransactionHandler.handleStopActivity(r.token, false /* show */,
                            0 /* configChanges */, mPendingActions, false /* finalStateRequest */,
                            "LIFECYCLER_STOP_ACTIVITY");
                    break;
                case ON_DESTROY:
                    mTransactionHandler.handleDestroyActivity(r.token, false /* finishing */,
                            0 /* configChanges */, false /* getNonConfigInstance */,
                            "performLifecycleSequence. cycling to:" + path.get(size - 1));
                    break;
                case ON_RESTART:
                    mTransactionHandler.performRestartActivity(r.token, false /* start */);
                    break;
                default:
                    throw new IllegalArgumentException("Unexpected lifecycle state: " + state);
            }
        }
    }

可以看到不同的狀態(tài)都有對應(yīng)的方法調(diào)用生命周期熬甫,mTransactionHandler上文提到過就是ActivityThread胰挑,所以這些生命周期方法都是在ActivityThread中調(diào)用的;拿ON_RESUME為例椿肩,找到對應(yīng)的handleResumeActivity方法瞻颂;

@Override
    public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward, String reason) {
        ...

        // TODO Push resumeArgs into the activity for consideration
        final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
        ...
    }

到這里activity生命周期就調(diào)用了,performResumeActivity具體實現(xiàn)在這里就不贅述了郑象,有興趣可以自己看一下贡这。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市厂榛,隨后出現(xiàn)的幾起案子盖矫,更是在濱河造成了極大的恐慌丽惭,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,036評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件辈双,死亡現(xiàn)場離奇詭異责掏,居然都是意外死亡,警方通過查閱死者的電腦和手機湃望,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評論 3 395
  • 文/潘曉璐 我一進店門拷橘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人喜爷,你說我怎么就攤上這事√汛剑” “怎么了檩帐?”我有些...
    開封第一講書人閱讀 164,411評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長另萤。 經(jīng)常有香客問我湃密,道長,這世上最難降的妖魔是什么四敞? 我笑而不...
    開封第一講書人閱讀 58,622評論 1 293
  • 正文 為了忘掉前任泛源,我火速辦了婚禮,結(jié)果婚禮上忿危,老公的妹妹穿的比我還像新娘达箍。我一直安慰自己,他們只是感情好铺厨,可當我...
    茶點故事閱讀 67,661評論 6 392
  • 文/花漫 我一把揭開白布缎玫。 她就那樣靜靜地躺著,像睡著了一般解滓。 火紅的嫁衣襯著肌膚如雪赃磨。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,521評論 1 304
  • 那天洼裤,我揣著相機與錄音邻辉,去河邊找鬼。 笑死腮鞍,一個胖子當著我的面吹牛值骇,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播移国,決...
    沈念sama閱讀 40,288評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼雷客,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了桥狡?” 一聲冷哼從身側(cè)響起搅裙,我...
    開封第一講書人閱讀 39,200評論 0 276
  • 序言:老撾萬榮一對情侶失蹤皱卓,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后部逮,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體娜汁,經(jīng)...
    沈念sama閱讀 45,644評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,837評論 3 336
  • 正文 我和宋清朗相戀三年兄朋,在試婚紗的時候發(fā)現(xiàn)自己被綠了掐禁。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,953評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡颅和,死狀恐怖傅事,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情峡扩,我是刑警寧澤蹭越,帶...
    沈念sama閱讀 35,673評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站教届,受9級特大地震影響响鹃,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜案训,卻給世界環(huán)境...
    茶點故事閱讀 41,281評論 3 329
  • 文/蒙蒙 一买置、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧强霎,春花似錦忿项、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至椿争,卻和暖如春怕膛,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背秦踪。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評論 1 269
  • 我被黑心中介騙來泰國打工褐捻, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人椅邓。 一個月前我還...
    沈念sama閱讀 48,119評論 3 370
  • 正文 我出身青樓柠逞,卻偏偏與公主長得像,于是被迫代替她去往敵國和親景馁。 傳聞我的和親對象是個殘疾皇子板壮,可洞房花燭夜當晚...
    茶點故事閱讀 44,901評論 2 355

推薦閱讀更多精彩內(nèi)容