使用Hilt注入Fragment的正确性咨询:实例安全与注解疑问
Hilt使用问题解答
问题1:让Hilt管理MainFragment实例是否安全?屏幕旋转时会出现什么情况?
这种做法不安全,会引发生命周期不一致的问题:
- Hilt注入的
mainFragment是由Hilt容器创建的实例,但Fragment的生命周期实际由FragmentManager管控。当屏幕旋转时,Activity会重建,Hilt会生成一个全新的MainFragment实例,但此时savedInstanceState != null,你的代码不会执行replace操作,界面上显示的是FragmentManager恢复的旧Fragment实例——这就导致Hilt持有的实例和界面上的实例完全脱节,后续如果操作这个注入的实例会引发各种异常。 - Fragment的实例化和状态恢复是Android系统的核心机制,直接让Hilt注入Fragment实例会绕过这个机制,破坏Fragment的生命周期一致性,属于错误用法。
问题2:由于该Fragment是动态注入到MainActivity中的,它是否不需要标注@AndroidEntryPoint?
必须给MainFragment标注@AndroidEntryPoint。原因是:
- 只要Fragment内部使用
@Inject注入依赖(比如你的someDependency),就需要@AndroidEntryPoint来让Hilt为该Fragment生成依赖注入的代理类,否则Hilt无法完成内部依赖的注入,运行时会抛出注入失败的异常。 @AndroidEntryPoint的作用是标记Android组件作为Hilt的注入入口,和组件是被直接启动还是被其他组件创建无关,只要内部有依赖注入需求就必须添加。
修正后的正确代码
MainActivity
@AndroidEntryPoint class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.main_activity) if (savedInstanceState == null) { supportFragmentManager.beginTransaction() .replace(R.id.container, MainFragment()) .commitNow() } } }
MainFragment
@AndroidEntryPoint class MainFragment @Inject constructor() : Fragment() { @Inject lateinit var someDependency: SomeDependency // 你的onCreateView、onViewCreated等生命周期方法 }
这样修改后,FragmentManager会正确管理Fragment的实例和生命周期,屏幕旋转时能正常恢复状态,同时Hilt也能完成Fragment内部的依赖注入。
内容的提问来源于stack exchange,提问作者mtw
相关产品推荐
相关产品推荐

