【问题标题】:Crash in gallery due to java.lang.RuntimeException: android.os.TransactionTooLargeException: data parcel size 539544 bytes由于 java.lang.RuntimeException 在画廊中崩溃:android.os.TransactionTooLargeException:数据包大小 539544 字节
【发布时间】:2018-02-07 10:33:18
【问题描述】:

当我打开图库并选择图像应用程序时出现崩溃 "java.lang.RuntimeException: android.os.TransactionTooLargeException: data parcel size 539544 bytes" 异常

代码如下

Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
startActivityForResult(intent, SELECT_PHOTO_FROM_GALLERY);

和在活动结果方法中

openDialog.dismiss();
    try {
    if (data == null || data.getData() == null) {
        Toast.makeText(getContext(), "Error getting image.", Toast.LENGTH_SHORT).show();
        return;
    }
    mUri = data.getData();
    createFile(mUri, null);
} catch (Exception e) {
    Log.e(TAG, "GALLERY EXCEPTION " + e.toString());
} catch (OutOfMemoryError E) {
    Log.e(TAG, "GALLERY MEMORY EXCEPTION " + E.toString());
}

我没有使用onSavedInstancestate()。和 我已经推荐了

What to do on TransactionTooLargeException

http://nemanjakovacevic.net/blog/english/2015/03/24/yet-another-post-on-serializable-vs-parcelable/

【问题讨论】:

  • openDialog.dismiss(); ????那应该怎么做?
  • createFile(mUri, null);` 你不认为这个函数会导致异常吗?所以发布代码。
  • When I open gallery and select a image app get crash with the exception 不信你。只有在 onActivityResult 中做某事,你才会得到那个例外。

标签: java android crash


【解决方案1】:

您需要在设置为 imageview 之前调整图像大小(如果您有非常大的图像,那么您需要在线程中调整图像大小)。

所以你需要调用createFile(this,mUri),它会返回位图。我现在已经硬编码了高度和宽度,所以你可以自己改变。

/**
 * Loads a bitmap and avoids using too much memory loading big images (e.g.: 2560*1920)
 */
private static Bitmap createFile(Context context, Uri theUri) {
    Bitmap outputBitmap = null;
    AssetFileDescriptor fileDescriptor;

    try {
        fileDescriptor = context.getContentResolver().openAssetFileDescriptor(theUri, "r");

        BitmapFactory.Options options = new BitmapFactory.Options();
        outputBitmap = BitmapFactory.decodeFileDescriptor(fileDescriptor.getFileDescriptor(), null, options);
        options.inJustDecodeBounds = true;

        int actualHeight = options.outHeight;
        int actualWidth = options.outWidth;

        float maxHeight = 740.0f;
        float maxWidth = 1280.0f;
        float imgRatio = actualWidth / actualHeight;
        float maxRatio = maxWidth / maxHeight;

        if (actualHeight > maxHeight || actualWidth > maxWidth) {
            if (imgRatio < maxRatio) {
                imgRatio = maxHeight / actualHeight;
                actualWidth = (int) (imgRatio * actualWidth);
                actualHeight = (int) maxHeight;
            } else if (imgRatio > maxRatio) {
                imgRatio = maxWidth / actualWidth;
                actualHeight = (int) (imgRatio * actualHeight);
                actualWidth = (int) maxWidth;
            } else {
                actualHeight = (int) maxHeight;
                actualWidth = (int) maxWidth;

            }
        }
        options.inSampleSize = calculateInSampleSize(options, actualWidth, actualHeight);
        options.inJustDecodeBounds = false;
        options.inTempStorage = new byte[16 * 1024];
        outputBitmap = BitmapFactory.decodeFileDescriptor(fileDescriptor.getFileDescriptor(), null, options);
        if (outputBitmap != null) {
            Log.d(TAG, "Loaded image with sample size " + options.inSampleSize + "\t\t"
                    + "Bitmap width: " + outputBitmap.getWidth()
                    + "\theight: " + outputBitmap.getHeight());
        }
        fileDescriptor.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return outputBitmap;
}

private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;

    if (height > reqHeight || width > reqWidth) {
        final int heightRatio = Math.round((float) height / (float) reqHeight);
        final int widthRatio = Math.round((float) width / (float) reqWidth);
        inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
    }
    final float totalPixels = width * height;
    final float totalReqPixelsCap = reqWidth * reqHeight * 2;
    while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) {
        inSampleSize++;
    }

    return inSampleSize;
}

【讨论】:

    【解决方案2】:

    不要在服务和应用程序之间交换大量数据 (>1MB)。我们无法通过意图大小 > 1MB 发送图像/数据。当您尝试通过意图将大型位图图像/图像/pojo 从一个活动发送到另一个活动时,发生 TransactionTooLargeException。

    解决方案:为此使用全局变量。

    您因此而遇到异常:

    Intent intent = new Intent(Intent.ACTION_PICK);
    intent.setType("image/*");
    startActivityForResult(intent, SELECT_PHOTO_FROM_GALLERY);
    

    如果图像大小将&lt; 1MB 肯定会起作用,但我确定图像大小将是&gt;1MB

    【讨论】:

      猜你喜欢
      • 2021-10-10
      • 1970-01-01
      • 2019-03-13
      • 1970-01-01
      • 2014-06-18
      • 1970-01-01
      • 1970-01-01
      • 2018-11-11
      • 1970-01-01
      相关资源
      最近更新 更多