//如:没有权限异常,文件太大,错误的文件描述符,等等;
…
case FAILED_TRANSACTION: {
const char* exceptionToThrow;
char msg[128];
//官方在FIXME中写道:事务过大是FAILED_TRANSACTION最常见的原因
//但它不是唯一的原因,Binder驱动可以返回 BR_FAILED_REPLY
//也有其他原因可能是:事务格式不正确,文件描述符FD已经被关闭等等
//parcelSize大于200K就会报错,canThrowRemoteException传递进来的是true
if (canThrowRemoteException && parcelSize > 200*1024) {
// bona fide large payload
exceptionToThrow = “android/os/TransactionTooLargeException”;
snprintf(msg, sizeof(msg)-1, “data parcel size %d bytes”, parcelSize);
} else {
…
}
//使用指定的类和消息内容抛出异常
jniThrowException(env, exceptionToThrow, msg);
} break;
…
}
}
此时我们看到: parcelSize大于200K就会报错,难道一定是200K以内?先别着急着下结论,继续往下看👇👇
3.提出疑问
法海:我有个疑问,我看到文档写的1M大小啊;
许仙:别急,妹夫,来先看一下文档的解释,看一下使用说明:
官方TransactionTooLargeException的文档中描述到:Binder 事务缓冲区有一个有限的固定大小,目前为 1MB,由进程所有正在进行的事务共享
可以看到写的是:共享事务的缓冲区
如来佛祖:汝等别急,我们简单测试一下,Intent传递201*1024
个字节数组,我们发现可以正常传递过去,Logcat仅仅输出了一个Error提示的日志信息,还是可以正常传递的
E/ActivityTaskManager: Transaction too large, intent: Intent { cmp=com.melody.test/.SecondActivity (has extras) }, extras size: 205848, icicle size: 0
我们再测试一个值,intent传递800*1024
个字节数组,我们发现会崩溃
android.os.TransactionTooLargeException: data parcel size 821976 bytes
at android.os.BinderProxy.transactNative(Native Method)
at android.os.BinderProxy.transact(BinderProxy.java:540)
at android.app.IApplicationThread S t u b Stub StubProxy.scheduleTransaction(IApplicationThread.java:2504)
at android.app.servertransaction.ClientTransaction.schedule(ClientTransaction.java:136)
不要着急,我们继续往下看分析
4.解答疑问
我们来看一下,下面两行代码
//frameworks/base/core/jni/android_util_Binder.cpp
//这个方法android_os_BinderProxy_transact里面的
IBinder* target = getBPNativeData(env, obj)->mObject.get();
status_t err = target->transact(code, *data, reply, flags);
从上面的分析和测试结果,我们从target->transact
这里来找err返回值
, 先根据头文件,搜索对应的cpp类,我们看一下这几个cpp类