Android live data - observe always fires after config change

怎甘沉沦 提交于 2020-05-25 15:26:51

问题


I'm currently refactoring my code to include ViewModel with LiveData provided by android.arch library. I have a simple activity that sends request for a password change to server and acts according to HTTP response code.

For that purpose I have created class that extends ViewModel for data and a repository class to call server. My ViewModel class has one MutableLiveData field which I'm subscribing to from my activity using .observe(...) method. The issue is that code inside .observe(...) fires all the time after configuration changes (i.e. screen rotation) and I have no idea why.

Here is the code of ViewModel, Repository and Activity classes accordingly:

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

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

Problem is that after the first time I send request to server using sendChangePasswordRequest(...) observe code in activity

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

fires every time after I rotate the screen. Why is that happening? Value of MutableLiveData responseCode hasn't been updated since the last server call, so why does .observe() fires if there were no changes to live data?


回答1:


That is an intended behavior, as you can see in 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.

If you want to observe the change in view state then you should create and observe a view state instead of a network request, google already provided an example for cases like this.




回答2:


In addition to answer above, it's important to understand the scenarios in which using ViewModel & LiveData observers, to observe only once, this article explains them and shows a way to deal with it easily: Working with LiveData and Events



来源:https://stackoverflow.com/questions/49318011/android-live-data-observe-always-fires-after-config-change

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!