When you have a big POJO with loads of variables (Booleans, Int, Strings) and you want to use the new Work Manager to start a job. You then create a Data file which gets added t
This solution works without using JSON, and serializes directly to byte array.
package com.andevapps.ontv.extension
import android.os.Parcel
import android.os.Parcelable
import androidx.work.Data
import java.io.*
fun Data.Builder.putParcelable(key: String, parcelable: Parcelable): Data.Builder {
val parcel = Parcel.obtain()
try {
parcelable.writeToParcel(parcel, 0)
putByteArray(key, parcel.marshall())
} finally {
parcel.recycle()
}
return this
}
fun Data.Builder.putParcelableList(key: String, list: List): Data.Builder {
list.forEachIndexed { i, item ->
putParcelable("$key$i", item)
}
return this
}
fun Data.Builder.putSerializable(key: String, serializable: Serializable): Data.Builder {
ByteArrayOutputStream().use { bos ->
ObjectOutputStream(bos).use { out ->
out.writeObject(serializable)
out.flush()
}
putByteArray(key, bos.toByteArray())
}
return this
}
@Suppress("UNCHECKED_CAST")
inline fun Data.getParcelable(key: String): T? {
val parcel = Parcel.obtain()
try {
val bytes = getByteArray(key) ?: return null
parcel.unmarshall(bytes, 0, bytes.size)
parcel.setDataPosition(0)
val creator = T::class.java.getField("CREATOR").get(null) as Parcelable.Creator
return creator.createFromParcel(parcel)
} finally {
parcel.recycle()
}
}
inline fun Data.getParcelableList(key: String): MutableList {
val list = mutableListOf()
with(keyValueMap) {
while (containsKey("$key${list.size}")) {
list.add(getParcelable("$key${list.size}") ?: break)
}
}
return list
}
@Suppress("UNCHECKED_CAST")
fun Data.getSerializable(key: String): T? {
val bytes = getByteArray(key) ?: return null
ByteArrayInputStream(bytes).use { bis ->
ObjectInputStream(bis).use { ois ->
return ois.readObject() as T
}
}
}
Add proguard rule
-keepclassmembers class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator CREATOR;
}