LiveData特性与数据丢失问题或异常问题解析

LiveData

  • 基本特性

    1.没有内存泄漏:因为 Observer被绑定到它们自己的 Lifecycle对象上,所以,当它们的 Lifecycle 被销毁时,它们能自动的被清理。

    2.不会因为 Activity 停止而崩溃:如果 Observer 的 Lifecycle 处于闲置状态(例如:activity 在后台时),它们不会收到变更事件。

    3.始终保持数据最新:如果 Lifecycle重新启动(例如:activity 从后台返回到启动状态)将会收到最新的位置数据(前提是有新数据更新,或者被重新订阅)。

    4.正确处理配置更改:如果 activity 或 fragment 由于配置更改(如:设备旋转)重新创建,将会立即收到最新的有效位置数据。

    5.资源共享:可以只保留一个 MyLocationListener 实例,只连接系统服务一次,并且能够正确的支持应用程序中的所有观察者。

    6.不再手动管理生命周期你可能已经注意到,fragment 只是在需要的时候观察数据,不用担心被停止或者在停止之后启动观察。由于 fragment 在观察数据时提供了其 Lifecycle,所以 LiveData会自动管理这一切。

  • 基本用法

/**

  • ViewModel
    **/
    public class SampleViewModel extends ViewModel {
    private MutableLiveData sampleLiveData;
    public MutableLiveData getSampleLiveData() {
    if (sampleLiveData == null) {
    sampleLiveData = new MutableLiveData();
    }
    return sampleLiveData;
    }
//主线程更新数据调用
sampleLiveData.setValue(data);

//子线程更新数据调用
sampleLiveData.postValue(data);

}
/**

  • Activity
    /
    public class SampleActivity extends AppCompatActivity {
    private SampleViewModel viewModel;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    viewModel = ViewModelProviders.of(this).get(SampleViewModel.class);
    final Observer observer = new Observer() {
    @Override
    public void onChanged(@Nullable final String dataStr) {
    textView.setText(dataStr);
    }
    };
    viewModel.getSampleLiveData().observe(this, observer);
    }
    }
    /
  • Fragment
    **/
    public class SampleFragment extends Fragment {
    private SampleViewModel viewModel;
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    viewModel = ViewModelProviders.of(this).get(SampleViewModel.class);
    final Observer observer = new Observer() {
    @Override
    public void onChanged(@Nullable final String dataStr) {
    textView.setText(dataStr);
    }
    };
    viewModel.getSampleLiveData().observe(this, observer);
    }
    }
    Note: 确保 LiveData 是在ViewModel 中更新数据,原因如下:

避免Activity和Fragment变的臃肿。这样UI只需要关心它需要展示的数据,而不需要关系数据的获取和状态。
抽离LiveData到ViewModel 中可以使Activity和Fragment在重建之后数据不会丢失。

observeForever

viewModel.getSampleLiveData().observeForever(observer);
viewModel.getSampleLiveData().removeObserver(observer);

自定义LiveData

public class CustomLiveData extends LiveData {
/**
* 有可被通知的observer
/
@Override
protected void onActive() {
super.onActive();
}
/
*
* 没有可被通知的observer
*/
@Override
protected void onInactive() {
super.onInactive();
}
}

MediatorLiveData

private MutableLiveData data1 = new MutableLiveData<>();
private MutableLiveData data2 = new MutableLiveData<>();
private MediatorLiveData mediatorLiveData = new MediatorLiveData<>();
private void sample(@NonNull LifecycleOwner owner) {
    mediatorLiveData.addSource(data1, new Observer() {
        @Override
        public void onChanged(@Nullable String s) {
            mediatorLiveData.setValue(s);
        }
    });
    mediatorLiveData.addSource(data2, new Observer() {
        @Override
        public void onChanged(@Nullable String s) {
            mediatorLiveData.setValue(s);
        }
    });
    
    mediatorLiveData.observe(owner, new Observer() {
        @Override
        public void onChanged(@Nullable String s) {
        }
    });
    // mediatorLiveData.removeSource();
}

关于更新数据丢失问题

在UI可见时,调用
liveData.postValue("a");
liveData.setValue("b");
会先收到"b",后收到"a"

在UI不可见时,调用
liveData.postValue("a");
liveData.setValue("b");
当UI可见,只会收到"a",因为setValue先执行,之后被postValue更新掉

在UI可见时,调用
liveData.setValue("a");
liveData.setValue("b");
liveData.setValue("c");
liveData.setValue("d");
liveData.setValue("e");
会按顺序收到"a","b","c","d","e"

在UI可见时,调用
liveData.postValue("a");
liveData.postValue("b");
liveData.postValue("c");
liveData.postValue("d");
liveData.postValue("e");
只会收到"e"

在UI可见时,调用
liveData.postValue("a");
liveData.postValue("b");
liveData.postValue("c");
liveData.postValue("d");
liveData.setValue("e");
会先收到"e",后收到"d"

在UI不可见时,调用
liveData.setValue("a");
liveData.setValue("b");
liveData.setValue("c");
liveData.setValue("d");
liveData.setValue("e");
当UI可见之后,只会收到"e"

在UI不可见时,调用
liveData.postValue("a");
liveData.postValue("b");
liveData.postValue("c");
liveData.postValue("d");
liveData.postValue("e");
当UI可见之后,只会收到"e"

在UI不可见时,调用
liveData.setValue("a");
liveData.setValue("b");
liveData.setValue("c");
liveData.setValue("d");
liveData.postValue("e");
当UI可见之后,只会收到"e"

在UI不可见时,调用
liveData.postValue("a");
liveData.postValue("b");
liveData.postValue("c");
liveData.postValue("d");
liveData.setValue("e");
当UI可见之后,只会收到"d"

你可能感兴趣的:(LiveData特性与数据丢失问题或异常问题解析)