注入改造Android Kotlin

时间:2020-01-01 09:18:03

标签: android kotlin retrofit dagger-2

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)

让我知道更多详细信息

1 个答案:

答案 0 :(得分:4)

您不需要在Retrofit中插入ApiManager实例。 Provide中已经有HeroesApi的{​​{1}}方法,因此您可以直接传递它。首先使用以下方法更改您的 ApiManager

ApiModule

然后更改您的 ApiModule

class ApiManager(private val mHeroesApi: HeroesApi) {

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

OR

您可以简单地将@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使用Provide方法。为此,请使用以下命令更改 ApiManager

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()) } } 中删除Provide的{​​{1}}方法,因为您的ApiManager在构造函数中只需要ApiModule且您已定义{{1 }}方法返回ApiManager,因此匕首已经知道如何构造HerosApi

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

Provide