106

最近我正在探索谷歌最近推出的 Android 架构。从文档中我发现了这个:

public class MyViewModel extends ViewModel {
    private MutableLiveData<List<User>> users;
    public LiveData<List<User>> getUsers() {
        if (users == null) {
            users = new MutableLiveData<List<Users>>();
            loadUsers();
        }
        return users;
    }

    private void loadUsers() {
        // do async operation to fetch users
    }
}

活动可以按如下方式访问此列表:

public class MyActivity extends AppCompatActivity {
    public void onCreate(Bundle savedInstanceState) {
        MyViewModel model = ViewModelProviders.of(this).get(MyViewModel.class);
        model.getUsers().observe(this, users -> {
            // update UI
        });
    }
}

我的问题是,我要这样做:

  1. loadUsers()函数中我异步获取数据,我将首先检查数据库(房间)中的数据

  2. 如果我没有在那里获取数据,我将调用 API 从 Web 服务器获取数据。

  3. 我会将获取的数据插入数据库(房间)并根据数据更新 UI。

推荐的方法是什么?

如果我开始Service从该loadUsers()方法调用 API,我该如何更新MutableLiveData<List<User>> users变量Service

4

5 回答 5

101

我假设您正在使用android 架构组件service, asynctask or handler实际上,无论您在哪里调用以更新数据都无关紧要。您可以使用方法从服务或异步任务中插入数据postValue(..)。您的课程将如下所示:

private void loadUsers() {
    // do async operation to fetch users and use postValue() method
    users.postValue(listOfData)
}

照原样usersLiveData数据库Room负责为用户提供数据,无论它被插入到哪里。

Note:在类似 MVVM 的架构中,存储库主要负责检查和拉取本地数据和远程数据。

于 2017-05-31T19:54:10.823 回答
48

您可以使用MutableLiveData<T>.postValue(T value)后台线程中的方法。

private void loadUsers() {
    // do async operation to fetch users and use postValue() method
   users.postValue(listOfData)
}
于 2017-07-30T12:46:20.483 回答
19

...在 loadUsers() 函数中,我正在异步获取数据 ...如果我启动一个服务以从 loadUsers() 方法调用 API,我如何从该服务更新 MutableLiveData> users 变量?

如果应用程序在后台线程上获取用户数据,postValue(而不是setValue)将很有用。

在 loadData 方法中有一个对 MutableLiveData“用户”对象的引用。loadData 方法还从某个地方(例如,存储库)获取一些新的用户数据。

现在,如果在后台线程上执行,则 MutableLiveData.postValue() 会更新 MutableLiveData 对象的外部观察者。

也许是这样的:

private MutableLiveData<List<User>> users;

.
.
.

private void loadUsers() {
    // do async operation to fetch users
    ExecutorService service =  Executors.newSingleThreadExecutor();
    service.submit(new Runnable() {
        @Override
        public void run() {
            // on background thread, obtain a fresh list of users
            List<String> freshUserList = aRepositorySomewhere.getUsers();

            // now that you have the fresh user data in freshUserList, 
            // make it available to outside observers of the "users" 
            // MutableLiveData object
            users.postValue(freshUserList);        
        }
    });

}
于 2017-06-08T20:21:13.700 回答
4

查看伴随新架构模块(如LiveDataViewModel. 他们深入讨论了这个确切的问题。

在他们的示例中,他们没有将其放入服务中。看看他们如何使用“存储库”模块和改造来解决它。底部的附录包括更完整的示例,包括通信网络状态、报告错误等。

于 2017-06-05T18:22:27.547 回答
3

如果你在 Repository 中调用你的 api,

存储库中:

public MutableLiveData<LoginResponseModel> checkLogin(LoginRequestModel loginRequestModel) {
    final MutableLiveData<LoginResponseModel> data = new MutableLiveData<>();
    apiService.checkLogin(loginRequestModel)
            .enqueue(new Callback<LoginResponseModel>() {
                @Override
                public void onResponse(@NonNull Call<LoginResponseModel> call, @Nullable Response<LoginResponseModel> response) {
                    if (response != null && response.isSuccessful()) {
                        data.postValue(response.body());
                        Log.i("Response ", response.body().getMessage());
                    }
                }

                @Override
                public void onFailure(@NonNull Call<LoginResponseModel> call, Throwable t) {
                    data.postValue(null);
                }
            });
    return data;
}

视图模型中

public LiveData<LoginResponseModel> getUser() {
    loginResponseModelMutableLiveData = repository.checkLogin(loginRequestModel);
    return loginResponseModelMutableLiveData;
}

活动/片段中

loginViewModel.getUser().observe(LoginActivity.this, loginResponseModel -> {
        if (loginResponseModel != null) {
            Toast.makeText(LoginActivity.this, loginResponseModel.getUser().getType(), Toast.LENGTH_SHORT).show();
        }
    });

注意:这里使用 JAVA_1.8 lambda,没有它也可以使用

于 2019-05-13T10:37:32.800 回答