Android Jetpack架构组件(四)一文带你了解LiveData(使用篇)

本文首发于微信公众号「后厂村码农」前端

前言

在2017年先后,RxJava一直很火,我在Android进阶三部曲第一部《Android进阶之光》中就介绍了RxJava的使用和原理。谷歌推出的LiveData和RxJava相似,也是基于观察者,你能够认为LiveData是轻量级的RxJava。起初LiveData并不被看好,随着谷歌的大力推广,LiveData也慢慢的进入了你们的视野。通常来讲,LiveData不多单独使用,它更多的和Android Jetpack的其余组件搭配使用,好比和ViewModel。这篇文章就来介绍LiveData的使用。java

1.什么是LiveData

LiveData如同它的名字同样,是一个可观察的数据持有者,和常规的observable不一样,LiveData是具备生命周期感知的,这意味着它可以在Activity、Fragment、Service中正确的处理生命周期。 程序员

mv4Y9I.png
LiveData的数据源通常是ViewModel,也能够是其它能够更新LiveData的组件。当数据更新后,LiveData 就会通知它的全部观察者,好比Activiy。与RxJava的方法不一样的是,LiveData并非通知全部观察者,它 只会通知处于Active状态的观察者,若是一个观察者处于Paused或Destroyed状态,它将不会收到通知。 这对于Activiy和Service特别有用,由于它们能够安全地观察LiveData对象而不用担忧内存泄漏的问题。开发者也不须要在onPause或onDestroy方法中解除对LiveData的订阅。还有一点须要注意的是一旦观察者从新恢复Resumed状态,它将会从新收到LiveData的最新数据。

1.LiveData的基本用法

LiveData是一个抽象类,它的最简单的实现类为MutableLiveData,这里举个最简单的例子。安全

public class MainActivity extends AppCompatActivity {
   private static final String TAG="MainActivity";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        MutableLiveData<String> mutableLiveData  = new MutableLiveData<>();
        mutableLiveData.observe(this, new Observer<String>() {//1
            @Override
            public void onChanged(@Nullable final String s) {
                Log.d(TAG, "onChanged:"+s);
            }
        });
        mutableLiveData.postValue("Android进阶三部曲");//2
    }
}

复制代码

注释1处的observe方法有两个参数分别是LifecycleOwner和 Observer<T> ,第一个参数就是MainActivity自己,第二个参数新建了一个Observer<String>,在onChanged方法中获得回调。注释处的postValue方法会在主线程中更新数据,这样就会获得打印的结果。 D/MainActivity: onChanged:Android进阶三部曲微信

在大多数状况下,LiveData的observe方法会放在onCreate方法中,若是放在onResume方法中,会出现屡次调用的问题。除了MutableLiveData的postValue方法,还可使用setValue方法,它们以前的区别是,setValue方法必须在主线程使用,若是是在工做线程中更新LiveData,则可使用postValue方法。app

2.更改LiveData中的数据

若是咱们想要在LiveData对象分发给观察者以前对其中存储的值进行更改,可使用Transformations.map()和Transformations.switchMap(),下面经过简单的例子来说解它们。ide

2.1 Transformations.map()

若是想要在LiveData对象分发给观察者以前对其中存储的值进行更改,可使用Transformations.map()。post

public class MainActivity extends AppCompatActivity {
   private static final String TAG="MainActivity";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        MutableLiveData<String> mutableLiveData  = new MutableLiveData<>();
        mutableLiveData.observe(this, new Observer<String>() {
            @Override
            public void onChanged(@Nullable final String s) {
                Log.d(TAG, "onChanged1:"+s);
            }
        });
        LiveData transformedLiveData =Transformations.map(mutableLiveData, new Function<String, Object>() {
            @Override
            public Object apply(String name) {
               return name + "+Android进阶解密";
            }
        });
        transformedLiveData.observe(this, new Observer() {
            @Override
            public void onChanged(@Nullable Object o) {
                Log.d(TAG, "onChanged2:"+o.toString());
            }
        });
        mutableLiveData.postValue("Android进阶之光");
    }
}
复制代码

经过Transformations.map(),在mutableLiveData的基础上又加上了字符串"+Android进阶解密"。 打印结果为: D/MainActivity: onChanged1:Android进阶之光 D/MainActivity: onChanged2:Android进阶之光+Android进阶解密this

2.2 Transformations.switchMap()

若是想要手动控制监听其中一个的数据变化,并能根据须要随时切换监听,这时可使用Transformations.switchMap(),它和Transformations.map()使用方式相似,只不过switchMap()必须返回一个LiveData对象。spa

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";
    MutableLiveData<String> mutableLiveData1;
    MutableLiveData<String> mutableLiveData2;
    MutableLiveData<Boolean> liveDataSwitch;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mutableLiveData1 = new MutableLiveData<>();
        mutableLiveData2 = new MutableLiveData<>();
        liveDataSwitch = new MutableLiveData<Boolean>();//1

        LiveData transformedLiveData= Transformations.switchMap(liveDataSwitch, new Function<Boolean, LiveData<String>>() {
            @Override
            public LiveData<String> apply(Boolean input) {
                if (input) {
                    return mutableLiveData1;
                } else {
                    return mutableLiveData2;
               }
            }
        });

        transformedLiveData.observe(this, new Observer<String>() {
            @Override
            public void onChanged(@Nullable final String s) {
                Log.d(TAG, "onChanged:" + s);
            }
        });
        liveDataSwitch.postValue(false);//2
        mutableLiveData1.postValue("Android进阶之光");
        mutableLiveData2.postValue("Android进阶解密");
    }
}
复制代码

注释1处新建一个MutableLiveData<Boolean>()来控制切换并赋值给liveDataSwitch,当liveDataSwitch的值为true时返回mutableLiveData1,不然返回mutableLiveData2。注释2处将liveDataSwitch的值更新为false,这样输出的结果为"Android进阶解密",达到了切换监听的目的。

3 合并多个LiveData数据源

MediatorLiveData继承自mutableLiveData,它能够将多个LiveData数据源集合起来,能够达到一个组件监听多个LiveData数据变化的目的。

public class MainActivity extends AppCompatActivity {
   private static final String TAG="MainActivity";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        MutableLiveData<String> mutableLiveData1  = new MutableLiveData<>();
        MutableLiveData<String> mutableLiveData2  = new MutableLiveData<>();
        MediatorLiveData liveDataMerger = new MediatorLiveData<String>();
        liveDataMerger.addSource(mutableLiveData1, new Observer() {
            @Override
            public void onChanged(@Nullable Object o) {
                Log.d(TAG, "onChanged1:"+o.toString());
            }
        });

        liveDataMerger.addSource(mutableLiveData2, new Observer() {
            @Override
            public void onChanged(@Nullable Object o) {
                Log.d(TAG, "onChanged2:"+o.toString());
            }
        });
        liveDataMerger.observe(this, new Observer() {
            @Override
            public void onChanged(@Nullable Object o) {
                Log.d(TAG, "onChanged:"+o.toString());
            }
        });
        mutableLiveData1.postValue("Android进阶之光");
    }
}
复制代码

为了更直观的举例,将LiveData和MediatorLiveData放到了同一个Activity中。经过MediatorLiveData的addSource将两个MutableLiveData合并到一块儿,这样当任何一个MutableLiveData数据发生变化时,MediatorLiveData均可以感知到。

打印的结果为: D/MainActivity: onChanged1:Android进阶之光

4 拓展LiveData对象

若是观察者的生命周期处于STARTED或RESUMED状态,LiveData会将观察者视为处于Active状态 。关于如何扩展LiveData,官网的例子是比较简洁的,以下所示。

public class StockLiveData extends LiveData<BigDecimal> {
    private static StockLiveData sInstance;
    private StockManager stockManager;

    private SimplePriceListener listener = 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) {
        stockManager = new StockManager(symbol);
    }

    @Override
    protected void onActive() {
        stockManager.requestPriceUpdates(listener);
    }

    @Override
    protected void onInactive() {
        stockManager.removeUpdates(listener);
    }
}
复制代码

上面的代码是一个观察股票变更的一个例子,对LiveData进行了拓展,实现了LiveData的两个空方法onActive和onInactive。当Active状态的观察者的数量从0变为1时会调用onActive方法,通俗来说,就是当LiveData对象具备Active状态的观察者时调用onActive方法,应该在onActive方法中开始观察股票价格的更新。当LiveData对象没有任何Active状态的观察者时调用onInactive方法,在这个方法中,断开与StockManager服务的链接。

在Fragment中使用StockLiveData,以下所示。

public class MyFragment extends Fragment {
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        StockLiveData.get(symbol).observe(this, price -> {
            // Update the UI.
        });
    }
}
复制代码

总结

这篇文章主要介绍了什么是LiveData,以及LiveData的使用方法,这里没有介绍LiveData和ViewModel的结合使用,以及LiveData的原理,这些会在后面的文章进行介绍。

更多的内容请关注个人独立博客的知识体系:
liuwangshu.cn/system/


这里不只分享大前端、Android、Java等技术,还有程序员成长类文章。

相关文章
相关标签/搜索