Android LiveData使用

关于LiveData的介绍可以看我上一篇文章
Android LiveData笔记
LiveData使用
首先创建MutableLiveData<T>对象,然后设置观察者,观察者有两种设置模式一种是

//关联宿主生命周期,宿主销毁后会自动取消观察者
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer)
//不关联宿主生命周期,宿主销毁不会取消观察者
public void observeForever(@NonNull Observer<? super T> observer)

例子使用的是第一种方式注册观察者

/**
 * 主线程上发送消息可以使用postValue, setValue
 * 子线程上发送消息必须使用postValue
 * 不论在哪个线程上,接受消息都在主线程上
 */
class LiveDataTestActivity : AppCompatActivity(){

    private val TAG = "LiveDataTestActivity";

    val mutableLiveData : MutableLiveData<String> = MutableLiveData()


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.frament_test)
        mutableLiveData.observe(this, Observer {
            Log.e(TAG, "onCreate$it")
        })
        sendMsgInOnCreate()
        mutableLiveData.observe(this, Observer {
            Log.e(TAG, "onCreateAfterSend$it")
        })


    }


    override fun onResume() {
        super.onResume()
        mutableLiveData.observe(this, Observer {
            Log.e(TAG, "onResume$it")
        })
    }

    fun sendMsgInOnCreate(){
        mutableLiveData.value = "SUCCESS--${Thread.currentThread().name}"
        mutableLiveData.value = "2SUCCESS--${Thread.currentThread().name}"
        mutableLiveData.value = "3SUCCESS--${Thread.currentThread().name}"
    }
}

在例子中,使用mutableLiveData对象在onCreate中发送了三条消息,在发送消息前后都注册了观察者。在onResum中也注册了观察,根据我的猜想打印的日志应该如下

E/LiveDataTestActivity: onCreateSUCCESS--main
E/LiveDataTestActivity: onCreate2SUCCESS--main
E/LiveDataTestActivity: onCreate3SUCCESS--main
E/LiveDataTestActivity: onCreateAfterSend3SUCCESS--main
E/LiveDataTestActivity: onResume3SUCCESS--main

但事实上输入的日志却是

E/LiveDataTestActivity: onCreate3SUCCESS--main
E/LiveDataTestActivity: onCreateAfterSend3SUCCESS--main
E/LiveDataTestActivity: onResume3SUCCESS--main

这是因为LiveData只会通知活跃状态的观察者。


        /**
         * Started state for a LifecycleOwner. For an {@link android.app.Activity}, this state
         * is reached in two cases:
         * <ul>
         *     <li>after {@link android.app.Activity#onStart() onStart} call;
         *     <li><b>right before</b> {@link android.app.Activity#onPause() onPause} call.
         * </ul>
         */
        STARTED,

在Lifecycle中onStart状态时在onStart方法调用后,onPause方法调用前被修改的
宿主生命状态必须为onStart状态观察者才会是活跃状态,所以在onCreate或者onResume()中注册的观察者并不会进入活跃状态,当生命周期进入onStart时三个观察者才会接受到消息,此时消息已经发送过了,所以三个观察者才会接受最后一条最新的消息。
如果将消息的发送放到onResume中,则三个观察者都会收到三条消息

override fun onResume() {
        super.onResume()
        mutableLiveData.observe(this, Observer {
            Log.e(TAG, "onResume$it")
        })
        sendMsgInOnCreate()
    }
E/LiveDataTestActivity: onCreateSUCCESS--main
E/LiveDataTestActivity: onCreateAfterSendSUCCESS--main
    onResumeSUCCESS--main
E/LiveDataTestActivity: onCreate2SUCCESS--main
    onCreateAfterSend2SUCCESS--main
E/LiveDataTestActivity: onResume2SUCCESS--main
    onCreate3SUCCESS--main
E/LiveDataTestActivity: onCreateAfterSend3SUCCESS--main
    onResume3SUCCESS--main

public static <X, Y> LiveData<Y> map( @NonNull LiveData<X> source, @NonNull final Function<X, Y> mapFunction)
Transformations.map方法是将LiveData的观察数据对象转换类型

val mutableLiveData3 : MutableLiveData<String> = MutableLiveData()
/**
     * liveData的数据转换
     */
    val liveDataMap :LiveData<Int> = Transformations.map(mutableLiveData3
    ) {
        1
    }

liveDataMap.observe(this, Observer {
            Log.e(TAG, "liveDataMap$it")
        })
        mutableLiveData3.value = "liveDataMap";

E/LiveDataTestActivity: liveDataMap1

MediatorLiveData<String>是将多个观察者放到一起统一观察

mediatorLiveData.addSource(mutableLiveData1, Observer {
            //数据源1有变换通知观察者更新
            mediatorLiveData.value = it
        })
        mediatorLiveData.addSource(mutableLiveData2, Observer {
            //数据源2有变换通知观察者更新
            mediatorLiveData.value = it
        })

        mediatorLiveData.observe(this, Observer {
            Log.e(TAG, "$it---${Thread.currentThread()}")
        })

        mutableLiveData1.value = "mutableLiveData1"
        mutableLiveData2.value = "mutableLiveData2"
E/LiveDataTestActivity: mutableLiveData1---Thread[main,5,main]
E/LiveDataTestActivity: mutableLiveData2---Thread[main,5,main]

MediatorLiveData源码

    @MainThread
    public <S> void addSource(@NonNull LiveData<S> source, @NonNull Observer<? super S> onChanged) {
        Source<S> e = new Source<>(source, onChanged);
        Source<?> existing = mSources.putIfAbsent(source, e);
        if (existing != null && existing.mObserver != onChanged) {
            throw new IllegalArgumentException(
                    "This source was already added with the different observer");
        }
        if (existing != null) {
            return;
        }
        if (hasActiveObservers()) {
            e.plug();
        }
    }

private static class Source<V> implements Observer<V> {
        final LiveData<V> mLiveData;
        final Observer<? super V> mObserver;
        int mVersion = START_VERSION;

        Source(LiveData<V> liveData, final Observer<? super V> observer) {
            mLiveData = liveData;
            mObserver = observer;
        }

        void plug() {
            mLiveData.observeForever(this);
        }

        void unplug() {
            mLiveData.removeObserver(this);
        }

        @Override
        public void onChanged(@Nullable V v) {
            if (mVersion != mLiveData.getVersion()) {
                mVersion = mLiveData.getVersion();
                mObserver.onChanged(v);
            }
        }
    }

在调用addSource(@NonNull LiveData<S> source, @NonNull Observer<? super S> onChanged)方法后,先将liveData 和传入的观察者包装成Source对象,接着调用Source对象的plug方法将传入的LiveData对象观察Source对象,在我们调用mutableLiveData1.value = "mutableLiveData1"对象时会出触发Source对象的onChanged方法,(前面分析LiveData的时候说过)在onChanged方法中会调用Source对象的mObserver.onChanged(v);方法也就是我们传入的

mediatorLiveData.addSource(mutableLiveData1, Observer {
            //数据源1有变换通知观察者更新
            mediatorLiveData.value = it
        })

我们传入的Observer中调用mediatorLiveData的setValue就会通知到注册在mediatorLiveData上的观察者。(有点绕)

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容