You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android ViewModel观察时数据丢失问题求助

问题分析与解决方案

核心问题

从AddNotificationFragment添加数据到MutableLiveData后,FirstFragment能实时收到更新,但返回FirstFragment时数据莫名消失,日志显示返回时LiveData的列表长度为0。

可能原因及修复方案

1. AddNotificationFragment使用了Fragment级别的ViewModel

如果AddNotificationFragment中获取ViewModel的方式是new ViewModelProvider(this),它操作的是自身Fragment级别的ViewModel实例,而非FirstFragment使用的Activity级别ViewModel。添加的数据仅存在于AddNotificationFragment的ViewModel中,Fragment销毁后数据丢失。

修复:
在AddNotificationFragment中,统一使用Activity级别的ViewModelProvider:

notificationsViewModel = new ViewModelProvider(requireActivity()).get(NotificationsViewModel.class);

2. ViewModel列表更新方式存在隐患

直接修改LiveData持有的原列表对象再重新设置引用,不符合LiveData的最佳实践,可能导致数据感知异常。

修复:
修改ViewModel的增删方法,每次创建新列表实例,确保LiveData能正确感知数据变化:

public void addNotification(NotificationContent notificationContent) {
    List<NotificationContent> currentList = getNotifications().getValue();
    List<NotificationContent> newList = new ArrayList<>(currentList);
    newList.add(notificationContent);
    notifications.setValue(newList);
}

public void removeNotification(NotificationContent notificationContent) {
    List<NotificationContent> currentList = getNotifications().getValue();
    List<NotificationContent> newList = new ArrayList<>(currentList);
    newList.remove(notificationContent);
    notifications.setValue(newList);
}

public void addNotification(int position, NotificationContent notificationContent) {
    List<NotificationContent> currentList = getNotifications().getValue();
    List<NotificationContent> newList = new ArrayList<>(currentList);
    newList.add(position, notificationContent);
    notifications.setValue(newList);
}

3. 观察者生命周期绑定错误

当前使用requireActivity()作为LifecycleOwner,观察者会在Activity生命周期内一直存在,可能引发重复观察或内存泄漏,也可能导致视图重建时接收异常数据。

修复:
使用Fragment视图生命周期作为观察者的LifecycleOwner:

notifs.observe(getViewLifecycleOwner(), new Observer<List<NotificationContent>>() {
    @Override
    public void onChanged(List<NotificationContent> notificationContents) {
        Log.d("ANDROIDAPP", String.format("onChanged: detected and done, item size %d", notificationContents.size()));
        adapter.updateNotifications(notificationContents);
    }
});

getViewLifecycleOwner()会绑定Fragment的视图生命周期,视图销毁时自动移除观察者,避免重复注册。

4. Adapter数据更新逻辑冗余

当前updateNotifications方法中this.mNotifications.clear()属于冗余操作,且直接引用ViewModel的列表存在外部修改风险。

修复:
简化Adapter的更新方法,创建列表副本:

public void updateNotifications(List<NotificationContent> newNotifications) {
    this.mNotifications = new ArrayList<>(newNotifications);
    this.notifyDataSetChanged();
}

通过创建副本,避免ViewModel中的列表修改直接影响Adapter数据,提高稳定性。

验证步骤

  1. 确认AddNotificationFragment的ViewModel获取方式与FirstFragment一致;
  2. 修改ViewModel的列表更新逻辑,使用新列表实例;
  3. 调整观察者的LifecycleOwner为getViewLifecycleOwner();
  4. 重新运行测试,查看返回FirstFragment时的日志,确认onChanged中的列表长度是否正确。

内容的提问来源于stack exchange,提问作者Kim Vallée

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 08:59:17