基于观察者模式的生命周期感知组件。

介绍

如果一个组件 ( 类 ) 需要感知 Activity ( 或 Fragment ) 的生命周期,以前的写法是在 Activity 的各个生命周期方法内去调用这个组件的方法,如果一个 Activity 引用了很多组件,并且这些组件都需要感知其生命周期,那么 Activity 的代码会越来越多不易维护。这时候需要 LifeCycle,使用观察者模式,Activity 为被观察者 ( LifecycleOwner ),各组件为观察者( LifecycleObserver ) 来感知 Activity 的生命周期,当 Activity 生命周期发生变化时,各组件就可以在自己内部收到通知去执行自己的逻辑,将代码从 Activity 中挪到组件自己内部,使 Activity 更简洁。

导入

导入的方式很简单,这里直接使用最新的 androix.* 包

implementation 'androidx.appcompat:appcompat:1.0.2'

使用

假如有一个这样的场景,我们有一个 LocationClient 类 ( 或者称之为组件 ) ,它可以获取到最新的位置信息,一般的需要在 Activity 的 onCreate() 方法中去初始化它,然后在 onResume() 中启动定位服务,在 onPause() 中停止定位服务,最后当 Activity 销毁时需要在 onDestroy() 方法中去停止定位以及释放一些资源。

那么以前的写法可能是以下这样的:

public class LocationClient {

    /**
     * 初始化
     */
    public void init() {
        // ...
    }

    /**
     * 启动定位服务
     */
    public void startLocateService() {
        // ...
    }

    /**
     * 停止定位服务
     */
    public void stopLocateService() {
        // ...
    }

    /**
     * 销毁并释放资源
     */
    public void destroy() {
        // ...
    }

}
public class LocateActivity extends AppCompatActivity {

    private LocationClient mLocationClient;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mLocationClient = new LocationClient();
        mLocationClient.init();
    }

    @Override
    protected void onResume() {
        super.onResume();
        mLocationClient.startLocateService();
    }

    @Override
    protected void onPause() {
        super.onPause();
        mLocationClient.stopLocateService();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mLocationClient.destroy();
    }

}

以上的写法看着是没什么问题,但是如果一个 Acitivty 中使用到的组件很多,例如地图组件等,那么 Activity 的生命周期方法内会充满这样的代码,显得臃肿,不易维护。

接下来看下使用 Lifecycle 的写法:

public class LocationClient implements LifecycleObserver {

    private LifecycleOwner mLifecycleOwner;

    public LocationClient(LifecycleOwner lifecycleOwner) {
        mLifecycleOwner = lifecycleOwner;
        mLifecycleOwner.getLifecycle().addObserver(this);
    }

    /**
     * 初始化
     */
    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    public void init() {
        // ...
    }

    /**
     * 启动定位服务
     */
    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    public void startLocateService() {
        // ...
    }

    /**
     * 停止定位服务
     */
    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    public void stopLocateService() {
        // ...
    }

    /**
     * 销毁并释放资源
     */
    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    public void destroy() {
        // ...
    }

}
public class LocateActivity extends AppCompatActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        new LocationClient(this);
    }

}

可以发现,使用 Lifecycle 的写法和以前相比,Activity 代码变得更加简洁,分析代码之前先解释一下 2 个类:

  • LifecycleOwner : 被观察的对象
  • LifecycleObserver : 观察者,当 LifecycleOwner 的生命周期发生变更的时候,会通知给它

所以从代码中可以看成,LifecycleOwner 被观察的对象就是这里的 Activity,这里我们的 Activity 最终继承自 ComponentActivity,ComponentActivity 实现了 LifecycleOwner 接口:

public class ComponentActivity extends Activity
  implements LifecycleOwner, KeyEventDispatcher.Component {
  // ...
}

所以 Activity 是一个被观察者,然后我们手动让 LocateClient 实现了LifecycleObserver,将其作为一个观察者,然后通过 mLifecycleOwner.getLifecycle().addObserver(this); 将 LocateClient 作为 LocateActivity 的观察者,最后在 LocateClient 中原本需要在 Activity 生命周期中调用的方法上面都加上了与之对应的 @OnLifecycleEvent() 生命周期注解,这样当 Activity 的生命周期发生变更的时候,会自动调用到 LocateClient 对应的方法,非常简便,Activity 更加轻量。

总结

使用 Lifecycle 的写法其实就是将 Activity 中的代码转移到了组件自己内部中,以前是 Activity 生命周期发生变更时需要 Activity 自己一个一个的去通知组件,现在是 Activity 不用去主动通知组件,如果一个组件想要感知 Activity 的生命周期,组件自己注册进来监听。重心由 Activity 转移到了组件中去,让 Activity 不需要关心组件的逻辑,最后 Lifecycle 配合 MVP 食用更加。

参考

Handling Lifecycles with Lifecycle-Aware Components