как избежать получения «android.os.TransactionTooLargeException» - PullRequest
0 голосов
/ 19 апреля 2019

В приложении для Android есть случаи, когда необходимо передать некоторые данные, пересечь активность / фрагмент, перейти в сервис и т. Д. В нем использовался parcelable и помещен в намерение / связку. Он работает нормально, за исключением случаев, когда время от времени происходит сбой свыше одного мегабайта от пакета.

android.os.TransactionTooLargeException: data parcel size 526576 bytes

Попытка выяснить, может ли он поместить содержимое передаваемого объекта в lruCache, поэтому в основном заменяет сохранение / загрузку передаваемого объекта собственной реализацией использования lruCache.

Есть ли у этого подхода какие-либо проблемы? Или любое предложение / альтернатива для решения проблемы?

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

Подход заключается в том, чтобы заменить сохранение / загрузку из части посылки с помощью самого lruCache:

    // having the cache somewhere
    val dataCache =  LruCache<String, IData>(200)

и только один строковый элемент сохранен / загружен с Посылкой:

    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 Ответ

0 голосов
/ 19 апреля 2019

Вы должны избегать передачи всего Объекта с большим количеством данных в следующее действие. Так что вполне возможно, что ваш объект может иметь много данных. Поэтому иногда система не может обрабатывать много данных для передачи за один раз. Попробуйте использовать Предпочтения, чтобы сохранить данные вашего объекта и получить то же самое для других действий.

Пожалуйста, ответьте здесь: Исключение при запуске действия android.os.TransactionTooLargeException: размер пакета данных

...