2017-10-11 6 views
0

私はAndroidに接続されていないAndroidStudioでモジュールをやろうとしていますが、アクティビティはありませんが、ルームデータベースのようなものがいくつかあります。ここで 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) 
} 

の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

<?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 Sによって提案された変更を行い、今私のようなエラーが発生しています:

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) 
} 

Appsライフサイクルのインターフェイスです。

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内側に注入することができます。

ライフサイクルインタフェースは、後で拡張する場合に備えて、アクティビティ/サービスの自動挿入に使用されます。例:

のAppエントリークラス

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 ... 
     }) 

あなたはAndroidSupportInjectionModuleを持っているあなたのGradleで短剣・アンドロイド・サポートのための依存関係を必要とするように注意してください。

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

ありがとうございましたが、ビルドしようとすると、次のようなエラーが表示されます。提案:AndroidManifest.xml:24:5-99:19の要素に 'tools:replace = "android:name"手伝ってくれますか? – Konrad

+0

コンパイラのアンダーライン.application(this)と "unresolved reference:application"と書かれています – Konrad

+0

まず「App」という別の名前を使用することをお勧めします。 YourCoolAppのようなものはDaggerApplication()を拡張して素晴らしいものになりました。次に、アンドロイドのようなあなたのマニフェストのあなたの<アプリケーション内であなたの名前のフルパスを使用する必要があります:name = "。com.yourpackage.YourCoolApp"。それは未解決だと言われています(最初に作業ビルドが必要です) –

関連する問題