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

Ara*_*yan 3 android viewmodel android-livedata

我是 Android 架构组件的新手,并尝试在我的 Activity 和 MyLifecycleService 中使用 LiveData,但有时应用程序会崩溃

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

这是我的服务代码

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

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

class MyActivityViewModel: ViewModel() {
val socketStatusMutableLiveData = OrderRxRepository.instance.mldSocketStatus
}
Run Code Online (Sandbox Code Playgroud)

以及我的活动中的代码

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

idu*_*olz 5

tl;dr你不能LiveData.observe()用两个不同的LifecycleOwners 来调用。就您而言,您的活动是其中之一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");
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

这解释了为什么您会遇到此问题,因为您尝试使用 Activity(一个LifecycleOwner)和 Service(另一个LifecycleOwner)观察同一个 LiveData。

更大的问题是您试图使用 LiveData 来做一些它不该做的事情。LiveData意味着LifecycleOwner在您尝试使其保存多个数据时保存单个数据LifecycleOwner

您应该考虑其他解决方案来解决您试图解决的问题LiveData。根据您的需要,这里有一些替代方案:

  • 全局单例- 如果您想将一些数据保留在内存中并使其在应用程序中的任何位置都可以访问,那么这非常有用。如果您希望数据“可观察”,请将其与 Rx 一起使用
  • LocalBroadcastManager - 如果您想在服务和活动之间进行通信,那就太棒了
  • 意图- 如果您还想在服务完成后确保您的活动仍然有效,那就太好了