#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