从源码看 Activity 生命周期(上篇)

简介: 从源码看 Activity 生命周期(上篇)

一路从 Zygote 说到 SystemServer ,从 AMS 的启动流程 说到 应用进程的创建,再到上一期的 Activity 启动流程,今天准备来说说大家耳熟能详的 Activity 的生命周期。关于生命周期的基础知识,官网上的这篇文章 了解 Activity 的生命周期 已经作了详细介绍。在本文中,我会从源码角度来切入生命周期的调用流程。


提到 Android 官网的 文档 部分,我想多说一句。不管是新知识点,还是你已经掌握的内容,这里都是一份绝佳的资料库。我现在每复习一个知识点,都会去重读一遍官网文档,总能有不一样的收货,文末也贴出了我的阅读笔记。


再回到本文来,其实如果有仔细阅读上一篇文章 庖丁解牛Activity 启动流程 的话,里面已经较为详细的介绍了生命周期的调用流程。只是上篇文章阅读体验的确不怎么好,所以这里把 Activity 的生命周期 单独拎出来说一说。

首先来看下 Google 给出的 Activity 经典生命周期图:

image.png

这张图应该没什么好说的了,大家肯定了如指掌。但是你了解每个生命周期背后的调动流程吗?

通过上篇文章我们都知道了 Activity 的启动由应用进程发起,通过 Binder 调用 AMS 完成,那么 AMS 所在进程是如何回调到到应用进程的生命周期方法的呢?


其实图中的每一个生命周期方法的调用流程都是同一个套路,大同小异,先搞清楚这个套路,其他问题就迎刃而解了。


生命周期的调用套路


为了方便讲解,我们以 Activity 最先被调用的生命周期 onCreate() 为例。

回顾 Activity 的启动流程,最后会调用到 ActivityStackSupervisorrealStartActivityLocked() 方法。


> ActivityStackSupervisor.java
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
                                          boolean andResume, boolean checkConfig) throws RemoteException {
    ......
    final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
                r.appToken);
    // 1. 添加 LaunchActivityItem callback
    clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                System.identityHashCode(r), r.info,
                mergedConfiguration.getGlobalConfiguration(),
                mergedConfiguration.getOverrideConfiguration(), r.compat,
                r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
                r.persistentState, results, newIntents, mService.isNextTransitionForward(),
                profilerInfo));
     final ActivityLifecycleItem lifecycleItem;
     if (andResume) {
         lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());
    } else {
        lifecycleItem = PauseActivityItem.obtain();
    }
    // 2. 设置生命周期状态
     clientTransaction.setLifecycleStateRequest(lifecycleItem);
    // 3. 调用 ClientLifecycleManager.scheduleTransaction()
     mService.getLifecycleManager().scheduleTransaction(clientTransaction);
    ......
    return true;
}
复制代码


已省略大量无关代码。

上述代码中构建了一个 ClientTransaction 对象,分别调用了它的 addCallback()setLifecycleStateRequest() 方法,最后调动 schchueduleTransaction 执行构造的 ClientTransaction 对象,分别对应注释的 123 处。下面来看一下这三个方法。


ClientTransaction.addCallback()

> ClientTransaction.java
    public void addCallback(ClientTransactionItem activityCallback) {
        if (mActivityCallbacks == null) {
            mActivityCallbacks = new ArrayList<>();
        }
        mActivityCallbacks.add(activityCallback);
    }
复制代码


mActivityCallbacks 是元素类型为 ClientTransactionItem 的集合。addCallback() 传入的参数是 LaunchActivityItem , 正是 ClientTransactionItem 的实现类。


ClientTransaction.setLifecycleStateRequest()

> ClientTransaction.java
   public void setLifecycleStateRequest(ActivityLifecycleItem stateRequest) {
        mLifecycleStateRequest = stateRequest;
    }
复制代码


mLifecycleStateRequest 表示当前的 ClientTransaction 执行之后应该处于的最终生命周期状态。


ClientLifecycleManager.scheduleTransaction()

注释 3 处 mService.getLifecycleManager().scheduleTransaction(clientTransaction);mService.getLifecycleManager() 返回的是 ClientLifecycleManager 对象,是 Android 9.0 新增的辅助处理生命周期的类,以往的源码中是没有的。看一下它的 scheduleTransaction() 方法。


> ClientLifecycleManager.java
    void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
        final IApplicationThread client = transaction.getClient(); // -> ApplicationThread
        transaction.schedule(); // ClientTransaction
        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();
        }
    }
复制代码


调用了 ClientTransactionschedule() 方法。

> ClientTransaction.java
    public void schedule() throws RemoteException {
        // 调用 ActivityThread.ApplicationThread.scheduleTransaction()
        mClient.scheduleTransaction(this);
    }
复制代码


首先明确一点,到目前为止的方法调用都处于 AMS 所在进程,并不是我们的应用进程。那么 mClient 是什么呢?java

private IApplicationThread mClient;
复制代码


IApplicationThread 是极其重要的一个 Binder 接口,它维护了应用进程和 AMS 的之间的通讯。这个 mClient 就是应用进程在 AMS 进程中的代理对象,AMS 通过 mClient 来指挥应用进程。


mClient 只是 AMS 进程中的一个 "傀儡" ,它的真身是 ActivityThread.ApplicationThread

private class ApplicationThread extends IApplicationThread.Stub {
        ......
        @Override
        public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
            // 这里调用的是父类 ClientTransactionHandler 的 scheduleTransaction() 方法
            ActivityThread.this.scheduleTransaction(transaction);
        }
        ......
}
复制代码


ActivityThread 并没有 scheduleTransaction() 方法,所以调用的是其父类 ClientTransactionHandler 的相应方法。

> ClientTransactionHandler.java
    void scheduleTransaction(ClientTransaction transaction) {
        transaction.preExecute(this);java
        // sendMessage() 方法在 ActivityThread类中实现
        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
    }
复制代码


ClientTransactionHandler 是一个抽象类,sendMeschusage() 也是一个抽象方法,其具体实现在 ActivityThread 类中,记住其参数 ActivityThread.H.EXECUTE_TRANSACTION


> ActivityThread.java
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);java
        msg.arg1 = arg1;
        msg.arg2 = arg2;
        if (async) {
            msg.setAsynchronous(true);chu
        }
        mH.sendMessage(msg);
    }
复制代码


其中的 mH 是  ActivityThread 的内部类 H ,是一个 Handler 对象。我们都知道 Handler 是用于线程间通讯的,那么这里是哪两个线程之间呢?AMS 通过 Binder 调用应用进程的对应方法,执行的是应用进程的 Binder 线程,而真正需要回调生命周期的是 主线程 ,所以这里进行通讯的就是 Binder 线程 和 主线程。


class H extends Handler {
        public void handleMessage(Message msg) {
            ......
             case EXECUTE_TRANSACTION:chu
                    final ClientTransaction transaction = (ClientTransaction) msg.obj;
                    // 执行 TransactionExecutor.execute()
                    mTransactionExecutor.execute(transaction);
                    if (isSystem()) {
                        transaction.recycle();
                    }
                    break;
            ......
        }
}
复制代码


获取到 AMS 发送过来的 ClientTransaction 对象,调用 TransactionExecutorexecute() 方法来执行此次事务。


> TransactionExecutor.java
    public void execute(ClientTransaction transaction) { clientTransaction.setLifecycleStateRequest(lifecycleItem);
        executeCallbacks(transaction);
        // 执行生命周期状态
        executeLifecycleState(transaction);
    }
复制代码


看到 execute() 中的两个方法,你应该有种似曾相识的感觉。回到文章开头处 ActivityStackSupervisorrealStartActivityLocked() 方法 :

final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
                                          boolean andResume, boolean checkConfig) throws RemoteException {
    ......
    // 1. addCallback()
    final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
                r.appToken);
    clientTransaction.addCallback(LaunchActivityItem.obtain(new ...
    // 2. setLifecycleStateRequest
         final ActivityLifecycleItem lifecycleItem;
     if (andResume) {
         lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());
    } else {
        lifecycleItem = PauseActivityItem.obtain();
    }
     clientTransaction.setLifecycleStateRequest(lifecycleItem);
    // 3. 调用 ClientLifecycleManager.scheduleTransaction()
     mService.getLifecycleManager().scheduleTransaction(clientTransaction);
    ......
    return true;
}
复制代码


addCallback()  >>> executeCallbacks()

setLifecycleStateRequest >>>  executeLifecycleState()

executeCallbacks() 会执行 addCallback() 方法添加的生命周期回调。当前添加的是 LaunchActivityItem

executeLifecycleState() 方法会将当前生命周期同步到 setLifecycleStateRequest() 方法设置的生命周期状态。当前设置的是 ResumeActivityItem

从源码来看看这两个方法是如何执行的。


TransactionExecutor.executeCallbacks()

> TransactionExecutor.java
    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);
            ......
            item.execute(mTransactionHandler, token, mPendingActions);
            item.postExecute(mTransactionHandler, token, mPendingActions);
            ......
        }
    }
复制代码


获取所有的 callback 并循环调用 execute()postExecute() 方法。这里的 calkback 只有一个元素 LaunchActivityItem

public class LaunchActivityItem extends ClientTransactionItem {
    @Override
    public void execute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
                mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
                mPendingResults, mPendingNewIntents, mIsForward,
                mProfilerInfo, client);
        // 调用 ActivityThread.handleLaunchActivity()
        client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
    }
}
复制代码


构建了 ActivityClientRecord 对象,接着调用 ActivityThreadhandleLaunchActivity() 方法。

> ActivityThread.java
    @Override
    public Activity handleLaunchActivity(ActivityClientRecord r,
            PendingTransactionActions pendingActions, Intent customIntent) {
        ......
        // Make sure we are running with the most recent config.
        handleConfigurationChanged(null, null);
        WindowManagerGlobal.initialize();
        final Activity a = performLaunchActivity(r, customIntent);activityIdleInternalLocked
        ......
        return a;
    }
复制代码


performLaunchActivity() 上篇文章已经详细介绍过,下面代码中仅保留生命周期相关代码。

> ActivityThread.java
    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        ActivityInfo aInfo = r.activityInfo;
        // 获取 Context
        ContextImpl appContext = createBaseContextForActivity(r);
        Activity activity = null;
        java.lang.ClassLoader cl = appContext.getClassLoader();
        // 反射创建 Activity
        activity = mInstrumentation.newActivity(
                cl, component.getClassName(), r.intent);
        // 获取 Application系统永远不会直接终止 Activity 以释放内存,而是会终止 Activity 所在的进程。系统不仅会销毁 Activity,还会销毁在该进程中运行的所有其他内容。
        if (activity != null) {activityIdleInternalLocked
            activity.attach(appContext, this, getInstrumentation(), r.token,
                    r.ident, app, r.intent, r.activityInfo, title, r.parent,
                    r.embedded  // 获取 Context
                    CID, r.lastNonConfigurationInstances, config,
                    r.referrer, r.voiceInteractor, window, r.configCallback);
            int theme = r.activityInfo.getThemeResource();
            if (theme != 0) {
                // 设置主题
                activity.setTheme(theme);
            }
            activity.mCalled = false;
            // 执行 onCreate()
            if (r.isPersistable()) {
                mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
            } else {
                mInstrumentation.callActivityOnCreate(activity, r.state);
            }
            r.activity = activity;
        }
        r.setState(ON_CREATE);
        mActivities.put(r.token, r);
        return activity;
    }
复制代码


重点关注 mInstrumentation.callActivityOnCreate()Instrumentation 是个很重要的类,它在 Activity 的启动,生命周期管理中都承担了重要的角色。

> Instrumentation.java
    public void callActivityOnCreate(Activity activity, Bundle icicle) {
        prePerformCreate(activity);
        activity.performCreate(icicle);
        postPerformCreate(activity);
    }
复制代码


> Activity.java
    final void performCreate(Bundle icicle, PersistableBundle persistentState) {
        mCanEnterPictureInPicture = true;
        restoreHasCurrentPermissionRequest(icicle);
        // 执行 onCreate()
        if (persistentState != null) {
            onCreate(icicle, persistentState);
        } else {
            onCreate(icicle);
        }
        ......
    }
复制代码


最终终于执行到了 Activity 的 onCreate() 方法,executeCallbacks() 方法也就到此结束了。当然,onCreate() 并不是一个长久存在的状态,那么如何过渡到下一个生命周期呢?来看看 executeLifecycleState() 方法。


TransactionExecutor.executeLifecycleState()

> TransactionExecutor.java
    private void executeLifecycleState(ClientTransaction transaction) {
        final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
        if (lifecycleItem == null) {
            // No lifecycle request, return early.
            return;
        }
        ......
        // Cycle to the state right before the final requested state.
        cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */);
        // Execute the final transition with proper parameters.
        lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
        lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
    }
复制代码


executeLifecycleState() 方法的参数是 ResumeActivityItem ,方法体内直接调用其 execute() 方法。

> ResumeActivityItem.java
    @Override
    public void execute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        client.handleResumeActivity(token, true /* finalStateRequest */, mIsForward,
                "RESUME_ACTIVITY");
    }
复制代码


可以看到和 onCreate() 的套路是一模一样的,调用 ActivityThread.handleResumeActivity() ,接着是 Instrumentation.callActivityOnResume() ,最后回调 Activity.onResume()

一个生命周期又完成了,onResume() 是一个相对可以长期存在的生命周期状态。


TransactionExecutor.cycleToPath()

等等,有没有感觉哪里不对劲?onStart() 哪里去了?

正常的生命周期流程应该是 onCreate() -> onStart() -> onResume() ,但是代码中好像又没有显示调用。其实是在 executeLifecycleState() 中的 cycleToPath() 方法中做了生命周期的同步。简单说就是,当前处于 onCreate() 状态,setLifecycleState() 设置的 final stateonResume() ,就需要执行 onCreate 到 onResume 之间的状态,即 onStart() 。下面简单看下源码。


> TransactionExecutor.java
    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);
        performLifecycleSequence(r, path);
    }
复制代码


getLifecyclePath() 方法就是根据 startfinish 计算出中间的生命周期路径。这里计算出来就是 ON_START

> TransactionExecutor.java
    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");> TransactionExecutor.java
                            "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);
            }
        }
    }
复制代码


找到 ON_START 分支,调用了 ActivityThread.handleStartActivity() 方法,又是一样的套路了,这里就不再赘述了。

依次类推,ActivityThread 中应该有如下方法:

handleLaunchActivity()
handleStartActivity()
handleResumeActivity()
handlePauseActivity()
handleStopActivity()
handleDestroyActivity()
复制代码


写到这,已经分析完了 onCreate()onStart()onResume() 这三个生命周期的调用时机和流程,剩下的 onPauseonStoponDestroy() 就放到下篇文章再说吧。

给大家分享一下我阅读 Activity 生命周期相关官方文档的一些笔记。


onCreate

您必须实现此回调,其在系统首次创建 Activity 时触发。Activity 会在创建后进入已创建状态。该逻辑在 Activity 的整个生命周期中只应发生一次。

onStart

当 Activity 进入“已开始”状态时,系统会调用此回调。onStart() 调用使 Activity 对用户可见,因为应用会为 Activity 进入前台并支持交互做准备。

onStart() 方法会非常快速地完成,并且与“已创建”状态一样,Activity 不会一直处于“已开始”状态。一旦此回调结束,Activity 便会进入已恢复状态,系统将调用 onResume() 方法。

onResume

Activity 会在进入“已恢复”状态时来到前台,然后系统调用 onResume() 回调。这是应用与用户交互的状态。应用会一直保持这种状态,直到某些事件发生,让焦点远离应用。

onPause

系统将此方法视为用户正在离开您的 Activity 的第一个标志(尽管这并不总是意味着活动正在遭到销毁);此方法表示 Activity 不再位于前台(尽管如果用户处于多窗口模式,Activity 仍然可见)。

onPause() 执行非常简单,而且不一定要有足够的时间来执行保存操作。因此,您不应使用 onPause() 来保存应用或用户数据、进行网络调用,或执行数据库事务。因为在该方法完成之前,此类工作可能无法完成。

完成 onPause() 方法并不意味着 Activity 离开“已暂停”状态。相反,Activity 会保持此状态,直到其恢复或变成对用户完全不可见。

onStop

如果您的 Activity 不再对用户可见,则说明其已进入已停止状态,因此系统将调用 onStop() 回调。

在 onStop() 方法中,应用应释放或调整应用对用户不可见时的无用资源。

您还应该使用 onStop() 执行 CPU 相对密集的关闭操作。

进入“已停止”状态后,Activity 要么返回与用户交互,要么结束运行并消失。

onDestroy

销毁 Ativity 之前,系统会先调用 onDestroy()。系统调用此回调的原因如下:

  1. Activity 正在结束(由于用户彻底关闭 Activity 或由于系统为 Activity 调用 finish()
  2. 由于配置变更(例如设备旋转或多窗口模式),系统暂时销毁 Activity


系统永远不会直接终止 Activity 以释放内存,而是会终止 Activity 所在的进程。系统不仅会销毁 Activity,还会销毁在该进程中运行的所有其他内容。


最后


目前为止,我们已经深入探讨了 Activity 的启动流程,Activity 的生命周期流程。但是关于 Activity 的知识点实在是有点多。

Activity 是什么?Activity 由什么组成?Activity 是如何显示到屏幕上的?

目测还可以再为 Activity 写四五篇文章,敬请期待。



相关文章
|
Android开发
源码分析 | 布局文件加载流程(上)
源码分析 | 布局文件加载流程(上)
源码分析 | 布局文件加载流程(上)
|
XML 数据格式
源码分析 | 布局文件加载流程(下)
源码分析 | 布局文件加载流程(下)
|
Android开发 UED 开发者
探究活动Activity(2)界面跳转及生命周期
探究活动Activity(2)界面跳转及生命周期
298 0
探究活动Activity(2)界面跳转及生命周期
|
Android开发
一道面试题:Activity是如何实现LifecycleOwner的?
Activity虽然实现了LifecycleOwner接口,但是并没有实现相关处理,而是通过添加一个Fragment来代理Lifecycle的分发。这种通过Fragment代理Activity行为的设
329 0
|
存储 XML Java
Activity 复习笔记 —— 唠唠生命周期
Activity 复习笔记 —— 唠唠生命周期
Activity 复习笔记 —— 唠唠生命周期
|
Java Android开发
【Android 插件化】Hook 插件化框架 ( Hook Activity 启动流程 | 主线程创建 Activity 实例之前使用插件 Activity 类替换占位的组件 )(一)
【Android 插件化】Hook 插件化框架 ( Hook Activity 启动流程 | 主线程创建 Activity 实例之前使用插件 Activity 类替换占位的组件 )(一)
295 0
|
Android开发
【Android 插件化】Hook 插件化框架 ( Hook Activity 启动流程 | 主线程创建 Activity 实例之前使用插件 Activity 类替换占位的组件 )(二)
【Android 插件化】Hook 插件化框架 ( Hook Activity 启动流程 | 主线程创建 Activity 实例之前使用插件 Activity 类替换占位的组件 )(二)
138 0
|
Android开发
【Android 插件化】Hook 插件化框架 ( Hook Activity 启动流程 | 主线程创建 Activity 实例之前使用插件 Activity 类替换占位的组件 )(四)
【Android 插件化】Hook 插件化框架 ( Hook Activity 启动流程 | 主线程创建 Activity 实例之前使用插件 Activity 类替换占位的组件 )(四)
173 0
|
Android开发
【Android 插件化】Hook 插件化框架 ( Hook Activity 启动流程 | 主线程创建 Activity 实例之前使用插件 Activity 类替换占位的组件 )(三)
【Android 插件化】Hook 插件化框架 ( Hook Activity 启动流程 | 主线程创建 Activity 实例之前使用插件 Activity 类替换占位的组件 )(三)
271 0
|
Android开发
【Android 插件化】Hook 插件化框架 ( Hook Activity 启动流程 | AMS 启动前使用动态代理替换掉插件 Activity 类 )(二)
【Android 插件化】Hook 插件化框架 ( Hook Activity 启动流程 | AMS 启动前使用动态代理替换掉插件 Activity 类 )(二)
193 0