Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android live data - observe always fires after config change

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?

like image 407
Alexandr Zhurkov Avatar asked Mar 16 '18 10:03

Alexandr Zhurkov


1 Answers

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.

like image 163
Keivan Esbati Avatar answered Oct 07 '22 02:10

Keivan Esbati