无法调用ConversionRates类的无参数构造函数



我有一个货币转换器安卓应用程序。我使用改造从API,但就我而言,我的应用程序无法从api获取数据它返回那个异常

无法为package name类调用无参数构造函数。ConversionRates。在Gson中为这种类型注册一个InstanceCreator可以解决这个问题。

converonrates数据类:

data class ConversionRates(
val AED: Double,
val AFN: Double,
val ALL: Double,
val AMD: Double,
val ANG: Double,
val AOA: Double,
val ARS: Double,
val AUD: Double,
val AWG: Double,
val AZN: Double,
val BAM: Double,
val BBD: Double,
val BDT: Double,
val BGN: Double,
val BHD: Double,
val BIF: Double,
val BMD: Double,
val BND: Double,
val BOB: Double,
val BRL: Double,
val BSD: Double,
val BTN: Double,
val BWP: Double,)

viewModel:

@HiltViewModelclass MainViewModel @Inject constructor(
private val repository: MainRepository,
private val dispatchers: DispatcherProvider) : ViewModel(){
sealed class CurrencyEvent {
class Success(val resultText: String): CurrencyEvent()
class Failure(val errorText: String): CurrencyEvent()
object Loading: CurrencyEvent()
object Empty: CurrencyEvent() }
private val _conversion= MutableStateFlow<CurrencyEvent>(CurrencyEvent.Empty)
val conversion: StateFlow<CurrencyEvent> = _conversion
fun convert(amountStr: String,
fromCurrency: String,
toCurrency: String ){
val fromAmount= amountStr.toFloatOrNull()
if( fromAmount== null){
_conversion.value=CurrencyEvent.Failure("Not a valid amount")
return
}
viewModelScope.launch (dispatchers.io){
_conversion.value= CurrencyEvent.Loading
when( val ratesResponse= repository.getRates(fromCurrency)) {
is Resource.Error -> _conversion.value= CurrencyEvent.Failure(ratesResponse.message!!)
is Resource.Success -> {
val rates = ratesResponse.data!!.conversion_rates
val rate = getRateForCurrency(toCurrency, rates)
if (rate==null){
_conversion.value= CurrencyEvent.Failure("Unexpected Error")
} else {
//val convertedCurrency = round(fromAmount * rate * 100)
_conversion.value= CurrencyEvent.Success(
"$fromAmount $fromCurrency = $toCurrency"
)
}
}
}
}
}
private fun getRateForCurrency(currency: String, rates: ConversionRates) = when (currency) {
"CAD" -> rates.CAD
"HKD" -> rates.HKD
"ISK" -> rates.ISK
"EUR" -> rates.EUR
"PHP" -> rates.PHP
"DKK" -> rates.DKK
"HUF" -> rates.HUF
"CZK" -> rates.CZK
"AUD" -> rates.AUD
"RON" -> rates.RON
"SEK" -> rates.SEK
"IDR" -> rates.IDR
"INR" -> rates.INR
"BRL" -> rates.BRL
"RUB" -> rates.RUB
"HRK" -> rates.HRK
"JPY" -> rates.JPY
"THB" -> rates.THB
"CHF" -> rates.CHF
"SGD" -> rates.SGD
"PLN" -> rates.PLN
"BGN" -> rates.BGN
"CNY" -> rates.CNY
"NOK" -> rates.NOK
"NZD" -> rates.NZD
"ZAR" -> rates.ZAR
"USD" -> rates.USD
"MXN" -> rates.MXN
"ILS" -> rates.ILS
"GBP" -> rates.GBP
"KRW" -> rates.KRW
"MYR" -> rates.MYR
else -> null
}}

CurrencyApi

interface CurrencyApi {
@GET("/v6/68c54e50f924117c29176f8f/latest/USD")
suspend fun getRates(
@Query("base_code") base_code : String
): Response<CurrencyResponse>}

Default Main Repo

class DefaultMainRepository @Inject constructor(
private val api :CurrencyApi): MainRepository {
override suspend fun getRates(base_code: String): Resource<CurrencyResponse> {
return try {
val response = api.getRates(base_code)
val result= response.body()
if (response.isSuccessful && result!=null){
Resource.Success(result)
} else{
Resource.Error(response.message())
}
}catch (e: Exception) {
Resource.Error(e.message?: "An error occured")
}
}}

MainRepo:

interface MainRepository {
suspend fun getRates(base_code: String) : Resource<CurrencyResponse>}

显然,kotlin数据类只能包含大约127个参数,所以你有两个选择。

  1. 将响应数据类分解为两个(RatesAToLRatesMToZ),并向API发出两个请求。

  2. 将JSON对象(converversion_rates)转换为对象列表Rate(val code: String, val amount: Double)。这可以使用Moshi自定义适配器来完成。

查看代码要点在这里自定义Moshi适配器完整项目在GitHub fxConverter

class MoshiJsonAdapter : JsonAdapter<InfoAndRatesResponse>() {
@FromJson
override fun fromJson(reader: JsonReader): InfoAndRatesResponse {
reader.beginObject()
var result = ""
var timeLastUpdateUnix = 0
var timeLastUpdateUtc = ""
var timeNextUpdateUnix = 0
var timeNextUpdateUtc = ""
var baseCode = ""
val rates = mutableListOf<Rate>()
while (reader.hasNext()) {
when (reader.nextName()) {
"result" -> result = reader.nextString()
"time_last_update_unix" -> timeLastUpdateUnix = reader.nextInt()
"time_last_update_utc" -> timeLastUpdateUtc = reader.nextString()
"time_next_update_unix" -> timeNextUpdateUnix = reader.nextInt()
"time_next_update_utc" -> timeNextUpdateUtc = reader.nextString()
"base_code" -> baseCode = reader.nextString()
"conversion_rates" -> {
reader.beginObject()
while (reader.peek() != JsonReader.Token.END_OBJECT) {
val code = reader.nextName()
val amount = when (code) {
baseCode -> reader.nextInt().toDouble()
else -> reader.nextDouble()
}
val infoBaseCode = baseCode
Timber.tag("MyTag")
.d(" code $code amount $amount infoBaseCode $infoBaseCode")
rates.add(
Rate(
code = code,
amount = amount,
infoBaseCode = infoBaseCode,
)
)
}
reader.endObject()
}
else -> reader.skipValue()
}
}
reader.endObject()
return InfoAndRatesResponse(
result = result,
timeLastUpdateUnix = timeLastUpdateUnix,
timeLastUpdateUtc = timeLastUpdateUtc,
timeNextUpdateUnix = timeNextUpdateUnix,
timeNextUpdateUtc = timeNextUpdateUtc,
baseCode = baseCode,
rates = rates
)
}
@ToJson
override fun toJson(writer: JsonWriter, value: 
InfoAndRatesResponse?) {
throw UnsupportedOperationException()
}
}

我不确定这一点,但是当它说"无法调用无参数构造器"时,对我来说,这听起来像是您需要能够创建一个没有参数的CurrencyResponse实例。也许试着设置一些默认值?我想试试这个:

data class ConversionRates(
val AED: Double = 0.0,
val AFN: Double = 0.0,
val ALL: Double = 0.0,
val AMD: Double = 0.0,
val ANG: Double = 0.0,
val AOA: Double = 0.0,
val ARS: Double = 0.0,
val AUD: Double = 0.0,
val AWG: Double = 0.0,
val AZN: Double = 0.0,
val BAM: Double = 0.0,
val BBD: Double = 0.0,
val BDT: Double = 0.0,
val BGN: Double = 0.0,
val BHD: Double = 0.0,
val BIF: Double = 0.0,
val BMD: Double = 0.0,
val BND: Double = 0.0,
val BOB: Double = 0.0,
val BRL: Double = 0.0,
val BSD: Double = 0.0,
val BTN: Double = 0.0,
val BWP: Double = 0.0,
)

相关内容

最新更新