Kotlin:Dagger2 @Inject context var始终为空
我正在尝试在AndroidStudio中与Android没有连接的模块,它没有任何活动,但我需要上下文像房间数据库的几件事情。
这是我的设置:
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
interface AppLifecycleCallbacks { fun onCreate(application: Application) fun onTerminate(application: Application) }
应用
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中
<?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>
而我尝试注入上下文到我的主类是这样的:
class LogNexoManager(app: Application){ var logRepository: LogRepository init { logRepository = LogRepositoryImpl(app) } }
抽样单元测试总是假的
@Test fun proceedWithLogs(){ val logManager = LogManager() }
而例外是:
kotlin.UninitializedPropertyAccessException:lateinit属性应用程序尚未初始化
更新:我做了@Emanuel S提出的更改,现在我有一个错误:
错误:任务':nexo:kaptDebugKotlin'的执行失败。 内部编译器错误。 查看日志了解更多详情
我的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() }
这是一个简单的测试用例。 没有测试,但应该显示你应该如何注入你的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) }
应用程序生命周期的界面。
interface AppLifecycleCallbacks { fun onCreate(application: Application) fun onTerminate(application: Application) }
你的应用程序应该扩展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() } }
最后你有一个提供的LogManager。
class LogManager (val app: App)
如果你真的想在你的LogManager中使用@Inject,你可以使用fun inject(logManager: LogManager)
将它注入到你的AppComponent中。
生命周期界面用于自动注入活动/服务,以备日后扩展。 例:
应用程序入口类
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 ... })
请注意,您需要在您的Gradle中使用dagger-android-support的依赖,才能拥有AndroidSupportInjectionModule。
implementation "com.google.dagger:dagger-android-support:2.11-rc2" // version may be not up 2 date later.