欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android开发Error(建议收藏下来以备不时之需)android.os.TransactionTooLargeException: data parcel size xxxx bytes...

程序员文章站 2022-04-15 17:43:53
...

前言

该异常触发的概率不大,很多Android猴子可能都没遇到过
但是真的出现的时候别不知道怎么解决

什么情况出现

界面跳转 intent 中的数据内容较多
Android调用系统裁减图片
批量插入大量数据到数据库(我是这种情况,一下主要针对批量插入数据库讲解)

系统源码

源码位置:android/frameworks/base/core/jni/android_util_Binder.cpp
是的你没看错,在以上三种传输中 大于200K就会报错

case FAILED_TRANSACTION: {
            ALOGE("!!! FAILED BINDER TRANSACTION !!!  (parcel size = %d)", parcelSize);
            const char* exceptionToThrow;
            char msg[128];
            // TransactionTooLargeException is a checked exception, only throw from certain methods.
            // FIXME: Transaction too large is the most common reason for FAILED_TRANSACTION
            //        but it is not the only one.  The Binder driver can return BR_FAILED_REPLY
            //        for other reasons also, such as if the transaction is malformed or
            //        refers to an FD that has been closed.  We should change the driver
            //        to enable us to distinguish these cases in the future.
            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 {
                // Heuristic: a payload smaller than this threshold "shouldn't" be too
                // big, so it's probably some other, more subtle problem.  In practice
                // it seems to always mean that the remote process died while the binder
                // transaction was already in flight.
                exceptionToThrow = (canThrowRemoteException)
                        ? "android/os/DeadObjectException"
                        : "java/lang/RuntimeException";
                snprintf(msg, sizeof(msg)-1,
                        "Transaction failed on small parcel; remote process probably died");
            }
            jniThrowException(env, exceptionToThrow, msg);
        } break;

解决方案

intent 传递的数据过大 把大型的序列化集合或者Bitmap缓存 传递缓存路径即可
Android调用系统裁减图片 Bitmap 过大 这个时候只能通过MediaStore.EXTRA_OUTPUT设置裁减图片保存位置,只传递图片路径,不直接传bitmap对象。
批量插入大量数据到数据库 改成分多批 根据自己实际数据量 去衡量每次批量传入多少合适 比如要批量传入100000条数据 每张表的数据还特别多 可以以500条为一批 按批插入