请仔细阅读前言 前言 主要是为了解决Fragment初次创建会执行生命周期的onViewCreated方法,会注册一次(在onViewCreated方法进行注册, 注册方法是viewModel!!.getDataxSuccess().observe(this, dataxSuccessObserver!!),具体看我的项目),跳到别的Fragment或者Activity,再返回当前Fragment时,又会执行生命周期的onViewCreated方法,然后再注册一次(在onViewCreated方法进行注册,viewModel!!.getDataxSuccess().observe(this, dataxSuccessObserver!!),具体看我的项目),所以在这种情况下,普通的MutableLiveData会注册多次后,会回调两次数据(按说会回调多次,但是实际上只回调两次,具体原因请查看),我们其实只需要回调一次数据就可以了,回调两次,会消耗手机性能,用这个SingleLiveData来写,SingleLiveData注册多次, 只会回调一次数据,正好符合我们的需要。


感受:一开始我也没注意到这种情况,还以为MutableLiveData注册多次
(注册方法是viewModel!!.getDataxSuccess().observe(this, dataxSuccessObserver!!),具体看我的项目),只回调一次,现实是MutableLiveData注册多次,按说会回调多次,但是实际上只回调两次(Android真是坑多,我也是服了,不知道设计人员为什么这么设计,真无语。。。)

解决方案

就是使用一个google大神实现的一个复写类SingleLiveData,其中的机制是用一个原子 AtomicBoolean记录一次setValue。在发送一次后在将AtomicBoolean设置为false,阻止后续前台重新触发时的数据发送。

package com.phone.common_library.manager;

import android.util.Log;

import androidx.annotation.MainThread;
import androidx.annotation.Nullable;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.Observer;

import java.util.concurrent.atomic.AtomicBoolean;

/**
 * A lifecycle-aware observable that sends only new updates after subscription, used for events like
 * navigation and Snackbar messages.
 * <p>
 * This avoids a common problem with events: on configuration change (like rotation) an update
 * can be emitted if the observer is active. This LiveData only calls the observable if there's an
 * explicit call to setValue() or call().
 * <p>
 * Note that only one observer is going to be notified of changes.
 *
 * 主要是为了解决Fragment初次创建会执行生命周期的onViewCreated方法,会注册一次(在onViewCreated方法进行注册,
 * 注册方法是viewModel!!.getDataxSuccess().observe(this, dataxSuccessObserver!!),具体看我的项目),跳到
 * 别的Fragment或者Activity,再返回当前Fragment时,又会执行生命周期的onViewCreated方法,然后再注册一次(在
 * onViewCreated方法进行注册,viewModel!!.getDataxSuccess().observe(this, dataxSuccessObserver!!),
 * 具体看我的项目),所以在这种情况下,普通的MutableLiveData会注册多次后,会回调两次数据(按说会回调多次,但是
 * 实际上只回调两次,具体原因请查看),我们其实
 * 只需要回调一次数据就可以了,回调多次,会消耗手机性能,用这个SingleLiveData来写,SingleLiveData注册多次,
 * 只会回调一次数据,正好符合我们的需要。
 *
 *
 * 感受:一开始我也没注意到这种情况,还以为MutableLiveData注册多次
 * (注册方法是viewModel!!.getDataxSuccess().observe(this, dataxSuccessObserver!!),具体看我的项目),
 * 只回调一次,现实是MutableLiveData注册多次,按说会回调多次,但是实际上只回调两次(Android真是坑多,我也是
 * 服了,不知道设计人员为什么这么设计,真无语。。。)
 *
 */
public class SingleLiveData<T> extends MutableLiveData<T> {

    private static final String TAG = SingleLiveData.class.getSimpleName();

    private final AtomicBoolean mPending = new AtomicBoolean(false);

    @MainThread
    public void observe(LifecycleOwner owner, final Observer<? super T> observer) {

        if (hasActiveObservers()) {
            Log.w(TAG, "Multiple observers registered but only one will be notified of changes.");
        }

        // Observe the internal MutableLiveData
        super.observe(owner, new Observer<T>() {
            @Override
            public void onChanged(@Nullable T t) {
                if (mPending.compareAndSet(true, false)) {
                    observer.onChanged(t);
                }
            }
        });
    }

    @MainThread
    public void setValue(@Nullable T t) {
        mPending.set(true);
        super.setValue(t);
    }

    /**
     * Used for cases where T is Void, to make calls cleaner.
     */
    @MainThread
    public void call() {
        setValue(null);
    }
}



推荐Android开源项目

项目功能介绍:RxJava2和Retrofit2项目,添加自动管理token功能,添加RxJava2生命周期管理,使用App架构设计是MVP模式和MVVM模式,同时使用组件化,部分代码使用Kotlin,此项目持续维护中。

项目地址:https://gitee.com/urasaki/RxJava2AndRetrofit2