Search code examples
androidandroid-architecture-componentsandroid-architecture-lifecycle

Strange LiveData behavior vs ObservableField


I have a problem with LiveData from new Android Architecture Components. I have used ObservableField before but wanted to try ACC.

When I set up value by MutableLiveData.setValue 4 times in one method in Activity I get only one call onChange, when I use ObservableField instead it works as I expect - it hits callback 4 times.

Why LiveData doesn't hit onChange for every single setValue?

ViewModel:

public class MainViewModel extends AndroidViewModel {

MutableLiveData<Boolean> booleanMutableLiveData;
ObservableField<Boolean> booleanObservableField;

public MainViewModel(@NonNull Application application) {
    super(application);
    booleanMutableLiveData = new MutableLiveData<>();
    booleanObservableField = new ObservableField<>();
}

public void changeBool()
{
    booleanMutableLiveData.setValue(false);
    booleanObservableField.set(false);
    booleanMutableLiveData.setValue(true);
    booleanObservableField.set(true);
    booleanMutableLiveData.setValue(false);
    booleanObservableField.set(false);
    booleanMutableLiveData.setValue(true);
    booleanObservableField.set(true);
}
}

And Activity:

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    final MainViewModel mainViewModel = ViewModelProviders.of(this).get(MainViewModel.class);

    mainViewModel.booleanMutableLiveData.observe(this, new Observer<Boolean>() {
        @Override
        public void onChanged(@Nullable Boolean aBoolean) {
            Log.e("Mutable Value", String.valueOf(aBoolean));
        }
    });

    mainViewModel.booleanObservableField.addOnPropertyChangedCallback(new Observable.OnPropertyChangedCallback() {
        @Override
        public void onPropertyChanged(Observable sender, int propertyId) {
            Log.e("Observable value", String.valueOf(mainViewModel.booleanObservableField.get()));
        }
    });

    mainViewModel.changeBool();

}
}

Stacktrace:

10-20 13:34:17.445 1798-1798/com.example.livedatasample E/Observable value: false
10-20 13:34:18.588 1798-1798/com.example.livedatasample E/Observable value: true
10-20 13:34:19.336 1798-1798/com.example.livedatasample E/Observable value: false
10-20 13:34:19.994 1798-1798/com.example.livedatasample E/Observable value: true
10-20 13:34:20.892 1798-1798/com.example.livedatasample E/Mutable Value: true

Solution

  • LiveData is life-cycle aware. In your case, you are changing its value in onCreate - liveData will call its observer when activity is started (exactly once in this case).

    LiveData considers an observer, which is represented by the Observer class, to be in an active state if its lifecycle is in the STARTED or RESUMED state. LiveData only notifies active observers about updates. Inactive observers registered to watch LiveData objects aren't notified about changes. https://developer.android.com/topic/libraries/architecture/livedata