Activity之间使用intent传递大量数据带来问题总结

转载请注明:大飞 http://blog.csdn.net/rflyee/article/details/47441405

Activity之间使用Parcel传递大量数据产生的问题。

Activity之间通过intent传递大量数据,导致新Activity无法启动。

Activity之间数据传递方式总结參考 这 里

比較经常使用的是直接利用intent传递,比方使用bundle。例如以下:

Intent intent =new Intent(ActivityA.this,ActivityB.class);
Bundle bundle =new Bundle();
bundle.putParcelableArrayList("data", dataList);
intent.putExtras(bundle);
startActivity(intent);

问题:当传递数据量过大,比方list的size过大,会导致B无法启动。现象即启动失败。activityB的oncreate()都不会运行。

分析:

官方文档提到TransactionTooLargeException异常,“The
Binder transaction failed because it was too large.”即数据传输过大异常。

而且提到这样一句话:“Parcel objects
stored in the Binder transaction buffe”,这表明实际上底层parcel对象在不同activity直接传递过程中保存在一个叫做“ Binder
transaction buffe”的地方,既然是缓冲区,肯定有限制大小。

官方文档还提到

“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.”

即缓冲区最大1MB,而且这是该进程中全部正在进行中的传输对象所公用的。至于都有哪些传输对象、详细怎么分配,这个还不太清楚。能够肯定的是Activity之间使用Parcel数据传输是有限制大小的。那么在传输大小可能非常大的情况下就要做点处理了。

-------

另外,

该博客“Yet
another post on Serializable vs Parcelable”中
在对照Serializable和Parcel时提到下面两点数据,仅供參考了解。实际使用各有不同

1. 使用Serializable和parcel传输同样对象,都转换为byte[]后,parcel大概是serializable的20倍了。

2. 可是官方建议使用Parcel,原因是说速度是serializable的将近10倍。

Serializable: it‘s
error prone and horribly slow. So in general: stay away from Serializable if
possible.

Parcelable: If
you want to pass complex user-defined objects, take a look at the Parcelable interface.
It‘s harder to implement, but it has considerable speed gains compared to Serializable.

可是有时候出现该问题时竟然不报错(我遇到的就没抛异常)。甚至没有特殊的log(adb logcat -v threadtime -s ActivityManager 、adb logcat -b events)

并没有像文章或者官方文档中提到的“ throwing a TransactionTooLargeException (or
just logging E:
!!! FAILED BINDER TRANSACTION !!!
 on pre 15 API levels)”

比較奇葩。

---------

针对parcel传递数据限制大小,自个儿做了个简单实验:

机型:Galaxy Nexus

系统:4.1.2  sdk16

过程:ActivityA,ActivityB。DataBean(每一个对象大概200byte),A启动B并使用Parcel对象传递list<dataBean>。

当list大小为900个时。无法启动B。即数据传输大概在200*900 < 200k

所以依照官方解释,对于详细某一次Activity间传输的大小限制是不确定的。根据使用环境而定。

解决方法:

括弧,赶紧下面解决方式都不是非常理想啊,,,

一. 限制传递数据量

二. 改变传输数据方式(參见Activity之间传递数据的方式

1. 静态static

2. 单例

3. Application

4. 持久化

转载请注明:大飞 http://blog.csdn.net/rflyee/article/details/47441405

參考:

http://stackoverflow.com/questions/12819617/issue-passing-large-data-to-second-activity

http://nemanjakovacevic.net/blog/english/2015/03/24/yet-another-post-on-serializable-vs-parcelable/

时间: 2024-10-13 08:13:38

Activity之间使用intent传递大量数据带来问题总结的相关文章

android中传递复杂参数,Activity之间通过Intent使用bundle,fragment之间和Activityty通过setArguments使用bundle

在Android开发中,Activity之间通过Intent使用bundle,fragment之间和Activityty通过setArguments使用bundle,对于一些简单的参数传递比较简单,而且方式也有多种,这个就不介绍了.在这里介绍一下复杂的参数传递,比如传递集合ArrayList,对象ArrayList<Object>. 无论是Activity之间参数传递,还是Fragment之间参数传递,或者是Activity与Fragment之间,都要使用Bundle,方式基本相同.Bundl

Android开发经验之—intent传递大数据

在Activity或者组件之前传递信息时,一般采用intent绑定bundle的方式传值,但在使用过程中需要注意的是不要用bundle传递大容量数据: 在做项目的过程中,需要将听写界面的听写结果信息传递到听写记录界面供显示用,但是由于传递的数据量过大导致程序ANR,甚至直接报异常(传递的信息里面有bitmap转换成的byte数组.每一个词组的拼音.词语.语音信息),经过分析发现是由于bundle不能传递大容量的数据信息,在stackoverflow里面查阅发现有同行遇到类似的问题: (1)"Th

Activity之间利用intent单个传递数据和批量传递数据

1.利用intent传递数据,若是单个传递数据时,利用putExtra即可完成传递 intent.putExtra("tel", "15607209140");//单个数据传递 Bundle b=new Bundle(); b.putString("name1", "zp"); b.putString("name2", "db");//批量传递数据 intent.putExtras(b)

Android activity之间的跳转和数据传递

1.Activity之间的跳转 并且 传递数据 A Activity进行的操作 Intent intent = new Intent(context, B.class); intent.putExtra("tn",tn); intent.putExtra("payMode",payMode); context.startActivity(intent); B activity接收数据 protected void onCreate(Bundle savedInsta

【Android】多个Activity之间利用bundle传递数值

安卓中的Activity相当于vb,mfc中的窗体,在多个Activity之间传递数据是一个相当核心的功能.下面举个例子来说明这个问题. 一.基本目标 用户在两个输入框中输入用户名.密码之后,跳到另一个Activity当中,显示其输入的内容, 然后这两个Activity能够轻松跳转. 二.制作过程 1.首先MainActivity的登录界面是沿用了<[Android]利用表格布局,Android中xml文件与java的交互制作登录界面>(点击打开链接)的布局,其布局文件activity_mai

在Activity之间使用Intent传值和Bundle传值的区别和方式

两者本质上没有任何区别.Bundle只是一个信息的载体 将内部的内容以键值对组织 Intent负责Activity之间的交互 自己是带有一个Bundle的Intent.putExtras(Bundle bundle)直接将Intent的内部Bundle设置为参数里的bundleIntent.getExtras()直接可以获取Intent带有的Bundle intent.putExtra(key, value)和Bundle bundle = intent.getExtras();bundle.p

Android Activity之间信息的传递

在Android中,活动是一个界面,当需要在界面之间相互切换的时候,需要用到Intent(意图)进行消息传递.使用startActivity(Intent)函数启动另一个活动. Bundle是一个key-Value类,可以用他携带信息. Bundle.putString("key","String")方法和Bundle.getString("key")方法放入与取出信息. 可以将信息放入到Intent中,使用方法Intent.putExtras(

Activity跳转时传递简单数据

一.新建一个空的工程 二.在主界面中添加一个按钮 三.新建一个空的activity,并命名为TheAty 四.修改MainActivity.java中的onCreate函数 protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.btnStartAty).set

activity之间值的传递和返回

activity1传值给activity2,我们可以用Intent.putExtra来实现,还可以用bundle来完成.在此不赘述. 在2返回值给1的时候我们也可以用这样的方式,然后跳转活动,startActivity. 但是,还有一个方法叫setResult(resultCode, intent Data) ,在活动二中使用 Intent i = new Intent(); i.putExtra("data", "this is a message "); set