这种异常造成的原因是因为intent或者Binder传输的数据太大导致的异常。 如果Binder的参数或返回值太大,不适合的事务缓冲区,然后调用将失败,并将被抛出TransactionTooLargeException。

我这里出现这个异常的原因是在列表页面点击列表item跳转详情页的时候,除了需要携带选中的item对应的bean参数以外,还要做viewpager左右滑动的操作,所以直接将外面列表的bean类的list 放到了intent中作为参数传递

intent.putExtra("wallpaperBeanList", info as Serializable)

这样当外面列表没有做加载更多只有十几条数据的时候还没有问题,当用户加载了很多分页,list中已经存了上百条甚至上千条数据的时候,再以这样的方式传递参数就会有两个问题出现:

第一,跳转速度慢,因为点击后要做大量的读写操作

第二,就是容易发生TransactionTooLargeException:data parcel size XXXXX  bytes异常,原因就是传输的数据太大了

通过观察在bugly上统计的版本信息发现,报TransactionTooLargeException异常的手机,集中在Android N的版本里,也就是版本号只有24和25的,低于24或者高于25的一概没有。我们的App最低兼容到了16,但是即便在很古老的4.0,4.1,4.4的手机上也没有报这个错误。显然在Android N中,一定有一些特别的地方。

看下官方文档对于7.0发生了什么变动的一段说明:

Many platform APIs have now started checking for large payloads being sent across Bindertransactions, and the system now rethrows TransactionTooLargeExceptions as RuntimeExceptions, instead of silently logging or suppressing them. One common example is storing too much data in onSaveInstanceState(), which causes ActivityThread.StopInfo to throw a RuntimeException when your app targets Android 7.0.

可以看到,7.0的改动日志里确实提到了,Binder的数据传输确实有了新的限制,当数据量比较大的时候就会抛出 TransactionTooLargeExceptions ,不过这里并没有具体的说明到底多大的数据量会造成这个问题。这应该就是原因所在了。限制Binder的数据量,自然是为了性能考虑,虽然可以理解但搞不懂为什么不直接说明具体的限制,当然也许不同配置的手机限制不同。

知道了问题的原因,接下来就是如何解决问题了。

解决方法:采用新的方式来做传递这样容易大的参数,将需要用intent传递的参数变小

我这里采用用一个静态类做这个list参数的存储,当用户初始化这个列表页面,数据加载出来的时候就会给这个静态类的list赋值,当用户加载更多成功的时候也做一次新的赋值,跳转详情页面的时候不做传递这个参数的操作,只传递一个选中的item 的position 的参数,详情页直接获取静态类的list参数,显示刚才用户选中位置的item的信息即可,然后这样做静态参数数据的存储,需要做好内存的释放优化工作,当页面销毁的时候手动将静态参数的list清空,释放内存占用。网上也有用EventBus传递的或者rxjava传递来解决的,我这里没有用这些,用了个比较简单的办法解决了。

总结:开发中遇到问题并不可怕,一定要培养自己分析问题、解决问题的能力。开发工作做的久了,就不能只会写代码了,分析解决问题的能力显然更加重要,对于个人的成长是非常有用的,虽然不一定都要有能力造轮子,但也要学会让自己进阶,提升,摆脱只能“搬砖”的水平,这样以后遇到更加苛刻的问题才能更有能力面对解决……

感谢作者原文地址:https://blog.csdn.net/wjj1996825/article/details/84771777

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐