Caused by: android.os.TransactionTooLargeException: data parcel size 1910660 bytes 问题原因与解决

从AActivity跳转BActivity通过intent.putExtra传递数据,结果报android.os.TransactionTooLargeException: data parcel size 551728 bytes错误,意思就是传输的数据过大,传递的是图片地址存储的 List< String >。准备到下个页面做预览功能

Caused by: android.os.TransactionTooLargeException: data parcel size 1910660 bytes 22 at 

android.os.BinderProxy.transactNative(Native Method) 23 at 

android.os.BinderProxy.transact(Binder.java:1154) 24 at 

android.app.IActivityManager$Stub$Proxy.startActivity(IActivityManager.java:3676) 25 at 

android.app.Instrumentation.execStartActivity(Instrumentation.java:1705) 26 ... 15 more

 

源码
遇到问题我们首先看下TransactionTooLargeException这个类的源码注释,里面肯定有说明

通过以下源码注释内容可以了解到以下几点信息:

(1)通过Intent传递或者返回的数据是存放在一个叫做Binder transaction buffer的缓存区,这个缓冲 区的大小为1Mb(Android 28 Platform),当缓冲区不够用时就会抛出异常


(2)如果有多个数据传递同时进行,是共用缓冲区的1Mb,而不是每一个传输各分配1Mb缓存。这就有可能当多个传输同时进行时,数据大小小于1M还是抛出TransactionTooLargeException异常


(3)建议的解决方法就是尽可能减小传输的数据,至于具体要多效合上也没个具体的数值,也不可能知道,因为并发传输的数量不固定,但是至少可以肯定的是超过1M肯定会抛异常

/**
 * The Binder transaction failed because it was too large.
 * <p>
 * During a remote procedure call, the arguments and the return value of the call
 * are transferred as {@link Parcel} objects stored in the Binder transaction buffer.
 * If the arguments or the return value are too large to fit in the transaction buffer,
 * then the call will fail and {@link TransactionTooLargeException} will be thrown.
 * </p><p>
 * The Binder transaction buffer has a limited fixed size, currently 1Mb, which
 * is shared by all transactions in progress for the process.  Consequently this
 * exception can be thrown when there are many transactions in progress even when
 * most of the individual transactions are of moderate size.
 * </p><p>
 * There are two possible outcomes when a remote procedure call throws
 * {@link TransactionTooLargeException}.  Either the client was unable to send
 * its request to the service (most likely if the arguments were too large to fit in
 * the transaction buffer), or the service was unable to send its response back
 * to the client (most likely if the return value was too large to fit
 * in the transaction buffer).  It is not possible to tell which of these outcomes
 * actually occurred.  The client should assume that a partial failure occurred.
 * </p><p>
 * The key to avoiding {@link TransactionTooLargeException} is to keep all
 * transactions relatively small.  Try to minimize the amount of memory needed to create
 * a {@link Parcel} for the arguments and the return value of the remote procedure call.
 * Avoid transferring huge arrays of strings or large bitmaps.
 * If possible, try to break up big requests into smaller pieces.
 * </p><p>
 * If you are implementing a service, it may help to impose size or complexity
 * contraints on the queries that clients can perform.  For example, if the result set
 * could become large, then don't allow the client to request more than a few records
 * at a time.  Alternately, instead of returning all of the available data all at once,
 * return the essential information first and make the client ask for additional information
 * later as needed.
 * </p>
 */

public class TransactionTooLargeException extends RemoteException {
    public TransactionTooLargeException() {
        super();
    }
 
    public TransactionTooLargeException(String msg) {
        super(msg);
    }
}

解决方法
根据官方的建议就是减小传输的数据大小,或者拆分数据分次传输,但是如果数据量真的很大且需一次性传输有没解决方法呢,当然有

1.数据保存到static全局变量中

2.数据保存到本地存储中,比如本地文件或数据库,在目标Activity中再提取出来

3.通过EventBus.postSticky传递包含传递数据的粘性事件,在目标Activity中接收该事件提取数据(关于粘性事件参考Android EventBus Sticky Events粘性事件详解)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值