Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android LiveData, ViewModel, Cannot add the same observer with different lifecycles

I'm new in android architecture components, and trying to use LiveData in my activity and MyLifecycleService, but sometimes the app crashed with

IllegalArgumentException: Cannot add the same observer with different lifecycles

here is my code in service

 private final MutableLiveData<SocketStatus> socketStatusMutableLiveData = OrderRxRepository.Companion.getInstance().getMldSocketStatus(); 
 socketStatusMutableLiveData.observe(this, socketStatus -> {
        if (socketStatus == null) return;
        ...
    });

for my activity I have activityViewModel class which contains the same livedata, here is the code

class MyActivityViewModel: ViewModel() {
val socketStatusMutableLiveData = OrderRxRepository.instance.mldSocketStatus
}

and the code in my activity

MyActivityViewModel viewModel = ViewModelProviders.of(this).get(MyActivityViewModel .class);
viewModel.getSocketStatusMutableLiveData().observe(this, socketStatus -> {
        if (socketStatus == null) return;
        ...
    });
like image 219
Ara Hakobyan Avatar asked Oct 20 '25 18:10

Ara Hakobyan


1 Answers

tl;dr You can't call LiveData.observe() with two different LifecycleOwners. In your case, your Activity is one LifecycleOwner and the other is your Service.

From Android's source code you can see that this exception is thrown if there is already a LifecyclerOwner observing and that LifecyclerOwner is different from the one you are trying to observe with.

public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) {
    ...
    LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
    ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
    if (existing != null && !existing.isAttachedTo(owner)) {
        throw new IllegalArgumentException("Cannot add the same observer"
                + " with different lifecycles");
    }
    ...
}

This explains why you are having this problem since you are trying to observe on the same LiveData with an Activity (which is one LifecycleOwner) and a Service (a different LifecycleOwner).

The bigger problem is that you are trying to use LiveData for something it wasn't meant to do. LiveData is meant to hold data for a single LifecycleOwner while you are trying to make it hold data for multiple LifecycleOwner.

You should consider other solutions to the problem you tried to solve with LiveData. Here are some alternatives depending on your needs:

  • Global singleton - great if you want to keep some data in memory and have it accessible everywhere in your app. Use it with Rx if you want your data to be "observable"
  • LocalBroadcastManager - great if you want to communicate between your service and activity
  • Intent - great if you want to also make sure your activity is alive once your service completes
like image 164
idunnololz Avatar answered Oct 23 '25 08:10

idunnololz



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!