【问题标题】:TransactionTooLargeException and FAILED BINDER TRANSACTION when trying to pick images in Android尝试在 Android 中选择图像时出现 TransactionTooLargeException 和 FAILED BINDER TRANSACTION
【发布时间】:2020-10-27 09:24:23
【问题描述】:

我使用 3 个片段显示在选项卡布局中,下一个问题是指其中一个片段。

我正在尝试在我的应用中选择单个或多个图像,我使用按钮和下一个代码打开图像选择器:

btn_galeria.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (ContextCompat.checkSelfPermission(getActivity().getApplicationContext(), Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                requestPermissions(new String[] { Manifest.permission.READ_EXTERNAL_STORAGE }, 10);
            }
            else {
                Intent intent = new Intent();
                intent.setType("image/*");
                intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
                intent.setAction(Intent.ACTION_GET_CONTENT);
                startActivityForResult(Intent.createChooser(intent,"Select picture"), PICK_IMAGE_MULTIPLE);
            }
        }
    });

但只要图像选择器打开,应用就会出现以下结果之一:

  • 使用 Android 模拟器 API 23:logcat 显示 E/JavaBinder: !!! FAILED BINDER TRANSACTION !!! (parcel size = 2572096) `图像选择器出现并且应用程序继续运行,我能够选择图像并且应用程序按预期工作。
  • 使用物理设备Huawei P30 Lite API 29:同样的错误E/JavaBinder: !!! FAILED BINDER TRANSACTION !!! (parcel size = 6639520),但这一次,即使图像选择器出现,应用程序在后台崩溃,原因如下:
2020-07-07 02:02:51.311 31240-31240/com.ssp.atencionvictimas E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.ssp.atencionvictimas, PID: 31240
    java.lang.RuntimeException: android.os.TransactionTooLargeException: data parcel size 6639520 bytes
        at android.app.servertransaction.PendingTransactionActions$StopInfo.run(PendingTransactionActions.java:161)
        at android.os.Handler.handleCallback(Handler.java:888)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:213)
        at android.app.ActivityThread.main(ActivityThread.java:8178)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1101)
     Caused by: android.os.TransactionTooLargeException: data parcel size 6639520 bytes
        at android.os.BinderProxy.transactNative(Native Method)
        at android.os.BinderProxy.transact(BinderProxy.java:526)
        at android.app.IActivityTaskManager$Stub$Proxy.activityStopped(IActivityTaskManager.java:4561)
        at android.app.servertransaction.PendingTransactionActions$StopInfo.run(PendingTransactionActions.java:145)
        at android.os.Handler.handleCallback(Handler.java:888) 
        at android.os.Handler.dispatchMessage(Handler.java:100) 
        at android.os.Looper.loop(Looper.java:213) 
        at android.app.ActivityThread.main(ActivityThread.java:8178) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1101) 
2020-07-07 02:02:51.317 31240-31240/com.ssp.atencionvictimas I/Process: Sending signal. PID: 31240 SIG: 9

基本上我要做的是让用户选择一个或多个图像(如果可能,最多 6 个)并使用已经制作的视图适配器显示所选图像。

这是在用户选择图像后执行的代码:

@Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        // Esta sección de código se ejecuta cuando se termina un Intent, y se regresa al Activity anterior

        if(requestCode == 1 && resultCode == RESULT_OK) {
            List<Bitmap> bitmaps = new ArrayList<>();
            ClipData clipdata = data.getClipData();
            ArrayList<Uri> mArrayUri = new ArrayList<>();
            ArrayList<String> ListaUris = new ArrayList<>();

            if(clipdata != null) {
                for(int i=0; i<clipdata.getItemCount(); i++) {
                    Uri imageUri = clipdata.getItemAt(i).getUri();
                    mArrayUri.add(imageUri);

                    try {
                        InputStream is = getActivity().getApplicationContext().getContentResolver().openInputStream(imageUri);
                        Bitmap bitmap = BitmapFactory.decodeStream(is);
                        bitmaps.add(bitmap);
                        Log.v("LOG_TAG", "URI DE IMAGEN: " + imageUri);

                        // Will return "image:x*"
                        String wholeID = DocumentsContract.getDocumentId(imageUri);

                        // Split at colon, use second item in the array
                        String id = wholeID.split(":")[1];

                        String[] column = { MediaStore.Images.Media.DATA };
                        // where id is equal to
                        String sel = MediaStore.Images.Media._ID + "=?";

                        Cursor cursor = getActivity().getApplicationContext().getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, column, sel, new String[]{ id }, null);

                        String filePath = "";
                        int columnIndex = cursor.getColumnIndex(column[0]);

                        if (cursor.moveToFirst()) {
                            filePath = cursor.getString(columnIndex);
                        }

                        cursor.close();
                        ListaUris.add(filePath);

                        Log.v("LOG_TAG", "FILEPATH: " + filePath);
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    }

                }
            }
            else {
                Uri imageUri = data.getData();
                mArrayUri.add(imageUri);

                try {
                    InputStream is = getActivity().getApplicationContext().getContentResolver().openInputStream(imageUri);
                    Bitmap bitmap = BitmapFactory.decodeStream(is);
                    bitmaps.add(bitmap);
                    Log.v("LOG_TAG", "URI DE IMAGEN: " + imageUri);

                    // Will return "image:x*"
                    String wholeID = DocumentsContract.getDocumentId(imageUri);

                    // Split at colon, use second item in the array
                    String id = wholeID.split(":")[1];

                    String[] column = { MediaStore.Images.Media.DATA };
                    // where id is equal to
                    String sel = MediaStore.Images.Media._ID + "=?";

                    Cursor cursor = getActivity().getApplicationContext().getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, column, sel, new String[]{ id }, null);

                    String filePath = "";
                    int columnIndex = cursor.getColumnIndex(column[0]);

                    if (cursor.moveToFirst()) {
                        filePath = cursor.getString(columnIndex);
                    }

                    cursor.close();
                    ListaUris.add(filePath);

                    Log.v("LOG_TAG", "FILEPATH: " + filePath);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
            }

            galleryAdapter = new GalleryAdapter(getActivity().getApplicationContext(),mArrayUri);
            gvGallery.setAdapter(galleryAdapter);
            gvGallery.setVerticalSpacing(gvGallery.getHorizontalSpacing());
            ViewGroup.MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams) gvGallery
                    .getLayoutParams();
            mlp.setMargins(0, gvGallery.getHorizontalSpacing(), 0, 0);

            Log.v("LOG_TAG", "CANTIDAD DE FOTOS: " + ListaUris.size());
            Log.v("LOG_TAG", "LISTA DE URIS: " + ListaUris);
        }

    }

但是即使我注释掉前面的代码,也会出现同样的行为,所以我认为这与意图返回或处理图库数据的方式有关。

【问题讨论】:

  • 如果您注释掉onActivityResult() 中的所有代码,您的应用仍然会因“失败的活页夹事务”错误而崩溃?
  • @DavidWasser 我遇到了同样的问题,我已经注释掉了 onActivityResult() 中的所有内容,我正在尝试选择 1000 多张图片。
  • 我不知道你为什么认为如果你选择 1000 张图像这会起作用。无论如何,我不明白你告诉我的事情,因为它们没有意义。您需要逐步剥离代码并重新添加部分,直到它崩溃,然后也许您可以隔离问题。抱歉,我帮不上忙。
  • @DavidWasser 我解决了,你可以在下面查看我的答案。

标签: android image android-intent gallery


【解决方案1】:

我通过在片段类上添加下一个方法覆盖解决了:

@Override
    public void onSaveInstanceState(Bundle outState) {
        if (outState != null)
            outState.clear();
    }

【讨论】:

    猜你喜欢
    • 2020-02-07
    • 2014-10-20
    • 1970-01-01
    • 2014-06-17
    • 2015-07-16
    • 2020-07-05
    • 2015-09-16
    • 1970-01-01
    • 2016-04-05
    相关资源
    最近更新 更多