2017-10-11 38 views
0

我正在嘗試在AndroidStudio中與Android沒有連接的模塊,它沒有任何活動,但是我需要上下文來處理房間數據庫等幾件事情。Kotlin:Dagger2 @Inject context var始終爲空

這裏是我的設置:

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 property app has not been initialized

UPDATE: 我做的@Emanuel小號提出的修改,現在我有這樣一個錯誤:

Error:Execution failed for task ':nexo:kaptDebugKotlin'. Internal compiler error. See log for more details

我的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() 
} 
+0

這應該修復'var app:Application? = null' –

+0

爲什麼不使用構造函數來聲明所需的依賴關係? –

+0

但我如何注入上下文來測試?一樣的方法? – Konrad

回答

2

這裏有一個簡單的測試案例。未經測試,但應顯示您應如何注入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)  

如果你真的想使用@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這個匕首的Android支持的依賴性有AndroidSupportInjectionModule。

implementation "com.google.dagger:dagger-android-support:2.11-rc2" // version may be not up 2 date later. 
+0

謝謝,但現在當我嘗試構建我有一個錯誤,如:建議:添加'tools:replace =「android:name」'到AndroidManifest.xml中的元素:24:5-99:19重寫。你能幫我嗎?我會接受你的答案,如果它能工作 – Konrad

+0

此外,編譯器強調。應用程序(這),並說「未解決的參考:應用程序」 – Konrad

+0

首先,我建議你使用不同的名稱,然後「應用程序」。類似YourCoolApp的擴展DaggerApplication()會很棒。第二,你需要在清單中的中使用完整路徑作爲名稱,如android:name =「。com.yourpackage.YourCoolApp」。它說尚未解決,因爲它尚未生成(必須有一個工作版本第一) –