Нулевой контекст при использовании Dagger 2

#android #kotlin #dependency-injection #dagger-2 #dagger

#Android #kotlin #внедрение зависимостей #dagger-2 #dagger

Вопрос:

Я впервые использую dagger, пытаясь внедрить контекст в репозиторий для загрузки ресурсов. Однако я получаю эту ошибку

  java.lang.NullPointerException: Attempt to invoke virtual method 
    'android.content.res.AssetManager android.content.Context.getAssets()'
    on a null object reference
    at android.content.ContextWrapper.getAssets(ContextWrapper.java:92)
    at myJSONLoader.getJsonAsset(myJSONLoader.kt:11)
    at repository.myRepository.getData(myRepository.kt:32)
    at presenter.myPresenter.getData(myPresenter.kt:28)
    at view.myFragment.onViewCreated(myFragment.kt:51)
  

Контекст не имеет значения null, но при отладке я вижу, что mBase имеет значение null. Как мне это исправить?

MyApp.kt

 class myApp : Application(), HasAndroidInjector {

@Inject
lateinit var androidInjector : DispatchingAndroidInjector<Any>

override fun onCreate() {
    super.onCreate()
    DaggerAppComponent.builder()
        .application(this)
        .appModule(AppModule(this))
        .build()
        .inject(this)
}

override fun androidInjector(): AndroidInjector<Any> = androidInjector

}
  

AppComponent.kt

 @Singleton
@Component(modules = [
AndroidInjectionModule::class,
AppModule::class,
ActivityModule::class])
interface AppComponent {

@Component.Builder
interface Builder {
    @BindsInstance
    fun application(application: Application): Builder
    fun appModule(appModule: AppModule): Builder
    fun build(): AppComponent
}
fun inject(activity: MainActivity)
fun inject(instance: myApp)
fun inject(repository: myRepository)
fun inject(presenter: myPresenter)
}
  

AppModule.kt

 @Module
class AppModule(private val app: Application) {

@Provides
@Singleton
fun provideContext(): Context = app

@Provides
@Singleton
fun provideMyRepository(): myContract.Repository = myRepository(app)
}
  

Repository.kt

 class myRepository @Inject constructor(private val context: Context) : myContract.Repository {
    private fun inject() {
    DaggerAppComponent.builder()
        .application(myApp())
        .appModule(AppModule(myApp()))
        .build().inject(this)
    }
}
  

build.gradle

 implementation 'com.google.dagger:dagger-android:2.23'
implementation 'com.google.dagger:dagger-android-support:2.23'// if you use the support libraries
kapt 'com.google.dagger:dagger-android-processor:2.23'
kapt 'com.google.dagger:dagger-compiler:2.23'
compileOnly 'javax.annotation:javax.annotation-api:1.3.2'
  

У меня не было проблем с внедрением репозитория в презентацию. Он вводит контекст в репозиторий.

Редактировать: я уже добавил имя приложения в манифест Android и попытался вызвать app.applicationcontext вместо app в AppModule

Ответ №1:

Вам следует узнать больше об архитектуре Dagger2. Я приглашаю вас к моему примерному приложению проекта Dagger2 для создания нового приложения Dagger2.

Вам не нужно регистрировать свое приложение как приложение Dagger внутри класса репозитория. Попробуйте инициализировать его в классе BaseApplication и сделать его своим классом приложения в манифесте.

Кстати, вы хотите контекст, но возвращаете «приложение», и это класс приложения.

Комментарии:

1. На самом деле я уже сделал эти части. Я добавил их в свой пост. И я пробовал app.ApplicationContext, но это тоже не работает

2. Неправильно то, что вы создаете класс MyRepository @Inject constructor(private val context: Context): myContract.Repository { private fun inject() { DaggerAppComponent.builder() .application(MyApp()) .AppModule(AppModule(MyApp())) .build().inject(this)} } это в вашем классе репозитория. Сделайте это в своем классе приложения

3. Можете ли вы привести пример того, как я бы ввел контекст, как вы это сделали в своем проекте?

4. Так же, как вы делали в своем проекте, но с app.context