Paper version : 2.6implementation 'io.paperdb:paperdb:2.6'
The error
2020-03-09 13:30:24.841 14867-14994/com.spel.substrack W/System.err: io.paperdb.PaperDbException: Couldn't read/deserialize file /data/user/0/com.spel.substrack/files/io.paperdb/abbonamenti.pt for table abbonamenti
2020-03-09 13:30:24.841 14867-14994/com.spel.substrack W/System.err: at io.paperdb.DbStoragePlainFile.readTableFile(DbStoragePlainFile.java:298)
2020-03-09 13:30:24.841 14867-14994/com.spel.substrack W/System.err: at io.paperdb.DbStoragePlainFile.select(DbStoragePlainFile.java:158)
2020-03-09 13:30:24.841 14867-14994/com.spel.substrack W/System.err: at io.paperdb.Book.read(Book.java:73)
2020-03-09 13:30:24.841 14867-14994/com.spel.substrack W/System.err: at com.spel.substrack.activities.MainActivity$onCreate$1.invoke(MainActivity.kt:69)
2020-03-09 13:30:24.841 14867-14994/com.spel.substrack W/System.err: at com.spel.substrack.activities.MainActivity$onCreate$1.invoke(MainActivity.kt:26)
2020-03-09 13:30:24.841 14867-14994/com.spel.substrack W/System.err: at org.jetbrains.anko.AsyncKt$doAsync$1.invoke(Async.kt:143)
2020-03-09 13:30:24.841 14867-14994/com.spel.substrack W/System.err: at org.jetbrains.anko.AsyncKt$doAsync$1.invoke(Unknown Source:0)
2020-03-09 13:30:24.841 14867-14994/com.spel.substrack W/System.err: at org.jetbrains.anko.AsyncKt$sam$java_util_concurrent_Callable$0.call(Unknown Source:2)
2020-03-09 13:30:24.841 14867-14994/com.spel.substrack W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:266)
2020-03-09 13:30:24.841 14867-14994/com.spel.substrack W/System.err: at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301)
2020-03-09 13:30:24.841 14867-14994/com.spel.substrack W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
2020-03-09 13:30:24.841 14867-14994/com.spel.substrack W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
2020-03-09 13:30:24.841 14867-14994/com.spel.substrack W/System.err: at java.lang.Thread.run(Thread.java:919)
2020-03-09 13:30:24.841 14867-14994/com.spel.substrack W/System.err: Caused by: com.esotericsoftware.kryo.KryoException: Buffer underflow.
2020-03-09 13:30:24.841 14867-14994/com.spel.substrack W/System.err: Serialization trace:
2020-03-09 13:30:24.841 14867-14994/com.spel.substrack W/System.err: mContent (io.paperdb.PaperTable)
2020-03-09 13:30:24.841 14867-14994/com.spel.substrack W/System.err: at com.esotericsoftware.kryo.io.Input.require(Input.java:199)
2020-03-09 13:30:24.841 14867-14994/com.spel.substrack W/System.err: at com.esotericsoftware.kryo.io.Input.readUtf8_slow(Input.java:560)
2020-03-09 13:30:24.842 14867-14994/com.spel.substrack W/System.err: at com.esotericsoftware.kryo.io.Input.readUtf8(Input.java:553)
2020-03-09 13:30:24.842 14867-14994/com.spel.substrack W/System.err: at com.esotericsoftware.kryo.io.Input.readString(Input.java:483)
2020-03-09 13:30:24.842 14867-14994/com.spel.substrack W/System.err: at com.spel.substrack.dataStructures.SubSerial.read(Subscription.kt:117)
2020-03-09 13:30:24.842 14867-14994/com.spel.substrack W/System.err: at com.spel.substrack.dataStructures.SubSerial.read(Subscription.kt:89)
2020-03-09 13:30:24.842 14867-14994/com.spel.substrack W/System.err: at com.esotericsoftware.kryo.Kryo.readObject(Kryo.java:734)
2020-03-09 13:30:24.842 14867-14994/com.spel.substrack W/System.err: at com.esotericsoftware.kryo.serializers.ObjectField.read(ObjectField.java:125)
2020-03-09 13:30:24.842 14867-14994/com.spel.substrack W/System.err: at com.esotericsoftware.kryo.serializers.FieldSerializer.read(FieldSerializer.java:543)
2020-03-09 13:30:24.842 14867-14994/com.spel.substrack W/System.err: at com.esotericsoftware.kryo.Kryo.readObject(Kryo.java:712)
2020-03-09 13:30:24.842 14867-14994/com.spel.substrack W/System.err: at io.paperdb.DbStoragePlainFile.readContent(DbStoragePlainFile.java:307)
2020-03-09 13:30:24.842 14867-14994/com.spel.substrack W/System.err: at io.paperdb.DbStoragePlainFile.readTableFile(DbStoragePlainFile.java:291)
2020-03-09 13:30:24.842 14867-14994/com.spel.substrack W/System.err: ... 12 more
2020-03-09 13:30:24.842 14867-14994/com.spel.substrack E/ERRORE LETTURA: Couldn't read/deserialize file /data/user/0/com.spel.substrack/files/io.paperdb/abbonamenti.pt for table abbonamenti
The code
import android.app.Activity
import android.content.Context
import android.os.Parcel
import android.os.Parcelable
import com.esotericsoftware.kryo.DefaultSerializer
import com.esotericsoftware.kryo.Kryo
import com.esotericsoftware.kryo.Serializer
import com.esotericsoftware.kryo.io.Input
import com.esotericsoftware.kryo.io.Output
import com.spel.substrack.R
import com.spel.substrack.adapters.SubscriptionItem
import java.time.LocalDate
//classe per l'abbonamento
@DefaultSerializer(SubSerial::class)
data class Subscription(
var ID: Int = -1,
var nome: String = "",
var costo: Float = 0.0f,
var valuta: String = "",
var listaPagamenti: MutableList<Pagamento> = mutableListOf(),
var sincronizzato: Boolean = false,
var periodicita: Periodicita = Periodicita.MENSILE,
var moltiplicatore: Int = 1,
var debitoAccumulato: Float = 0.0f,
var debitoInStatistiche: Boolean = false,
var debitoIncrementoRinnvo : Boolean = false,
var note: String = "",
var tags: List<TAGS> = listOf(),
var colore: String = "",
var linkLogo : String = ""): Parcelable {
//costruttore per recuperare i dati dalla parcella
constructor(parcel: Parcel) : this(
ID = parcel.readInt(),
nome = parcel.readString() ?: "",
costo = parcel.readFloat(),
valuta = parcel.readString() ?: "",
listaPagamenti = parcel.readArray(ClassLoader.getSystemClassLoader())?.toMutableList() as MutableList<Pagamento>,
sincronizzato = parcel.readByte() != 0.toByte(),
periodicita = Periodicita.codeToPeriodicita(parcel.readInt()),
moltiplicatore = parcel.readInt(),
debitoAccumulato = parcel.readFloat(),
debitoInStatistiche = parcel.readByte() != 0.toByte(),
debitoIncrementoRinnvo = parcel.readByte() != 0.toByte(),
note = parcel.readString() ?: "",
tags = parcel.createIntArray()?.asList()?.map { TAGS.codeToTAG(it) } ?: emptyList<TAGS>(),
colore = parcel.readString() ?: "",
linkLogo = parcel.readString() ?: ""
)
//funzione per scrivere nella parcella
override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeInt(ID)
parcel.writeString(nome)
parcel.writeFloat(costo)
parcel.writeString(valuta)
parcel.writeParcelableArray(listaPagamenti.toTypedArray(),Parcelable.CONTENTS_FILE_DESCRIPTOR)
parcel.writeByte(if (sincronizzato) 1 else 0)
parcel.writeInt(periodicita.code)
parcel.writeInt(moltiplicatore)
parcel.writeFloat(debitoAccumulato)
parcel.writeByte(if (debitoInStatistiche) 1 else 0)
parcel.writeByte(if (debitoIncrementoRinnvo) 1 else 0)
parcel.writeString(note)
parcel.writeIntArray(tags.map { it.code }.toIntArray())
parcel.writeString(colore)
parcel.writeString(linkLogo)
}
//restituisco un hash per l'oggetto
override fun describeContents() = hashCode()
//creatore dell'oggetto parcellable
companion object CREATOR : Parcelable.Creator<Subscription> {
override fun createFromParcel(parcel: Parcel): Subscription {
return Subscription(parcel)
}
override fun newArray(size: Int): Array<Subscription?> {
return arrayOfNulls(size)
}
}
}
//serializzatore per subScription
class SubSerial : Serializer<Subscription>(){
//riporto l'abbonametno in serializzato
override fun write(kryo: Kryo?, output: Output?, sub: Subscription?) {
if(kryo != null && output != null && sub != null){
output.writeInt(sub.ID)
output.writeString(sub.nome)
output.writeFloat(sub.costo)
output.writeString(sub.valuta)
kryo.writeClassAndObject(output,sub.listaPagamenti)
output.writeBoolean(sub.sincronizzato)
output.writeInt(sub.periodicita.code)
output.writeInt(sub.moltiplicatore)
output.writeFloat(sub.debitoAccumulato)
output.writeBoolean(sub.debitoInStatistiche)
output.writeBoolean(sub.debitoIncrementoRinnvo)
output.writeString(sub.note)
kryo.writeObject(output,sub.tags.map { it.code })
output.writeString(sub.colore)
output.writeString(sub.linkLogo)
}
}
//restituisco l'abbonamento dal serializzato
override fun read(kryo: Kryo?, input: Input?, type: Class<Subscription>?): Subscription {
return if(kryo != null && input != null && type != null){
Subscription(
ID = input.readInt(),
nome = input.readString(),
costo = input.readFloat(),
valuta = input.readString(),
listaPagamenti = kryo.readClassAndObject(input) as MutableList<Pagamento>,
sincronizzato = input.readBoolean(),
periodicita = Periodicita.codeToPeriodicita(input.readInt()),
moltiplicatore = input.readInt(),
debitoAccumulato = input.readFloat(),
debitoInStatistiche = input.readBoolean(),
debitoIncrementoRinnvo = input.readBoolean(),
note = input.readString(),
tags = (kryo.readClassAndObject(input) as List<Int>).map { TAGS.codeToTAG(it)},
colore = input.readString(),
linkLogo = input.readString()
)
}else{
Subscription()
}
}
}
//classe per lo storico dei pagamenti
@DefaultSerializer(PagSerial::class)
data class Pagamento(
var ID: Int = 0,
var dataPagamento: LocalDate? = null,
var costo: Float = 0.0f
): Parcelable{
//costruttore per ricreare l'oggetto dalla parcella
constructor(parcel: Parcel) : this(
parcel.readInt(),
LocalDate.ofEpochDay(parcel.readLong()),
parcel.readFloat()
)
//scrvivo nella parcella
override fun writeToParcel(dest: Parcel?, flags: Int) {
if(dest != null) {
dest.writeInt(ID)
dataPagamento?.let {
dest.writeLong(it.toEpochDay())
}
dest.writeFloat(costo)
}
}
//restituisco un hash del contenuto
override fun describeContents() = hashCode()
//creatore dell'oggetto parcellable
companion object CREATOR : Parcelable.Creator<Pagamento> {
override fun createFromParcel(parcel: Parcel): Pagamento {
return Pagamento(parcel)
}
override fun newArray(size: Int): Array<Pagamento?> {
return arrayOfNulls(size)
}
}
}
//serializzatore per i pagamenti
class PagSerial : Serializer<Pagamento>(){
//creazione da oggetto a dato serializzato
override fun write(kryo: Kryo?, output: Output?, pag : Pagamento?) {
if(kryo != null && output != null && pag != null){
output.writeInt(pag.ID)
pag.dataPagamento?.let {
output.writeLong(it.toEpochDay())
}
output.writeFloat(pag.costo)
}
}
//lettura dal dato serailizzato a pagamento
override fun read(kryo: Kryo?, input: Input?, type: Class<Pagamento>?): Pagamento {
return if(kryo != null && input != null && type != null) {
Pagamento(input.readInt(), LocalDate.ofEpochDay(input.readLong()), input.readFloat())
}else{
Pagamento()
}
}
}
//enumeratore per la periodicità di pagamento
enum class Periodicita(val code: Int){
MENSILE(R.string.rinnovo_mensile),
ONE_TIME(R.string.rinnovo_onetime),
GIORNALIERO(R.string.rinnovo_giornaliero),
SETTIMANALE(R.string.rinnovo_settimanale),
ANNUALE(R.string.rinnovo_annuale);
//companion object dell'enumeratore
companion object {
//funzione che restituisce la periodicità da un codice
fun codeToPeriodicita(code: Int): Periodicita {
//restituisco la periodicità corrispondente
return when (code) {
MENSILE.code -> {
MENSILE
}
ONE_TIME.code -> {
ONE_TIME
}
GIORNALIERO.code -> {
GIORNALIERO
}
SETTIMANALE.code -> {
SETTIMANALE
}
ANNUALE.code -> {
ANNUALE
}
else -> {
MENSILE
}
}
}
}
}
//enumeratore per i tag
enum class TAGS(val code: Int) {
CASA(R.string.tag_casa),
MEDIA(R.string.tag_media),
MUSICA(R.string.tag_musica),
CINEMA(R.string.tag_cinema),
SALUTE(R.string.tag_salute),
SERVIZI(R.string.tag_servizi),
GIOCHI(R.string.tag_giochi),
TRASPORTI(R.string.tag_trasporti),
TECNOLOGIA(R.string.tag_tecno),
SPORT(R.string.tag_sport),
INTRATTENIMENTO(R.string.tag_intratt),
SHOPPING(R.string.tag_shopping),
INTERNET(R.string.tag_internet);
//companion object dell'enumeratore
companion object {
//funzione che restituisce il tag da un codice
fun codeToTAG(code: Int): TAGS {
//restituisco il tag corripspondente
return when (code) {
CASA.code ->{CASA}
MEDIA.code ->{MEDIA}
MUSICA.code ->{MUSICA}
CINEMA.code ->{CINEMA}
SALUTE.code ->{SALUTE}
SERVIZI.code ->{SERVIZI}
GIOCHI.code ->{GIOCHI}
TRASPORTI.code ->{TRASPORTI}
TECNOLOGIA.code ->{TECNOLOGIA}
SPORT.code ->{SPORT}
INTRATTENIMENTO.code ->{INTRATTENIMENTO}
SHOPPING.code ->{SHOPPING}
INTERNET.code ->{INTERNET}
//restituisco il primo tag della lista
else -> {CASA}
}
}
}
}
The init of Paper in the onCreate
//inizializzo il database e aggiungo il serializzatore
Paper.init(this)
Paper.addSerializer(Subscription::class.java,SubSerial())
Paper.addSerializer(Pagamento::class.java,PagSerial())
The reding of the list of Subscription
//inizilizzo il view pager
viewPager = binding.mainViewPager
//variabile per gli abbonamenti
var abbonamenti: List<Subscription> = emptyList()
//ricavo la lista degli abbonamenti
doAsync {
//ricavo la lista degli abbonamenti
try {
abbonamenti = Paper.book().read(
KEY_SUBSCRIPTION_BOOK,
emptyList<Subscription>()
).toList()
}catch (ex: Exception){
ex.printStackTrace()
Log.e("ERRORE LETTURA", ex.message.toString())
}
//nel thread principale
uiThread {
//pulisco la lista di abbonamenti
listaAbbonamenti.clear()
//aggiungo glia bbonamenti ricavati alla lista
listaAbbonamenti.addAll(abbonamenti)
//imposto l'adapter per il view pager
viewPager.adapter =
PagerAdapter(FRAG_NUMB, supportFragmentManager, listaAbbonamenti)
//inizializzo i compas List<Subscription>onenti restanti del layout
initLayout()
}
}
Anyone know how to solve the reading problem?
Can I use the serializer created with the Parcellable interface for reading and writing the database? Or does it have to be defined a separate serializer anyway?
Paper version : 2.6
implementation 'io.paperdb:paperdb:2.6'
The error
The code
The init of Paper in the onCreate
The reding of the list of Subscription
Anyone know how to solve the reading problem?
Can I use the serializer created with the Parcellable interface for reading and writing the database? Or does it have to be defined a separate serializer anyway?