【发布时间】:2022-01-02 14:04:32
【问题描述】:
需要在我的应用中使用摄像头进行工作,我发现 API >= 28 与我以前可以使用 startActivityForResult 的方式相比发生了变化。
但是我在启动相机应用程序时遇到问题,并立即在调试/运行控制台中收到“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,因此我覆盖了它并在其上设置了一个断点以查看发生了什么,但它顺利通过了(据我所知)。
对这个有点不知所措。
【问题讨论】:
-
一般原因是Intent的Bundle只能是1MB左右。高于此异常被抛出。这适用于 SaveInstanceState 中的捆绑包,也适用于应用程序中的任何意图。根据时间,这可能是启动相机的意图,尽管它也可能是 onSaveInstanceState。
-
有没有一种简单的方法可以确定到底是哪一个?我是否需要以某种方式清除现有意图?调用相机的 Activity 通过 Intent 传递了一些东西,不幸的是,所有这些都是必需的,因为一旦拍摄了图像,就需要将其发送到 Web 服务。
-
我只是尝试从传递给活动的意图中删除每个额外的内容,不幸的是它没有解决我的问题。真的希望此错误消息在尝试找出问题所在时更有帮助。我看到 Github 上有一个工具,我确实尝试过那个工具,但它没有打印出任何东西到 logcat。
-
是的,问题是您在事件循环中的 2 或 3 次调用远离了在它崩溃时创建意图的位置。他们真的应该立即检查以使其更容易。您可以做的一件事是将 onSaveInstanceState 替换为不调用 super 且不向包中添加任何内容的函数,这将消除一条途径。
-
TakePicture(以及启动另一个活动的任何内容)与您保存的实例状态的大小或您获得的异常无关。听起来您的应用程序中有其他东西占用了过多的空间。你看过toolargetool这样的工具吗?
标签: java android android-camera