3

I'm a Dagger newb and have a trouble with using it.

What I want to develop is that using RxAndroidBle and to initialize it by Dagger for providing Context.

So I researched how it can be implemented, and I wrote some codes and It seems to be working for me but not working at all.

The followings are my codes.

AppComponent.kt

@Singleton
@Component(modules = [
    AppModule::class,
    BluetoothModule::class,
    AndroidInjectionModule::class])
interface AppComponent : AndroidInjector<BluetoothController> {

    @Component.Builder
    interface Builder {

        @BindsInstance
        fun application(app: Application): Builder

        fun build(): AppComponent
    }
}

AppModule.kt

@Module
class AppModule {

    @Provides
    @Named("appContext")
    @Singleton
    fun provideContext(application: Application): Context =
            application.applicationContext
}

BluetoothModule.kt

@Module
class BluetoothModule {

    @Provides
    @Named("rxBleClient")
    @Singleton
    fun provideRxBleClient(@Named("appContext") context: Context):RxBleClient =
            RxBleClient.create(context)
}

BluetoothController.kt for injecting by DaggerApplication.

class BluetoothController : DaggerApplication() {

    override fun applicationInjector(): AndroidInjector<out DaggerApplication> {
        return DaggerAppComponent.builder().application(this).build()
    }
}

I've inserted android:name".BluetoothController" to AndroidManifest.xml

And this is how I would use it.

@field:[Inject Named("rxBleClient")]
lateinit var rxBleClient: RxBleClient

But it always occurs an error says: lateinit property context has not been initialized

What things I've missed? Can anyone help me?

Thanks in advance.

Awesometic
  • 33
  • 5

2 Answers2

2

Add the below code to make this happen.

  1. Create ActivityBuilderModule for injecting within the activity. Consider our activity as MainActivity

    @Module
    abstract class ActivityBuilderModule {
         @ContributesAndroidInjector(modules=[MainActivityModule::class])
         abstract fun contributeSplashActivity(): MainActivity
    }
    
  2. Create your MainActivityModule

    @Module
    class MainActivityModule{
         @Provides()
         fun contributeSplashActivity(mainActivity: MainActivity): 
            MainActivity=mainActivity
     }
    
  3. Modify your component.

    @Singleton
    @Component(modules = [
    AppModule::class,
    BluetoothModule::class,
    ActivityBuilderModule::class,
    AndroidInjectionModule::class])
    interface AppComponent : AndroidInjector<BluetoothController> {
    
        @Component.Builder
        interface Builder {
    
            @BindsInstance
            fun application(app: Application): Builder
    
            fun build(): AppComponent
        }
    }
    
  4. Within MainActivity just inject.

    class MainActivity{
          ...
          @Inject
          lateinit var rxBleClient: RxBleClient
          override fun onCreate(savedInstanceState: Bundle?) {
    
            AndroidInjection.inject(this)
            super.onCreate(savedInstanceState)
          }
    }
    

Let us know in case of any issue.

Nitesh Tiwari
  • 4,742
  • 3
  • 28
  • 46
0

the context object is not initialized before its called

Though i dont know, how chained your initialization are.

Use @Inject to add deppendencies, do something like this

    @Module
class BluetoothModule(val context : Context) {

    //@Inject private lateinit var context : Context
    @Provides
    @Named("rxBleClient")
    @Singleton
    fun provideRxBleClient():RxBleClient =
            RxBleClient.create(context)
}

let your call be like this

val component = AppComponent()
 component.bluetoothModule(appContext)
          .//other calls here
          .build()
Declan Nnadozie
  • 1,805
  • 1
  • 10
  • 20
  • I tried that put the injection code for Context separately but it doesn't work.. Thank you for your reply! – Awesometic Aug 08 '18 at 13:35
  • trying adding the context via Bluetooth constructor..... the above code @Awesometic – Declan Nnadozie Aug 08 '18 at 13:55
  • It seems the suggested answer doesn't use of the dagger.android features.. AppComponent is already defined with the class extends DaggerApplication class. And I found that it isn't needed to inject between module classes. Is it right? I'm a newb so I searched as much as I can. :) But anyway your answer inspires me in some way and I could get the answer. Thanks. – Awesometic Aug 09 '18 at 04:36