Hilt中Activity Context、Activity与Activity Scoped注入的疑问解析
Hilt库相关技术问题与解答
技术问题
- 在良好设计模式中,为何应注入Context而非Activity对象?
- 仅标注@ActivityContext是否足够,还是需同时指定@ActivityScoped注解?
- 若仅给PermissionHelper添加@ActivityScoped却遗漏@ActivityContext,Hilt/Dagger会自动处理依赖作用域吗?是否需明确告知Hilt该Context为Activity Context并与注入的Activity绑定?
- Dagger是否允许像Menu类这样混合作用域?比如@ActivityScoped的类依赖@Singleton的对象?
相关代码示例
无作用域标注的PermissionHelper
该对象与注入的Activity绑定,Activity重建时会生成新实例,且使用Activity Context,生命周期与Activity一致
public class PermissionHelper { private final Context mActivity; @Inject public PermissionHelper(@ActivityContext Context activity) { this.mActivity = activity; } }
标注@ActivityScoped但未加@ActivityContext的PermissionHelper
该对象与注入的Activity绑定,Activity重建时复用实例,但未添加@ActivityContext,需确认Hilt能否自动识别Context类型
@ActivityScoped public class PermissionHelper { private final Context mActivity; @Inject public PermissionHelper(Context activity) { this.mActivity = activity; } }
跨作用域依赖的Menu类示例
Menu类为@ActivityScoped,依赖@Singleton的SharedPref,验证Dagger是否允许此类跨作用域依赖
@ActivityScoped public class Menuu extends BaseObservablee<Menuu.ListenerMenu> { @Inject public Menuu(Context context, SharedPref sharedPreferences) { applicationcontext = context; this.sharedPref = sharedPreferences; } }
验证后的解答
- 问题1解答:注入Context而非Activity是为了遵循依赖注入的核心目标——解耦。直接注入Activity会让下层组件与具体的Activity类强绑定,不利于维护和复用;而注入Context既能提供LayoutInflater、Activity级上下文等所需能力,又能避免在领域层等下层代码中直接依赖UI层的Activity类。
- 问题2解答:仅标注@ActivityContext是不够的。@ActivityContext的作用是告诉Hilt注入的是Activity级别的Context,而非应用级Context;但如果需要让这个依赖的生命周期与Activity绑定(比如重建时复用实例),还需同时添加@ActivityScoped注解,明确其作用域。
- 问题3解答:需要同时兼顾Activity作用域和Activity Context。@ActivityScoped能确保依赖随Activity的创建和销毁而生命周期绑定,避免内存泄漏;但如果不添加@ActivityContext,Hilt无法自动识别要注入的是Activity Context,可能会注入应用级Context,导致依赖无法感知当前Activity的生命周期。因此必须明确标注@ActivityContext,让Hilt将该Context与注入的Activity绑定。
- 问题4解答:Dagger允许这种跨作用域的依赖。@ActivityScoped的组件依赖@Singleton的对象是完全合法的——窄作用域(Activity级)的组件可以依赖宽作用域(应用级)的组件,因为宽作用域的实例生命周期更长,能被窄作用域组件安全复用。另外,若类未指定作用域,Hilt会根据其依赖的作用域来管理实例:如果依赖了@Singleton的对象,该类的实例若未指定自身作用域,会被当作无作用域对象,每次注入都会生成新实例,但依赖的@Singleton对象会在应用生命周期内共享。
内容的提问来源于stack exchange,提问作者Nadin Martini
相关产品推荐
相关产品推荐

