美文网首页
Android LiveData使用

Android LiveData使用

作者: 东土也 | 来源:发表于2022-03-04 11:05 被阅读0次

    关于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上的观察者。(有点绕)

    相关文章

      网友评论

          本文标题:Android LiveData使用

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