包 android.arch.lifecycle
提供了类和接口让你构建拥有生命周期的组件--可以根据activity或者fragment的生命周期做出调整的组件。
大部分的APP组件都是在Android框架中定义的,都会有生命周期。这些生命周期过程被操作系统或者框架代码管理着。它们是Android运行的核心,你的应用必须遵守它们。不这样做可能会引起内存泄漏或者应用挂掉。
想想一下,我们有个activity在屏幕上显示设备的位置。一个通常的办法可能是下面这样的:
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(); } }
尽管这个示例看起来没毛病,在真实的APP开发中,你对onStart()、 onStop()
方法有太多的调用,这会导致代码非常臃肿。
此外,有些组件不会在onStart()方法中就已经处于started状态了。如果我们需要在开始观察位置之前检查一些配置将会发生什么呢?有些情况是这样的:在activity停止之后,检查过程才停止,这就意味着,myLocationListener.start()的调用是在 myLocationListener.stop()
调用之后,基本上永远保持连接状态。
class MyActivity extends AppCompatActivity { private MyLocationListener myLocationListener; public void onCreate(...) { myLocationListener = new MyLocationListener(this, location -> { // update UI }); } public void onStart() { super.onStart(); Util.checkUserStatus(result -> { // what if this callback is invoked AFTER activity is stopped? if (result) { myLocationListener.start(); } }); } public void onStop() { super.onStop(); myLocationListener.stop(); } }
包 android.arch.lifecycle
提供了类和接口帮助你通过富有弹性和独立的方式解决这些问题。
Lifecycle
Lifecycle
类持有关于activity或者fragment等组件的生命周期状态,允许其他对象观察这些状态。
Lifecycle
使用两个主要的枚举跟踪关联的组件的生命周期。
Event:这些生命周期事件由框架和 Lifecycle类
发送。这些事件与activities和fragments回调事件一 一对应。
State: Lifecycle
对象追踪的组件的当前状态。
设想state是图表中的节点,event是两个节点之间的边框线。
通过在方法上加上注解,可以让一个类监控组件的生命周期。
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()
,需要被子类实现。
这个类从个体类(activity,fragment)中抽象了生命周期的所有权,允许编写可以与它们一起工作的组件。任何一个自定义的应用类都可以实现这个接口。
针对上面的示例,我们可以使我们的MyLocationListener
类称为一个 LifecycleObserver
,然后通过 Lifecycle
的方法onCreate初始化它。
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
不是处在一个良好的状态,通常情况下要避免调用特定的回调方法。例如,在activity的onSaveInstance方法调用之后,调用了运行fragment事物的回调方法,将会导致奔溃,所以,我们不要去调用那个回调方法。
为了让这个方案易于使用,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
,我们只需要初始化它就行了。全部的设置和数据清除的操作全部由自己来完成。
可以和 Lifecycle
协同工作的类称为有生命周期的组件。提供与Android生命周期协同工作的类的类库推荐对外提供有生命周期的组件,以便它们的调用客户端不用手动管理生命周期,从而易于集成。
LiveData
是有生命周期的组件的一个例子。将 LiveData
和 ViewModel
一起使用,更易于在遵循Android生命周期的情况下使用数据填充UI层。
Best practices for Lifecycles
1 保持你的UI控制层(activities,fragments)越轻越好。它们不应该自己去取数据,相反,使用一个 ViewModel
去做,并且观察 LiveData
反应到UI层上。
2 尝试编写数据驱动UI,当数据变化时,你的UI层控制器负责更新控件,或者通知用户操作到ViewModel
。
3 把数据操作逻辑放在ViewModel
类中,ViewModel
应该像UI层与其他APP组件之间的连接器。不过,要小心,获取数据(例如,从网路获取数据)并不是ViewModel
的责任。ViewModel
应该调用适当的组件去做这个工作,然后提供结果给UI层控制器。
4 使用Data Binding在控件和控制器之间保持干净的接口。这允许在activity和fragment中,你把你的控件更声明化(声明性编程),并且更新最少的代码。
5 如果你的UI很复杂,考虑创建一个presenter类持有UI的变化。这通常过度封装了,但是可以让UI层的测试更加容易。
6 决不要在 ViewModel
层引用 View
或者Activity
上下文。如果ViewModel比activity的生命周期长的话,activity将会内存泄漏,不能正确的GC。
Addendum
Implementing LifecycleOwner in custom activities and fragments
任何一个自定义的fragment和activity都可以通过实现内建的LifecycleRegistryOwner 接口变成LifecycleOwner
,而不是继承 LifecycleFragment
或者 LifecycleActivity
。
public class MyFragment extends Fragment implements LifecycleRegistryOwner { LifecycleRegistry lifecycleRegistry = new LifecycleRegistry(this); @Override public LifecycleRegistry getLifecycle() { return lifecycleRegistry; } }
如果你有个自定义的想要变成 LifecycleOwner
的类,你可以使用 LifecycleRegistry 类,但是你需要转发事件到这个类中。如果他们实现了 LifecycleRegistryOwner
接口,这个事件转发对fragments,activities会自动的进行。
来自 https://developer.android.google.cn/topic/libraries/architecture/lifecycle.html