注入改造 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
中已有 HeroesApi
的 Provide
方法,因此您可以直接传递它。首先将 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
中删除 ApiManager
的 Provide
方法,因为您的 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.
}
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
中已有 HeroesApi
的 Provide
方法,因此您可以直接传递它。首先将 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
中删除 ApiManager
的 Provide
方法,因为您的 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.
}