Jetpack:Lifeccyle入门指南

为何须要咱们管理Activity和Fragment的生命周期?这些不是Framework自动帮咱们搞定的么?(手动黑人问号)刚看到这样的标题我也是很懵逼,不就是onCreate->onSart()->onResume()->onPause()->onStop()->onDestory()么?难道还有什么高深的地方么?android

题外话git

在讲Data Bing Library的文章中,大多数同窗反馈在实际开发中没什么必要。由于没深爱过,无法名正言顺为其正名。刚好周末逛到郭霖公众号一篇讲Data Bing 在RecyclerView的实践,讲的挺好,你们有空移步前去阅读。引用《卖油翁的故事》道理->熟能生巧,爱得够深,就能擦出火花。github

若是你对Data Binding Library有独特的看法或见解,能够前往Data Binding Library(数据绑定库)讨论数据库

Abount Lifecycle-Aware Components

该组件能在像Activity、Fragment等等具备生命周期的组件发生状态改变时,以轻量级的和易维护的代码做出响应动做。bash

吃个栗子就懂意思了:网络

//为了考虑大多数同窗学习过Java,就贴Java的代码
//定义个监听类,用来在Activity生命周期发生变化时,对定位服务资源做相关处理
class MyLocationListener {
    public MyLocationListener(Context context, Callback callback) {
        // ...
    }

    void start() {
        // connect to system location service
    }

    void stop() {
        // disconnect from system location service
    }
}
//在Activity中回调监听类相关方法
class MyActivity extends AppCompatActivity {
    private MyLocationListener myLocationListener;

    @Override
    public void onCreate(...) {
        myLocationListener = new MyLocationListener(this, (location) -> {
            // update UI
        });
    }
    
    @Override
    public void onStart() {
        super.onStart();
        myLocationListener.start();
        // manage other components that need to respond
        // to the activity lifecycle
    }

    @Override
    public void onStop() {
        super.onStop();
        myLocationListener.stop();
        // manage other components that need to respond
        // to the activity lifecycle
    }
}
复制代码

毕竟拿人手短,吃人嘴软,吃了人家的栗子就得给人家分析。ide

这个栗子仍是挺简单的,只是简单调用了MyLocationListener对象的两个回调方法,可是在实际开发中,大多数状况下会在Activity的onCreate()、onStart()等等生命周期中作大量的业务逻辑处理和UI更新,并且若是不止一个监听类须要被回调的话,就意味着要在Activity中管理多个其余组件的生命周期或者回调。那代码的维护性和可读性就很是差。(另外,在发生某种竞态条件的状况下,可能会致使Activity的onStop()方法在onStart()方法前就发生了)post

为了解决这种痛点,在包android.arch.lifecycle 中提供类和接口来独立的管理Activity和Fragment组件的生命周期。学习

Lifecycle

生命周期是一个类包含组件的生命周期状态的信息(例如Activity和Fragment),并容许其余对象观察到这个状态。 Lifecycle对象以两种主要的枚举类型跟踪它关联组件的生命周期状态:ui

  • Event Framework和Lifecycle类分发生命周期事件(Lifecycle Event),并映射到Activity或者Fragment的回调事件。
  • State Lifecycle对象跟踪组件的当前状态。

生命周期状态
方框中的 INITALZIEDDESTROYED等等表示组件的状态,而箭头上的 ON_CREATEON_START等等则表示事件。假如Framework或者Lifecycle类分发 ON_CREATE事件,表示关联的组件的状态从初始化到onCreate状态,对应调用组件的onCreate()方法。

经过在类的方法上添加注解来监听组件的生命周期。而后将该类以观察者形式添加到具备生命周期的类中。

//MyObserver做为一个观察者来监听有生命周期的类
public class MyObserver implements LifecycleObserver {
    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    public void connectListener() {
        ...
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    public void disconnectListener() {
        ...
    }
}
//myLifecycleOwner是一个实现了LifecycleOwner 接口的类,继续看下文
myLifecycleOwner.getLifecycle().addObserver(new MyObserver());
复制代码

LifecycleOwner

LifecycleOwner,是只有一个getLifecycle()方法的接口,实现该接口的类表示具备生命周期。若是想管理整个应用的生命周期,用 ProcessLifecycleOwner代替LifecycleOwner。LifecycleOwner接口将全部具备生命周期的类的生命周期全部权抽象出来,以方即可以在其生命周期进行读写。实现了LifecycleObserver接口的类能够注册到实现了LifecycleOwner的类,以观察对应组件的生命周期。例如上文的:

myLifecycleOwner.getLifecycle().addObserver(new MyObserver());
复制代码

这样作带来的好处是什么? 经过这种观察者模式,能够将日常根据Activity或Fragment生命周期状态的逻辑分离到单独类中进行处理,以便更好的逻辑开发、功能迭代和后期维护。

class MyActivity extends AppCompatActivity {
    private MyLocationListener myLocationListener;

    public void onCreate(...) {
        myLocationListener = new MyLocationListener(this, getLifecycle(), location -> {
            // update UI
        });
        Util.checkUserStatus(result -> {
            if (result) {
                myLocationListener.enable();
            }
        });
  }
}
复制代码

讲到这里基本就已经知道如何使用Lifecycle-Aware Components管理Activity或Fragment的生命周期了。若是LifecycleObserver须要监听其余Activity或Fragment的生命周期,只须要从新初始化并注册到新的Activity或Fragment便可。资源的设置和清除回收不须要咱们担忧。

Custom LifecycleOwner

在Support Library 26.1.0和更高版本,Activity和Fragment已经默认实现了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;
    }
}
复制代码

最好实践

  • 保持UI(Activity或Fragment)精简。不要在Activity或Fragment中取获取应用数据,采用ViewModel或者Livedata。也就是为何有MVP、MVVM模式。
  • 尝试写数据驱动类型UI。在数据发生变化的时候经过UI控制器更新UI或者通知用户进行操做。
  • 把数据的处理逻辑放到ViewModel类中。ViewModel做为UI界面与数据的桥梁,处理数据与UI界面交互的逻辑。注意不是获取数据的逻辑,例如获取网络数据或者数据库数据。
  • 使用数据绑定库(Data Binding Library)在UI界面和UI控制器之间进行维护。这样有利于减小在Activity或Fragment中更新UI的代码。在Java中可使用Butter Knife库。
  • 若是UI界面很复杂,能够创建一个主持(Presenter)类去处理视图。MVP模式?
  • 使用Kotlin协同机制管理耗时任务。

使用lifecycle-aware components的场景

lifecycle-aware组件在不一样状况能让咱们更方便的管理Acitivity和Fragment的生命周期。那在什么情景下适合使用该组件呢?

  • 粗细粒度的切换。例如在定位中,若是当前界面可见,那么定位精度应该更细,定位请求更频繁,以提升响应性。当切换到后台时,请求定位的频率就要放缓,以下降功耗
  • 开始和中止视频缓冲。这个是高手,在应用加载的时候尽早缓冲视频,减小用户等待时间在应用退出是结束缓冲。
  • 开始和中止网络链接。根据App状态自动切换链接的状态。
  • 开始和中止绘制图片。应用在后台时不会绘制,返回前台继续绘制。

存在的一些问题

当Fragment或AppCompatActivity在调用onSaveInstanceState()方法保存状态后,它们的视图在ON_START事件被调用以前是不会改变的,在这期间UI被更改会引发不一致的问题,这就是为何FragmentManager在状态保存后运行FragmentTransaction会抛出异常。

所以若是AppCompatActivity的onStop()方法在调用onSaveInstanceState()方法以后,就会形成一个缺口:UI状态改变是不容许,但生命周期尚未改成CREATED的状态。为此,Lifecycle类经过将状态标记为CREATED,但直到调用onStop()方法前,不分发该事件,此时去检测当前的状态也可得到真实的值。可是还存在如下两个问题:

  • 在Android 6.0和更低版本,系统调用onSaveInstanceState()方法,但它不必定调用onStop()方法。这样就会形成事件没法分发,潜在的致使观察者觉得lifecycle处于活动状态,尽管此时它处于中止状态。
  • 任何想要在LiveData暴露相似行为的类必须实现Lifecycle 版本 beta 2 和更低版本提供的方法。

更多信息请参考官网

总结

本文是对官网知识的理解或翻译,建议再进一步阅读原文,毕竟原文才是原汁原味,知识点也多。 从第一次看官网懵懵懂懂,到开始了解,又掌握一个知识点。不只光讲Lifecycle-Aware Components的知识点,还讲到日常开发应用的最佳实践,这些对实际开发都有很强指导做用。

Welcom to visit my github

本文是Jetpack系列文章第二篇

第一篇: Jetpack:你还在findViewById么?

第三篇: Jetpack:在数据变化时如何优雅更新Views数据

相关文章
相关标签/搜索