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

从源码看 Activity 生命周期(上篇)一路从 Zygote 说到 SystemServer ,从 AMS 的启动流程 说到 应用进程的创建,再到上一期的 Activity 启动流程,今天准备来说说大家耳熟能详的 Activity 的生命周期。关于生命周期的基础知识,官网上的这篇文章 了解 Activity 的生命周…

本文是我的 AOSP 系列 第六篇文章,往期目录如下:

Java 世界的盘古和女娲 —— Zygote

Zygote家的大儿子 —— SystemServer

Android 世界中,谁喊醒了 Zygote ?

“无处不在” 的系统核心服务 —— ActivityManagerService 启动流程解析

庖丁解牛Activity 启动流程

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

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

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

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

(

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

通过上篇文章我们都知道了 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 写四五篇文章,敬请期待。

—- 分割线

买了一个服务器,准备用 Halo 搭建个人博客,好好整理一下之前写过的各个系列的文章。求推荐域名! 求推荐域名! 求推荐域名!

文章首发微信公众号: 秉心说TM , 专注 Kotlin、 Java 、 Android 原创知识分享,AOSP 源码解析。

更多最新原创文章,扫码关注我吧!

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

今天的文章从源码看 Activity 生命周期(上篇)分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/19432.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注