Android开发:Bundle传递数据至Fragment时arguments为null,数据在哪一环节丢失?
问题分析与解决方案
你的核心问题很明确:你只是创建了Bundle对象,但从未将这个Bundle关联到OnboardingFragment的实例上。Fragment的arguments属性不会自动填充,必须在Fragment实例化时显式设置,否则它永远是null。
为什么当前代码失效?
在第一个ViewModel的sendData方法里,你调用了OnboardingViewModel.newBundle(it)生成了Bundle,但这个Bundle只是一个孤立的对象,没有和任何Fragment绑定。OnboardingFragment初始化时没有收到这个Bundle,所以它的arguments自然是null。
修复步骤与代码示例
1. 给OnboardingFragment添加带参数的实例创建方法
我们需要在Fragment中新增一个静态方法,用来生成带参数的Fragment实例,同时把Bundle设置给它的arguments:
class OnboardingFragment : Fragment(), ViewPager.OnPageChangeListener, View.OnClickListener { // 新增静态方法,创建带参数的Fragment实例 companion object { fun newInstance(configuration: ConfigurationDto): OnboardingFragment { return OnboardingFragment().apply { // 将生成的Bundle设置给Fragment的arguments arguments = OnboardingViewModel.newBundle(configuration) } } } private fun setupViewModel() { viewModel = ViewModelProvider(this, viewModelFactory).get(OnboardingViewModel::class.java) lifecycle.addObserver(viewModel) // 现在arguments应该能正常获取到值了 Log.d("some", "arguments in vm: $arguments") viewModel.setInitialData(arguments) } // 你的其他原有代码... }
2. 修改第一个ViewModel的sendData方法,创建带参数的Fragment并跳转
原来的代码只生成了Bundle,现在需要改为创建带参数的Fragment实例,然后执行页面跳转/替换操作:
fun sendData(it: ConfigurationDto?) { Log.d("some", "sendData : $it") if (it != null) { // 创建带参数的OnboardingFragment实例 val onboardingFragment = OnboardingFragment.newInstance(it) // 这里根据你的页面导航方式执行跳转,比如用FragmentManager替换容器 // 示例(需要替换成你的容器ID): (context as? FragmentActivity)?.supportFragmentManager?.beginTransaction() ?.replace(R.id.your_fragment_container_id, onboardingFragment) ?.addToBackStack(null) // 可选,加入回退栈 ?.commit() } }
3. 确认ConfigurationDto的序列化正确性
确保你的ConfigurationDto确实实现了Serializable接口,否则Bundle无法正确序列化/反序列化数据:
data class ConfigurationDto(/* 你的字段 */) : Serializable
额外提示
如果你的项目使用了Navigation组件,也可以通过navArgs()来更安全地获取参数,避免直接操作arguments,但核心逻辑还是要确保Fragment在创建时携带了正确的Bundle参数。
内容的提问来源于stack exchange,提问作者Morozov




