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

AndroidViewModel的onChanged()跨Activity使用时无法生效

开发场景说明

正在开发一款聊天应用,包含两个核心Activity:

  • 联系人Activity:负责展示联系人列表
  • 消息Activity:负责展示单条会话的聊天内容

在联系人Activity中,使用如下代码初始化ChatViewModel,通过观察对应LiveData填充RecyclerView,功能运行完全正常:

contactsViewModel = new ViewModelProvider(this, ViewModelProvider.AndroidViewModelFactory
                .getInstance(this.getApplication())).get(ChatViewModel.class);

 contactsViewModel.getAllUsers().observe(this, new Observer<List<UserContacts>>() {
            @Override
            public void onChanged(List<UserContacts> userContacts) {
                contactAdapter.submitList(userContacts);
                if(!userContacts.isEmpty())
                {
                    userList = userContacts;
                }
            }
        });
异常表现

点击某条联系人进入消息Activity后,需要获取该联系人的基础信息,因此在消息Activity中复用了相同的ViewModel初始化与观察逻辑,代码如下:

chatViewModel = new ViewModelProvider(this,ViewModelProvider.AndroidViewModelFactory.getInstance(this.getApplication())).get(ChatViewModel.class);
    
chatViewModel.getAllUsers().observe(this, new Observer<List<UserContacts>>() {
                @Override
                public void onChanged(List<UserContacts> userContacts) {
                    Toast.makeText(ChatActivity.this, "Inside", Toast.LENGTH_SHORT).show();

                    for(int i = 1; i <= userContacts.size();i++)
                    {
                        UserContacts user = userContacts.get(i);
                        if(user.getId() == id)
                        {
                            reciever = user.getFriend();
                            profile = user.getPicture();
                            firstName = user.getFirstName();
                            lastName = user.getLastName();
                            friendPublicKeyString = user.getFriendPublicKey();
                        }
                    }
                }
            });

实际运行时,该观察逻辑的onChanged()方法没有按预期触发:经调试确认,联系人Activity的对应回调可正常执行,消息Activity的执行链路完全没有进入onChanged(),所有关联的联系人信息变量最终被赋值为null。

  • 调试参考1:联系人Activity的回调执行状态
  • 调试参考2:消息Activity的回调未触发状态
现有各层代码实现
  1. ChatViewModel构造函数:关联Repository并初始化所有联系人数据
public ChatViewModel(@NonNull Application application) {
        super(application);
        chatRepository = new ChatRepository(application);
        allContacts = chatRepository.getAllContacts();
        oneChat = chatRepository.getOneChat();
        allChatsJustForId = chatRepository.getAllChatsJustForId();
    }
  1. ChatViewModel对外暴露联系人LiveData的方法
public LiveData<List<UserContacts>> getAllUsers()
    {
        return allContacts;
    }
  1. ChatRepository构造函数:从Room数据库初始化所有联系人数据
public ChatRepository(Application application)
    {
        ChatDatabase db = ChatDatabase.getInstance(application);
        chatDao = db.chatDao();

        userContactsDao = db.userContactsDao();
        allContacts = userContactsDao.getAllContacts();

        senderHelperDao = db.senderHelperDao();

        oneChat = senderHelperDao.getOneChat();

        allChatsJustForId = chatDao.getAllChatJustSoICanSeeMaxPrimaryKey();
    }
  1. ChatRepository对外暴露联系人LiveData的方法
public LiveData<List<UserContacts>> getAllContacts()
    {
        return allContacts;
    }
  1. UserContactsDao中查询联系人的DAO定义
@Query("SELECT * FROM UserContacts ORDER BY priority DESC")
    LiveData<List<UserContacts>> getAllContacts();
问题排查方向
  • 代码逻辑bug校验:消息Activity的观察回调内循环从i=1开始取值、循环终止条件为i <= userContacts.size(),存在数组越界风险(List索引从0开始,当i等于集合大小时直接取值会抛出IndexOutOfBoundsException),需要先修正循环范围为i=0; i < userContacts.size()。
  • ViewModel作用域校验:当前代码中ViewModelProvider的第一个参数传入的是当前Activity实例,两个Activity会分别从各自的ViewModelStore中获取独立的ChatViewModel实例,并非全局共享。虽然Room生成的LiveData支持多观察者同时观察,但需要确认观察注册时Activity是否处于活跃状态、是否有前置代码抛出异常导致observe()调用未执行到。
  • 前置变量校验:确认消息Activity中用于匹配联系人的id变量是否正确从Intent中获取,避免空值、类型不匹配导致的前置逻辑崩溃,阻断观察逻辑的注册流程。
  • 数据源单例校验:确认Room数据库实例、DAO实例、Repository层持有的LiveData引用均为单例,避免因为多实例初始化导致的LiveData绑定异常,无法向观察者推送数据。

内容的提问来源于stack exchange,提问作者M.Ahmed

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.26 16:36:05