首页 > 解决方案 > 通过 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;

标签: androidmvvmexception-handlingretrofit

解决方案


这是带有错误处理的 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;
            }

        });

如果有帮助,别忘了投票。快乐编码


推荐阅读