[英]Android + Kotlin + Hilt: Cannot @Inject in a non activity class
我最近开始学习 Hilt,现在它让我头疼多于快乐,但我喜欢挑战,所以让我们 go 进入正题。
我在理解如何注入非活动类时遇到很多问题,例如注入上下文或任何其他 class。
到目前为止,我的大部分非活动类都是对象(单例),但由于我无法注入 object,所以我决定将它们转换为类。
我正在尝试使用字段注入进行注入,因为如果我将构造函数注入与@AndroidEntryPoint一起使用,它会抱怨 class 必须继承自 AppCompatActivity 左右...
让我们举一个简单的例子来说明我的问题。
我的应用程序是一个多模块应用程序,我在“通用”模块中有一个 AWFile class(可从所有其他模块访问 [我说的是 Gradle 模块,现在不是 Hilt 模块]),它执行文件操作,因此开始测试使用 Hilt 注入我创建了一个方法doSomething并且在doSomething中我试图访问appSettings ,一个 class 我持有通过字段注入注入的所有应用程序配置,但即使应用程序构建良好我总是得到 null -实际上是一个错误-在字段中(我也不确定如何获取上下文)。
AW应用:
@HiltAndroidApp
class AWApplication : MultiDexApplication() {
}
文件:
class AWFile @Inject constructor() {
@Inject
lateinit var app: AppSettings
@Inject
lateinit var context: Context
fun doSomething(){
var color = app.actionBarEndColor
var ctx = context
}
...
}
依赖项(在应用程序模块中):
@Module
@InstallIn(SingletonComponent::class)
class Dependencies {
@Provides
@ApplicationContext
fun provideContext(@ApplicationContext appContext: Context): Context {
return appContext
}
}
“通用”项目模块中的依赖项:
@Module
@InstallIn(SingletonComponent::class)
class Dependencies {
@ApplicationContext
lateinit var appContext: Context
@Provides
@Singleton
fun bindsAppSettings(): AppSettings {
return AppSettings()
}
@Provides
@Singleton
fun bindsAWFile(): AWFile {
return AWFile()
}
}
主要活动:
@AndroidEntryPoint
class MainActivity : FragmentActivity() {
@Inject
lateinit var awFile: AWFile
@Inject
lateinit var app: AppSettings
override fun onCreate(savedInstanceState: Bundle?) {
requestWindowFeature(Window.FEATURE_CUSTOM_TITLE)
super.onCreate(savedInstanceState)
awFile.doSomething()
}
调试到 AWFile > doSomething 时的错误:
kotlin.UninitializedPropertyAccessException: lateinit property app has not been initialized (the same for context)
编辑 1:尝试按照 @CommonsWare 的建议在 AWFile 中进行构造函数注入(而不是字段注入)。
AW文件声明:
class AWFile @Inject constructor(private var app: AppSettings, private var context: Context)
“通用”模块 > 依赖项:
@Module
@InstallIn(SingletonComponent::class)
class Dependencies {
@ApplicationContext
lateinit var appContext: Context
@Provides
@Singleton
fun bindsAppSettings(): AppSettings {
return AppSettings()
}
@Provides
@Singleton
fun bindsAWFile(): AWFile {
return AWFile()
}
}
结果:
该应用程序不构建。 它抱怨在 bindsAWFile() > AWFile(我用来提供 AWFile 的方法)中没有为应用程序传递参数,我不知道如何传递它:s
编辑 2:仍然遵循@CommonsWare 的建议。
依赖项:
@Module
@InstallIn(SingletonComponent::class)
class Dependencies {
@ApplicationContext
lateinit var appContext: Context
@Provides
@Singleton
fun bindsAppSettings(): AppSettings {
return AppSettings()
}
@Provides
@Singleton
fun bindsAWFile(appSettings: AppSettings): AWFile {
return AWFile(appSettings, appContext)
}
}
结果:
...Caused by: kotlin.UninitializedPropertyAccessException: lateinit property appContext has not been initialized
at dependencies.Dependencies.getAppContext(Dependencies.kt:18)...
编辑 3:已解决。
应用程序依赖项 class:
@Module
@InstallIn(SingletonComponent::class)
class Dependencies {
@Provides
@Singleton
fun provideContext(@ApplicationContext appContext: Context): Context {
return appContext
}
}
“公共”模块依赖关系 class:
@Module
@InstallIn(SingletonComponent::class)
class Dependencies {
@Provides
@Singleton
fun bindsAppSettings(): AppSettings {
return AppSettings()
}
@Provides
@Singleton
fun bindsAWFile(appSettings: AppSettings, context: Context): AWFile {
return AWFile(appSettings, context)
}
}
现在它正在运行,关键是首先在应用程序依赖项模块中提供上下文,其次将 appSettings 和上下文作为参数包含到 bindsAWFile 方法声明中,然后按照@CommonsWare 的建议将其传递给 AWFile。
Hilt 是一场噩梦,但感谢您花时间@CommonsWare。
好的,经过几个小时的努力,我得到了解决方案。
应用程序依赖项 class:
@Module
@InstallIn(SingletonComponent::class)
class Dependencies {
@Provides
@Singleton
fun provideContext(@ApplicationContext appContext: Context): Context {
return appContext
}
}
“公共”模块依赖关系 class:
@Module
@InstallIn(SingletonComponent::class)
class Dependencies {
@Provides
@Singleton
fun bindsAppSettings(): AppSettings {
return AppSettings()
}
@Provides
@Singleton
fun bindsAWFile(appSettings: AppSettings, context: Context): AWFile {
return AWFile(appSettings, context)
}
}
代码rest保持不变。
现在它正在运行,关键是首先在应用程序依赖项模块中提供上下文,其次将 AppSettings 和上下文作为参数包含到 bindsAWFile 方法声明中,然后按照@CommonsWare 的建议将其传递给 AWFile。
注意@ApplicationContext的重要性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.