【问题标题】:Android Kotlin with Dagger2, lateinit var has not been initialized带有 Dagger2 的 Android Kotlin,lateinit var 尚未初始化
【发布时间】:2018-08-08 09:41:12
【问题描述】:

我是 Dagger 新手,使用它时遇到问题。

我想要开发的是使用 RxAndroidBle 并通过 Dagger 对其进行初始化以提供上下文。

所以我研究了它是如何实现的,我写了一些代码,它似乎对我有用,但根本不起作用。

以下是我的代码。

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
}

蓝牙模块.kt

@Module
class BluetoothModule {

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

BluetoothController.kt 用于由 DaggerApplication 注入。

class BluetoothController : DaggerApplication() {

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

我已插入 安卓:名称“.BluetoothController” 到 AndroidManifest.xml

这就是我将如何使用它。

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

但总是出现错误提示:lateinit 属性上下文尚未初始化

我错过了什么?谁能帮帮我?

提前致谢。

【问题讨论】:

    标签: android kotlin dagger


    【解决方案1】:

    添加下面的代码来实现这一点。

    1. 创建ActivityBuilderModule 用于在活动中注入。将我们的活动视为MainActivity

      @Module
      abstract class ActivityBuilderModule {
           @ContributesAndroidInjector(modules=[MainActivityModule::class])
           abstract fun contributeSplashActivity(): MainActivity
      }
      
    2. 创建您的MainActivityModule

      @Module
      class MainActivityModule{
           @Provides()
           fun contributeSplashActivity(mainActivity: MainActivity): 
              MainActivity=mainActivity
       }
      
    3. 修改你的组件。

      @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. 在 MainActivity 中只注入。

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

    如有任何问题,请告诉我们。

    【讨论】:

    • 我已经按照您建议的方式解决了我的问题 :) 谢谢!这就是我错过的原因。
    • 很高兴它有帮助!
    【解决方案2】:

    上下文对象在被调用之前没有被初始化

    虽然我不知道,你的初始化是如何链接的。

    使用@Inject 添加依赖,做这样的事情

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

    让你的电话是这样的

    val component = AppComponent()
     component.bluetoothModule(appContext)
              .//other calls here
              .build()
    

    【讨论】:

    • 我试过把 Context 的注入代码分开放,但是不行。。谢谢你的回复!
    • 尝试通过蓝牙构造函数添加上下文.....上面的代码@Awesometic
    • 似乎建议的答案没有使用 dagger.android 功能。AppComponent 已经定义了类扩展 DaggerApplication 类。而且我发现不需要在模块类之间注入。这样对吗?我是新手,所以我尽可能多地搜索。 :) 但无论如何,你的回答在某种程度上激励了我,我可以得到答案。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2020-09-23
    • 2020-08-08
    • 1970-01-01
    • 1970-01-01
    • 2022-11-22
    • 2023-03-25
    • 2020-04-14
    • 2022-12-15
    相关资源
    最近更新 更多