how to avoid getting the "android.os.TransactionTooLargeException"

500 views Asked by At

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)
    }
1

There are 1 answers

1
Ajay Mehta On

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.

Please my answer for here: Exception when starting activity android.os.TransactionTooLargeException: data parcel size