Android 实时数据 - 配置更改后观察总是触发

Android live data - observe always fires after config change

我目前正在重构我的代码以包含 ViewModel 和 android.arch 库提供的 LiveData。我有一个简单的 activity,它向服务器发送密码更改请求并根据 HTTP 响应代码执行操作。

为此,我创建了 class 来扩展数据的 ViewModel 和一个存储库 class 来调用服务器。我的 ViewModel class 有一个 MutableLiveData 字段,我正在使用 .observe(...) 方法从我的 activity 订阅它。问题是 .observe(...) 中的代码在配置更改(即屏幕旋转)后一直触发,我不知道为什么。

下面是 ViewModel、Repository 和 Activity class 相应的代码:

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)
        ...
}

密码更改存储库

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);
    }
}

Activity

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(...) 向服务器发送请求后观察 activity

中的代码
passwordViewModel.getResponseCode().observe(this, responseCode -> {
           Log.info("Server response is " + responseCode);
        });

每次旋转屏幕后都会触发。为什么会这样? MutableLiveData responseCode 的值自上次服务器调用以来尚未更新,那么如果实时数据没有更改,为什么 .observe() 会触发?

这是预期的行为,如您在 documents 中所见:

observe (LifecycleOwner owner, Observer observer) Adds the given observer to the observers list within the lifespan of the given owner. The events are dispatched on the main thread. If LiveData already has data set, it will be delivered to the observer.

如果您想观察视图状态的变化,那么您应该创建并观察视图状态而不是网络请求,google 已经为这种情况提供了 example

除了上面的回答之外,了解使用 ViewModel 和 LiveData 观察者的场景也很重要,只观察一次,这篇文章解释了它们并展示了一种轻松处理它的方法:Working with LiveData and Events