Kir*_*man 56 android android-architecture-components
LiveData
在某些情况下,new 可以用作RxJava可观察对象的替代品.但是,与之不同的是Observable
,LiveData
没有错误回调.
我的问题是:我应该如何处理错误LiveData
,例如,当某些网络资源由于某个网络资源而无法检索时IOException
?
小智 43
在Google 针对Android架构组件的示例应用程序中,他们将LiveData发出的对象包装在一个类中,该类可以包含发出的对象的状态,数据和消息.
使用此方法,您可以使用状态来确定是否存在错误.
小智 19
您可以扩展MutableLiveData
并创建一个持有人模型来包装您的数据。
这是你的包装模型
public class StateData<T> {
@NonNull
private DataStatus status;
@Nullable
private T data;
@Nullable
private Throwable error;
public StateData() {
this.status = DataStatus.CREATED;
this.data = null;
this.error = null;
}
public StateData<T> loading() {
this.status = DataStatus.LOADING;
this.data = null;
this.error = null;
return this;
}
public StateData<T> success(@NonNull T data) {
this.status = DataStatus.SUCCESS;
this.data = data;
this.error = null;
return this;
}
public StateData<T> error(@NonNull Throwable error) {
this.status = DataStatus.ERROR;
this.data = null;
this.error = error;
return this;
}
public StateData<T> complete() {
this.status = DataStatus.COMPLETE;
return this;
}
@NonNull
public DataStatus getStatus() {
return status;
}
@Nullable
public T getData() {
return data;
}
@Nullable
public Throwable getError() {
return error;
}
public enum DataStatus {
CREATED,
SUCCESS,
ERROR,
LOADING,
COMPLETE
}
}
Run Code Online (Sandbox Code Playgroud)
这是您扩展的LiveData对象
public class StateLiveData<T> extends MutableLiveData<StateData<T>> {
/**
* Use this to put the Data on a LOADING Status
*/
public void postLoading() {
postValue(new StateData<T>().loading());
}
/**
* Use this to put the Data on a ERROR DataStatus
* @param throwable the error to be handled
*/
public void postError(Throwable throwable) {
postValue(new StateData<T>().error(throwable));
}
/**
* Use this to put the Data on a SUCCESS DataStatus
* @param data
*/
public void postSuccess(T data) {
postValue(new StateData<T>().success(data));
}
/**
* Use this to put the Data on a COMPLETE DataStatus
*/
public void postComplete() {
postValue(new StateData<T>().complete());
}
}
Run Code Online (Sandbox Code Playgroud)
这就是你的使用方式
StateLiveData<List<Book>> bookListLiveData;
bookListLiveData.postLoading();
bookListLiveData.postSuccess(books);
bookListLiveData.postError(e);
Run Code Online (Sandbox Code Playgroud)
以及如何观察它:
private void observeBooks() {
viewModel.getBookList().observe(this, this::handleBooks);
}
private void handleBooks(@NonNull StateData<List<Book>> books) {
switch (stepIds.getStatus()) {
case SUCCESS:
List<Book> bookList = books.getData();
//TODO: Do something with your book data
break;
case ERROR:
Throwable e = books.getError();
//TODO: Do something with your error
break;
case LOADING:
//TODO: Do Loading stuff
break;
case COMPLETE:
//TODO: Do complete stuff if necessary
break;
}
}
Run Code Online (Sandbox Code Playgroud)
roy*_*oyB 16
使用某种错误消息传递从LiveData返回的数据
public class DataWrapper<T>T{
private T data;
private ErrorObject error; //or A message String, Or whatever
}
Run Code Online (Sandbox Code Playgroud)
//现在在你的LifecycleRegistryOwner
课堂上
LiveData<DataWrapper<SomeObjectClass>> result = modelView.getResult();
result.observe(this, newData ->{
if(newData.error != null){ //Can also have a Status Enum
//Handle Error
}
else{
//Handle data
}
});
Run Code Online (Sandbox Code Playgroud)
只是抓住一个Exception
或扔掉它.使用错误Object将此数据传递给UI.
MutableLiveData<DataWrapper<SomObject>> liveData = new...;
//On Exception catching:
liveData.set(new DataWrapper(null, new ErrorObject(e));
Run Code Online (Sandbox Code Playgroud)
另一种方法是使用不同类型的MediatorLiveData
来源LiveData
.这将使您分离每个事件:
例如:
open class BaseViewModel : ViewModel() {
private val errorLiveData: MutableLiveData<Throwable> = MutableLiveData()
private val loadingStateLiveData: MutableLiveData<Int> = MutableLiveData()
lateinit var errorObserver: Observer<Throwable>
lateinit var loadingObserver: Observer<Int>
fun <T> fromPublisher(publisher: Publisher<T>): MediatorLiveData<T> {
val mainLiveData = MediatorLiveData<T>()
mainLiveData.addSource(errorLiveData, errorObserver)
mainLiveData.addSource(loadingStateLiveData, loadingObserver)
publisher.subscribe(object : Subscriber<T> {
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
}
}
Run Code Online (Sandbox Code Playgroud)
在此示例中,LiveData
一旦MediatorLiveData
具有活动观察者,将开始观察加载和错误.
归档时间: |
|
查看次数: |
17467 次 |
最近记录: |