Android 从程序启动startActivity到生命周期变化的过程

Posted yuminfeng728

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 从程序启动startActivity到生命周期变化的过程相关的知识,希望对你有一定的参考价值。

在上篇文章中,我们了解了android应用程序是如何启动的,也介绍了具体的流程调用。知道了整个APP的启动过程都是由ActivityThread类中执行的,而且启动中的生命周期的变化都是通过Handler消息机制来完成的。那么这篇将要具体介绍从启动到startActivity时生命周期变化的过程。
从上篇知道执行了ApplicationThread中scheduleLaunchActivity,在这个方法中我们可以看到通过Handler机制,将ActivityClientRecord作为消息对象发送给Handler进行处理,可以在handleMessage中处理接收的消息。

public void handleMessage(Message msg) 
    if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
    switch (msg.what) 
        case LAUNCH_ACTIVITY: 
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
            final ActivityClientRecord r = (ActivityClientRecord) msg.obj;

            r.packageInfo = getPackageInfoNoCheck(
                    r.activityInfo.applicationInfo, r.compatInfo);
            handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
         break;

        ....

ActivityThread#handleLaunchActivity
其中传入的customIntent 为null

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) 
    // If we are getting ready to gc after going to the background, well
    // we are back active so skip it.
    unscheduleGcIdler();
    mSomeActivitiesChanged = true;

    if (r.profilerInfo != null) 
        mProfiler.setProfiler(r.profilerInfo);
        mProfiler.startProfiling();
    

    // Make sure we are running with the most recent config.
    //step1:处理config
    handleConfigurationChanged(null, null);

    if (localLOGV) Slog.v(
        TAG, "Handling launch of " + r);

    // Initialize before creating the activity
    //step2: 初始化windowManager
    WindowManagerGlobal.initialize();

    //step3:执行启动Activity
    Activity a = performLaunchActivity(r, customIntent);

    if (a != null) 
        r.createdConfig = new Configuration(mConfiguration);
        reportSizeConfigurations(r);
        Bundle oldState = r.state;
        handleResumeActivity(r.token, false, r.isForward,
                !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);

        if (!r.activity.mFinished && r.startsNotResumed) 
            // The activity manager actually wants this one to start out paused, because it
            // needs to be visible but isn't in the foreground. We accomplish this by going
            // through the normal startup (because activities expect to go through onResume()
            // the first time they run, before their window is displayed), and then pausing it.
            // However, in this case we do -not- need to do the full pause cycle (of freezing
            // and such) because the activity manager assumes it can just retain the current
            // state it has.

            //step 4
            performPauseActivityIfNeeded(r, reason);

            // We need to keep around the original state, in case we need to be created again.
            // But we only do this for pre-Honeycomb apps, which always save their state when
            // pausing, so we can not have them save their state when restarting from a paused
            // state. For HC and later, we want to (and can) let the state be saved as the
            // normal part of stopping the activity.
            if (r.isPreHoneycomb()) 
                r.state = oldState;
            
        
     else 
        // If there was an error, for any reason, tell the activity manager to stop us.
        try 
            ActivityManager.getService()
                .finishActivity(r.token, Activity.RESULT_CANCELED, null,
                        Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
         catch (RemoteException ex) 
            throw ex.rethrowFromSystemServer();
        
    

step 3:执行启动Activity

ActivityThread#performLaunchActivity
其中传入的customIntent 为null

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) 
    // System.out.println("##### [" + System.currentTimeMillis() + "] //ActivityThread.performLaunchActivity(" + r + ")");

    //step 1: 
    ActivityInfo aInfo = r.activityInfo;
    if (r.packageInfo == null) 
        r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                Context.CONTEXT_INCLUDE_CODE);
    

    //step 2:查找出设置的默认启动的component 名字
    ComponentName component = r.intent.getComponent();
    if (component == null) 
        component = r.intent.resolveActivity(
            mInitialApplication.getPackageManager());
        r.intent.setComponent(component);
    

    //step 3:
    if (r.activityInfo.targetActivity != null) 
        component = new ComponentName(r.activityInfo.packageName,
                r.activityInfo.targetActivity);
    

    //step 4:
    ContextImpl appContext = createBaseContextForActivity(r);

    //step 5: 初始化Actvity类
    Activity activity = null;
    try 
        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 
        //step 6: 初始化Application类
        Application app = r.packageInfo.makeApplication(false, mInstrumentation);

        if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
        if (localLOGV) Slog.v(
                TAG, r + ": app=" + app
                + ", appName=" + app.getPackageName()
                + ", pkg=" + r.packageInfo.getPackageName()
                + ", comp=" + r.intent.getComponent().toShortString()
                + ", dir=" + r.packageInfo.getAppDir());

        if (activity != null) 
            CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
            Configuration config = new Configuration(mCompatConfiguration);
            if (r.overrideConfig != null) 
                config.updateFrom(r.overrideConfig);
            
            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
                    + r.activityInfo.name + " with config " + config);
            Window window = null;
            if (r.mPendingRemoveWindow != null && r.mPreserveWindow) 
                window = r.mPendingRemoveWindow;
                r.mPendingRemoveWindow = null;
                r.mPendingRemoveWindowManager = null;
            
            appContext.setOuterContext(activity);

            //step 7: 调用Actvity.attch 方法
            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);

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

            //step 8: 调用Actvity.onCreate 方法
            activity.mCalled = false;
            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.stopped = true;
            if (!r.activity.mFinished) 

                //step 9: 调用Actvity.onStart 方法
                activity.performStart();
                r.stopped = false;
            

            //step 10:
            if (!r.activity.mFinished) 
                if (r.isPersistable()) 
                    if (r.state != null || r.persistentState != null) 
                        mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
                                r.persistentState);
                    
                 else if (r.state != null) 
                    mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
                
            

            //step 11:
            if (!r.activity.mFinished) 
                activity.mCalled = false;
                if (r.isPersistable()) 
                    mInstrumentation.callActivityOnPostCreate(activity, r.state,
                            r.persistentState);
                 else 
                    mInstrumentation.callActivityOnPostCreate(activity, r.state);
                
                if (!activity.mCalled) 
                    throw new SuperNotCalledException(
                        "Activity " + r.intent.getComponent().toShortString() +
                        " did not call through to super.onPostCreate()");
                
            
        
        r.paused = true;

        mActivities.put(r.token, r);

     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;

我们可以看到从这个方法中才真正进入了Activity的生命周期的调用。首先通过查找出默认启动的ComponentName,然后通过反射初始化了Activity对象。接着调用makeApplication来完成Application对象的初始化。我们可以先来分析下这个方法:

LoadedApk#makeApplication

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

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

    Application app = null;

    //step1 : 设置默认Application为系统提供的类
    String appClass = mApplicationInfo.className;
    if (forceDefaultAppClass || (appClass == null)) 
        appClass = "android.app.Application";
    

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

        //step 2: 实例化Application对象
        ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
        app = mActivityThread.mInstrumentation.newApplication(
                cl, appClass, appContext);
        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;

    //step 3: 调用Application中的onCreate方法
    if (instrumentation != null) 
        try 
            instrumentation.callApplicationOnCreate(app);
         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);
            
        
    

    // Rewrite the R 'constants' for all library apks.
    SparseArray<String> packageIdentifiers = getAssets().getAssignedPackageIdentifiers();
    final int N = packageIdentifiers.size();
    for (int i = 0; i < N; i++) 
        final int id = packageIdentifiers.keyAt(i);
        if (id == 0x01 || id == 0x7f) 
            continue;
        

        rewriteRValues(getClassLoader(), packageIdentifiers.valueAt(i), id);
    

    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

    return app;

从上面我们了解创建了Activity对象后,马上就通过makeApplication方法实例化Application对象,完成了对Application的初始化后,通过instrumentation调用callApplicationOnCreate方法来调用Application.onCreate()方法。这里我们看到了,启动应用程序时,最先调用的是Application中的onCreate()方法。

完成了Application中的onCreate()调用后,下面继续分析上面的performLaunchActivity方法,这时进入了step 7 阶段,执行activity.attach 方法。

Activity#attach

final void attach(Context context, ActivityThread aThread,
        Instrumentation instr, IBinder token, int ident,
        Application application, Intent intent, ActivityInfo info,
        CharSequence title, Activity parent, String id,
        NonConfigurationInstances lastNonConfigurationInstances,
        Configuration config, String referrer, IVoiceInteractor voiceInteractor,
        Window window, ActivityConfigCallback activityConfigCallback) 

    //step 1: 设置上下文context
    attachBaseContext(context);

    //step 2:
    mFragments.attachHost(null /*parent*/);

    //step 3: 初始化window
    mWindow = new PhoneWindow(this, window, activityConfigCallback);
    mWindow.setWindowControllerCallback(this);
    mWindow.setCallback(this);
    mWindow.setOnWindowDismissedCallback(this);
    mWindow.getLayoutInflater().setPrivateFactory(this);
    if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) 
        mWindow.setSoftInputMode(info.softInputMode);
    
    if (info.uiOptions != 0) 
        mWindow.setUiOptions(info.uiOptions);
    
    mUiThread = Thread.currentThread();

    mMainThread = aThread;
    mInstrumentation = instr;
    mToken = token;
    mIdent = ident;
    mApplication = application;
    mIntent = intent;
    mReferrer = referrer;
    mComponent = intent.getComponent();
    mActivityInfo = info;
    mTitle = title;
    mParent = parent;
    mEmbeddedID = id;
    mLastNonConfigurationInstances = lastNonConfigurationInstances;
    if (voiceInteractor != null) 
        if (lastNonConfigurationInstances != null) 
            mVoiceInteractor = lastNonConfigurationInstances.voiceInteractor;
         else 
            mVoiceInteractor = new VoiceInteractor(voiceInteractor, this, this,
                    Looper.myLooper());
        
    

    mWindow.setWindowManager(
            (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
            mToken, mComponent.flattenToString(),
            (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
    if (mParent != null) 
        mWindow.setContainer(mParent.getWindow());
    
    mWindowManager = mWindow.getWindowManager();
    mCurrentConfig = config;

    mWindow.setColorMode(info.colorMode);

我们首先来分析这个方法,这是执行生命周期方法中最先被执行的方法,因为被final修饰所以无法被子类复写。所以平时的开发中无需关注这个方法,但是它在onCreate之前被执行。这个方法中,执行几个关键操作,关联了Context,初始化window和其他属性的赋值。

完成了Activity中attch调用后,performLaunchActivity方法继续进入了 step 8,执行mInstrumentation.callActivityOnCreate

Instrumentation#callActivityOnCreate

public void callActivityOnCreate(Activity activity, Bundle icicle) 
    prePerformCreate(activity);
    activity.performCreate(icicle);
    postPerformCreate(activity);

Activity#performCreate

final void performCreate(Bundle icicle) 
    restoreHasCurrentPermissionRequest(icicle);
    onCreate(icicle);
    mActivityTransitionState.readState(icicle);
    performCreateCommon();

方法中直接调用了onCreate方法,继续查看该方法:

Activity.onCreate

protected void onCreate(@Nullable Bundle savedInstanceState) 
    if (DEBUG_LIFECYCLE) Slog.v(TAG, "onCreate " + this + ": " + savedInstanceState);

    if (getApplicationInfo().targetSdkVersion > O && mActivityInfo.isFixedOrientation()) 
        final TypedArray ta = obtainStyledAttributes(com.android.internal.R.styleable.Window);
        final boolean isTranslucentOrFloating = ActivityInfo.isTranslucentOrFloating(ta);
        ta.recycle();

        if (isTranslucentOrFloating) 
            throw new IllegalStateException(
                    "Only fullscreen opaque activities can request orientation");
        
    

    if (mLastNonConfigurationInstances != null) 
        mFragments.restoreLoaderNonConfig(mLastNonConfigurationInstances.loaders);
    
    if (mActivityInfo.parentActivityName != null) 
        if (mActionBar == null) 
            mEnableDefaultActionBarUp = true;
         else 
            mActionBar.setDefaultDisplayHomeAsUpEnabled(true);
        
    
    if (savedInstanceState != null) 
        mAutoFillResetNeeded = savedInstanceState.getBoolean(AUTOFILL_RESET_NEEDED, false);
        mLastAutofillId = savedInstanceState.getInt(LAST_AUTOFILL_ID,
                View.LAST_APP_AUTOFILL_ID);

        if (mAutoFillResetNeeded) 
            getAutofillManager().onCreate(savedInstanceState);
        

        Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);
        mFragments.restoreAllState(p, mLastNonConfigurationInstances != null
                ? mLastNonConfigurationInstances.fragments : null);
    
    mFragments.dispatchCreate();
    getApplication().dispatchActivityCreated(this, savedInstanceState);
    if (mVoiceInteractor != null) 
        mVoiceInteractor.attachActivity(this);
    
    mCalled = true;

完成了Activity中onCreate调用后,performLaunchActivity方法继续进入了 step 9,执行activity.performStart();

Activity#performStart

final void performStart() 
    mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
    mFragments.noteStateNotSaved();
    mCalled = false;
    mFragments.execPendingActions();
    mInstrumentation.callActivityOnStart(this);
    if (!mCalled) 
        throw new SuperNotCalledException(
            "Activity " + mComponent.toShortString() +
            " did not call through to super.onStart()");
    
    mFragments.dispatchStart();
    mFragments.reportLoaderStart();

    // This property is set for all builds except final release
    boolean isDlwarningEnabled = SystemProperties.getInt("ro.bionic.ld.warning", 0) == 1;
    boolean isAppDebuggable =
            (mApplication.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;

    if (isAppDebuggable || isDlwarningEnabled) 
        String dlwarning = getDlWarning();
        if (dlwarning != null) 
            String appName = getApplicationInfo().loadLabel(getPackageManager())
                    .toString();
            String warning = "Detected problems with app native libraries\\n" +
                             "(please consult log for detail):\\n" + dlwarning;
            if (isAppDebuggable) 
                  new AlertDialog.Builder(this).
                      setTitle(appName).
                      setMessage(warning).
                      setPositiveButton(android.R.string.ok, null).
                      setCancelable(false).
                      show();
             else 
                Toast.makeText(this, appName + "\\n" + warning, Toast.LENGTH_LONG).show();
            
        
    

    mActivityTransitionState.enterReady(this);

Instrumentation#callActivityOnStart

public void callActivityOnStart(Activity activity) 
    activity.onStart();

Activity#onStart

protected void onStart() 
    if (DEBUG_LIFECYCLE) Slog.v(TAG, "onStart " + this);
    mCalled = true;

    mFragments.doLoaderStart();

    getApplication().dispatchActivityStarted(this);

    if (mAutoFillResetNeeded) 
        AutofillManager afm = getAutofillManager();
        if (afm != null) 
            afm.onVisibleForAutofill();
        
    

完成了Activity中onStart调用后,performLaunchActivity方法继续进入了 step 10,11,执行mInstrumentation.callActivityOnRestoreInstanceState 和 mInstrumentation.callActivityOnPostCreate,这里分别调用的是Activity中的onRestoreInstanceState和 onPostCreate 方法。

至此,我们知道Activity已经经历了onCreate,onStart生命周期方法。那么我们继续进入handleLaunchActivity中的step4,执行了handleResumeActivity。

ActivityThread#handleResumeActivity

final void handleResumeActivity(IBinder token,
        boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) 
    ActivityClientRecord r = mActivities.get(token);
    if (!checkAndUpdateLifecycleSeq(seq, r, "resumeActivity")) 
        return;
    

    // If we are getting ready to gc after going to the background, well
    // we are back active so skip it.
    unscheduleGcIdler();
    mSomeActivitiesChanged = true;

    // TODO Push resumeArgs into the activity for consideration

    // step 1:执行resume方法
    r = performResumeActivity(token, clearHide, reason);

    if (r != null) 
        final Activity a = r.activity;

        if (localLOGV) Slog.v(
            TAG, "Resume " + r + " started activity: " +
            a.mStartedActivity + ", hideForNow: " + r.hideForNow
            + ", finished: " + a.mFinished);

        final int forwardBit = isForward ?
                WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0;

        // If the window hasn't yet been added to the window manager,
        // and this guy didn't finish itself or start another activity,
        // then go ahead and add the window.
        boolean willBeVisible = !a.mStartedActivity;
        if (!willBeVisible) 
            try 
                willBeVisible = ActivityManager.getService().willActivityBeVisible(
                        a.getActivityToken());
             catch (RemoteException e) 
                throw e.rethrowFromSystemServer();
            
        

        //step 2: 添加view到window
        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;
                // Normally the ViewRoot sets up callbacks with the Activity
                // in addView->ViewRootImpl#setView. If we are instead reusing
                // the decor view we have to notify the view root that the
                // callbacks may have changed.
                ViewRootImpl impl = decor.getViewRootImpl();
                if (impl != null) 
                    impl.notifyChildRebuilt();
                
            
            if (a.mVisibleFromClient) 
                if (!a.mWindowAdded) 
                    a.mWindowAdded = true;
                    wm.addView(decor, l);
                 else 
                    // The activity will get a callback for this @link LayoutParams change
                    // earlier. However, at that time the decor will not be set (this is set
                    // in this method), so no action will be taken. This call ensures the
                    // callback occurs with the decor set.
                    a.onWindowAttributesChanged(l);
                
            

        // If the window has already been added, but during resume
        // we started another activity, then don't yet make the
        // window visible.
         else if (!willBeVisible) 
            if (localLOGV) Slog.v(
                TAG, "Launch " + r + " mStartedActivity set");
            r.hideForNow = true;
        

        // Get rid of anything left hanging around.
        cleanUpPendingRemoveWindows(r, false /* force */);

        // The window is now visible if it has been added, we are not
        // simply finishing, and we are not starting another activity.
        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) 
                r.activity.makeVisible();
            
        

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

        // Tell the activity manager we have resumed.
        if (reallyResume) 
            try 
                ActivityManager.getService().activityResumed(token);
             catch (RemoteException ex) 
                throw ex.rethrowFromSystemServer();
            
        

     else 
        // If an exception was thrown when trying to resume, then
        // just end this activity.
        try 
            ActivityManager.getService()
                .finishActivity(token, Activity.RESULT_CANCELED, null,
                        Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
         catch (RemoteException ex) 
            throw ex.rethrowFromSystemServer();
        
    

这个方法中主要完成了两个主要的操作,step 1:执行了performResumeActivity方法,step 2 :将decorView加入到window中。我们先分析step 1,step 2 将会专门进行分析。

ActivityThread#performResumeActivity

public final ActivityClientRecord performResumeActivity(IBinder token,
        boolean clearHide, String reason) 
    ActivityClientRecord r = mActivities.get(token);
    if (localLOGV) Slog.v(TAG, "Performing resume of " + r
            + " finished=" + r.activity.mFinished);
    if (r != null && !r.activity.mFinished) 
        if (clearHide) 
            r.hideForNow = false;
            r.activity.mStartedActivity = false;
        
        try 
            r.activity.onStateNotSaved();
            r.activity.mFragments.noteStateNotSaved();

            //执行 Activity 中 onNewIntent 方法
            if (r.pendingIntents != null) 
                deliverNewIntents(r, r.pendingIntents);
                r.pendingIntents = null;
            

            //执行 Activity 中 onActivityResult 方法
            if (r.pendingResults != null) 
                deliverResults(r, r.pendingResults);
                r.pendingResults = null;
            

            //step 1: 执行Activity 中 performResume 
            r.activity.performResume();

            synchronized (mResourcesManager) 
                // If there is a pending local relaunch that was requested when the activity was
                // paused, it will put the activity into paused state when it finally happens.
                // Since the activity resumed before being relaunched, we don't want that to
                // happen, so we need to clear the request to relaunch paused.
                for (int i = mRelaunchingActivities.size() - 1; i >= 0; i--) 
                    final ActivityClientRecord relaunching = mRelaunchingActivities.get(i);
                    if (relaunching.token == r.token
                            && relaunching.onlyLocalRequest && relaunching.startsNotResumed) 
                        relaunching.startsNotResumed = false;
                    
                
            

            EventLog.writeEvent(LOG_AM_ON_RESUME_CALLED, UserHandle.myUserId(),
                    r.activity.getComponentName().getClassName(), reason);

            r.paused = false;
            r.stopped = false;
            r.state = null;
            r.persistentState = null;
         catch (Exception e) 
            if (!mInstrumentation.onException(r.activity, e)) 
                throw new RuntimeException(
                    "Unable to resume activity "
                    + r.intent.getComponent().toShortString()
                    + ": " + e.toString(), e);
            
        
    
    return r;

我们可以看到方法里面调用了performResume:

Activity#performResume

final void performResume() 

    //step 1: 判断是否mStop,进而确定是否执行activity.onRestart();
    performRestart();

    mFragments.execPendingActions();

    mLastNonConfigurationInstances = null;

    mCalled = false;
    // mResumed is set by the instrumentation

    //step 2: 执行activity.onResume()
    mInstrumentation.callActivityOnResume(this);
    if (!mCalled) 
        throw new SuperNotCalledException(
            "Activity " + mComponent.toShortString() +
            " did not call through to super.onResume()");
    

    // invisible activities must be finished before onResume() completes
    if (!mVisibleFromClient && !mFinished) 
        Log.w(TAG, "An activity without a UI must call finish() before onResume() completes");
        if (getApplicationInfo().targetSdkVersion
                > android.os.Build.VERSION_CODES.LOLLIPOP_MR1) 
            throw new IllegalStateException(
                    "Activity " + mComponent.toShortString() +
                    " did not call finish() prior to onResume() completing");
        
    

    // Now really resume, and install the current status bar and menu.
    mCalled = false;

    mFragments.dispatchResume();
    mFragments.execPendingActions();

    //step 3: 
    onPostResume();
    if (!mCalled) 
        throw new SuperNotCalledException(
            "Activity " + mComponent.toShortString() +
            " did not call through to super.onPostResume()");
    

上面方法中就完成了activity.onResume()的调用。生命周期执行到这里时,用户就能看到界面显示的内容。那么下面文章我们将继续来分析view是如何显示在界面中。

以上是关于Android 从程序启动startActivity到生命周期变化的过程的主要内容,如果未能解决你的问题,请参考以下文章

Android学习总结——实现Home键功能

如何从 android 活动启动 Unity 应用程序?

Android - 检测应用程序从家庭或历史启动

从 Android Studio 运行时,为啥 Android 应用程序会在后台启动?

Android:从应用程序类启动新活动

从 android 浏览器启动自定义 android 应用程序