操作Lifecycle
来源:互联网 发布:机器人算法工程师 编辑:程序博客网 时间:2024/06/06 09:59
android.arch.lifecycle包提供了类和接口让开发者用来创建兼顾生命周期的组件,也就是说这些组件会自动根据当前Activity或Fragment的生命周期来调整行为。如果没有配合生命周期进行资源的获取和释放,可能导致内存泄露甚至是闪退。
位置监听的实现一般是下面这样子的:
class MyLocationListener { public MyLocationListener(Context context, Callback callback) { // ... } void start() { // connect to system location service } void stop() { // disconnect from system location service }}class MyActivity extends AppCompatActivity { private MyLocationListener myLocationListener; public void onCreate(...) { myLocationListener = new MyLocationListener(this, (location) -> { // update UI }); } public void onStart() { super.onStart(); myLocationListener.start(); } public void onStop() { super.onStop(); myLocationListener.stop(); }}
这样做有两个缺点。
一个是要去重写生命周期回调的方法,如果有多种监听,生命周期回调的方法就会变得很复杂。
第二个是尽管监听方法是写在回调当中的,但是方法的实际执行顺序并不一定按照这个顺序,比如onStart()中注册监听前可能需要进行一系列判断,但是可能onStop()在判断完成之前已经调用了,也就是移除监听之后才会去注册监听。这种情况下就会导致内存泄露。
这个时候Lifecycle这个类就很好地帮我们解决了这个问题。
Lifecycle
Lifecycle类中保存了应用组件(比如Activity或者Fragment)的生命周期状态,并且让其他对象可以观察到具体状态。
Lifecycle使用两个主要的枚举类来跟踪绑定的系统组件的状态。
- Event:系统和Lifecycle类所分发的生命周期事件,映射到Activity和Fragment中即是各个生命周期回调。
- State:所绑定系统组件的当前状态。
下图就展示了Event和State:
一个类可以通过给方法添加注解的方式来监听组件的生命周期状态。
public class MyObserver implements LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) public void onResume() { } @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) public void onPause() { }}aLifecycleOwner.getLifecycle().addObserver(new MyObserver());
LifecycleOwner
LifecycleOwner是一个只有单个方法的接口,只包含子类必须实现的getLifecycle()方法。
This class abstracts the ownership of a Lifecycle from individual classes (for example, activities and fragments) and allows writing components that can work with both of them. Any custom application class can implement the LifecycleOwner interface.
这个类把Activity或者Fragment中生命周期的所有权抽象出来,并且可以创建可以和这两者一起配合的组件。任何自定义的application类都可以实现这个接口。
在Architecture库正式发布之前,support库的Fragment和AppcompatActivity还没有实现这个接口,正式发布之后才会去实现。正式发布之前暂时使用LifecycleActivity和LifecycleFragment。
所以开篇的例子就可以优化为Activity继承于LifecycleActivity,MyLocationListener作为一个LifecycleObserver使用Lifecycle实例化,这样MyLocationListener就可以自动释放资源了。
class MyActivity extends LifecycleActivity { private MyLocationListener myLocationListener; public void onCreate(...) { myLocationListener = new MyLocationListener(this, getLifecycle(), location -> { // update UI }); Util.checkUserStatus(result -> { if (result) { myLocationListener.enable(); } }); }}
另一个使用场景就是需要获取当前生命周期的阶段,以判断进行某项操作是否合适,以免导致闪退等问题。此时可以调用Lifecycle类的方法查询阶段:
class MyLocationListener implements LifecycleObserver { private boolean enabled = false; public MyLocationListener(Context context, Lifecycle lifecycle, Callback callback) { ... } @OnLifecycleEvent(Lifecycle.Event.ON_START) void start() { if (enabled) { // connect } } public void enable() { enabled = true; if (lifecycle.getState().isAtLeast(STARTED)) { // connect if not connected } } @OnLifecycleEvent(Lifecycle.Event.ON_STOP) void stop() { // disconnect if connected }}
这样一实现,LocationListener这个类就完全兼顾到了生命周期,可以自己进行初始化和清除回收,不用交给Activity来管理。如果我们还要在其他Activity或者Fragment中使用这个LocationListener,只要初始化就可以了,后续的操作LocationListener自己会处理。
可以配合Lifecycle类一起使用的类就叫做Lifecycle-aware component。推荐那些提供需要搭配Android生命周期进行使用的类的第三方库提供这种Lifecycle-aware组件,这样使用方就可以很方便地集成进去,节省掉很多处理生命周期的问题。
比如LiveData就是这样一个组件。LiveData搭配ViewModel进行使用就可以在兼顾Android生命周期的前提下比较轻松地提供数据。
Lifecycle最佳实践
- UI控制器(Activity和Fragment)应该尽可能简洁 ,应该把获取数据的工作交给ViewModel去完成,然后监听LiveData来更新界面。
- UI控制器的作用应该是在数据改变时更新数据,或者把用户操作反馈给ViewModel。
- 把数据逻辑放到ViewModel当中。ViewModel应该作为UI控制器和应用其他部分交互的中间者。需要注意的是,ViewModel的职责不是获取数据,而是调用其他组件来完成这件事,然后把结果返回给UI控制器。
- 使用DataBinding在UI控制器和View之间保持一个清爽的结构,View会更有说明性,也会减少Activity和Fragment中使用的更新UI的代码。如果不想用DataBinding,也可以使用ButterKnife之类的库。
- 如果UI太过复杂,可以考虑创建一个Presenter来修改UI。
- 绝对不要在ViewModel中引用View或者Activity的context,如果configuration发生改变就会导致内存泄露。
自定义实现LifecycleOwner
可以不用继承于LifecycleActivity或者LifecycleFragment,直接实现LifecycleRegisteryOwner接口把任意Activity或者Fragment变成一个LifecyleOwner:
public class MyFragment extends Fragment implements LifecycleRegistryOwner { LifecycleRegistry lifecycleRegistry = new LifecycleRegistry(this); @Override public LifecycleRegistry getLifecycle() { return lifecycleRegistry; }}
如果是某个自定义类要成为LifecycleOwner,同样也是实现LifecycleRegistryOwner接口,只不过要自己把事件转发到这个类当中,如果是Activity和Fragment是会自动转发的。
- 操作Lifecycle
- lifecycle
- LifeCycle
- Lifecycle
- Activity Lifecycle & Fragment Lifecycle
- hibernate lifecycle
- android lifecycle
- android:lifecycle
- unity lifecycle
- Lifecycle(生命周期)
- Activity Lifecycle
- Activity Lifecycle
- Application lifecycle
- Activity Lifecycle
- Service Lifecycle
- Tomcat Lifecycle
- plm(Product lifecycle management)
- Lifecycle of an ActionForm
- 在腾讯蓝鲸平台上存储emoji表情的一种解决方案
- 设计模式笔记之状态模式
- 数据结构实验之串二:字符串匹配(串)
- 群环域
- EndNote参考文献格式_国标
- 操作Lifecycle
- [RK3288][Android6.0] 调试笔记 --- 开机动画时间的确定
- Android之Litepal的使用
- [GNU/Linux] 常见的IO模型
- bitmap的六种压缩方式,Android图片压缩
- hive内部表、外部表、分区表、视图
- java中的final关键字
- 前端学习资料大全(看到这篇博文,我都0.0.......)
- poj 3268一道最短路径题