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.
 * 

* 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. *

* 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. *

* 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. *

* 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. *

* 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. *

*/ 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粘性事件详解)

你可能感兴趣的:(Android,android,java,eclipse)