Я пытаюсь сохранить экземпляр моего Kotlin класса в файле JSON с помощью библиотеки Gson. Однако когда я запускаю Gson (). Из Json, я получаю следующую ошибку:
java .lang.RuntimeException: Не удалось вызвать publi c com.keikakupet. PetStatus () без аргументов
Насколько я понимаю, ошибка заключается в том, что Gson требует, чтобы у моего класса был первичный конструктор, который не принимает аргументов, чтобы он мог создать нужный объект (в данном случае объект PetStatus ). Однако у меня есть такой конструктор. Я не уверен, что часть проблемы заключается в том, что я запускаю метод из init. Кто-нибудь знает, как можно исправить эту ошибку?
Мой код:
package com.keikakupet
import android.content.Context
import android.util.Log
import com.google.gson.Gson
import java.io.File
import java.util.*
import java.io.BufferedReader
class PetStatus constructor(){
var maxHealth: Int = 10
var currentHealth: Int = 10
var healthIncrementer: Int = 2 // amount by which health increments when a task is completed
var healthDecrementer: Int = 0 // amount by which health decrements when user approaches / misses deadline
var isHungry: Boolean = false
var isTired: Boolean = false
var isSick: Boolean = false
var isAlive: Boolean = true
init{
//if a json exists, use it to update PetStatus
val context = getContext()
var file = File(context.getFilesDir(), "PetStatus.json")
if(file.exists()){
Log.d("FILE_EXISTS", "File exists!")
val bufferedReader: BufferedReader = file.bufferedReader()
val json = bufferedReader.readText()
val retrievedStatus = Gson().fromJson(json, PetStatus::class.java)
Log.d("JSON_RETRIEVED", json)
}
else
Log.d("FILE_DNE", "File does not exist!")
updateJson()
}
// method to update pet's health and ailment upon completing a task
fun processCompletedTask(){
incrementHealth()
removeAilment()
Log.d("TASK_COMPLETE", "completed task processed")
}
fun getHealthPercent(): Int {
return currentHealth / maxHealth
}
// method to update pet's health and ailment upon missing a task
fun processMissedTask(){
decrementHealth()
addAilment()
Log.d("TASK_MISSED", "missed task processed")
}
/*
Potentially creating another method to update pet's
health and status because of an approaching deadline.
*/
// method to decrement the pet's health
private fun decrementHealth(){
currentHealth-=healthDecrementer
if(currentHealth <= 0)
isAlive = false
updateJson()
}
// method to increment the pet's health
private fun incrementHealth(){
val sum = currentHealth + healthIncrementer
if(sum > maxHealth)
currentHealth = maxHealth
else
currentHealth = sum
updateJson()
}
// method to add an ailment to the pet
private fun addAilment(){
// if no ailment, randomly assign hungry or tired
if(!isHungry && !isTired && !isSick){
val rand = Random()
val randBool = rand.nextBoolean()
if(randBool)
isHungry = true
else
isTired = true
healthDecrementer = 1
}
// otherwise, if hungry XOR tired, assign the other
else if(isHungry && !isTired){
isTired = true
healthDecrementer = 2
}
else if(isTired && !isHungry){
isHungry = true
healthDecrementer = 2
}
// otherwise, if both hungry AND tired, assign sick
else if(isHungry && isTired){
isSick = true
healthDecrementer = 3
}
updateJson()
}
// method to remove an ailment from the pet
private fun removeAilment(){
// if sick, remove sick
if(isSick){
isSick = false
healthDecrementer = 2
}
// otherwise, if hungry and tired, remove one of the two randomly
else if(isHungry && isTired){
val rand = Random()
val randBool = rand.nextBoolean()
if(randBool)
isHungry = false
else
isTired = false
healthDecrementer = 1
}
// otherwise, if hungry XOR tired, remove relevant ailment
else if(isHungry && !isTired){
isHungry = false
healthDecrementer = 0
}
else if(isTired){
isTired = false
healthDecrementer = 0
}
updateJson()
}
private fun updateJson(){
val gson = Gson()
var json: String = gson.toJson(this)
Log.d("JSON_UPDATE", json)
val context = getContext()
var file = File(context.getFilesDir(), "PetStatus.json")
file.writeText(json)
val bufferedReader: BufferedReader = file.bufferedReader()
json = bufferedReader.readText()
Log.d("JSON_FROM_FILE", json)
}
companion object {
private lateinit var context: Context
fun setContext(con: Context) {
context=con
}
fun getContext() : Context {
return context
}
}
}
Информация Logcat:
Caused by: java.lang.RuntimeException: Failed to invoke public com.keikakupet.PetStatus() with no args
at com.google.gson.internal.ConstructorConstructor$3.construct(ConstructorConstructor.java:118)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:212)
at com.google.gson.Gson.fromJson(Gson.java:927)
at com.google.gson.Gson.fromJson(Gson.java:892)
at com.google.gson.Gson.fromJson(Gson.java:841)
at com.google.gson.Gson.fromJson(Gson.java:813)
at com.keikakupet.PetStatus.<init>(PetStatus.kt:32)
at java.lang.reflect.Constructor.newInstance0(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
at com.google.gson.internal.ConstructorConstructor$3.construct(ConstructorConstructor.java:110)
... 4981 more