这属于android中最常见的TransactionTooLargeException的后果表现之一。
该问题较多出现在使用PackageManager查询系统的应用的信息,通过Intent来过滤匹配目标应用组件(android四大组件)时,典型堆栈如下:
|
这是Java层的堆栈,原始抛出异常的地方在于文件frameworks/base/core/jni/android_util_Binder.cpp:
|
该FAILED_TRANSACTION错误码定义于:
/bionic/libc/kernel/common/linux/binder.h中的BR_FAILED_REPLY
|
其原因总结如下,首先Android系统对于Binder IPC每进程的事务buffer上限是1M(为所有Binder事务共享,且不区分目标系统的ram配置等因素),在通过PackageManager中获取系统内应用时,比如应用的Icon是个bitmap,且不同应用所制作Icon的品质(像素数)上差异很大。会占用大量内存导致Binder事务内存超过上限。
Binder事务buffer的尺寸定义在ProcessState.cpp:
|
App icon对应的数据模型如下:
|
该问题是android系统的限制,只能通过上层来捕获该异常来绕过。当然也不仅限于PackageManager,其他系统服务,应用间的Binder调用也可以带来这一问题。
最后的最后,由于在c++向java层抛出这个异常的场景有多种(见上边c++代码中“FAILED_TRANSACTION”处的注释),所以当你收到了TransactionTooLargeException的时候,不意味着真正的Transaction is Too Large。