使用ViewModel时,View会观察ViewModel。它必须注册为观察员。在Google的official tutorial中,此注册被委托给observe()
对象的LiveData
方法。
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 an asynchronous operation to fetch users.
}
}
public class MyActivity extends AppCompatActivity {
public void onCreate(Bundle savedInstanceState) {
// Create a ViewModel the first time the system calls an activity's onCreate() method.
// Re-created activities receive the same MyViewModel instance created by the first activity.
MyViewModel model = ViewModelProviders.of(this).get(MyViewModel.class);
model.getUsers().observe(this, users -> {
// update UI
});
}
}
方法getUsers()
返回LiveData
对象本身。它的observe()
方法用于注册观察者。 View不会观察ViewModel
,而是观察其实现的一部分。
现在这是最佳做法,在使用ViewModels
时,不要以LiveData
对象的形式观察自己,而是要实现部分实现?或者这是低质量的介绍?
答案 0 :(得分:0)
我说是的,这是ViewModel通过某种形式的Observable公开其数据的最佳做法,无论是LiveData还是RX Observable。
这打破了其他架构,例如MVP,其中演示者通常会引用View,当某些内容发生变化时会调用它。有关ViewModel应引用的内容的指南非常具体。
A ViewModel must never reference a view, Lifecycle, or any class that may hold a reference to the activity context.
通过ViewModel将您的数据公开为Observable,这意味着视图可以来去,一旦订阅,将接收最新数据和任何后续更新。指南再次提供了一些细节。
If the activity is re-created, it receives the same MyViewModel instance that was created by the first activity. When the owner activity is finished, the framework calls the ViewModel objects's onCleared() method so that it can clean up resources
https://developer.android.com/topic/libraries/architecture/viewmodel.html
答案 1 :(得分:0)
根据克里斯的回答,我给出了自己的答案。我认为教程不是最佳实践,原因很简单,对象不应该公开它的内部实现。基于Chris的论证,我正在寻找一种可以在不丢失命名功能的情况下获得封装的选项。结果是方法observerUsers()
,它在内部委托给LiveData
对象。
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MainActivityViewModel model = ViewModelProviders.of(this).get(MainActivityViewModel.class);
model.observeUsers(this,
new Observer<List<User>>() {
@Override
public void onChanged(@Nullable List<User> users) {
updateUI();
}
}
);
}
void updateUI() {
}
static class MainActivityViewModel extends ViewModel {
private MutableLiveData<List<User>> users;
public void observeUsers(@NonNull LifecycleOwner owner,
@NonNull Observer<List<User>> observer) {
getUsers().observe(owner, observer);
}
private LiveData<List<User>> getUsers() {
if (users == null) {
users = new MutableLiveData<>();
loadUsers();
}
return users;
}
private void loadUsers() {
// Do an asynchronous operation to fetch users.
}
}
static class User {
}
}
仍然List<User>
暴露了内部实施。它可以改进为Users
类。
我将所有内容放在一个文件中并使用内部静态类。这并不是最佳实践。只是为了能够在一个文件中快速编辑所有内容。特别是模型User
属于它自己的文件,而我经常将ViewModel
放入它所属的View
类中。
我的第二个评论点与ViewModel
本身观察基础模型的情况相符。在这种情况下,观察者方法onChange()
非常通用,需要非常通用的更新方法,如updateUI()
。您可能希望观察模型的更具体事件以进行特定更新。