深入理解 Activity 的生命周期

0.133字数 1783阅读 774

对于 Android 开发者来说,Activity 应该是非常熟悉的,一提到 Activity,可能大家首先会想到 Activity 的生命周期、启动模式等开发中经常用到的知识,但是有没有更深入的去了解过在 Framework 层面 Activity 是一个怎样的存在呢?
这篇文章就带大家从 Framework 层面更深入地理解 Activity 的生命周期,在这篇文章中会带大家重新认识几个类:

  • Activity:四大组件之一,开发者只需要继承 Activity,重写生命周期方法即可,不需要关心生命周期的方法是怎么被调用的
  • ActivityThread:在其中创建了 Activity、Window、Instrumentation 实例对象,是,是调用 Activity 生命周期方法的源头
  • Instrumentation:ActivityThread 并不会直接调用 Activity 的生命周期方法,而是通过 Instrumentation 对象间接地调用 Activity 的生命周期方法
  • IActivityManager:AIDL 接口,定义了应用进程调用系统进程 ActivityManagerService 中 Activity 实例的方法
  • IApplicationThread:AIDL 接口,定义了系统进程 ActivityManagerService 调用应用进程中 Activity 生命周期的方法,其在应用进程中的实现类是 ActivityThread 的内部类 ApplicationThread

一. Activity 中的启动源码分析

首先,我们从一个非常熟悉的概念开始。启动一个 Activity,相信大家都驾轻就熟,方法如下,我们就从这个方法开始

startActivity(new Intent(MainActivity.this, SecondActivity.class));

调用 Activity#startActivity(Intent intent) 方法之后,会有如下的方法调用链

public class Activity {

    @Override
    public void startActivity(Intent intent) {
        this.startActivity(intent, null);
    }

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

    public void startActivityForResult(@RequiresPermission Intent intent, int requestCode) {
        startActivityForResult(intent, requestCode, null);
    }

    public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
        if (mParent == null) {
            options = transferSpringboardActivityOptions(options);
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
            if (ar != null) {
                mMainThread.sendActivityResult(
                    mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                    ar.getResultData());
            }
            if (requestCode >= 0) {
                // If this start is requesting a result, we can avoid making
                // the activity visible until the result is received.  Setting
                // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
                // activity hidden during this time, to avoid flickering.
                // This can only be done when a result is requested because
                // that guarantees we will get information back when the
                // activity is finished, no matter what happens to it.
                mStartedActivity = true;
            }

            cancelInputsAndStartExitTransition(options);
            // TODO Consider clearing/flushing other event sources and events for child windows.
        } else {
            if (options != null) {
                mParent.startActivityFromChild(this, intent, requestCode, options);
            } else {
                // Note we want to go through this method for compatibility with
                // existing applications that may have overridden it.
                mParent.startActivityFromChild(this, intent, requestCode);
            }
        }
    }
}

从上面代码调用链中可以发现,启动 Activity 最后走到了 Activity#startActivityForResult(@RequiresPermission Intent intent, int requestCode, @Nullable Bundle options) 方法中
1. 在 Activity 中的 mParentActivityGroup 的遗留产物,而 ActivityGroup 现在已被废弃,所以这里只分析 mParent == null 的情况
2. 上面代码中,最重要的是 mInstrumentation.execStartActivity 方法的调用,mInstrumentation 就是一个 Instrumentation 的对象,接下来进入到 Instrumentation#execStartActivity 方法中

二. Instrumentation 中的启动源码分析

public class Instrumentation {
    
    // ......

    public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, String target,
        Intent intent, int requestCode, Bundle options) {
        // 代码 1
        IApplicationThread whoThread = (IApplicationThread) contextThread;
        if (mActivityMonitors != null) {
            synchronized (mSync) {
                final int N = mActivityMonitors.size();
                // 循环遍历 mActivityMonitors 中对象
                for (int i=0; i<N; i++) {
                    final ActivityMonitor am = mActivityMonitors.get(i);
                    ActivityResult result = null;
                    if (am.ignoreMatchingSpecificIntents()) {
                        result = am.onStartActivity(intent);
                    }
                    // 如果找到则直接返回结果
                    if (result != null) {
                        am.mHits++;
                        return result;
                    } else if (am.match(who, null, intent)) {
                        am.mHits++;
                        if (am.isBlocking()) {
                            return requestCode >= 0 ? am.getResult() : null;
                        }
                        break;
                    }
                }
            }
        }
        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess(who);
            // 代码 2,真正启动 Activity 的代码
            int result = ActivityManager.getService()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target, requestCode, 0, null, options);
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }

    // ......
}

在上述代码2处是真正启动 Activity 的代码。在这行代码有两个问题,我们依次寻找下面两个问题的答案
1. 那么 ActivityManager.getService() 得到了一个什么对象呢?
2. 在调用 startActivity 方法时传入的 IApplicationThread 对象有何用处呢?

我们来到 ActivityManager.getService() 方法中,代码如下

public class ActivityManager {

    /**
     * @hide
     */
    public static IActivityManager getService() {
        return IActivityManagerSingleton.get();
    }

    private static final Singleton<IActivityManager> IActivityManagerSingleton =
            new Singleton<IActivityManager>() {
                @Override
                protected IActivityManager create() {
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                    final IActivityManager am = IActivityManager.Stub.asInterface(b);
                    return am;
                }
            };
}
  1. 在 ActivityManager 中通过 getService() 方法向外暴露一个 IActivityManager 对象,而此 IActivityManager 对象在 ActivityManager 中是个单例。在 Singleton#create() 方法中创建 IActivityManager 对象时,是通过进程间通信的 AIDL 方式创建 IActivityManager 对象的
  2. 这儿就涉及到 ActivityManagerService 和 AIDL 进程间通信(如果不熟悉的话,建议阅读 Android 中的 IPC 机制,复习一下)了。我们可以这样理解,在 AIDL 进程间通信时涉及到两个进程:客户端进程和服务端进程。
    • 在 IActivityManager AIDL 中:客户端进程是我们的应用进程,服务端进程是 ActivityManagerService 所在的系统进程
    • ActivityManagerService 是系统进程中提供服务的 Binder 对象,并且 ActivityManagerService 实现了 IActivityManager 接口,通过 ActivityManager.getService() 得到的 IActivityManager 对象,是客户端进程调用 ActivityManagerService 中方法的客户端对象
  3. Instrumentation#execStartActivity 方法 代码1 处我们得到了一个 IApplicationThread 对象,在调用 IActivityManager.startActivity 方法时将此 IApplicationThread 对象传给 ActivityManagerService,其实 IApplicationThread 也是一个 AIDL 接口,只不过它和 IActivityManager 调用方向相反。
    • 在 IApplicationThread AIDL 中,服务端进程是应用所在的进程,客户端进程是 ActivityManagerService 所在的系统进程。
    • 实现 IApplicationThread 接口的 Binder 类在应用进程中,是 ActivityThread 中的内部类 ApplicationThread,在 ActivityManagerService 中也持有一个 IApplicationThread 对象,用于调用 ApplicationThread 所提供的服务端方法

三. ApplicationThread & ActivityThread & Instrumentation 中生命周期方法的调用

在应用进程经 IActivityManager 通过 AIDL 方式调用系统进程中的 ActivityManagerService#startActivity 之后会走到 ActivityManagerService 中的逻辑,在 ActivityManagerService 处理完成之后,也会经 IApplicationThread 通过 AIDL 方式调用应用进程中 ApplicationThread 中的 scheduleLaunchActivity 方法,源码如下

public final class ActivityThread {
    
    final H mH = new H();

    /......
    private class ApplicationThread extends IApplicationThread.Stub {
        
        @Override
        public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
                ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
                CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
                int procState, Bundle state, PersistableBundle persistentState,
                List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
                boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {

            updateProcessState(procState, false);

            ActivityClientRecord r = new ActivityClientRecord();

            r.token = token;
            r.ident = ident;
            r.intent = intent;
            r.referrer = referrer;
            r.voiceInteractor = voiceInteractor;
            r.activityInfo = info;
            r.compatInfo = compatInfo;
            r.state = state;
            r.persistentState = persistentState;

            r.pendingResults = pendingResults;
            r.pendingIntents = pendingNewIntents;

            r.startsNotResumed = notResumed;
            r.isForward = isForward;

            r.profilerInfo = profilerInfo;

            r.overrideConfig = overrideConfig;
            updatePendingConfiguration(curConfig);

            sendMessage(H.LAUNCH_ACTIVITY, r);
        }  
    }

    private void sendMessage(int what, Object obj) {
        sendMessage(what, obj, 0, 0, false);
    }

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

上面这段代码也不难理解,在 scheduleLaunchActivity 方法中,生成一个 ActivityClientRecord 对象之后,通过一个 H 类的对象发送一个 H.LAUNCH_ACTIVITY 消息,此 H 类是一个 Handler 的子类,源码如下:

public final class ActivityThread {
    /......
    private class H extends Handler {
         public static final int LAUNCH_ACTIVITY         = 100;
         public static final int PAUSE_ACTIVITY          = 101;
         /......
         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;
                case RELAUNCH_ACTIVITY: {
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart");
                    ActivityClientRecord r = (ActivityClientRecord)msg.obj;
                    handleRelaunchActivity(r);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                } 
                /.....
         }
    }
    /......
}

在 H 类中处理 H.LAUNCH_ACTIVITY 消息时,调用了 handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) 方法如下:

    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.
        handleConfigurationChanged(null, null);

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

        // Initialize before creating the activity
        WindowManagerGlobal.initialize();
        // 代码 1
        Activity a = performLaunchActivity(r, customIntent);

        if (a != null) {
            r.createdConfig = new Configuration(mConfiguration);
            reportSizeConfigurations(r);
            Bundle oldState = r.state;
            // 代码 2
            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.
                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();
            }
        }
    }

在上面代码中有两处代码很重要:

  1. 代码1 处调用 performLaunchActivity(ActivityClientRecord r, Intent customIntent) 执行 Activity 的 create 流程
  2. 代码2 处调用 handleResumeActivity(IBinder token, boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) 执行 Activity 的 resume 流程

performLaunchActivity(ActivityClientRecord r, Intent customIntent) 源码如下,重要的代码都加了相应的注释

    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");
        
        // 从 ActivityClientRecord 对象中解析出 Activity 信息
        ActivityInfo aInfo = r.activityInfo;
        if (r.packageInfo == null) {
            r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                    Context.CONTEXT_INCLUDE_CODE);
        }

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

        if (r.activityInfo.targetActivity != null) {
            component = new ComponentName(r.activityInfo.packageName,
                    r.activityInfo.targetActivity);
        }

        ContextImpl appContext = createBaseContextForActivity(r);
        Activity activity = null;
        try {
            // 通过 Instrumentation 和 ClassLoader 对象创建相应的 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) {
            if (!mInstrumentation.onException(activity, e)) {
                throw new RuntimeException(
                    "Unable to instantiate activity " + component
                    + ": " + e.toString(), e);
            }
        }

        try {
            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);
                // 代码1,调用 Activity 的 attach 方法,其中创建了 Activity 所对应的 Window 对象
                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);
                }

                activity.mCalled = false;
                // 代码2,通过 mInstrumentation 调用 Activity 对象的 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.stopped = true;
                if (!r.activity.mFinished) {
                    activity.performStart();
                    r.stopped = false;
                }
                if (!r.activity.mFinished) {
                    // 代码3,通过 mInstrumentation 调用 Activity 对象的 onRestoreInstanceState 方法
                    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);
                    }
                }
                if (!r.activity.mFinished) {
                    activity.mCalled = false;
                    // 代码4,通过 mInstrumentation 调用 Activity 对象的 onPostCreate 方法
                    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;
            
            // 代码5
            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;
    }

对上面的代码做简单的说明:

  1. 代码1 处调用了 Activity#attach 方法,如下所示,在其中最重要的就是为 Activity 创建了对应的 Window 对象

    • Activity 实现了 Window 中的几个 Callback,其中最重要的就是 Window#Callback 接口,Window 接收到的键盘、触摸等事件就是通过此接口传递到 Activity 中的
    • 为此 Window 对象添加 WindowManager 对象
    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) {
        attachBaseContext(context);
    
        mFragments.attachHost(null /*parent*/);
        
        // 创建 Activity 对应的 Window 对象,并实现 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());
            }
        }
         
        // 为 Window 对象添加 WindowManager 对象
        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);
    }
    
  2. 在代码 2 处调用了 Instrumentation#callActivityOnCreate 方法,如下所示,可以看到最终调用了 Activity#onCreate 方法

    // Instrumentation
    public void callActivityOnCreate(Activity activity, Bundle icicle,
            PersistableBundle persistentState) {
        prePerformCreate(activity);
        activity.performCreate(icicle, persistentState);
        postPerformCreate(activity);
    }
    
    // Activity 
    final void performCreate(Bundle icicle) {
        restoreHasCurrentPermissionRequest(icicle);
        onCreate(icicle);
        mActivityTransitionState.readState(icicle);
        performCreateCommon();
    }
    
  3. 代码 3 处和代码 4 处和代码 2 处相同,都是先调用了 Instrumentation 中的 callActivityOnRestoreInstanceStatecallActivityOnPostCreate 方法,然后在其中又调用了 Activity 中的 performRestoreInstanceStateonPostCreate 方法的。

可见 ActivityThread 中持有 Instrumentation 和 Activity 的实例对象,但是不会直接调用 Activity 的生命周期方法,而是通过 Instrumentation 对象间接的调用 Activity 的生命周期方法,上面只分析了 create 阶段的方法调用过程,其实 resume、start、stop、pause 和 destory 阶段的生命周期方法调用过程都是类似的

推荐阅读更多精彩内容