我目前正在重构我的代码,将ViewModel包含在android.arch库提供的LiveData中。我有一个简单的活动,可以将密码更改请求发送到服务器,并根据HTTP响应代码执行操作。
为此,我创建了一个类,它扩展了ViewModel的数据和一个存储库类来调用服务器。我的ViewModel类有一个MutableLiveData字段,我使用.observe(...)方法从我的活动订阅。问题是.observe(...)中的代码在配置更改(即屏幕旋转)后一直触发,我不明白为什么。
以下是ViewModel,Repository和Activity类的代码:
ChangePasswordViewModel
public class ChangePasswordViewModel extends ViewModel{
private MutableLiveData<Integer> responseCode;
private PasswordChangeRepository passwordChangeRepository;
public ChangePasswordViewModel() {
responseCode = new MutableLiveData<>();
passwordChangeRepository = new PasswordChangeRepositoryImpl();
}
public MutableLiveData<Integer> responseCodeLiveData() {
return responseCode;
}
public void sendChangePasswordRequest(String newPassword){
passwordChangeRepository.changePassword(newPassword, passChangeCallback());
}
// Callback that fires after server sends a response
private Callback passChangeCallback(){
...
responseCode.postValue(serverResponse)
...
}
PasswordChangeRepository
public class PasswordChangeRepositoryImpl {
public void changePassword(String newPassword, Callback<Void> callback){
//Sending new password to server and processing response in callback
ServerCalls.changePassword(newPassword, callback);
}
}
活动
public class ChangePasswordActivity extends AppCompatActivity{
...
private void init(){
//Getting appropriate view model
passwordViewModel = ViewModelProviders.of(this).get(ChangePasswordViewModel.class);
// Starting to observe LiveData
passwordViewModel.getResponseCode().observe(this, responseCode -> {
Log.info("Server response is " + responseCode);
});
//Sending new password to server
buttonPassChange.setOnClickListener(view ->
passwordViewModel.sendChangePasswordRequest("newPass")
);
}
...
}
问题是我第一次使用sendChangePasswordRequest(...)向服务器发送请求后,观察活动中的代码
passwordViewModel.getResponseCode().observe(this, responseCode -> {
Log.info("Server response is " + responseCode);
});
旋转屏幕后,每次都会触发。为什么会这样?自上次服务器调用以来,MutableLiveData responseCode的值没有更新,为什么.observe()会在实时数据没有变化的情况下触发?
答案 0 :(得分:5)
这是一种预期的行为,您可以在documents中看到:
观察(LifecycleOwner所有者, 观察者观察者)将给定的观察者添加到给定所有者的生命周期内的观察者列表中。事件是 在主线程上发送。如果LiveData已经有数据集,那么 将交付给观察员。
如果您想观察视图状态的变化,那么您应该创建并观察视图状态而不是网络请求,谷歌已经为此类案例提供了example。
答案 1 :(得分:0)
除了上面的回答外,重要的是要了解使用ViewModel和LiveData观察器仅观察一次的场景,本文将对它们进行解释并给出一种轻松处理它的方法:Working with LiveData and Events