javaandroiddependency-injectiondagger-2generated-code

How to use Dagger in Java library module in Android Studio?


I'm using Dagger in a Java library module in an Android Studio project and here's what my build.gradle for the module looks like:

apply plugin: 'java-library'

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])

    implementation 'com.google.dagger:dagger:2.24'
    annotationProcessor 'com.google.dagger:dagger-compiler:2.24'
}

sourceCompatibility = "7"
targetCompatibility = "7"

I can see that the Dagger is properly generating implementations and they are present in build/generated/sources/annotationProcessor but for some reason I cannot access them in the code. Also, the generated files shows an error at the package statement that states:

Package name "com.example.javamodule" does not correspond to the file path "java.main.com.example.javamodule"

I have two questions here. First, how can I access the Dagger generated classes in my java module code and second, how to remove the above-mentioned error from the generated classes?


Solution

  • In your java library's gradle file:

    plugins {
        id 'java-library'
        id 'kotlin'
        id 'kotlin-kapt'
    }
    
    java {
        sourceCompatibility = JavaVersion.VERSION_1_7
        targetCompatibility = JavaVersion.VERSION_1_7
    }
    
    dependencies {
        implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    
        //Dependency injection
        implementation 'com.google.dagger:dagger:2.27'
        kapt 'com.google.dagger:dagger-compiler:2.24'
    }
    

    Then create a class and its dependencies:

    class First
    @Inject
    constructor(
        private val second: Second,
        private val third: Third
    ) {
        fun firstFunction() {
            print(second.secondMessage())
            print(third.name)
        }
    }
    
    class Second(
        private val name: String
    ) {
        fun secondMessage(): String {
            return name
        }
    }
    
    class Third(
        val name: String
    )
    

    Then create your dagger module:

    @Module
    class ModuleUtil {
    
        @Provides
        fun providesSecond(): Second {
            return Second("second")
        }
    
        @Provides
        fun providesThird(): Third {
            return Third("third")
        }
    
    }
    

    Then create your dagger component:

    @Singleton
    @Component(modules = [
        ModuleUtil::class
    ])
    interface MainComponent {
    
        fun maker(): First
    
    }
    

    An object to handle the generated component:

    object DaggerWrapper {
    
        lateinit var mainComponent: MainComponent
    
        fun initComponent() {
            mainComponent = DaggerMainComponent
                .builder()
                .build()
        }
    
    }
    

    And finally in your app android module(eg. inside an Activity):

    DaggerWrapper.initComponent()
                val mainComponent = DaggerWrapper.mainComponent
                val first = mainComponent.maker()
                first.firstFunction()