Home > database >  dagger2 is throwing an error: cannot be provided without an @Provides-annotated method. in my androi
dagger2 is throwing an error: cannot be provided without an @Provides-annotated method. in my androi

Time:04-09

Hello folks please help me to debug this dagger2 issue,I am very new to dagger2 and just started with a project.

public abstract interface ApplicationComponent {
            ^
  java.util.Map<java.lang.Class<? 
  >,javax.inject.Provider<dagger.android.AndroidInjector.Factory<?>>> is injected at
      dagger.android.DispatchingAndroidInjector(injectorFactoriesWithClassKeys, �)
  dagger.android.DispatchingAndroidInjector<java.lang.Object> is injected at
      com.example.dictionary.App.dispatchingServiceInjector
  com.example.dictionary.App is injected at
      
  com.example.dictionary.di.components.ApplicationComponent.inject(com.example.dictionary.App)
  error: [Dagger/MissingBinding] 
 java.util.Map<java.lang.String,javax.inject.Provider<dagger.android.AndroidInjector.Factory<? 
 >>> cannot be provided without an @Provides-annotated method.

My implementations are:

interface ApiService {
    companion object {
        const val BASE_URL= "https://od-api.oxforddictionaries.com/"
    }

    @GET("api/v2/entries/en-gb/")
         fun getMeaning(@Query("word") word: String): Observable<Response>
    }
}




open class RemoteDataSource @Inject constructor(private val apiService: ApiService) {
     fun getWordMeaning(word: String) = apiService.getMeaning(word)
} 



@ApplicationScope
@Component(modules = [ApplicationModule::class, NetworkModule::class])
interface ApplicationComponent {
    fun inject(app: App)
    fun inject(mainActivity: MainActivity)
}


@Module
class ApplicationModule(private val application: Application) {

      @ApplicationScope
      @Provides
      fun provideApplicationContext(): Context = application.applicationContext

      @ApplicationScope
      @Provides
      fun provideSharedPreferences(): SharedPreferences =
          PreferenceManager.getDefaultSharedPreferences(application)

      @ApplicationScope
      @Provides
      fun providerDisplayMetrics(): DisplayMetrics = application.resources.displayMetrics
}



@Module
class NetworkModule(
      private val baseUrl: String,
      private val application: Application
) {
      companion object {
      const val CACHE_SIZE = 10 * 1024 * 1024L // 10 MiB
      const val TIME_OUT = 10L // time in minutes to get the response from server
  }

  @ApplicationScope
  @Provides
  fun provideGson(): Gson = GsonBuilder().create()

  @ApplicationScope
  @Provides
  fun provideOkHttpCache() = Cache(application.cacheDir, CACHE_SIZE)

  @ApplicationScope
  @Provides
  fun provideOkHttpClient(cache: Cache): OkHttpClient = with(OkHttpClient.Builder()) {
    writeTimeout(3, TimeUnit.MINUTES)
        .connectTimeout(3, TimeUnit.MINUTES)
        .readTimeout(TIME_OUT, TimeUnit.MINUTES)
    cache(cache)
    addInterceptor(headersInterceptor())
    build()
 }

 @ApplicationScope
 @Provides
 fun provideRetrofit(gson: Gson, okHttpClient: OkHttpClient): Retrofit = Retrofit.Builder()
    .baseUrl(baseUrl)
    .client(okHttpClient)
    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
    .addConverterFactory(GsonConverterFactory.create(gson))
    .build()

 @ApplicationScope
 @Provides
 fun provideApiService(retrofit: Retrofit): ApiService = 
     retrofit.create(ApiService::class.java)

 private var authRequest: String? = null

 private fun headersInterceptor() = Interceptor { chain ->
    val requestBuilder = chain.request().newBuilder()
    requestBuilder.addHeader("Accept", "application/json")
    requestBuilder.addHeader("app_id", "SOME APP ID")
    requestBuilder.addHeader("app_key", "Some API KEY")
    chain.proceed(
        requestBuilder.build()
    )
 }
 }



   class App : Application(), HasAndroidInjector {

   @Inject
   lateinit var dispatchingServiceInjector: 
   DispatchingAndroidInjector<Any>

        override fun onCreate() {
             super.onCreate()
             applicationComponent.inject(this)
    
             RxJavaPlugins.setErrorHandler {
                  it.printStackTrace()
             }
        }

        override fun androidInjector(): AndroidInjector<Any> {
               return dispatchingServiceInjector
        }

        val applicationComponent: ApplicationComponent by 
        lazy<ApplicationComponent>(mode = LazyThreadSafetyMode.NONE) {
             DaggerApplicationComponent
             .builder()
             .applicationModule(ApplicationModule(this))
             .networkModule(NetworkModule(ApiService.BASE_URL, this))
             .build()
        }
   }

I tried re-building the code, also attempted invalidate cache and restart to re-install dependencies, as dagger2 requires re-building the project every time once a new dependency injection is implemented, followed YouTube tutorials, to implement this so far, but unable to detect the problem, although in the build crash its indicating to provide @Provides, but in my NetworkModule, ApplicationModule I set this @Provides annotation.

Please help to figure out the solution.

CodePudding user response:

As suggested in this answer https://stackoverflow.com/a/66133688/2462531 ,just add your App class in android manifest under application tag.

<application ... 
 android: name = ".App" ...>
 ...
  • Related