阅读 389

Android架构组件-LifeCycle

在2017年谷歌推出Android新的架构组件-一组可以帮助开发者设计强大的,可测试的和可维护的应用程序组件库。

下面我将重点介绍以下几个实用组件:

LifeCycle 

LiveData 

ViewModel

-----------------------------------------------

生命周期感知组件-LifeCycle

官网地址

1、LifeCycle能够做什么

支持生命周期的组件执行操作以响应另一个组件(例如Activity和Fragment)的生命周期状态更改。
这些组件可帮助您生成组织性更好,并且通常重量更轻的代码,这些代码更易于维护。

2、为什么需要Lifecycle组件

常见的模式是在Activity和Fragment的生命周期方法中实现依赖组件的操作。
但是,这种模式导致代码的组织不良以及错误泛滥,一堆看不懂的代码。
通过使用生命周期感知组件,您可以将相关组件的代码从生命周期方法中移出并移入组件本身。

下面来看个例子:

假如需要在生命周期中处理某些事情,可能会有两种方式,一、直接在Activity或者Fragment中的生命周期方法中写代码逻辑;二、写一个接口,定义类似生命周期的方法,在Activity或Fragment中调用相应的方法将逻辑剥离,不过也离不开Activity或Fragment。

/** * Main Presenter */
public class MainPresenter implements IPresenter {    

    public MainPresenter(Context context){  }    

    @Override    
    public void onResume() {    }    

    @Override    
    public void onStop() {    }    

}复制代码

public interface IPresenter {
    void onResume();
    void onStop();
}
复制代码

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";
    private IPresenter mPresenter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "onCreate: ");
        setContentView(R.layout.activity_main);
        mPresenter = new MainPresenter(this);
    }
    @Override
    protected void onResume() {
        super.onResume();
        Log.d(TAG, "onResume: ");
        mPresenter.onResume();
    }
    @Override
    protected void onStop() {
        super.onStop();
        Log.d(TAG, "onStop: ");
        mPresenter.onStop();
    }
}
复制代码

IPresenter中定义和生命周期相关的几个方法,然后在MainActivity中调用对应的方法。这样做会有个问题:在MainActivity中的每个生命周期方法中都要调用一次IPresenter中的接口。那有没有更好的办法呢,这时候LifeCycle就该上场了:

public class MainPresenter implements IPresenter {
    private static final String TAG = "MainPresenter";
    public MainPresenter(Context context){
    }
    @Override
    public void onCreate(LifecycleOwner owner) {
        Log.d(TAG, "onCreate: ");
    }
    @Override
    public void onStart(LifecycleOwner owner) {
        Log.d(TAG, "onStart: ");
    }
    @Override
    public void onResume(LifecycleOwner owner) {
        Log.d(TAG, "onResume: ");
    }
    @Override
    public void onPause(LifecycleOwner owner) {
        Log.d(TAG, "onPause: ");
    }
    @Override
    public void onStop(LifecycleOwner owner) {
        Log.d(TAG, "onStop: ");
    }
    @Override
    public void onDestroy(LifecycleOwner owner) {
        Log.d(TAG, "onDestroy: ");
    }
}复制代码

public interface IPresenter extends DefaultLifecycleObserver{

}复制代码
public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";
    private IPresenter mPresenter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "onCreate: ");
        setContentView(R.layout.activity_main);
        mPresenter = new MainPresenter(this);
        getLifecycle().addObserver(mPresenter);
    }
}复制代码

代码是不是很简单,尤其是Activity。

IPrestener接口继承DefaultLifecycleObserver接口,然后MainPresenter实现IPresenter接口,在MainPresenter中,可以把DefaultLifecycleObserver中生命周期的方法全实现,也可以选择实现其中几个,比如你只关心MainActivity的onCreate() 和onDestroy(),那么你就可以在MainPresenter中实现onCreate()和onDestroy()方法。借助实现DefaultLifecycleObserver接口可以让我们少写很多代码。

到这里大家可能就非常想知道Lifecycle组件实现的原理是什么?那么接着向下看。

3、LifeCycle实现原理

先来看一张图:


我们以V4包中的Fragment(AppCompatActivity类似)为例,看下Fragment和LifecycleOwner、LifecycleObserver、Lifecycle之间的类关系图。

  • Lifecycle组件成员Lifecycle被定义成了抽象类,LifecycleOwner、LifecycleObserver被定义成了接口;

  • Fragment实现了LifecycleOwner接口,该只有一个返回Lifecycle对象的方法getLifecyle();

  • Fragment中getLifecycle()方法返回的是继承了抽象类Lifecycle的LifecycleRegistry。

  • LifecycleRegistry中定义嵌套类ObserverWithState,该类持有GenericLifecycleObserver对象,而GenericLifecycleObserver是继承了LifecycleObserver的接口。

再来看一张时序图:


  • 我们在Fragment(AppCompatActivity也一样)中调用getLifecycle()方法得到LifecycleRegistry对象,然后调用addObserver()方法并将实现了LifecycleObserver接口的对象作为参数传进去。这样一个过程就完成了注册监听的过程。

  • 后续就是Fragment生命周期变化时,通知LifecycleObserver的过程:Fragment的performXXX()、onXXX()方法;LifecycleRegistry的handleLifecycleEvent()方法;LifecycleObserver的onXXX()方法。

  • 如果你细心点看上面的时序图,你会发现Fragment中performCreate()、performStart()、performResume()会先调用自身的onXXX()方法,然后再调用LifecycleRegistry的handleLifecycleEvent()方法;而在performPause()、performStop()、performDestroy()中会先LifecycleRegistry的handleLifecycleEvent()方法 ,然后调用自身的onXXX()方法。

可以看看Fragment源码

4、细节

我们要做的内容主要是实现LifecycleObserver接口,然后通过实现了LifecycleOwner接口的对象进行注册,以监听其生命周期,后续就是坐等通知了。

5、实现LifecycleObserver接口

 从上面的类关系图,我们可以看到有三个接口GenericLifecycleObserver、FullLifecycleObserver、DefaultLifecycleObserver都直接或者间接继承了LifecycleObserver。然而GenericLifecycleObserver是隐藏的,我们用不了。那我们该怎么实现LifecycleObserver接口呢,有两种方式:

  • 实现DefaultLifecycleObserver接口,然后重写里面生命周期方法(如上);
  • 直接实现LifecycleObserver接口,然后通过注解的方式来接收生命周期的变化;
class MyLocationListener implements LifecycleObserver {
    private boolean enabled = false;
    public MyLocationListener(Context context, Lifecycle lifecycle, Callback callback) {
       ...
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    void start() {
        
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    void stop() {
        
    }
}复制代码

对于这两种形式,Lifecycle.java文档中是建议使用第一种方式,因为文档中说明了,随着Java8成为主流,注解的方式会被弃用。

6、添加观察者

 实现LifecycleOwner后,最后一步,我们直接看添加观察者( addObserver(实现LifecycleObserver的观察者class) )

生命周期感知组件的最佳实践

  • 尽可能保持您的UI控制器(Activity或Fragment)尽可能精简。他们不应该试图获取他们自己的数据;相反,使用ViewModel来做到这一点,并观察一个LiveData对象,以反映到视图的变化。
  • 尝试编写数据驱动的用户界面,其中您的用户界面控制器的职责是在数据更改时更新视图,或将用户操作通知给用户ViewModel
  • 把你的数据逻辑放在你的ViewModelclass上。ViewModel应该充当您的UI控制器和其他应用程序之间的连接器。但要小心,ViewModel不是用来获取数据的(例如,从网络)。相反,ViewModel应该调用适当的组件来获取数据,然后将结果提供给UI控制器。
  • 使用Data Binding 在视图和UI控制器之间保持干净的界面。这使您可以使您的视图更具说明性,并最大限度地减少需要在Activity和Fragment中编写的更新代码。如果你喜欢用Java编程语言来做到这一点,可以使用像Butter Knife这样的库来避免样板代码并且有更好的抽象。
  • 如果您的UI很复杂,请考虑创建一个 presenter类来处理UI修改。这可能是一项艰巨的任务,但它可以使您的UI组件更易于测试。
  • 避免在你的ViewModel中引用一个ViewActivity上下文。如果ViewModel比Activity活的更长(在配置更改的情况下),Activity就会发生泄漏并且垃圾收集器无法妥善处理。

尊重版权,感谢:http://shymanzhu.com/2017/12/02/Android%20%E6%9E%B6%E6%9E%84%E7%BB%84%E4%BB%B6%EF%BC%88%E4%B8%80%EF%BC%89%E2%80%94%E2%80%94Lifecycle-Aware%20Components


关注下面的标签,发现更多相似文章
评论