EasyPusher 结合Android Architecture Component便捷开发一

在今年的Google I/O大会上,Google 发布了一个新的概念:Android Achitecture Component,即基于安卓的一系列更加便捷开发的基础库,主要包括便捷的生命周期管理和便捷的数据存储.这篇文章我们来看看使用其中的生命周期管理模块,如何使得EasyPusher更加便于开发和集成.

我们先认识一下开发一款类似EasyPusher这种基于摄像头的APP存在的痛点.

我们需要关注如下几个事件的变动,并适当地响应这些变动:

graph LR
ActivityCreate-->ActivityResume
ActivityResume-->TextureAvailable
ActivityResume-->onRequestPermissionsResult
onRequestPermissionsResult-->ActivityPaused
TextureAvailable-->ActivityPaused
ActivityPaused-->TextureDestoryed
TextureDestoryed-->ActivityDestoryed
  • ActivityCreate VIEW初始化,回调设置,权限申请
  • ActivityResume Activity到前台,尝试启动预览
  • TextureAvailable Texture准备完毕,尝试启动预览
  • onRequestPermissionsResult 权限获取完成,尝试启动预览
  • ActivityPaused Activity到后台,关闭预览,如果未finish,尝试启动后台预览
  • TextureDestoryed
  • ActivityDestoryed 如果使能后台预览,尝试启动后台预览,否则关闭摄像头.
事件 响应 可能性
ActivityCreate VIEW初始化,回调设置,权限申请 Activity 可能初次启动,也有可能在后台恢复;摄像头有可能已经在后台运行,也有可能尚未启动
ActivityResume Activity到前台,(根据摄像头的权限申请情况)尝试启动预览 权限可能已经申请过了,也可能没有;
TextureAvailable Texture准备完毕,(根据摄像头的权限申请情况)尝试启动预览 权限可能已经申请过了,也可能没有;
onRequestPermissionsResult 权限获取完成,尝试启动预览
ActivityPaused Activity到后台,关闭预览,如果未finish,尝试启动后台预览 可能需要启动后台预览
ActivityDestoryed 如果使能后台预览,尝试启动后台预览,否则关闭摄像头. 可能需要启动后台预览

从图表可以看出,安卓的生命周期比较复杂不受控制.

这些存在生命周期的组件,导致依附于其的业务逻辑,需要根据组件不同的生命阶段做出不同的逻辑处理.典型的就是在onCreate里创建,onDestory里销毁;试想一下,一个功能复杂的APP,每一个业务逻辑模块都这样来一遍,就会导致onCreate\onDestory越来越臃肿,Activity的代码量越来越大,越来越难以维护.

再加上Activity的各种不可预测的销毁和重建,会使得这些功能更加难以维护:

App components, like activities and fragments, have a lifecycle managed by the Android Framework. The Framework may decide to destroy or re-create them based on some user actions or device events that are completely out of your control.

我们很期望这样一种机制,各个业务模块都在自己内部响应生命周期更改,这样的话Activity或者Fragment或者Service就只需要实现一种”组装”的功能,那就太好了!而我们使用Architecture Component就可以实现这样的业务模块.

Architecture Component主要有如下概念:

  • ViewModel 提供一种创建和存储绑定于特定的生命周期组件的对象的方法,这里的”绑定”,指的是在特定的生命周期内有效.由组件内部进行管理,并且可以方便地进行数据共享.存储的数据目标并不会在“recreate”的时候被销毁重建,而是在系统内部进行保持。
  • Lifecycle
    Lifecycle 记录着一个组件 (比如activity或者fragment) 的状态,并且允许其他对象来获取这种状态.Lifecycle 使用两种枚举类型来追踪组件的生命周期.
    1. Event
      生命周期的更改事件.由系统或者Lifecycle类来进行调度.这些事件对应着Activity或者Fragment中的一系列函数回调.
    2. State
      当前组件的生命周期的状态.
  • LifecycleOwner/LifecycleRegistryOwner - 表示一种具有生命周期的组件本身,比如Activity\Fragment.
  • LifecycleObserver
    表示组件观察者.组件观察者通过annotation来监听组件的生命周期更改.
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());
  • LiveData - 兼容了Lifecycle的可观察者。允许用户进行跨组件地观察数据更改,并且在组件终止时取消订阅。下面表示一个Location对应的LiveData类,该类实现了LiveData的onActive以及onInactive方法,并做出对应的初始化与反初始化。当位置信息更改时,调用setValue方法进行赋值,这样LiveData内部会通知各个观察者数据更新。
public class LocationLiveData extends LiveData<Location> {
    private LocationManager locationManager;

    private SimpleLocationListener listener = new SimpleLocationListener() {
        @Override
        public void onLocationChanged(Location location) {
            setValue(location);
        }
    };

    public LocationLiveData(Context context) {
        locationManager = (LocationManager) context.getSystemService(
                Context.LOCATION_SERVICE);
    }

    @Override
    protected void onActive() {
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, listener);
    }

    @Override
    protected void onInactive() {
        locationManager.removeUpdates(listener);
    }
}

LiveData的调用示例:

public class MyFragment extends LifecycleFragment {
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        LiveData<Location> myLocationListener = ...;
        Util.checkUserStatus(result -> {
            if (result) {
                myLocationListener.observe(this, location -> {
                    // update UI
                });
            }
        });
    }
}

实际上ViewModel与LiveData的结合使用十分适用于异步加载的应用场景:

public class MyViewModel extends ViewModel {
    private MutableLiveData<List<User>> users;
    public LiveData<List<User>> getUsers() {
        if (users == null) {
            users = new MutableLiveData<List<Users>>();
            loadUsers();
        }
        return users;
    }

    private void loadUsers() {
        // do async operation to fetch users
    }
}

再做个总结:
1. 具有生命周期(Lifecycle)的Activity,Fragment可作为一种LifecycleOwner;
2. LifecyclerObserver可获取,监测LifecycleOwner的生命周期的状态以及状态变更;
3. ViewModel可在Activty recreate的时候保持数据不被销毁,但是finish的时候销毁;同时可用于在Fragment之间方便地数据共享.
4. LiveData类似于观察者模式里的被观察者,只不过观察者只能是LifecycleOwner,同时,在观察者的生命周期终结时,自动反注册.

这几个概念,如果不应用到实践中,乍一看会觉得云里雾里,读者会觉得作者废话半天到底在逼逼叨什么?

好吧,下一篇文章我们将会看到这几个概念的组合所产生的影响和威力,届时,作者将把EasyPusher APP剥离,底层代码形成库,大家可以发现原来几行代码就可以实现一个Pusher了.

猜你喜欢

转载自blog.csdn.net/jyt0551/article/details/77939182