Android Intent传递数据大小限制详解
前言
在sendbroadcast,startactivity时,我们会用到intent。
intent可以携带一些数据,比如基本类型数据int、boolean,或是string,或是序列化对象,parcelable与serializable。
intent传递数据时,如果数据太大,可能会出现异常。比如app闪退,或是intent发送不成功,logcat报错等等。
这就牵涉到一个问题:intent 传递数据大小限制。
intent到底能够携带多少数据呢?
使用intent传送数据时,可能会出现异常
在intent中传入一个parcelable对象;例如传入一个bitmap对象。
代码参考: github.com/rustfisher/…
bitmap b1 = bitmap.createscaledbitmap(srcbmp, dstwid, dstheight, false); intent intent = new intent(msg_intent); intent.putextra(k_pic, b1);
选择bitmap的原因是,bitmap实现了parcelable接口,并且可以通过getbytecount()得知所占内存大小。
sendbroadcast时,报出如下信息
v/activitymanager: broadcast: intent { act=intent_bi flg=0x10 (has extras) } ordered=false userid=0 callerapp=processrecord{27aeaaf5 31217:com.rustfisher.basic4/u0a113}
e/javabinder: !!! failed binder transaction !!!
w/broadcastqueue: failure sending broadcast intent { act=intent_bi flg=0x10 (has extras) }
android.os.transactiontoolargeexception
at android.os.binderproxy.transactnative(native method)
at android.os.binderproxy.transact(binder.java:504)
at android.app.applicationthreadproxy.scheduleregisteredreceiver(applicationthreadnative.java:1170)
at com.android.server.am.broadcastqueue.performreceivelocked(broadcastqueue.java:576)
at com.android.server.am.broadcastqueue.delivertoregisteredreceiverlocked(broadcastqueue.java:848)
at com.android.server.am.broadcastqueue.processnextbroadcast(broadcastqueue.java:917)
at com.android.server.am.broadcastqueue$broadcasthandler.handlemessage(broadcastqueue.java:254)
at android.os.handler.dispatchmessage(handler.java:111)
at android.os.looper.loop(looper.java:194)
at android.os.handlerthread.run(handlerthread.java:61)
at com.android.server.servicethread.run(servicethread.java:46)
查看异常类transactiontoolargeexception,它继承了remoteexception
package android.os; public class transactiontoolargeexception extends remoteexception { public transactiontoolargeexception() { super(); } public transactiontoolargeexception(string msg) { super(msg); } }
追踪到binder,它的transactnative方法会报出remoteexception
public native boolean transactnative(int code, parcel data, parcel reply, int flags) throws remoteexception;
抛出异常与binder有关。
intent携带信息的大小受binder限制
intent携带信息的大小其实是受binder限制。本文标题也可以改为“binder传递数据大小限制”。
数据以parcel对象的形式存放在binder传递缓存中。
如果数据或返回值比传递buffer大,则此次传递调用失败并抛出transactiontoolargeexception异常。
binder传递缓存有一个限定大小,通常是1mb。但同一个进程中所有的传输共享缓存空间。
多个地方在进行传输时,即时它们各自传输的数据不超出大小限制,transactiontoolargeexception异常也可能会被抛出。
在使用intent传递数据时,1mb并不是安全上限。因为binder中可能正在处理其它的传输工作。
不同的机型和系统版本,这个上限值也可能会不同。
在其它地方,例如onsaveinstancestate(@nonnull bundle outstate),也可能会遇到与binder有关的。
为什么binder要限制传输数据的大小
个人推测,作为一种ipc的方式,binder并不是为传输大量数据而设计。
传输大量数据,可以考虑url之类的方法。
参考
- …
- …
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对的支持。
上一篇: 孕妇长痘痘吃什么水果好
下一篇: 详解JS实现简单的时分秒倒计时代码