关于ViewModel中UnPeekLiveData一次消费问题
2026/6/27 5:25:33 网站建设 项目流程

mvvm模式开发中不免用到ViewModel的生成,局部的还好说,当前用当前申请,今天遇到的一个坑是全局的

public static <T extends ViewModel> T getAppVM(Class<T> modelClass) { ViewModelProvider.AndroidViewModelFactory instance = ViewModelProvider.AndroidViewModelFactory.getInstance(Utils.getApp()); ViewModelProvider viewModelProvider = new ViewModelProvider((BaseApp) Utils.getApp(), instance); return viewModelProvider.get(modelClass); }

全局申请没什么问题,但是ViewModel中的liveData一开始设置的

public final UnPeekLiveData<String> radioLiveData = new UnPeekLiveData();

没注意这里有什么问题,然后在Service中获取实例,在Activity中也获取实例,在当前页面中的时候Activity能收到radioLiveData事件,是因为Activity中先获取的ViewModel的实例,Service后获取的实例,所以没什么问题,但是!!!!!当切出Activity再重新进入获取ViewModel实例的时候,此时Activity的顺序比Service要晚了,发送同一个事件的时候,Service消费了,Activity也就不再处理了

究其原因就是UnPeekLiveData是一次性消费事件

public final MutableLiveData<String> radioLiveData = new MutableLiveData();

换成MutableLiveData事件

改用普通MutableLiveData(推荐用于状态,而非事件)

如果这个数据是“当前状态”(比如网络请求结果、最新数据),而不是“一次性提示”,直接换成MutableLiveData

private MutableLiveData<String> mData = new MutableLiveData<>();

这样setValue后,所有活动观察者都会收到,不会被消耗掉。

这样也就解决了问题

额外提醒(避坑)

  • Service 中的观察者生命周期:如果你在 Service 里用observeForever,退出 Service 时务必调用removeObserver,否则会造成内存泄漏,且残留的观察者会一直拦截 Activity 的事件(因为消费顺序永远比 Activity 早)。

  • BaseApp作为ViewModelStoreOwner:虽然你的写法能让两者共享实例,但Application的生命周期比 Activity/Service 都长,如果 ViewModel 持有 Activity Context 引用,会引发内存泄漏,请确保 ViewModel 不持有 UI 相关的引用。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询