注入改造 android kotlin

Inject retrofit android kotlin

ApiModule.kt

@Module
class ApiModule {

    @Provides
    @Singleton
    fun provideRetrofit(): Retrofit {
        return Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .build()
    }

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


    @Provides
    @Singleton
    fun provideApiManager(): ApiManager {
        return ApiManager()
    }
}

ApiManager.kt

class ApiManager {

    @Inject
    lateinit var mRetrofit: Retrofit

    fun getAllHeroes(): MutableLiveData<Result<List<Hero>>> {
        val mHeroesApi = mRetrofit.create(HeroesApi::class.java)
        return NetworkHandler<List<Hero>>().makeCall(mHeroesApi.getAllHeroes())
    }
}

HeroesApi.kt

interface HeroesApi {

    @GET("/marvel")
    fun getAllHeroes(): Call<List<Hero>>

}

我收到错误

Caused by: kotlin.UninitializedPropertyAccessException: lateinit property mRetrofit has not been initialized
        at com.hardik.repository.network.ApiManager.getAllHeroes(ApiManager.kt:17)
        at com.hardik.repository.Repository.getHeroesFromNetwork(Repository.kt:16)
        at com.hardik.androidtemplate.usecase.GetHeroesUseCase.execute(GetHeroesUseCase.kt:14)
        at com.hardik.androidtemplate.viewmodel.HeroListViewModel.<init>(HeroListViewModel.kt:9)

让我知道更多详情

您不需要在 ApiManager 中注入 Retrofit 实例。您的 ApiModule 中已有 HeroesApiProvide 方法,因此您可以直接传递它。首先将 ApiManager 更改为:

class ApiManager(private val mHeroesApi: HeroesApi) {

    fun getAllHeroes(): MutableLiveData<Result<List<Hero>>> {
        return NetworkHandler<List<Hero>>().makeCall(mHeroesApi.getAllHeroes())
    }
}

然后改变你的ApiModule

@Module
class ApiModule {

   // Rest code same as it is already

    @Provides
    @Singleton
    // Since you already have Provide method which provides HerosApi,
    // Dagger will automatically inject this below.
    fun provideApiManager(herosApi: HerosApi): ApiManager {
        return ApiManager(herosApi)
    }
}

您可以简单地将 ApiManager 更改为将 HorseApi 注入构造函数,您甚至不需要为 ApiManager 使用 Provide 方法。为此,将 ApiManager 更改为以下内容:

// Notice the @Inject before constructor
class ApiManager @Inject constructor(private val mHeroesApi: HeroesApi) {

    fun getAllHeroes(): MutableLiveData<Result<List<Hero>>> {
        return NetworkHandler<List<Hero>>().makeCall(mHeroesApi.getAllHeroes())
    }
}

然后,您可以从 ApiModule 中删除 ApiManagerProvide 方法,因为您的 ApiManager 只需要在构造函数中使用 HerosApi 并且您已经定义了 Provide 方法 returns HerosApi 所以 dagger 已经知道如何构造你的 ApiManager.

因此您的 ApiModule 最终将如下所示:

@Module
class ApiModule {

    @Provides
    @Singleton
    fun provideRetrofit(): Retrofit {
        return Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .build()
    }

    @Provides
    @Singleton
    fun provideUserApi(retrofit: Retrofit): HeroesApi {
        return retrofit.create(HeroesApi::class.java)
    }
    // There's no need for providing ApiManager.
}