[英]Android live data - observe always fires after config change
我目前正在重構我的代碼以包含 ViewModel 和 android.arch 庫提供的 LiveData。 我有一個簡單的活動,它將更改密碼的請求發送到服務器並根據 HTTP 響應代碼進行操作。
為此,我創建了為數據擴展 ViewModel 的類和一個用於調用服務器的存儲庫類。 我的 ViewModel 類有一個 MutableLiveData 字段,我使用 .observe(...) 方法從我的活動中訂閱該字段。 問題是 .observe(...) 中的代碼在配置更改(即屏幕旋轉)后一直觸發,我不知道為什么。
以下是相應的 ViewModel、Repository 和 Activity 類的代碼:
更改密碼視圖模型
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)
...
}
密碼更改存儲庫
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() 會觸發?
除了上面的回答,了解使用 ViewModel 和 LiveData 觀察者的場景很重要,只觀察一次,本文解釋了它們並展示了一種輕松處理它的方法: Working with LiveData and Events
我使用了 MutableSharedFlow 而不是 MutableLiveData,並解決了與您相同的問題。
你可以試試這個:
private val responseCode = MutableSharedFlow<Int>()
...
fun passChangeCallback() {
viewModelScope.launch {
responseCode.emit(serverResponse)
}
因為 MutableSharedFlow 不會重放已經由 defalut 發出的值。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.