美文网首页
AAC---LiveData

AAC---LiveData

作者: None_Ling | 来源:发表于2018-06-25 21:05 被阅读10次

    LiveData

    LiveData是一个与Activity/Fragment生命周期相关(lifecycle-aware)的Observer类。而这种相关性(awareness )会导致LiveData中的数据只有在Active状态下才会被回调。

    我们可以通过实现了LifeCycleOwner接口的对象来提供生命周期的感知。而LiveData这种方式会使得不用再考虑Activity或者Fragment的泄露,当生命周期结束时,会自动销毁Observer对象。

    使用LiveData的好处

    • 保证UI与数据状态同步
      LiveData使用Observer模式,只有当Lifecycle的状态改变时候,才会回调给Observer。
    • 没有内存泄漏
      Observer绑定了Lifecycle,并且在关联的LifeCycle被销毁时,将Observer清除
    • 没有因为Activity Stop导致的Crash
      当Lifecycle处于inactive状态时,例如一个Activity回退到Activity栈中,就不会受到任何LiveData的事件了
    • 不用再手动管理生命周期
      UI组件只需要关心数据,而不用在onResume、onStop等回调函数中处理
    • 始终保持最新数据
      当LifeCycle变成inactive状态时,它接收最新的数据,当LifeCycle再次变成active状态,会将最新的数据回调。比如在后台一个Activity收到了最新的数据,而当它回到前台时候,则会将数据回调。
    • 合理的Configuration改变
      旋转时候,它会立马接收到最新的可用数据,而不会因为重新创建Activity而重新创建
    • 共享资源
      可以通过继承一个LiveData对象,并且使用单例模式来封装一个系统的Service,以至于它可以在App内共享。LiveData对象一旦连接系统Service,当有Observer需要资源的话,就可以监听LiveData对象了

    使用方法

    1. build.gradle中添加配置
    dependencies {
        def lifecycle_version = "1.1.1"
    
        // ViewModel and LiveData
        implementation "android.arch.lifecycle:extensions:$lifecycle_version"
        // alternatively - just ViewModel
        implementation "android.arch.lifecycle:viewmodel:$lifecycle_version" // use -ktx for Kotlin
        // alternatively - just LiveData
        implementation "android.arch.lifecycle:livedata:$lifecycle_version"
        // alternatively - Lifecycles only (no ViewModel or LiveData).
        //     Support library depends on this lightweight import
        implementation "android.arch.lifecycle:runtime:$lifecycle_version"
    
        annotationProcessor "android.arch.lifecycle:compiler:$lifecycle_version"
        // alternately - if using Java8, use the following instead of compiler
        implementation "android.arch.lifecycle:common-java8:$lifecycle_version"
    
        // optional - ReactiveStreams support for LiveData
        implementation "android.arch.lifecycle:reactivestreams:$lifecycle_version"
    
        // optional - Test helpers for LiveData
        testImplementation "android.arch.core:core-testing:$lifecycle_version"
    }
    
    1. 创建与LifeCycleOwner相关联的LiveData对象
    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            ActivityMainBinding mBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
            MutableLiveData<UserData> liveData = new MutableLiveData<>();
            liveData.observe(this, new Observer<UserData>() {
                @Override public void onChanged(@Nullable UserData userData) {
                    // TODO:
                }
            });
        }
    
    }
    
    1. LiveData中的数据有变化时候,则可以调用setValue或者在非主线程中调用postValue改变,而修改后的值会通过onChanged方法回调。
    liveData.setValue(new UserData());
    liveData.postValue(new UserData());
    

    MutableLiveData与MediatorLiveData

    • MutableLiveData:可变的LiveData
      普通的LiveData将setValue以及postValue的作用于定义成protected,除非继承LiveData否则访问这两个函数。而MutableLiveData只是Override这两个函数,将protected作用域扩大成了public,以至于外部可以访问。
    • MediatorLiveData:多来源的LiveData
      它可以对一个数据结构添加多个数据来源,addSource函数添加LiveData类型的数据来源,而后回调给MediatorLiveData达到多路数据源的效果。比如同一种数据,来自网络与文件缓存。
    MutableLiveData<UserData> localCache = new MutableLiveData<>();
    localCache.observe(this, userData -> {
                // TODO:
            });
    MutableLiveData<UserData> networkData = new MutableLiveData<>();
    networkData.observe(this, userData -> {
                // TODO:
            });
    MediatorLiveData<String> live1 = new MediatorLiveData<>();
    live1.addSource(localCache, userData -> live1.setValue(userData.getUserName()));
    live1.addSource(networkData, userData -> live1.setValue(userData.getUserName()));
    

    与Room与ViewModel组件相辅相成

    • Room:
      Room中Query返回的对象可以是一个LiveData,而当数据库中数据有改变时,该LiveData也会收到最新的数据
    • ViewModel:
      ViewModel的作用也就是请求数据,或者做一些前台耗时操作,当数据返回或者操作完成后,通过LiveData回调给UI Controller修改UI

    继承LiveData

    通过继承LiveData类重写onActive以及onInactive函数来完成对数据请求/前台耗时操作的回调等等

    public class StockLiveData extends LiveData<BigDecimal> {
        private StockManager mStockManager;
    
        private SimplePriceListener mListener = new SimplePriceListener() {
            @Override
            public void onPriceChanged(BigDecimal price) {
                setValue(price);
            }
        };
    
        public StockLiveData(String symbol) {
            mStockManager = new StockManager(symbol);
        }
    
        @Override
        protected void onActive() {
            mStockManager.requestPriceUpdates(mListener);
        }
    
        @Override
        protected void onInactive() {
            mStockManager.removeUpdates(mListener);
        }
    }
    

    以下为当使用单例LiveData时的情况

    public class StockLiveData extends LiveData<BigDecimal> {
        private static StockLiveData sInstance;
        private StockManager mStockManager;
    
        private SimplePriceListener mListener = new SimplePriceListener() {
            @Override
            public void onPriceChanged(BigDecimal price) {
                setValue(price);
            }
        };
    
        @MainThread
        public static StockLiveData get(String symbol) {
            if (sInstance == null) {
                sInstance = new StockLiveData(symbol);
            }
            return sInstance;
        }
    
        private StockLiveData(String symbol) {
            mStockManager = new StockManager(symbol);
        }
    
        @Override
        protected void onActive() {
            mStockManager.requestPriceUpdates(mListener);
        }
    
        @Override
        protected void onInactive() {
            mStockManager.removeUpdates(mListener);
        }
    }
    

    Transformations

    主要为了在数据(Value)分发前,修改分发的值。

    • Transformations.map
    LiveData<User> userLiveData = ...;
    LiveData<String> userName = Transformations.map(userLiveData, user -> {
        user.name + " " + user.lastName
    });
    
    • Transformations.switchMap
    private LiveData<User> getUser(String id) {
      ...;
    }
    LiveData<String> userId = ...;
    LiveData<User> user = Transformations.switchMap(userId, id -> getUser(id) );
    

    参考资料

    LiveData

    相关文章

      网友评论

          本文标题:AAC---LiveData

          本文链接:https://www.haomeiwen.com/subject/lhwyyftx.html