调用TakePicture时出现Android TransactionTooLargeException

问题描述 投票:0回答:2

需要在我的应用程序中使用相机进行工作,我发现与我以前可以使用 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,因此我重写了它并在其上设置了一个断点以查看发生了什么,但它顺利完成了(据我所知)。

对这个有点不知所措。

java android android-camera
2个回答
1
投票

关于 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 个活动结合起来)。


0
投票

2024 年更新,有一个库可以通过有效管理数据大小来帮助修复 TransactionTooLargeException。该库确保 Bundle 中保存的数据不超过事务缓冲区限制。

您可以在 GitHub 上找到 BundleSaver 库:https://github.com/kernel0x/bundlesaver

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.