最近我正在探索谷歌最近推出的Android架构。从Documentation我发现了这个:
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
});
}
}
我的问题是,我将这样做:
在loadUsers()
函数中我异步获取数据,我将首先检查数据库(Room)中的数据
如果我没有获取数据,我将进行API调用以从Web服务器获取数据。
我会将获取的数据插入数据库(Room)并根据数据更新UI。
建议的方法是什么?
如果我开始Service
从loadUsers()
方法调用API,如何从MutableLiveData<List<User>> users
更新Service
变量?
答案 0 :(得分:59)
我假设您正在使用android architecture components。实际上,无论您在何处调用service, asynctask or handler
来更新数据都无关紧要。您可以使用postValue(..)
方法从服务或asynctask插入数据。你的课程看起来像这样:
private void loadUsers() {
// do async operation to fetch users and use postValue() method
users.postValue(listOfData)
}
由于users
为LiveData
,Room
数据库负责在任何位置插入用户数据。
Note:
在类似MVVM的体系结构中,存储库主要负责检查和提取本地数据和远程数据。
答案 1 :(得分:41)
请使用后台主题中的实时数据&lt; postValue(..)方法。
private void loadUsers() {
// do async operation to fetch users and use postValue() method
users.postValue(listOfData)
}
答案 2 :(得分:15)
...在loadUsers()函数中我异步获取数据... 如果我启动一个服务从loadUsers()方法调用API,如何 我可以更新MutableLiveData&gt;用户变量 服务?
如果应用在后台线程上提取用户数据,则postValue(而非setValue)将非常有用。
在loadData方法中,有一个对MutableLiveData“users”对象的引用。 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);
}
});
}
答案 3 :(得分:4)
查看LiveData
和ViewModel
等新架构模块附带的Android architecture guide。他们深入讨论了这个问题。
在他们的例子中,他们没有把它放在服务中。看看他们是如何使用&#34;存储库&#34;来解决它的。模块和改造。底部的附录包括更完整的示例,包括通信网络状态,报告错误等。
答案 4 :(得分:2)
https://developer.android.com/topic/libraries/architecture/guide.html
对你的问题有很好的答案。一直滚动到底部,看看如何在数据库中保存响应并使用LiveData更新UI。
答案 5 :(得分:1)
如果要在存储库中调用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;
}
在 ViewModel
中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,您可以不使用它