请仔细阅读前言 前言 主要是为了解决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