调用TakePicture启动相机触发TransactionTooLargeException如何解决?
问题根源与解决方案
1. 修正FileProvider路径配置错误
你当前的file_paths.xml配置与实际代码中的存储路径不匹配:<files-path>的path属性是相对于应用getFilesDir()返回路径的相对路径,你代码中创建的图片存放目录是getFilesDir()下的app_images文件夹,原配置中的path="./files/"会指向不存在的getFilesDir()/files/目录,会触发FileProvider授权异常,部分系统处理该异常时会触发Binder数据超限。
修正后的file_paths.xml如下:
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <files-path name="files" path="."/> <files-path name="app_images" path="app_images/"/> </paths>
2. 手动授予Uri临时访问权限
部分定制ROM对Activity Result API的自动权限授权适配存在缺陷,启动相机前手动给目标相机应用授予Uri读写权限可规避该问题,在mGetContent.launch(uri)前添加以下代码:
Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); ResolveInfo resolveInfo = getPackageManager().resolveActivity(captureIntent, PackageManager.MATCH_DEFAULT_ONLY); if (resolveInfo != null) { grantUriPermission(resolveInfo.activityInfo.packageName, uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION); }
3. 排查全局变量序列化问题
该异常触发在Activity实例状态保存阶段,检查你的Activity中是否存在未加transient修饰的大对象(如Bitmap、大容量集合、长字符串等),这些实现了Serializable/Parcelable的对象会被系统自动序列化到InstanceState中,超过Binder 1MB的大小限制就会抛出该异常。
不需要保存到实例状态的全局变量都添加transient关键字修饰,例如:
private transient ActivityResultLauncher<Uri> mGetContent;
4. 升级Activity相关依赖
旧版本的AndroidX Activity/Fragment库存在已知的Activity Result数据序列化bug,将依赖升级到最新稳定版即可修复:
// 模块级build.gradle依赖示例 implementation 'androidx.activity:activity:1.7.2' implementation 'androidx.fragment:fragment:1.6.1'
5. 临时规避方案
如果无法快速定位大对象来源,可重写onSaveInstanceState清空不必要的状态数据:
@Override protected void onSaveInstanceState(@NonNull Bundle outState) { outState.clear(); // 如有需要保存的小体积自定义数据,此处手动写入 super.onSaveInstanceState(outState); }
内容的提问来源于stack exchange,提问作者Raymond Herring

