简体   繁体   English

Android LiveData,ViewModel,无法添加具有不同生命周期的同一观察者

[英]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 我是android架构组件的新手,并尝试在我的活动和MyLifecycleService中使用LiveData,但有时应用程序崩溃了

IllegalArgumentException: Cannot add the same observer with different lifecycles IllegalArgumentException:无法添加具有不同生命周期的相同观察者

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 对于我的活动,我有activityViewModel类,它包含相同的livingata,这里是代码

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

tl;dr You can't call LiveData.observe() with two different LifecycleOwner s. tl; dr你不能用两个不同的LifecycleOwner调用LiveData.observe() In your case, your Activity is one LifecycleOwner and the other is your Service. 在您的情况下,您的Activity是一个LifecycleOwner ,另一个是您的服务。

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. 从Android的源代码中,您可以看到,如果已经有LifecyclerOwner观察并且LifecyclerOwner与您尝试观察的那个不同,则抛出此异常。

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 ). 这解释了为什么您遇到此问题,因为您尝试使用Activity(一个LifecycleOwner )和一个Service(一个不同的LifecycleOwner )观察相同的LiveData。

The bigger problem is that you are trying to use LiveData for something it wasn't meant to do. 更大的问题是,您正在尝试将LiveData用于不应该执行的操作。 LiveData is meant to hold data for a single LifecycleOwner while you are trying to make it hold data for multiple LifecycleOwner . LiveData用于保存单个LifecycleOwner数据,同时您尝试使其保存多个LifecycleOwner数据。

You should consider other solutions to the problem you tried to solve with LiveData . 您应该考虑使用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" 如果您希望数据“可观察”,请将其与Rx一起使用
  • LocalBroadcastManager - great if you want to communicate between your service and activity LocalBroadcastManager - 如果您想在服务和活动之间进行通信, 那就太棒了
  • Intent - great if you want to also make sure your activity is alive once your service completes 意图 - 如果你想在服务完成后确保你的活动还活着,那就太棒了

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM