android - 通过 mvvm android 处理异常
问题描述
我正在使用 MVVM 架构通过在 android studio 中进行改造来实现 Web 服务。我已经在我的视图类中处理了服务的响应。但我面临的问题是如何处理异常并将它们传递给我的视图类。一种方法是在我的 Bean 类中创建构造函数并将响应和错误都传递给它并更新 UI。但我想要更优化的方式来处理 UI 内的异常。
这是我的存储库代码:
final MutableLiveData<MyBeanClass> myBeanClass = new MutableLiveData<>();
ApiInterface apiInterface = ApiClient.getClientAuthentication().create(ApiInterface.class);
Call<MyBeanClass> call = apiInterface.getData(id);
call.enqueue(new Callback<MyBeanClass>() {
@Override
public void onResponse(Call<MyBeanClass> call, Response<MyBeanClass> response) {
if(response.body()!=null) {
myBeanClass.setValue(response.body());
}
}
@Override
public void onFailure(Call<MyBeanClass> call, Throwable t) {
//How to handle exceptions here and pass the exception to UI without making constructor in bean class
}
});
return myBeanClass;
解决方案
这是带有错误处理的 mvvm 的完整实现。首先创建一个具有 UI 状态和资源的类。
public class Resource<T> {
@NonNull public final Status status;
@Nullable public final T data;
@Nullable public final String message;
private Resource(@NonNull Status status, @Nullable T data,
@Nullable String message) {
this.status = status;
this.data = data;
this.message = message;
}
public static <T> Resource<T> success(@NonNull T data) {
return new Resource<>(Status.SUCCESS, data, null);
}
public static <T> Resource<T> error(String msg, @Nullable T data) {
return new Resource<>(Status.ERROR, data, msg);
}
public static <T> Resource<T> loading(@Nullable T data) {
return new Resource<>(Status.LOADING, data, null);
}
public enum Status { SUCCESS, ERROR, LOADING }
}
在你的 Repository 类上做
public LiveData<Resource<MyBeanClass>> getDetail(String movieId) {
final MutableLiveData<Resource<MyBeanClass>> myBeanClass = new MutableLiveData<>();
ApiInterface apiInterface = new ApiClient().getClient().create(ApiInterface.class);
Call<MyBeanClass> call = apiInterface.getData(id);
call.enqueue(new Callback<MyBeanClass>() {
@Override
public void onResponse(Call<MyBeanClass> call, Response<MyBeanClass> response) {
if (response.body() != null) {
MyBeanClass body = response.body();
myBeanClass.setValue(Resource.success(body));
}
}
@Override
public void onFailure(Call<MyBeanClass> call, Throwable t) {
myBeanClass.setValue(Resource.error(t.getMessage(),null));
}
});
return myBeanClass;
}
在您的 viewModel 类上
public class MyViewModel extends ViewModel {
private LiveData<Resource<MyBeanClass>> myLiveData;
public void init(String id) {
movieLiveData = new MyRepository().getInstance().getDetail(id);
}
public LiveData<Resource<MyBeanClass>> getMyLiveData() {
return myLiveData;
}
}
在你的活动课上
final MyViewModel viewModel =
ViewModelProviders.of(this).get(MyViewModel.class);
viewModel.init(id);
viewModel.getMyLiveData().observe(this, finalData -> {
switch (finalData.status) {
case SUCCESS:
loadDetail(finalData.data);
break;
case LOADING:
break;
case ERROR:
Toast.makeText(this, "no Internet", Toast.LENGTH_SHORT).show();
break;
}
});
如果有帮助,别忘了投票。快乐编码
推荐阅读
- java - build.xml fx:association 抛出 NullPointerException
- visual-studio - 从 GitHub.com 克隆 VS 项目并将其作为文件结构加载到 VS 中,而不是 VS 项目
- php - WordPress PHP 和 PHP 到 JSON 编码的数组
- r - 基于R中的另一个数据框在数据框中查找值
- arrays - 从 csv 文件创建对象数组的问题
- mysql - Laravel 6 - 更新模型时间戳
- python - 从两个一维向量 a、b 和 A[i,j] 创建一个布尔数组 A,如果 a[i]==b[j]
- c++ - 如何为对象中的数据动态赋值?
- c++ - C++ 语法中的函数指针
- python - 是否有将两个列表中的匹配索引对连接到二维列表中的功能?