使用生命周期感知型组件处理生命周期。

生命周期感知型组件可执行操作来响应另一个组件(如 Activity 和 Fragment)的生命周期状态的变化。这些组件有助于写出更有条理且往往更精简的代码,这样的代码更易于维护。

一种常见的模式是在 Activity 和 Fragment 的生命周期方法中实现依赖组件的操作。但是,这种模式会导致代码条理性很差而且会扩散错误。通过使用生命周期感知型组件,可以将依赖组件的代码从生命周期方法移入组件本身中。

androidx.lifecycle 软件包提供了可用于构建生命周期感知型组件的类和接口 - 这些组件可以根据 Activity 或 Fragment 的当前生命周期状态自动调整其行为。

Lifecycle 是一个类,用于存储有关组件(如 Activity 或 Fragment)的生命周期状态的信息,并允许其他对象观察此状态。

Lifecycle 使用两种主要枚举跟踪其关联组件的生命周期状态:

活动

从框架和 Lifecycle 类分派的生命周期事件。这些事件映射到 Activity 和 Fragment 中的回调事件。

状态转换

由 Lifecycle 对象跟踪的组件的当前状态。

类可以通过向其方法添加注解来监控组件的生命周期状态。然后,可以通过调用 Lifecycle 类的 addObserver() 方法并传递观察者的实例来添加观察者,如以下示例中所示:

    public class MyObserver implements LifecycleObserver {
        @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
        public void connectListener() {
            ...
        }

        @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
        public void disconnectListener() {
            ...
        }
    }

    myLifecycleOwner.getLifecycle().addObserver(new MyObserver());

在上面的示例中,myLifecycleOwner 对象实现了 LifecycleOwner 接口,我们将在接下来的部分中对该接口进行说明。

具体示例

引入androidx.appcompat依赖

dependencies {
    implementation 'androidx.appcompat:appcompat:1.1.0'
    // ...
}

构建一个观察者MyObserver1,监听生命周期的变化。

import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.OnLifecycleEvent;

public class MyObserver1 implements LifecycleObserver {
    private static final String TAG = "rustAppOb1";

    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    public void doOnCreate() {
        Log.d(TAG, "[obs]doOnCreate"); // 监听生命周期的变化
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    public void doOnStart() {
        Log.d(TAG, "[obs]doOnStart");
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    public void doOnResume() {
        Log.d(TAG, "[obs]doOnResume");
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    public void doOnResume2() {
        Log.d(TAG, "[obs]doOnResume2");
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    public void doOnPause() {
        Log.d(TAG, "[obs]doOnPause");
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    public void doOnStop() {
        Log.d(TAG, "[obs]doOnStop");
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    public void doOnDestroy() {
        Log.d(TAG, "[obs]doOnDestroy");
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_ANY)
    public void doOnAny() {
        Log.d(TAG, "[obs]doOnAny");
    }
}

在 activity 中使用,各个生命周期打印 log。继承 androidx.appcompat.app.AppCompatActivity

public class Lc1Act extends AppCompatActivity {
    private static final String TAG = "rustAppLc1";

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        Log.d(TAG, "[act]onCreate: start");
        super.onCreate(savedInstanceState);
        ActLc1Binding binding = DataBindingUtil.setContentView(this, R.layout.act_lc1);

        getLifecycle().addObserver(new MyObserver1());
        Log.d(TAG, "[act]onCreate: END");
    }

    @Override
    protected void onStart() {
        Log.d(TAG, "[act]onStart: start");
        super.onStart();
        Log.d(TAG, "[act]onStart: END");
    }

    @Override
    protected void onResume() {
        Log.d(TAG, "[act]onResume: start");
        super.onResume();
        Log.d(TAG, "[act]onResume: END");
    }

    @Override
    protected void onPause() {
        Log.d(TAG, "[act]onPause: start");
        super.onPause();
        Log.d(TAG, "[act]onPause: END");
    }

    @Override
    protected void onStop() {
        Log.d(TAG, "[act]onStop: start");
        super.onStop();
        Log.d(TAG, "[act]onStop: END");
    }

    @Override
    protected void onDestroy() {
        Log.d(TAG, "[act]onDestroy: start");
        super.onDestroy();
        Log.d(TAG, "[act]onDestroy: END");
    }

    @Override
    public void onBackPressed() {
        Log.d(TAG, "[act]onBackPressed");
        super.onBackPressed();
    }
}

运行日志

D/rustAppLc1: [act]onCreate: start
D/rustAppLc1: [act]onCreate: END
D/rustAppOb1: [obs]doOnCreate
D/rustAppOb1: [obs]doOnAny
D/rustAppLc1: [act]onStart: start
D/rustAppLc1: [act]onStart: END
D/rustAppOb1: [obs]doOnStart
D/rustAppOb1: [obs]doOnAny
D/rustAppLc1: [act]onResume: start
D/rustAppLc1: [act]onResume: END
D/rustAppOb1: [obs]doOnResume
D/rustAppOb1: [obs]doOnResume2
D/rustAppOb1: [obs]doOnAny
D/rustAppLc1: [act]onBackPressed
D/rustAppOb1: [obs]doOnPause
D/rustAppOb1: [obs]doOnAny
D/rustAppLc1: [act]onPause: start
D/rustAppLc1: [act]onPause: END
D/rustAppOb1: [obs]doOnStop
D/rustAppOb1: [obs]doOnAny
D/rustAppLc1: [act]onStop: start
D/rustAppLc1: [act]onStop: END
D/rustAppOb1: [obs]doOnDestroy
D/rustAppOb1: [obs]doOnAny
D/rustAppLc1: [act]onDestroy: start
D/rustAppLc1: [act]onDestroy: END

从 log 中可以看出 activity 生命周期和观察者回调函数执行的先后顺序。 新建 activity 时,先执行 activity 的生命周期函数,再执行观察者的监听方法。 销毁界面时,先执行的时观察者的方法,然后是 activity 的方法。 即先建立页面,再建立观察者;退出时先退观察者,再退界面。

如果弹出 AlertDialog,activity 回调 onWindowFocusChanged(boolean hasFocus),观察者不会响应。

LifecycleOwner

LifecycleOwner 是单一方法接口,表示类具有 Lifecycle(生命周期)。 它具有一个方法(即 getLifecycle()),该方法必须由类实现。 如果尝试管理整个应用进程的生命周期,请参阅 ProcessLifecycleOwner。

此接口从各个类(如 Fragment 和 AppCompatActivity)抽象化 Lifecycle 的所有权,并允许编写与这些类搭配使用的组件。任何自定义应用类均可实现 LifecycleOwner 接口。

实现 LifecycleObserver 的组件可与实现 LifecycleOwner 的组件无缝协同工作,因为所有者可以提供生命周期,而观察者可以注册以观察生命周期。

上面的MyObserver1类实现 LifecycleObserver,然后在 onCreate() 方法中使用 Activity 的 Lifecycle 对其进行初始化。 这样,MyObserver1 类便可以“自给自足”,这意味着,对生命周期状态的变化做出响应的逻辑会在 MyObserver1(而不是在 Activity)中进行声明。让各个组件存储自己的逻辑,可使 Activity 和 Fragment 逻辑更易于管理。

持有 Lifecycle 的观察者示例

观察者可以持有 Lifecycle 对象。在进行一些操作前,可以判断页面当前的状态。

新建 MyObserver2 类。持有 Lifecycle 实例。

import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.OnLifecycleEvent;

public class MyObserver2 implements LifecycleObserver {
    private static final String TAG = "rustAppOb2";

    private Lifecycle lifecycle;

    public MyObserver2(Lifecycle lifecycle) {
        this.lifecycle = lifecycle;
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_ANY)
    public void doOnAny() {
        Log.d(TAG, "[obs2]doOnAny; lifecycle-cur-state: " + lifecycle.getCurrentState());
        Log.d(TAG, "doOnAny: atLeast INITIALIZED: " + lifecycle.getCurrentState().isAtLeast(Lifecycle.State.INITIALIZED));
        Log.d(TAG, "doOnAny: atLeast CREATED: " + lifecycle.getCurrentState().isAtLeast(Lifecycle.State.CREATED));
        Log.d(TAG, "doOnAny: atLeast STARTED: " + lifecycle.getCurrentState().isAtLeast(Lifecycle.State.STARTED));
        Log.d(TAG, "doOnAny: atLeast RESUMED: " + lifecycle.getCurrentState().isAtLeast(Lifecycle.State.RESUMED));
        Log.d(TAG, "doOnAny: atLeast DESTROYED: " + lifecycle.getCurrentState().isAtLeast(Lifecycle.State.DESTROYED));
    }
}

观察 ON_ANY 这个事件,打一些 log,看看 lifecycle 的状态。 使用了 isAtLeast 方法。

Activity 中注册这个观察者。

getLifecycle().addObserver(new MyObserver2(getLifecycle()));

运行部分log信息

D/rustAppLc1: [act]onCreate: start
D/rustAppLc1: [act]onCreate: END
D/rustAppOb2: [obs2]doOnAny; lifecycle-cur-state: CREATED
D/rustAppOb2: doOnAny: atLeast INITIALIZED: true
D/rustAppOb2: doOnAny: atLeast CREATED: true
D/rustAppOb2: doOnAny: atLeast STARTED: false
D/rustAppOb2: doOnAny: atLeast RESUMED: false
D/rustAppOb2: doOnAny: atLeast DESTROYED: true

观察Lifecycle.State枚举,它把生命周期状态按顺序排列。

  public enum State {
        DESTROYED,
        INITIALIZED,
        CREATED,
        STARTED,
        RESUMED;

        public boolean isAtLeast(@NonNull State state) {
            return compareTo(state) >= 0;
        }
    }

isAtLeast 比较当前状态和传入的状态。返回 true 则标明相对传入的 state,当前是“安全”的。

实现自定义 LifecycleOwner

上面的 activity 继承自 androidx.appcompat.app.AppCompatActivity,它的父类实现了 LifecycleOwner 接口。 我们也可以实现自定义 LifecycleOwner。

如果有一个自定义类并希望使其成为 LifecycleOwner,可以使用 LifecycleRegistry 类,但需要将事件转发到该类,如以下代码示例中所示:

    public class MyActivity extends Activity implements LifecycleOwner {
        private LifecycleRegistry lifecycleRegistry;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);

            lifecycleRegistry = new LifecycleRegistry(this);
            lifecycleRegistry.markState(Lifecycle.State.CREATED);
        }

        @Override
        public void onStart() {
            super.onStart();
            lifecycleRegistry.markState(Lifecycle.State.STARTED);
        }

        @NonNull
        @Override
        public Lifecycle getLifecycle() {
            return lifecycleRegistry;
        }
    }