需要在我的应用程序中使用相机进行工作,我发现与我以前可以使用 startActivityForResult 的方式相比,API >= 28 中的情况发生了变化。
但是,我遇到了一个问题:启动相机应用程序,并立即在调试/运行控制台中收到“TransactionTooLargeException”错误消息。
为了调出相机,我正在做
mGetContent = registerForActivityResult(
new ActivityResultContracts.TakePicture(),
result -> {
if (result) {
}
}
);
其中 mGetContent 在类中定义为
private ActivityResultLauncher<Uri> mGetContent;
在我的 AndroidManifest.xml 文件中,我有以下内容
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.test.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
在我的 file_paths 文件中
<?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="./files/"/>
</paths>
我在我的活动中设置了一个按钮,我可以使用
启动相机findViewById(R.id.button)).setOnClickListener(v -> {
File directory = new File(context.getFilesDir(), "app_images");
if (!directory.exists()) directory.mkdir();
File file = new File(directory, "image.jpg");
Uri uri = getUriForFile(this, "com.test.fileprovider", file);
mGetContent.launch(uri);
};
一旦我点击按钮,相机应用程序打开,我就收到了我只能假设是一条过于笼统的错误消息。
E/JavaBinder: !!! FAILED BINDER TRANSACTION !!! (parcel size = 1284092)
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.test, PID: 14296
java.lang.RuntimeException: android.os.TransactionTooLargeException: data parcel size 1284092 bytes
at android.app.servertransaction.PendingTransactionActions$StopInfo.run(PendingTransactionActions.java:161)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7397)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:935)
Caused by: android.os.TransactionTooLargeException: data parcel size 1284092 bytes
at android.os.BinderProxy.transactNative(Native Method)
at android.os.BinderProxy.transact(BinderProxy.java:511)
at android.app.IActivityTaskManager$Stub$Proxy.activityStopped(IActivityTaskManager.java:4524)
at android.app.servertransaction.PendingTransactionActions$StopInfo.run(PendingTransactionActions.java:145)
一直尝试通过 Google 搜索来查找内容,但无法确定实际问题是什么。
一些建议将我引向了 onSaveInstanceState,因此我重写了它并在其上设置了一个断点以查看发生了什么,但它顺利完成了(据我所知)。
对这个有点不知所措。
关于 onSaveInstanceState 中的捆绑包的构成令人惊叹。
我的应用程序中有一些图像视图、图像按钮和一般按钮,以使我们的员工更轻松。
我将所有 ImageView 和 ImageButton 的“saveState”从默认的 true 更改为 false,因为我不关心它们处于什么状态,它们只是视觉指南。
将 android:viewHierarchyState 从 1.2MB 降低到 1.6KB,我的 Parcel 大小现在为 3.3KB,并且在暂停应用程序以调出相机应用程序时不再崩溃。
TooLargeTool 很有用,但我无法让它按照 Github 页面所说的方式工作,我告诉它“startLogging”,并且在发生崩溃的活动中,我设置了一个断点并检查它是否正在使用“进行日志记录” isLogging',它返回“true”。
最后我只是让它在 onSaveInstanceState 中记录
TooLargeTool.bundleBreakdown(outState)
的输出。
感谢 Gabe Sechan 和 ianhanniballake 向我指出它可能是什么,对于这个特殊的例外,没有太多的信息,我的意思是,有,但似乎每个人都不同。
真心希望 Google 能够打印出一组更好的错误消息,以便更轻松地找出问题所在的活动(或者在我的情况下,将所有 3 个活动结合起来)。
2024 年更新,有一个库可以通过有效管理数据大小来帮助修复 TransactionTooLargeException。该库确保 Bundle 中保存的数据不超过事务缓冲区限制。
您可以在 GitHub 上找到 BundleSaver 库:https://github.com/kernel0x/bundlesaver