android - 使用巨型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。
这个recycleview 可能会超载,成千上万的项目。它们每个都包含: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);
}
解决方案
这通常是由于在 onSaveInstanceState 中保存了大量数据造成的,不仅针对发生异常的 Activity,还针对当前在后台堆栈中的其他 Activity。
一种解决方案是使用 ViewModel 类而不是 onSaveInstanceState 来维护状态:
对于少量数据,您仍然可以使用 onSaveInstanceState,但请记住,它会累加所有活动。
推荐阅读
- visual-studio-code - 如何从 VSCode 语言服务器生成控制台输出/日志
- ms-access - 如何阻止此窗口出现
- wordpress - 如何为 woocommerce“即将推出”产品显示特定徽章
- javascript - 使用 forLoop 渲染信息卡和模式框仅超出其中一个字段的最后一个结果
- html - 对实体“id”的引用必须以“;”结尾 分隔符
- json - SwiftUI - 发出获取请求时收到错误
- angular - Angular Material Table 组件在首次加载时未显示数据
- javascript - 插件定义 PostCSS 配置 JS 文件上需要 VS 空对象 ({}) 之间的区别?
- python - 无法创建非常宽的画布
- spring-integration - Spring Integration DSL:将一些消息发送到 Flow inputChannel 的简单方法