Android 如何将ViewModel与存储库连接,以便将数据传播到视图(MVVM、Livedata)

Android 如何将ViewModel与存储库连接,以便将数据传播到视图(MVVM、Livedata),android,android-architecture-components,android-livedata,Android,Android Architecture Components,Android Livedata,我添加了一些代码,使我的问题更清楚 改装接口: public interface JsonPlaceHolderAPI { public static final String BASE_URL = "https://jsonplaceholder.typicode.com/"; @GET("todos/{number}") Call<ResponseBody> getJsonResponse(@Path("number") String number);

我添加了一些代码,使我的问题更清楚

改装接口:

public interface JsonPlaceHolderAPI {
    public static final String BASE_URL = "https://jsonplaceholder.typicode.com/";

    @GET("todos/{number}")
    Call<ResponseBody> getJsonResponse(@Path("number") String number);
}
公共接口JSONPlaceholder API{
公共静态最终字符串BASE_URL=”https://jsonplaceholder.typicode.com/";
@获取(“todos/{number}”)
调用getJsonResponse(@Path(“number”)字符串号);
}
repository:-->fetchResponse()将Viewmodel的MutableLiveData作为参数,并使用它更新其值,然后触发View以更改其UI

public class Repository {

    private final JsonPlaceHolderAPI api;

    public Repository() {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .build();
        api = retrofit.create(JsonPlaceHolderAPI.class);
    }


    public void fetchResponse(String number, final MutableLiveData<CharSequence> mld){
        final MutableLiveData<CharSequence> ml = new MutableLiveData<>();

        api.getJsonResponse(number).enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                try {
                    mld.setValue(response.body().string());

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {}
        });
    }
}
公共类存储库{
私有最终JSONAPI;
公共存储库(){
改装改装=新改装.Builder()
.baseUrl(基本URL)
.build();
api=reformation.create(JsonPlaceHolderAPI.class);
}
公共void fetchResponse(字符串编号,最终可变LiveData mld){
final MutableLiveData ml=新的MutableLiveData();
getJsonResponse(number).enqueue(新回调()函数){
@凌驾
公共void onResponse(调用、响应){
试一试{
setValue(response.body().string());
}捕获(IOE异常){
e、 printStackTrace();
}
}
@凌驾
public void onFailure(Call,Throwable t){}
});
}
}
viewModel:

public class MainActivityViewModel extends AndroidViewModel {
    MutableLiveData<CharSequence> response = new MutableLiveData<>();
    Repository repository;

    public MainActivityViewModel(@NonNull Application application) {
        super(application);
        repository = new Repository();
    }


    public void fetchData(String number) {
        response.setValue("Loading data");
        repository.fetchResponse(number, response);
    }

    public LiveData<? extends CharSequence> getLiveData() {
        return response;
    }
}
public类MainActivityViewModel扩展了AndroidViewModel{
MutableLiveData响应=新的MutableLiveData();
储存库;
public MainActivityViewModel(@NonNull应用程序){
超级(应用);
repository=新存储库();
}
公共数据(字符串编号){
响应设置值(“加载数据”);
fetchResponse(编号、响应);
}
公共LiveDataApi
TodoApi的公共接口{
@获取(“todos/”)
调用getTodos();
@获取(“todos/{id}”)
调用getTodo(@Path(“id”)long-id);
}
代表
public类TodoRepository{
私有静态最终字符串TAG=“TodoRepository”;
私有静态最终TodoRepository-ourInstance=新TodoRepository();
私有TodoApi;
私有MutableLiveData todoListLiveData=新的MutableLiveData();
私有MutableLiveData-todoLiveData=新的MutableLiveData();
公共静态TodoRepository getInstance(){
回归自然状态;
}
私人存款{
api=ApiBuilder.create(TodoApi.class);
}
公共LiveData getTodos(){
api.getTodos().enqueue(新回调()函数){
@凌驾
public void onResponse(@NonNull调用,@NonNull响应){
todoListLiveData.setValue(response.body());
}
@凌驾
public void onFailure(@NonNull Call Call,@NonNull Throwable t){
d(标记“onFailure:无法从服务器获取todo列表”);
}
});
返回到olistLiveData;
}
公共LiveData getTodo(长id){
getTodo(id).enqueue(newcallback()){
@凌驾
public void onResponse(@NonNull调用,@NonNull响应){
setValue(response.body());
}
@凌驾
public void onFailure(@NonNull Call Call,@NonNull Throwable t){
Log.d(标记“onFailure:failed to get to”);
}
});
返回数据;
}
}
视图模型
公共类MainActivityViewModel扩展了ViewModel{
私有静态最终字符串TAG=“MainActivityViewModel”;
私有TodoRepository存储库=TodoRepository.getInstance();
私有MutableLiveData isLoading=新的MutableLiveData();
私有LiveData数据;
公共维护活动视图模型(){
超级();
isLoading.setValue(真);
todoLiveData=repository.getTodos();
}
@凌驾
已清除的受保护的void(){
super.onCleared();
}
public MutableLiveData getIsLoading(){
返回卸载;
}
公共LiveData getTodoLiveData(){
返回数据;
}
}
看法 @凌驾

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    todoListRecyclerView = findViewById(R.id.todo_recycler_view);
    loadingIndicator = findViewById(R.id.todo_loading_indicator);
    mViewModel = ViewModelProviders.of(this).get(MainActivityViewModel.class);
    getSupportActionBar().setTitle("Todos");

    mViewModel.getIsLoading().observe(this, new Observer<Boolean>() {
        @Override
        public void onChanged(Boolean isLoading) {
            if (isLoading) loadingIndicator.setVisibility(View.VISIBLE);
            else loadingIndicator.setVisibility(View.GONE);
        }
    });

    mViewModel.getTodoLiveData().observe(this, new Observer<List<Todo>>() {
        @Override
        public void onChanged(List<Todo> todos) {
            mViewModel.getIsLoading().postValue(false);
            initRecyclerView(todos);
        }
    });
}
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ToDoListerCyclerView=findViewById(R.id.todo\u recycler\u视图);
loadingIndicator=findViewById(R.id.todo\u loading\u indicator);
mViewModel=ViewModelProviders.of(this.get)(MainActivityViewModel.class);
getSupportActionBar().setTitle(“Todos”);
mViewModel.getIsLoading().observe(这是一个新的观察者(){
@凌驾
更改公共void(布尔值isLoading){
if(isLoading)loadingIndicator.setVisibility(View.VISIBLE);
else加载indicator.setVisibility(View.GONE);
}
});
mViewModel.getTodoLiveData().observe(这是一个新的观察者(){
@凌驾
更改后的公共作废(列出待办事项){
mViewModel.getIsLoading().postValue(false);
initRecyclerView(todos);
}
});
}
全样品

我很感谢您与我分享了这一点。但是,在这一次中,存储库不返回数据。相反,它返回调用,viewmodel发出http请求。这将很好地工作,但我认为它违反了分离。因为viewmodel发出http请求。是的,您是对的。但它可以很容易地更改为执行ne来自存储库的twork调用然后返回livedata并从viewmodel和view中观察。我已经更新了我的回答哦,我明白你的意思,它可以工作。出于某种原因,我认为更新livedata是viewmodel的责任。但是在您的示例中,它是直接从repository更新的。为什么您更喜欢用户postValue()而不是setValue()?它没有在后台运行threadCall.enqueue方法是
public interface TodoApi {
    @GET("todos/")
    Call<List<Todo>> getTodos();

    @GET("todos/{id}")
    Call<Todo> getTodo(@Path("id") long id);
}
    public class TodoRepository {
    private static final String TAG = "TodoRepository";
    private static final TodoRepository ourInstance = new TodoRepository();
    private TodoApi api;

    private MutableLiveData<List<Todo>> todoListLiveData = new MutableLiveData<>();
    private MutableLiveData<Todo> todoLiveData = new MutableLiveData<>();

    public static TodoRepository getInstance() {
        return ourInstance;
    }

    private TodoRepository() {
        api = ApiBuilder.create(TodoApi.class);
    }

    public LiveData<List<Todo>> getTodos() {
        api.getTodos().enqueue(new Callback<List<Todo>>() {
            @Override
            public void onResponse(@NonNull Call<List<Todo>> call, @NonNull Response<List<Todo>> response) {
                todoListLiveData.setValue(response.body());
            }

            @Override
            public void onFailure(@NonNull Call<List<Todo>> call, @NonNull Throwable t) {
                Log.d(TAG, "onFailure: failed to fetch todo list from server");
            }
        });
        return todoListLiveData;
    }

    public LiveData<Todo> getTodo(long id) {
        api.getTodo(id).enqueue(new Callback<Todo>() {
            @Override
            public void onResponse(@NonNull Call<Todo> call, @NonNull Response<Todo> response) {
                todoLiveData.setValue(response.body());
            }

            @Override
            public void onFailure(@NonNull Call<Todo> call, @NonNull Throwable t) {
                Log.d(TAG, "onFailure: failed to get todo");
            }
        });
        return todoLiveData;
    }
}
    public class MainActivityViewModel extends ViewModel {
    private static final String TAG = "MainActivityViewModel";

    private TodoRepository repository = TodoRepository.getInstance();

    private MutableLiveData<Boolean> isLoading = new MutableLiveData<>();
    private LiveData<List<Todo>> todoLiveData;

    public MainActivityViewModel() {
        super();
        isLoading.setValue(true);
        todoLiveData = repository.getTodos();
    }

    @Override
    protected void onCleared() {
        super.onCleared();
    }

    public MutableLiveData<Boolean> getIsLoading() {
        return isLoading;
    }

    public LiveData<List<Todo>> getTodoLiveData() {
        return todoLiveData;
    }
}
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    todoListRecyclerView = findViewById(R.id.todo_recycler_view);
    loadingIndicator = findViewById(R.id.todo_loading_indicator);
    mViewModel = ViewModelProviders.of(this).get(MainActivityViewModel.class);
    getSupportActionBar().setTitle("Todos");

    mViewModel.getIsLoading().observe(this, new Observer<Boolean>() {
        @Override
        public void onChanged(Boolean isLoading) {
            if (isLoading) loadingIndicator.setVisibility(View.VISIBLE);
            else loadingIndicator.setVisibility(View.GONE);
        }
    });

    mViewModel.getTodoLiveData().observe(this, new Observer<List<Todo>>() {
        @Override
        public void onChanged(List<Todo> todos) {
            mViewModel.getIsLoading().postValue(false);
            initRecyclerView(todos);
        }
    });
}