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

时间:2018-10-08 08:20:10

标签: android viewmodel android-livedata

我是android体系结构组件的新手,并尝试在我的活动和MyLifecycleService中使用LiveData,但有时应用程序因

而崩溃
  

IllegalArgumentException:无法添加具有不同生命周期的同一观察者

这是我的服务代码

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

对于我的活动,我有activityViewModel类,其中包含相同的实时数据,这是代码

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

和我活动中的代码

MyActivityViewModel viewModel = ViewModelProviders.of(this).get(MyActivityViewModel .class);
viewModel.getSocketStatusMutableLiveData().observe(this, socketStatus -> {
        if (socketStatus == null) return;
        ...
    });

1 个答案:

答案 0 :(得分:2)

tl; dr 您不能用两个不同的LiveData.observe()来呼叫LifecycleOwner。在您的情况下,您的活动是一个LifecycleOwner,另一个是您的服务。

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

这说明了为什么会遇到此问题,因为您试图通过活动(是一个LifecycleOwner)和一个服务(是一个不同的LifecycleOwner)在同一个LiveData上进行观察。

更大的问题是,您正在尝试将LiveData用于原本不想做的事情。 LiveData用于保存单个LifecycleOwner的数据,而您正试图使其保存多个LifecycleOwner的数据。

对于使用LiveData尝试解决的问题,您应该考虑其他解决方案。根据您的需求,有一些替代方案:

  • 全局单例-如果您想将一些数据保留在内存中并使其在应用程序中的任何位置均可访问,则非常有用。如果您希望数据“可观察”,请与Rx一起使用
  • LocalBroadcastManager -如果您想在服务和活动之间进行交流,则非常有用
  • 意图-非常有用,如果您还想确保服务完成后活动仍然活跃