美文网首页Android
android.os.TransactionTooLargeEx

android.os.TransactionTooLargeEx

作者: kevinsEegets | 来源:发表于2020-12-02 16:49 被阅读0次

首先看看Logcat日志如下:

1Caused by: android.os.TransactionTooLargeException: data parcel size 1278400 bytes
2at android.os.BinderProxy.transactNative(Native Method)
3at android.os.BinderProxy.transact(BinderProxy.java:532)
4at android.app.IActivityTaskManager$Stub$Proxy.activityStopped(IActivityTaskManager.java:4561)
5at android.app.servertransaction.PendingTransactionActions$StopInfo.run(PendingTransactionActions.java:145)
6at android.os.Handler.handleCallback(Handler.java:900)
7at android.os.Handler.dispatchMessage(Handler.java:103)
8at android.os.Looper.loop(Looper.java:219)
9at android.app.ActivityThread.main(ActivityThread.java:8347)
10at java.lang.reflect.Method.invoke(Native Method)
11at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
12at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1055)

原因分析

从上述日志可以看出。出现问题的原因是因为binder事务发送和接收的序列化对象过大,超过binder上限时,就会抛出该异常。
Google定义的上限时1M,但这是对整个进程的所有binder事务定义的,单个binder传递是小于该值的。

Android7.0之前该异常并不会影响app运行,之后会报以上异常。

出现场景

  • intent跳转时,bundle携带的数据量过大(比如,传递一个超大的数据集合或者bitmap)
  • Activity或Fragment执行onSaveInstanceState保存过多数据

分析工具

使用github上大佬提供的专门用于分析调试TransactionTooLargeException的工具toolargetool

toolargetool

A tool for debugging TransactionTooLargeException on Android.
https://github.com/guardian/toolargetool

解决办法

  • 根据Google建议,Activity跳转时intent携带的数据不要过大

  • 特别留意onSavedInstanceState场景,尽量避免过大的数据被保存

  • Fragment传递数据时,限制setArguments里的数据量过大

实际应用

我们有一个需求,使用ViewPager2实现直播间纵滑功能。

当切换的直播间比较多时,该bug可能会被触发造成崩溃。

我们首先在项目中引入toolargetool库进行分析(引入忽略,github上有详细接入流程)
我们使用adb logcat -s ToolargeTool检测一下日志输出


12-02 16:35:33.087 16961 16961 D TooLargeTool: LivePlayerPageActivity.onSaveInstanceState wrote: Bundle131394213 contains 5 keys and measures 19.0 KB when serialized as a Parcel
12-02 16:35:33.087 16961 16961 D TooLargeTool: * android:viewHierarchyState = 1.0 KB

12-02 16:35:52.402 16961 16961 D TooLargeTool: LivePlayerPageActivity.onSaveInstanceState wrote: Bundle140574781 contains 5 keys and measures 57.8 KB when serialized as a Parcel
12-02 16:35:52.402 16961 16961 D TooLargeTool: * android:viewHierarchyState = 14.2 KB

12-02 16:36:23.626 16961 16961 D TooLargeTool: LivePlayerPageActivity.onSaveInstanceState wrote: Bundle216803432 contains 5 keys and measures 83.2 KB when serialized as a Parcel
12-02 16:36:23.626 16961 16961 D TooLargeTool: * android:viewHierarchyState = 37.2 KB

12-02 16:37:12.587 16961 16961 D TooLargeTool: LivePlayerPageActivity.onSaveInstanceState wrote: Bundle91071570 contains 5 keys and measures 118.5 KB when serialized as a Parcel
12-02 16:37:12.587 16961 16961 D TooLargeTool: * android:viewHierarchyState = 76.1 KB

12-02 16:37:37.113 16961 16961 D TooLargeTool: LivePlayerPageActivity.onSaveInstanceState wrote: Bundle45092331 contains 5 keys and measures 166.8 KB when serialized as a Parcel
12-02 16:37:37.113 16961 16961 D TooLargeTool: * android:viewHierarchyState = 122.2 KB

12-02 16:39:31.786 16961 16961 D TooLargeTool: LivePlayerPageActivity.onSaveInstanceState wrote: Bundle267655365 contains 5 keys and measures 202.2 KB when serialized as a Parcel
12-02 16:39:31.786 16961 16961 D TooLargeTool: * android:viewHierarchyState = 159.7 KB

根据日志可以看出,当我们切换(纵滑)了多次直播间之后,android:viewHierarchyState = 122.2 KB值一直是增加的,当这个值增加到大约超过500kb时就会爆出该异常。
这里我们大概就能确定,造成该异常的直接原因就是viewpager2嵌入了Fragment,每切换一次Viewpager2,Fragment中的保存的状态就会增加

最简单的解决办法就是不保存状态。在我们的viewpager2中增加该代码android:saveEnabled="false"

reference:

Android view turn off implicit state retaining for some view

聊一聊Android的TransactionTooLargeException

相关文章

  • android.os.TransactionTooLargeEx

    首先看看Logcat日志如下: 原因分析 从上述日志可以看出。出现问题的原因是因为binder事务发送和接收的序列...

网友评论

    本文标题:android.os.TransactionTooLargeEx

    本文链接:https://www.haomeiwen.com/subject/qwfuwktx.html