关于ViewModel中UnPeekLiveData一次消费问题

📅 2026/6/27 5:25:39
关于ViewModel中UnPeekLiveData一次消费问题
mvvm模式开发中不免用到ViewModel的生成局部的还好说当前用当前申请今天遇到的一个坑是全局的public static T extends ViewModel T getAppVM(ClassT 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 UnPeekLiveDataString radioLiveData new UnPeekLiveData();没注意这里有什么问题然后在Service中获取实例在Activity中也获取实例在当前页面中的时候Activity能收到radioLiveData事件是因为Activity中先获取的ViewModel的实例Service后获取的实例所以没什么问题但是当切出Activity再重新进入获取ViewModel实例的时候此时Activity的顺序比Service要晚了发送同一个事件的时候Service消费了Activity也就不再处理了究其原因就是UnPeekLiveData是一次性消费事件public final MutableLiveDataString radioLiveData new MutableLiveData();换成MutableLiveData事件改用普通MutableLiveData推荐用于状态而非事件如果这个数据是“当前状态”比如网络请求结果、最新数据而不是“一次性提示”直接换成MutableLiveData。private MutableLiveDataString mData new MutableLiveData();这样setValue后所有活动观察者都会收到不会被消耗掉。这样也就解决了问题额外提醒避坑Service 中的观察者生命周期如果你在 Service 里用observeForever退出 Service 时务必调用removeObserver否则会造成内存泄漏且残留的观察者会一直拦截 Activity 的事件因为消费顺序永远比 Activity 早。BaseApp作为ViewModelStoreOwner虽然你的写法能让两者共享实例但Application的生命周期比 Activity/Service 都长如果 ViewModel 持有 Activity Context 引用会引发内存泄漏请确保 ViewModel 不持有 UI 相关的引用。