Api 调用失败无法为 class 创建转换器 Retrofit/Moshi
Api call failed Unable to create converter for class Retrofit/Moshi
我正在实施 retrofit 和 moshi 来向服务器发出请求(我是使用改造的新手)。我按照我在互联网上找到的一些关于如何实施它的指南进行操作,但是在启动应用程序时我收到以下错误:
Error Api call failed Unable to create converter for class com.example.kvn.data.model.JConfig
for method ApiClient.getApiConfig
这是我使用的代码:
AppModule.kt
@Module
@InstallIn(ApplicationComponent::class)
object AppModule {
@Singleton
@Provides
fun providerDB(@ApplicationContext ctx: Context) =
Room.databaseBuilder(ctx, AppDB::class.java, DB_NAME).build()
@Singleton
@Provides
fun providerDao(db: AppDB) = db.getDao()
@Singleton
@Provides
fun provideHttpClient(): OkHttpClient {
return OkHttpClient
.Builder()
.readTimeout(15, TimeUnit.SECONDS)
.connectTimeout(15, TimeUnit.SECONDS)
.build()
}
@Singleton
@Provides
fun provideConverterFactory() = MoshiConverterFactory.create()
@Singleton
@Provides
fun provideRetrofit(
okHttpClient: OkHttpClient,
moshiConverterFactory: MoshiConverterFactory
): Retrofit {
return Retrofit.Builder()
.baseUrl(BASE_URL)
.client(okHttpClient)
.addConverterFactory(moshiConverterFactory)
.build()
}
@Singleton
@Provides
fun providerApi(retrofit: Retrofit) = retrofit.create(ApiClient::class.java)
}
Remote.kt
/*@JsonClass(generateAdapter = true)
data class JConfig(
@Json(name = "data") val data:List<Config>
)
data class Config(
@Json(name = "codigo") var codigo: Int,
@Json(name = "tipo") var tipo: String,
@Json(name = "empresa") var empresa: Int,
@Json(name = "sucursal") var sucursal: Int,
@Json(name = "esquema") var esquema: Int,
@Json(name = "horainicio") var hini: String,
@Json(name = "horafinal") var hfin: String,
@Json(name = "fecha") var fecha: String,
@Json(name = "seguimiento") var seguimiento: Int
)*/
@JsonClass(generateAdapter = true)
data class JConfig(
@Json(name = "data") val data:List<Config>
)
data class Config(
var codigo: Int,
var tipo: String,
var empresa: Int,
var sucursal: Int,
var esquema: Int,
var horainicio: String,
var horafinal: String,
var fecha: String,
var seguimiento: Int
)
ApiClient.kt
interface ApiClient {
@POST(API_CONFIGURACION)
suspend fun getApiConfig(@Body imei: String): Response<JConfig>
}
WebDataSource.kt
class WebDataSource @Inject constructor(private val web:ApiClient) {
suspend fun getWebConfiguracion(imei:String): Response<JConfig> {
return web.getApiConfig(imei)
}
}
AppViewModel.kt
class AppViewModel @ViewModelInject constructor(private val repository: Repository) : ViewModel() {
private val _response: MutableLiveData<NetworkResult<JConfig>> = MutableLiveData()
val response: LiveData<NetworkResult<JConfig>> = _response
fun fetchConfigResponse(imei:String) = viewModelScope.launch {
repository.getWebConfiguracion(imei).collect { values ->
_response.value = values
}
}
fun saveOrUpdateConf(conf:Config) {
viewModelScope.launch {
if (isConfigEmpty()) {
repository.saveConfiguracion(conf)
}else {
repository.updateConfiguracion(conf)
}
}
}
suspend fun setupConfig(T:()->Unit) {
if (isConfigEmpty()) {
T()
}else {
val cf = repository.getConfiguracion().value!!
if (yesterday(cf[0].fecha)) {
T()
}
}
}
}
FBase.kt
@AndroidEntryPoint
class FBase : Fragment() {
private val viewmodel by activityViewModels<AppViewModel>()
private var _bind:FragmentFBaseBinding? = null
private val bind get() = _bind!!
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_bind = FragmentFBaseBinding.inflate(inflater, container, false)
return bind.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupObserver("888888882222331")
}
private fun setupObserver(imei:String) {
fetchResponse(imei)
viewmodel.response.observe(viewLifecycleOwner) { response ->
when(response) {
is NetworkResult.Loading -> { /*Notification*/ }
is NetworkResult.Success -> {
val rs = response.data?.data?.get(0)!!
viewmodel.saveOrUpdateConf(rs)
}
is NetworkResult.Error -> { Log.d("TAG","Error ${response.message}") }
}
}
}
private fun fetchResponse(imei: String) {
viewmodel.fetchConfigResponse(imei)
//add notification
}
}
依赖项和插件
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-android-extensions'
id 'kotlin-kapt'
id 'dagger.hilt.android.plugin'
}
// HILT
implementation 'com.google.dagger:hilt-android:2.28.1-alpha'
kapt 'com.google.dagger:hilt-android-compiler:2.28.1-alpha'
implementation 'androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha02'
kapt 'androidx.hilt:hilt-compiler:1.0.0-alpha02'
// TOOLS
implementation 'com.squareup.moshi:moshi-kotlin:1.13.0'
implementation 'com.squareup.moshi:moshi:1.13.0'
kapt 'com.squareup.moshi:moshi-kotlin-codegen:1.13.0'
implementation 'com.squareup.retrofit2:converter-moshi:2.9.0'
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
retrofit之前用volley和moshi一起requests没问题,retrofit之后不知道怎么解决
对不起我的英语。
谢谢
我找到了错误的来源,当使用moshi with retrofit时,所有数据类必须有@JsonClass(generateAdapter = true)
的注解
我们必须更改代码:
@JsonClass(generateAdapter = true)
data class JConfig(
@Json(name = "data") val data:List<Config>
)
data class Config(
var codigo: Int,
var tipo: String,
var empresa: Int,
var sucursal: Int,
var esquema: Int,
var horainicio: String,
var horafinal: String,
var fecha: String,
var seguimiento: Int
)
为此:
@JsonClass(generateAdapter = true)
data class JConfig(
@Json(name = "data") val data:List<Config>
)
@JsonClass(generateAdapter = true)
data class Config(
var codigo: Int,
var tipo: String,
var empresa: Int,
var sucursal: Int,
var esquema: Int,
var horainicio: String,
var horafinal: String,
var fecha: String,
var seguimiento: Int
)
我正在实施 retrofit 和 moshi 来向服务器发出请求(我是使用改造的新手)。我按照我在互联网上找到的一些关于如何实施它的指南进行操作,但是在启动应用程序时我收到以下错误:
Error Api call failed Unable to create converter for class com.example.kvn.data.model.JConfig
for method ApiClient.getApiConfig
这是我使用的代码:
AppModule.kt
@Module
@InstallIn(ApplicationComponent::class)
object AppModule {
@Singleton
@Provides
fun providerDB(@ApplicationContext ctx: Context) =
Room.databaseBuilder(ctx, AppDB::class.java, DB_NAME).build()
@Singleton
@Provides
fun providerDao(db: AppDB) = db.getDao()
@Singleton
@Provides
fun provideHttpClient(): OkHttpClient {
return OkHttpClient
.Builder()
.readTimeout(15, TimeUnit.SECONDS)
.connectTimeout(15, TimeUnit.SECONDS)
.build()
}
@Singleton
@Provides
fun provideConverterFactory() = MoshiConverterFactory.create()
@Singleton
@Provides
fun provideRetrofit(
okHttpClient: OkHttpClient,
moshiConverterFactory: MoshiConverterFactory
): Retrofit {
return Retrofit.Builder()
.baseUrl(BASE_URL)
.client(okHttpClient)
.addConverterFactory(moshiConverterFactory)
.build()
}
@Singleton
@Provides
fun providerApi(retrofit: Retrofit) = retrofit.create(ApiClient::class.java)
}
Remote.kt
/*@JsonClass(generateAdapter = true)
data class JConfig(
@Json(name = "data") val data:List<Config>
)
data class Config(
@Json(name = "codigo") var codigo: Int,
@Json(name = "tipo") var tipo: String,
@Json(name = "empresa") var empresa: Int,
@Json(name = "sucursal") var sucursal: Int,
@Json(name = "esquema") var esquema: Int,
@Json(name = "horainicio") var hini: String,
@Json(name = "horafinal") var hfin: String,
@Json(name = "fecha") var fecha: String,
@Json(name = "seguimiento") var seguimiento: Int
)*/
@JsonClass(generateAdapter = true)
data class JConfig(
@Json(name = "data") val data:List<Config>
)
data class Config(
var codigo: Int,
var tipo: String,
var empresa: Int,
var sucursal: Int,
var esquema: Int,
var horainicio: String,
var horafinal: String,
var fecha: String,
var seguimiento: Int
)
ApiClient.kt
interface ApiClient {
@POST(API_CONFIGURACION)
suspend fun getApiConfig(@Body imei: String): Response<JConfig>
}
WebDataSource.kt
class WebDataSource @Inject constructor(private val web:ApiClient) {
suspend fun getWebConfiguracion(imei:String): Response<JConfig> {
return web.getApiConfig(imei)
}
}
AppViewModel.kt
class AppViewModel @ViewModelInject constructor(private val repository: Repository) : ViewModel() {
private val _response: MutableLiveData<NetworkResult<JConfig>> = MutableLiveData()
val response: LiveData<NetworkResult<JConfig>> = _response
fun fetchConfigResponse(imei:String) = viewModelScope.launch {
repository.getWebConfiguracion(imei).collect { values ->
_response.value = values
}
}
fun saveOrUpdateConf(conf:Config) {
viewModelScope.launch {
if (isConfigEmpty()) {
repository.saveConfiguracion(conf)
}else {
repository.updateConfiguracion(conf)
}
}
}
suspend fun setupConfig(T:()->Unit) {
if (isConfigEmpty()) {
T()
}else {
val cf = repository.getConfiguracion().value!!
if (yesterday(cf[0].fecha)) {
T()
}
}
}
}
FBase.kt
@AndroidEntryPoint
class FBase : Fragment() {
private val viewmodel by activityViewModels<AppViewModel>()
private var _bind:FragmentFBaseBinding? = null
private val bind get() = _bind!!
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_bind = FragmentFBaseBinding.inflate(inflater, container, false)
return bind.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupObserver("888888882222331")
}
private fun setupObserver(imei:String) {
fetchResponse(imei)
viewmodel.response.observe(viewLifecycleOwner) { response ->
when(response) {
is NetworkResult.Loading -> { /*Notification*/ }
is NetworkResult.Success -> {
val rs = response.data?.data?.get(0)!!
viewmodel.saveOrUpdateConf(rs)
}
is NetworkResult.Error -> { Log.d("TAG","Error ${response.message}") }
}
}
}
private fun fetchResponse(imei: String) {
viewmodel.fetchConfigResponse(imei)
//add notification
}
}
依赖项和插件
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-android-extensions'
id 'kotlin-kapt'
id 'dagger.hilt.android.plugin'
}
// HILT
implementation 'com.google.dagger:hilt-android:2.28.1-alpha'
kapt 'com.google.dagger:hilt-android-compiler:2.28.1-alpha'
implementation 'androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha02'
kapt 'androidx.hilt:hilt-compiler:1.0.0-alpha02'
// TOOLS
implementation 'com.squareup.moshi:moshi-kotlin:1.13.0'
implementation 'com.squareup.moshi:moshi:1.13.0'
kapt 'com.squareup.moshi:moshi-kotlin-codegen:1.13.0'
implementation 'com.squareup.retrofit2:converter-moshi:2.9.0'
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
retrofit之前用volley和moshi一起requests没问题,retrofit之后不知道怎么解决
对不起我的英语。
谢谢
我找到了错误的来源,当使用moshi with retrofit时,所有数据类必须有@JsonClass(generateAdapter = true)
我们必须更改代码:
@JsonClass(generateAdapter = true)
data class JConfig(
@Json(name = "data") val data:List<Config>
)
data class Config(
var codigo: Int,
var tipo: String,
var empresa: Int,
var sucursal: Int,
var esquema: Int,
var horainicio: String,
var horafinal: String,
var fecha: String,
var seguimiento: Int
)
为此:
@JsonClass(generateAdapter = true)
data class JConfig(
@Json(name = "data") val data:List<Config>
)
@JsonClass(generateAdapter = true)
data class Config(
var codigo: Int,
var tipo: String,
var empresa: Int,
var sucursal: Int,
var esquema: Int,
var horainicio: String,
var horafinal: String,
var fecha: String,
var seguimiento: Int
)