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

ViewPager2+TabLayout下Hilt Fragment onAttach多次调用崩溃问题解决

ViewPager2 + Hilt Fragment 二次重载崩溃解决方案

崩溃信息

java.lang.IllegalStateException: onAttach called multiple times with different Context! Hilt Fragments should not be retained.

问题根源

代码中ResourceStore提前创建并缓存了所有DashboardNew Fragment实例,FragmentStateAdapter的createFragment方法直接返回这些缓存的旧实例。当宿主TabLayoutDemo Fragment重建时,ViewPager2尝试将旧Fragment实例重新绑定到新的Context上,但Hilt绑定的Fragment不允许重复关联不同Context——Hilt已为旧实例注入了与旧Context绑定的依赖,重复attach会导致上下文冲突,触发崩溃。

修复步骤

1. 修改FragmentStateAdapter的createFragment方法

不再复用提前创建的Fragment实例,每次调用createFragment时生成新实例:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    binding.viewpager.adapter = object : FragmentStateAdapter(this) {
        override fun createFragment(position: Int): Fragment {
            // 每次创建新的Fragment实例,避免复用缓存的旧实例
            return DashboardNew.create()
        }

        override fun getItemCount(): Int {
            return ResourceStore.tabList.size
        }
    }

    TabLayoutMediator(binding.tabs, binding.viewpager) { tab, position ->
        tab.text = getString(ResourceStore.tabList[position])
    }.attach()
}

2. 移除缓存的Fragment实例列表

删除ResourceStore中提前创建的pagerFragments,Fragment实例由FragmentStateAdapter按需创建即可:

interface ResourceStore {
    companion object {
        val tabList = listOf(
            R.string.Dashboard, R.string.Tracking, R.string.Fastags,R.string.Reports, R.string.Documents, R.string.Maintance, R.string.Alerts, R.string.Device
        )
    }
}

额外注意事项

确保DashboardNew Fragment没有设置setRetainInstance(true),Hilt官方明确禁止保留Hilt Fragment实例,这也是错误提示中强调的核心限制。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 23:21:07