如何处理LiveData的错误状态?
在某些情况下,新的LiveData
可以用作RxJava的observables的替代品。 但是,与Observable
不同的是, LiveData
没有错误回调。
我的问题是:我应该如何处理LiveData
错误,例如,当它由某个网络资源支持时,由于IOException
可能无法检索?
在Google的一个针对Android架构组件的示例应用程序中,他们将LiveData发送的对象封装在一个类中,该类可以包含发出的对象的状态,数据和消息。
使用这种方法,您可以使用状态来确定是否有错误。
使用某种错误信息包装从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() } }