这是一个在Android应用上重试API调用的按钮的正确方法吗?

问题描述 投票:1回答:1

我正在开发的项目从中间没有Room的API获取用户列表(仅限网络架构)。我实际上已经按照我希望它的方式运行代码,但我想知道这是否是正确的方法。下面我在标记我怀疑的地方。

我的UI是由ListAdapter支持的RecyclerView。我有一个ViewModel(mainViewModel),它正在观察Repository类提供的用户列表,还有一个布尔值来显示或不显示“再试一次”按钮。

在MainActivity.java中我有

// Observing the boolean that represents if the api call failed
mainViewModel.getCallFailure().observe(this, new Observer<Boolean>() {
    @Override
    public void onChanged(Boolean aBoolean) {
        if (aBoolean) {
            tryAgainButton.setVisibility(View.VISIBLE);
        } else {
            tryAgainButton.setVisibility(View.GONE);
        }
    }
});

// Setting up onClickListener
tryAgainButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        mainViewModel.retryCall(); // HERE IS WHERE I'M HAVING DOUBTS
    }
});

MainViewModel.java有

public class MainViewModel extends ViewModel {

    ...

    public LiveData<Boolean> getCallFailure(){
        return userRepo.getCallFailure();
    }

    // THIS IS THE METHOD I'M CALLING FROM THE UI
    public void retryCall(){
        userRepo.getRetryCallback();
    }
}

最后,Repository.java是

public class Repository {
    private Call<UsersResponse> retryCall;
    private Callback<UsersResponse> callback;
    private final MutableLiveData<Boolean> callFailure = new MutableLiveData<>();

    public LiveData<List<UserModel>> getListUsers(){
        final MutableLiveData<List<UserModel>> users = new MutableLiveData<>();
        callFailure.setValue(false);

        (Api.getClient().getUsersList()).enqueue(new Callback<UsersResponse>() {
            @Override
            public void onResponse(Call<UsersResponse> call, Response<UsersResponse> response) {
                users.setValue(response.body().getUsersList());
                callFailure.setValue(false);
            }

            @Override
            public void onFailure(Call<UsersResponse> call, Throwable t) {
                Log.d("Response GET", t.toString());
                callFailure.setValue(true);
                setCallback(this);
                retryCall = call.clone();
            }
        });

        return users;
    }

    private void setCallback(Callback<UsersResponse> usersResponseCallback) {
        callback = usersResponseCallback;
    }

    public LiveData<Boolean> getCallFailure(){
        return callFailure;
    }

    public void getRetryCallback(){
        retryCall.enqueue(callback);
    }
}

我试着提到我认为相关的代码,我管理一个ProgressDialog,就像我在Repository中使用boolean callFailure一样,它正在创造奇迹。但说实话,在MainActivity.java文件中调用mainViewModel.retryCall();感觉不舒服,我真的很感激任何建议!

java android retrofit retrofit2 viewmodel
1个回答
0
投票

在我使用MVVM创建的项目中,我的活动和片段通知我的ViewModel,就像你公开(通过调用一个像触发器一样的方法)并通过LiveData观察结果。

对我来说奇怪的一件事是你的存储库存储了一部分状态(重试和失败)。在我的项目中,我把这个逻辑放在ViewModel中,我的存储库在这里做简单的操作(比如网络调用)。但这更像是个人选择。


编辑:这是我将如何根据您的代码完成此操作(可能存在更好的方法)。

基本上,我更喜欢在ViewModel中管理LiveData对象而不是在Repository中,因为在我看来,存储库层只是应用程序和数据之间的桥梁(在网络或数据库中),以及UI的状态(如重试按钮可见性)必须由ViewModel管理。

repository.Java:

public class Repository {
    public void getListUsers(Callback<UserResponse> callback) {
        (Api.getClient().getUsersList()).enqueue(callback);
    }
}

main view model.Java:

public class MainViewModel extends ViewModel {

    ...

    private final MutableLiveData<Boolean> callFailure = new MutableLiveData<>();
    private final MutableLiveData<List<UserModel>> users = new MutableLiveData<>();

    public LiveData<Boolean> getCallFailure() {
        return callFailure;
    }

    public LiveData<Boolean> getUsers() {
        return users;
    }

    // THIS IS THE METHOD I'M CALLING FROM THE UI
    public void retryGetUsers() {
        callFailure.setValue(false);
        getUsers();
    }

    private void getUsers() {
        userRepo.getListUsers(new Callback<UserResponse>(){
            @Override
            public void onResponse(Call<UsersResponse> call, Response<UsersResponse> response) {
                users.setValue(response.body().getUserList());
            }

            @Override
            public void onFailure(Call<UsersResponse> call, Throwable t) {
                callFailure.setValue(true);
            }
        });
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.