【问题标题】:How should I use Dagger2 with Retrofit?我应该如何将 Dagger2 与 Retrofit 一起使用?
【发布时间】:2019-06-14 11:14:23
【问题描述】:

我在一个项目中工作,我需要用 Dagger 2 注入 Retrofit 对象。我搜索信息但我只能执行几个步骤,现在我不知道如何继续:

我的组件:

@Singleton
@Component(modules = arrayOf(NetworkModule::class))
interface NetworkComponent {
    fun inject(foo: TheApplication)
}

我的模块:

@Module
class NetworkModule {

    @Provides
    @Singleton
    fun provideRetrofit(): Retrofit {
        return Retrofit.Builder()
            .baseUrl("https://api.chucknorris.io/")
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .build()
    }

}

现在我看到我必须创建一个从 Application 扩展的 Class 以初始化 Component 并创建一个 @Inject 下一个:

class TheApplication: Application() {

    override fun onCreate() {
        super.onCreate()
        val net: NetworkModule = Dagger...
    }
}

理论上,当我输入Dagger... 时,它应该是DaggerNetworkComponent,但我重建了项目,但仍然丢失。 任何人都可以向我解释 Application.class 的用途以及我该如何继续?

【问题讨论】:

  • 请分享您的component 代码
  • 我贴一个组件代码,不知道是不是和你问的一样
  • 为什么你的@Component 被称为NetworkModule,它出于某种原因循环地将自己称为一个模块?而您的实际网络模块称为NetworksModule?
  • 名字随机选择与他们无关
  • 您的代码一切正常。我假设匕首注释处理器未连接或未配置。检查是否通过“kapt”配置而不是“annotatinProcessor”将匕首注释处理器添加为依赖项

标签: android kotlin retrofit dagger-2


【解决方案1】:

试试这个

AppComponent.kt

@Component(modules = [NetworkModule::class]) 
@Singleton 
interface AppComponent {
    fun inject(app: MyApp)
}

NetworkModule.kt

@Module
class NetworkModule {

    @Singleton
    @Provides
    fun provideRetrofit(okHttpClient: OkHttpClient): Retrofit {
        return Retrofit.Builder()
            .addConverterFactory(GsonConverterFactory.create())
            .baseUrl("YOUR_BASE_URL")
            .client(okHttpClient)
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .build()
    }

    @Singleton
    @Provides
    fun provideApi(retrofit: Retrofit): WebApi {
        return retrofit.create(WebApi::class.java)
    }

    @Singleton
    @Provides
    fun provideOkHttpClient(
        interceptors: ArrayList<Interceptor>
    ): OkHttpClient {
        val clientBuilder = OkHttpClient.Builder()
            .followRedirects(false)
        interceptors.forEach {
            clientBuilder.addInterceptor(it)
        }
        return clientBuilder.build()
    }


    @Singleton
    @Provides
    fun provideInterceptors(): ArrayList<Interceptor> {
        val interceptors = arrayListOf<Interceptor>()
        val loggingInterceptor = HttpLoggingInterceptor().apply {
            level = if (BuildConfig.DEBUG) {
                HttpLoggingInterceptor.Level.BODY
            } else {
                HttpLoggingInterceptor.Level.NONE
            }
        }
        interceptors.add(loggingInterceptor)
        return interceptors
    }
}

MyApp.kt

class MyApp : Application() {
    companion object {
        lateinit var instance: MyApp
            private set
    }

    lateinit var appComponent: AppComponent
        private set


    override fun onCreate() {
        super.onCreate()
        instance = this
        initComponent()
    }

    private fun initComponent() {
        appComponent = DaggerAppComponent.builder()
            .build()
        appComponent.inject(this)
    }
}

AndroidManifest.xml

<application
            android:name=".MyApp"
            ....

【讨论】:

  • MyAppApplication 类,我创建了AppComponent 应用范围
  • @David 其他提供者方法用于提供拦截器和OkHttpClient 的依赖项。您可以根据您的用例删除/修改它。
  • 如果不是很多工作,你能解释一下为什么我应该使用Aplication 类来初始化我要注入的类中的DaggerNetworkComponent 吗? (你怎么能看到我是最新的 Dagger2)。现在我应该如何注入Retrofit
  • @David,抱歉没有收到您的问题!但据我了解,我刚刚使用Application 类将AppComponent 定义为应用程序级别。正如您在 AppComoment 中定义的 fun inject(app: MyApp) 一样,需要在 Application 类中注入组件。
  • @David,比如说我想使用WebApi,然后@Inject lateinit var webApi: WebApi
猜你喜欢
  • 1970-01-01
  • 2020-01-20
  • 2018-10-25
  • 1970-01-01
  • 2019-05-31
  • 2016-06-29
  • 1970-01-01
  • 1970-01-01
  • 2019-08-26
相关资源
最近更新 更多