如何处理LiveData的错误状态?

在某些情况下,新的LiveData可以用作RxJava的observables的替代品。 但是,与Observable不同的是, LiveData没有错误回调。

我的问题是:我应该如何处理LiveData错误,例如,当它由某个网络资源支持时,由于IOException可能无法检索?

在Google的一个针对Android架构组件的示例应用程序中,他们将LiveData发送的对象封装在一个类中,该类可以包含发出的对象的状态,数据和消息。

https://github.com/googlesamples/android-architecture-components/blob/master/GithubBrowserSample/app/src/main/java/com/android/example/github/vo/Resource.java

使用这种方法,您可以使用状态来确定是否有错误。

使用某种错误信息包装从LiveData返回的数据

 public class DataWrapperT{ private T data; private ErrorObject error; //or A message String, Or whatever } 

//现在在您的LifecycleRegistryOwner类中

 LiveData> result = modelView.getResult(); result.observe(this, newData ->{ if(newData.error != null){ //Can also have a Status Enum //Handle Error } else{ //Handle data } }); 

只是赶上一个Exception或抛出它。 使用错误对象传递这个数据到用户界面。

 MutableLiveData> liveData = new...; //On Exception catching: liveData.set(new DataWrapper(null, new ErrorObject(e)); 

另一种方法是使用MediatorLiveData ,它将采用不同types的LiveData源。 这会让你分离每个事件:

例如:

 open class BaseViewModel : ViewModel() { private val errorLiveData: MutableLiveData = MutableLiveData() private val loadingStateLiveData: MutableLiveData = MutableLiveData() lateinit var errorObserver: Observer lateinit var loadingObserver: Observer fun  fromPublisher(publisher: Publisher): MediatorLiveData { val mainLiveData = MediatorLiveData() mainLiveData.addSource(errorLiveData, errorObserver) mainLiveData.addSource(loadingStateLiveData, loadingObserver) publisher.subscribe(object : Subscriber { override fun onSubscribe(s: Subscription) { s.request(java.lang.Long.MAX_VALUE) loadingStateLiveData.postValue(LoadingState.LOADING) } override fun onNext(t: T) { mainLiveData.postValue(t) } override fun onError(t: Throwable) { errorLiveData.postValue(t) } override fun onComplete() { loadingStateLiveData.postValue(LoadingState.NOT_LOADING) } }) return mainLiveData } } 

在这个例子中,一旦MediatorLiveData将有活跃的观察者,加载和错误的LiveData将开始被观察。

在我的应用程序中,我不得不将RxJava Observables翻译成LiveData。 在这样做的时候,我当然必须保持错误状态。 这是我做的(Kotlin)

 class LiveDataResult(val data: T?, val error: Throwable?) class LiveObservableData(private val observable: Observable) : LiveData>() { private var disposable = CompositeDisposable() override fun onActive() { super.onActive() disposable.add(observable.subscribe({ postValue(LiveDataResult(it, null)) }, { postValue(LiveDataResult(null, it)) })) } override fun onInactive() { super.onInactive() disposable.clear() } }