In the android app there are cases need to pass some data around, crossing activity/fragment, pass to service etc. It has been using the parcelable and put in the intent/bundle. It works fine except get crash on over the one meg limit of the parcelable sometime.
android.os.TransactionTooLargeException: data parcel size 526576 bytes
Trying to see if it could put the content of the parcelable object into a lruCache, so basically replacing the parcelable's saving/loading with its own implementation of using lruCache.
Does this approach have any issue? Or any suggestion/alternative to address the problem?
@ApiSerializable
class DataItem (
@SerializedName("uuid")
var uuid: String = "",
@SerializedName("image")
val mainImage: Image?, //another parcelable type
@SerializedName("entities")
var entities: List<EntityInfo>?,
//......
// a lot of data
//......
//......
) : BaseDataItem(), IData {
override fun uuid(): String {
return uuid
}
//......
constructor(parcel: Parcel) : this(
parcel.readString(), //uuid
//...
//...
parcel.readParcelable(Image::class.java.classLoader),
mutableListOf<EntityInfo>().apply {
parcel.readTypedList(this, EntityInfo.CREATOR)
}) {
}
override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeString(uuid ?: "")
//......
//......
parcel.writeParcelable(mainImage, flags)
parcel.writeTypedList(entities)
}
override fun describeContents(): Int {
return 0
}
companion object CREATOR : Parcelable.Creator<DataItem> {
override fun createFromParcel(parcel: Parcel): DataItem {
return DataItem(parcel)
}
override fun newArray(size: Int): Array<DataItem?> {
return arrayOfNulls(size)
}
}
}
The approach is to replace the saving/loading from the parcel part with using lruCache itself:
// having the cache somewhere
val dataCache = LruCache<String, IData>(200)
and only one string member is saved/loaded with the Parcel:
fun init (copyData: DataItem) {
// do sopy over from the copyData
}
constructor(parcel: Parcel) : this() {
uuid = parcel.readString(), //uuid
val _thisCopy = dataCache.get(uuid)
init(_thisCopy)
}
override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeString(uuid ?: "")
dataCache.put(uuid, this)
}
You should avoid passing whole Object with large amount of data to your Next activity. So it might possible that your Object can have many data. So sometime system can not handle much data to transfer at a time. Try to use Preferences to store your object data and retrieve the same on other activity.