[英]Kotlin: Dagger2 @Inject context var is always null
I am trying to to do module in AndroidStudio which is not connected with Android, it has no Activities, but i need Context for several things like Room database. 我正在尝试在未与Android连接的AndroidStudio中执行模块,它没有活动,但是我需要使用Context作为Room数据库之类的几件事。
Here is my setup: 这是我的设置:
AppComponent AppComponent
@Singleton
@Component(modules = arrayOf(AndroidSupportInjectionModule::class, AppModule::class))
interface AppComponent : AndroidInjector<NexoApplication> {
@Component.Builder
interface Builder {
@BindsInstance
fun application(application: NexoApplication): Builder
fun build(): AppComponent
}
override fun inject(app: NexoApplication)
}
AppModule 应用模块
@Module
class AppModule {
@Singleton @Provides
fun provideLogger(application: NexoApplication) = LogNexoManager(application)
}
AppLifecycleCallbacks AppLifecycleCallbacks
interface AppLifecycleCallbacks {
fun onCreate(application: Application)
fun onTerminate(application: Application)
}
App 应用程式
class NexoApplication: DaggerApplication() {
@Inject lateinit var appLifecycleCallbacks: AppLifecycleCallbacks
override fun applicationInjector() = DaggerAppComponent.builder()
.application(this)
.build()
override fun onCreate() {
super.onCreate()
appLifecycleCallbacks.onCreate(this)
}
override fun onTerminate() {
appLifecycleCallbacks.onTerminate(this)
super.onTerminate()
}
}
AndroidManifest.xml AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.elstatgroup.elstat">
<application
android:name="com.elstatgroup.elstat.NexoApplication"
android:allowBackup="true"
android:label="@string/app_name"
android:supportsRtl="true">
</application>
And i try to inject context to my main class like this: 我尝试将上下文注入我的主类,如下所示:
class LogNexoManager(app: Application){
var logRepository: LogRepository
init {
logRepository = LogRepositoryImpl(app)
}
}
Sample unit test is always false 样品单元测试始终为假
@Test
fun proceedWithLogs(){
val logManager = LogManager()
}
And the exception is: 唯一的例外是:
kotlin.UninitializedPropertyAccessException: lateinit property app has not been initialized
kotlin.UninitializedPropertyAccessException:lateinit属性应用尚未初始化
UPDATE: I made the changes proposed by @Emanuel S and now i have an error like: 更新:我进行了@Emanuel S提出的更改,现在出现类似以下错误:
Error:Execution failed for task ':nexo:kaptDebugKotlin'.
错误:任务':nexo:kaptDebugKotlin'的执行失败。 Internal compiler error.
内部编译器错误。 See log for more details
请参阅日志以获取更多详细信息
My Build.gradle file is: 我的Build.gradle文件是:
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
android {
compileSdkVersion 26
defaultConfig {
minSdkVersion 15
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
} }
ext.daggerVersion = '2.11'
ext.roomVersion = '1.0.0-alpha9'
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:26.1.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation('com.android.support.test.espresso:espresso-core:3.0.1', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
// RxJava
implementation 'io.reactivex.rxjava2:rxjava:2.1.0'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
// Room
implementation "android.arch.persistence.room:runtime:$roomVersion"
implementation "android.arch.persistence.room:rxjava2:$roomVersion"
kapt "android.arch.persistence.room:compiler:$roomVersion"
compile "org.jetbrains.kotlin:kotlin-stdlib:1.1.51"
androidTestImplementation "android.arch.persistence.room:testing:$roomVersion"
compile "com.google.dagger:dagger:$daggerVersion"
compile "com.google.dagger:dagger-android:$daggerVersion"
compile "com.google.dagger:dagger-android-support:$daggerVersion"
kapt "com.google.dagger:dagger-android-processor:$daggerVersion"
kapt "com.google.dagger:dagger-compiler:$daggerVersion"
implementation "com.google.dagger:dagger-android-support:2.11-rc2" // version may be not up 2 date later.
}
repositories {
mavenCentral()
}
Here's a simple test case. 这是一个简单的测试用例。 Not tested but should show the concept how you should inject into your LogManager.
未测试,但应显示出如何将其注入LogManager的概念。
@Singleton
@Component(modules = arrayOf(AndroidSupportInjectionModule::class, AppModule::class))
interface AppComponent : AndroidInjector<App> { {
@Component.Builder
interface Builder {
@BindsInstance
fun application(application: App): Builder
fun build(): AppComponent
}
override fun inject(app: App)
}
@Module
class AppModule {
@Singleton @Provides
fun provideYourDb(application: App) = Room.databaseBuilder(application, YourDb::class.java, "your.db").build()
@Singleton @Provides
fun provideLogger(application: App) = LogManager(application)
}
An interface for the Apps lifecycle. Apps生命周期的界面。
interface AppLifecycleCallbacks {
fun onCreate(application: Application)
fun onTerminate(application: Application)
}
Your application should extend DaggerApplication(). 您的应用程序应扩展DaggerApplication()。
class App:DaggerApplication() {
@Inject lateinit var appLifecycleCallbacks: AppLifecycleCallbacks
override fun applicationInjector() = DaggerAppComponent.builder()
.application(this)
.build()
override fun onCreate() {
super.onCreate()
appLifecycleCallbacks.onCreate(this)
}
override fun onTerminate() {
appLifecycleCallbacks.onTerminate(this)
super.onTerminate()
}
}
finally you have a provided LogManager. 最后,您提供了LogManager。
class LogManager (val app: App)
If you really want to use @Inject inside your LogManager you can inject it inside your AppComponent using fun inject(logManager: LogManager)
. 如果您确实想在LogManager中使用@Inject,则可以使用
fun inject(logManager: LogManager)
将其fun inject(logManager: LogManager)
。
The lifecycle interface is used for auto injection of activities/services in case you want to extend it later. 生命周期界面用于活动/服务的自动注入,以备将来扩展时使用。 Example:
例:
App entry class 应用程式入门课程
override fun onCreate() {
super.onCreate()
applyAutoInjector()
appLifecycleCallbacks.onCreate(this)
}
fun Application.applyAutoInjector() = registerActivityLifecycleCallbacks(
object : Application.ActivityLifecycleCallbacks {
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
handleActivity(activity)
}
//truncated ...
})
Take care that you need the dependencies for dagger-android-support in your gradle to have AndroidSupportInjectionModule. 请注意,您的gradle中需要dagger-android-support的依赖项才能拥有AndroidSupportInjectionModule。
implementation "com.google.dagger:dagger-android-support:2.11-rc2" // version may be not up 2 date later.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.