Dagger-Android库:如何为非Activity/Fragment类提供Application Context
如何在Dagger Android中为非Activity/Fragment类提供Context
嘿,我完全懂你现在的困惑——用了Dagger Android的新写法后,想给非Activity/Fragment的普通类注入Context确实容易摸不着头脑。我之前也踩过类似的坑,下面给你一步步拆解怎么实现:
假设你的目标普通类是这样的(比如叫SampleClass):
class SampleClass @Inject constructor(private val context: Context) { // 这里可以用Context做你需要的操作,比如访问资源、操作SharedPreferences等 fun doSomething() { val sharedPref = context.getSharedPreferences("my_prefs", Context.MODE_PRIVATE) // ... 你的业务逻辑 } }
步骤1:确保Application层的Dagger配置到位
首先得确认你的App类已经正确实现了HasAndroidInjector,这是Dagger Android的基础配置:
class MyApp : Application(), HasAndroidInjector { @Inject lateinit var androidInjector: DispatchingAndroidInjector<Any> override fun onCreate() { super.onCreate() DaggerAppComponent.factory().create(this).inject(this) } override fun androidInjector(): AndroidInjector<Any> = androidInjector }
步骤2:根据类的生命周期选择Context来源
情况1:类和某个Activity绑定(用Activity Context)
如果你的SampleClass只在某个Activity里使用,那就在该Activity的Dagger模块中提供Context:
@Module abstract class MainActivityModule { @ContributesAndroidInjector abstract fun contributeMainActivity(): MainActivity // 提供当前Activity的Context @Provides fun provideActivityContext(activity: MainActivity): Context = activity }
这里要注意:Activity Context的生命周期和Activity绑定,如果SampleClass的生命周期比Activity长,会有内存泄漏风险,这种情况建议用Application Context。
情况2:类是全局可用的(用Application Context)
如果你的类需要在整个App中复用,就在App级别的模块里提供Application Context:
@Module class AppModule { @Provides fun provideApplicationContext(application: Application): Context = application } // 对应的AppComponent @Component(modules = [AndroidInjectionModule::class, AppModule::class]) interface AppComponent { fun inject(app: MyApp) @Component.Factory interface Factory { fun create(@BindsInstance application: Application): AppComponent } }
步骤3:在目标位置注入你的普通类
现在你可以在需要使用SampleClass的地方直接注入了,比如在Activity里:
class MainActivity : AppCompatActivity() { @Inject lateinit var sampleClass: SampleClass override fun onCreate(savedInstanceState: Bundle?) { AndroidInjection.inject(this) // 别忘这一步,初始化Dagger注入 super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // 现在就能正常使用带Context的SampleClass了 sampleClass.doSomething() } }
额外注意点
- 如果你用的是构造注入(就像上面的
SampleClass那样用@Inject标注构造函数),只要Dagger组件能扫描到这个类的包,就不需要额外写@Provides方法,Dagger会自动识别构造函数的依赖。 - 一定要区分Activity Context和Application Context的使用场景:如果你的类需要持有Context的时间超过Activity的生命周期,必须用Application Context,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Damn Vegetables
相关产品推荐
相关产品推荐

