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

ViewModel的MutableLiveData赋值后Data Binding显示null如何解决

问题原因
  • 核心问题:默认情况下,by viewModels()生成的ViewModel实例作用域和当前所属Activity绑定,你在两个不同的Activity中各初始化了一次LockDetailsModel,拿到的是两个完全独立的实例。你在LockActivity中给name赋值的操作只作用于该页面对应的ViewModel实例,第二个展示页面拿到的是全新的未赋值的实例,所以name的值为null。
  • 其他可能排查点:若已确保ViewModel是同一个实例仍出现null,可检查布局文件中是否正确声明了绑定变量、绑定表达式是否书写正确,比如是否漏写了@{lockDetails.name}。
解决方案

根据你的业务场景选择对应的方案即可:

场景1:仅需要传递单次数值,无需跨页面同步更新

直接通过Intent携带参数传递即可,无需共享ViewModel:

  1. 在LockActivity跳转时添加参数:
val intent = Intent(this, ConnectLockActivity::class.java)
intent.putExtra("unit_name", unitName.toString())
startActivity(intent)
  1. 在展示页面的Activity中拿到参数后赋值给ViewModel:
val viewModel: LockDetailsModel by viewModels()
val unitName = intent.getStringExtra("unit_name").orEmpty()
viewModel.setName(unitName)
// 原有绑定逻辑保持不变
val binding: ActivityConnectLockBinding = DataBindingUtil.setContentView(this, R.layout.activity_connect_lock)
binding.lockDetails = viewModel
binding.lifecycleOwner = this

场景2:需要跨页面同步更新name数据

建议调整为单Activity多Fragment的架构,两个页面均作为Fragment存在,此时通过by activityViewModels()获取的ViewModel会绑定到宿主Activity的作用域,两个Fragment拿到的是同一个实例,可以正常共享数据:

// Fragment中获取共享ViewModel的方式
val viewModel: LockDetailsModel by activityViewModels()

如果必须保留双Activity的架构,可以自定义作用域到Application的ViewModelStore,实现全局共享ViewModel(不推荐,会导致ViewModel的生命周期过长,内存泄漏风险升高)。

额外优化建议

可以给LiveData设置初始默认值,避免空值展示:

// 修改ViewModel中的name声明,设置初始空字符串
var name = MutableLiveData<String>("")

内容的提问来源于stack exchange,提问作者mengmeng

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 06:27:02