切换新Activity时触发TransactionTooLargeException崩溃求助
这个问题我之前做相机类应用时也碰到过,TransactionTooLargeException本质是因为Binder进程间通信的缓冲区有大小限制(通常约1MB),当Activity之间传递的数据(或者系统自动保存的Activity状态数据)超过这个阈值时就会崩溃。结合你的场景,大概率是拍摄页面持有了大体积的图像资源(比如未释放的Bitmap),在你启动首页Activity时,系统尝试保存当前拍摄页面的状态,把这些大资源塞进了Bundle里,直接触发了限制。
给你几个针对性的解决方案:
1. 优化返回逻辑,避免不必要的Activity状态传递
你当前直接启动首页的方式会让系统保留拍摄页面的状态,不如调整Intent的启动标记,让首页回到栈顶并清理中间页面,同时结束当前拍摄页面:
@Override public void onBackPressed() { // 先释放拍摄相关的资源(关键!) releaseCaptureResources(); // 配置Intent标记,回到已有的首页实例,清理栈中多余页面 Intent intent = new Intent(getApplicationContext(), BottomNavigationActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); startActivity(intent); // 结束当前拍摄页面,避免它留在栈中占用资源 finish(); }
这里的FLAG_ACTIVITY_CLEAR_TOP会把栈中首页之上的所有Activity都销毁,FLAG_ACTIVITY_SINGLE_TOP确保如果首页已经在栈顶,不会重新创建新实例,大幅减少状态传递的数据量。
2. 必须释放拍摄页面的大资源
在返回前一定要主动释放拍摄产生的大对象,比如Bitmap、相机硬件资源:
private void releaseCaptureResources() { // 回收拍摄得到的Bitmap if (mCapturedBitmap != null) { if (!mCapturedBitmap.isRecycled()) { mCapturedBitmap.recycle(); } mCapturedBitmap = null; } // 关闭相机预览、释放相机资源(如果使用原生Camera API) if (mCamera != null) { mCamera.stopPreview(); mCamera.release(); mCamera = null; } // 如果用的是CameraX,也要停止预览、解绑用例 if (mPreviewUseCase != null) { mCameraProvider.unbind(mPreviewUseCase); mPreviewUseCase = null; } }
这些大资源如果不释放,系统会把它们纳入Activity的状态保存逻辑,直接导致Bundle体积超标。
3. 检查是否在Intent中传递了大对象
如果你之前启动拍摄页面时,或者返回时在Intent里传递了Bitmap、大字节数组这类数据,一定要改成传递文件路径而非对象本身。比如拍摄后把图片保存到本地缓存,然后传递缓存路径给首页,首页再通过路径加载图片。
4. 避免在onSaveInstanceState中保存大数据
如果你重写了拍摄页面的onSaveInstanceState方法,检查是否保存了Bitmap、大集合这类数据,只保留必要的小数据(比如拍摄模式、是否开启闪光灯这类配置)即可。
按照上面的步骤调整后,基本就能解决这个崩溃问题了,核心就是减少跨Activity传递的数据量,及时释放大资源。
内容的提问来源于stack exchange,提问作者Pritesh Vishwakarma

