首页 > 解决方案 > 使用巨型recycleview时出现android.os.TransactionTooLargeException

问题描述

有时我的主要活动中会遇到这个烦人的异常。
堆栈跟踪是这样的:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.tomatedigital.lottogram, PID: 4430
    java.lang.RuntimeException: android.os.TransactionTooLargeException: data parcel size 543588 bytes
        at android.app.ActivityThread$StopInfo.run(ActivityThread.java:4156)
        at android.os.Handler.handleCallback(Handler.java:789)
        at android.os.Handler.dispatchMessage(Handler.java:98)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6944)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
     Caused by: android.os.TransactionTooLargeException: data parcel size 543588 bytes
        at android.os.BinderProxy.transactNative(Native Method)
        at android.os.BinderProxy.transact(Binder.java:761)
        at android.app.IActivityManager$Stub$Proxy.activityStopped(IActivityManager.java:5147)
        at android.app.ActivityThread$StopInfo.run(ActivityThread.java:4148)
        at android.os.Handler.handleCallback(Handler.java:789) 
        at android.os.Handler.dispatchMessage(Handler.java:98) 
        at android.os.Looper.loop(Looper.java:164) 
        at android.app.ActivityThread.main(ActivityThread.java:6944) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374) 

跟踪本身并不是很有帮助,因为它没有指定哪个组件或哪个事务 ID 或标签与异常相关(谷歌请考虑你放在那里的废话的可调试性)......但我确实怀疑它是我在主要活动中的recycleview。

这个rec​​ycleview 可能会超载,成千上万的项目。它们每个都包含:3 个小字符串、1 个大字符串和一个小位图。

当这个 recyclerview 被重载并且活动被挂起时,这个异常被抛出。由于 recyclerview 是通过扩展 layout.xml 创建的,因此 android 会自动保存其状态。

有什么简单的方法可以解决这个问题吗?
是否可以将App设置为允许“超大交易”?
我能做些什么?

================更新=================== 提供有关我的活动的其他信息

 @Override
    protected void onSaveInstanceState(@NonNull Bundle outState) {
        outState.putSerializable("media", this.media); //this is a domain class
        outState.putBoolean("canceled", this.canceled);
        outState.putInt("speed", this.speed);
        outState.putLong("startTime", this.startTime);
        outState.putSerializable("comments", (Serializable) this.adapter.getList()); //this is the large data
        outState.putBoolean("commentLoadComplet", this.complete);
        outState.putSerializable("fetched", (Serializable) this.fetched);
        outState.putSerializable("igiboAttendees", (Serializable) this.igiboAttendees);
        outState.putLong("winnerId", this.winnerId);

        super.onSaveInstanceState(outState);
    }

标签: androidandroid-recyclerviewandroid-transitionsparcel

解决方案


这通常是由于在 onSaveInstanceState 中保存了大量数据造成的,不仅针对发生异常的 Activity,还针对当前在后台堆栈中的其他 Activity。

一种解决方案是使用 ViewModel 类而不是 onSaveInstanceState 来维护状态:

ViewModel 概述

对于少量数据,您仍然可以使用 onSaveInstanceState,但请记住,它会累加所有活动。


推荐阅读