简体   繁体   中英

Android Kotlin with Dagger2, lateinit var has not been initialized

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.

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM