【问题标题】:BitmapFactory.decodeStream from Assets sometimes fails on Android 7来自 Assets 的 BitmapFactory.decodeStream 在 Android 7 上有时会失败
【发布时间】:2016-10-03 03:30:16
【问题描述】:

我刚刚从 androidTargetSdk=23 移动到 androidTargetSdk=24。我也在使用 JDK 1.8 和 sourceCompatibility="1.7" 和 targetCompatibility="1.7"。

以下用于解码资产的现有代码在 Android Studio 的模拟器 Galaxy_S6_API_24 和 Genymotion API 24 模拟器上出现故障(但在运行 API 19 和 21 的真实设备上运行良好)。

myInputStream = getActivity().getAssets().open("images/" + imageName);
BitmapFactory.Options opts = new BitmapFactory.Options();

// Find the size of the image
// (http://developer.android.com/training/displaying-bitmaps/load-bitmap.html)
opts.inJustDecodeBounds = true;
BitmapFactory.decodeStream(myInputStream, null, opts);

// For debugging this issue to keep it simple I've stopped calling calculateInSampleSize()
//opts.inSampleSize = ImageUtils.calculateInSampleSize(opts, width, height);
opts.inSampleSize = 1;
opts.inJustDecodeBounds = false;

bm = BitmapFactory.decodeStream(myInputStream, null, opts);
imageView.setImageBitmap( bm );

调试这段代码时myInputStream不为空,所以找到了asset。方法 decodeStream() 返回 null。

为了进一步调试,我将代码更改为以下内容。此代码有效 - BitmapFactory.decodeStream() 返回有效位图。

myInputStream = getActivity().getAssets().open("images/" + imageName);
BitmapFactory.Options opts = new BitmapFactory.Options();

// Find the size of the image
// (http://developer.android.com/training/displaying-bitmaps/load-bitmap.html)
opts.inJustDecodeBounds = true;
//BitmapFactory.decodeStream(myInputStream, null, opts);

// For debugging this issue to keep it simple I've stopped calling calculateInSampleSize()
//opts.inSampleSize = ImageUtils.calculateInSampleSize(opts, width, height);
opts.inSampleSize = 1;
opts.inJustDecodeBounds = false;

bm = BitmapFactory.decodeStream(myInputStream, null, opts);
imageView.setImageBitmap( bm );

顶部的失败代码和上面直接运行的代码之间的唯一区别是我已经注释掉了对 BitmapFactory.decodeStream() 的第一次调用。

为了进一步调试,我简化了代码。这有效:

myInputStream = getActivity().getAssets().open("images/" + imageName);
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inSampleSize = 1;
bm = BitmapFactory.decodeStream(myInputStream, null, opts);
imageView.setImageBitmap( bm );

但这无法显示图像(注意我在下面调用了 decodeStream 两次):

myInputStream = getActivity().getAssets().open("images/" + imageName);
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inSampleSize = 1;
bm = BitmapFactory.decodeStream(myInputStream, null, opts);
bm = BitmapFactory.decodeStream(myInputStream, null, opts);
imageView.setImageBitmap( bm );

这也失败了:

myInputStream = getActivity().getAssets().open("images/" + imageName);
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inSampleSize = 1;
bm = BitmapFactory.decodeStream(myInputStream, null, opts);
BitmapFactory.Options opts2 = new BitmapFactory.Options();
opts2.inSampleSize = 1;
bm = BitmapFactory.decodeStream(myInputStream, null, opts2);
imageView.setImageBitmap( bm );

使用调试器,我已进入 BitMapFactory.decodeStream() 的 API 24 源代码。问题是由于对 nativeDecodeAsset() 的调用失败。它总是在第二次使用相同的输入资产调用时失败。我的猜测是我使用了正确的本机库,但它有一个错误或者我使用的库是错误的。

正如我之前提到的,我在运行 API 19 和 21 的真实设备上看不到这个问题。我只在 Android Studio 的模拟器 Galaxy_S6_API_24 和 Genymotion API 24 模拟器上看到它。

我不清楚如何调试它。我在哪里可以获得与我的构建匹配的本机库的源代码?你能建议一个解决方案还是我应该检查什么来解决这个问题?我想证明我的代码可以在 Android 7.0 上运行,而无需使用真实设备!

【问题讨论】:

  • 你在 build.gradle 文件中使用“shrinkResources”吗??
  • 我没有在 gradle 中使用“shrinkResources”。我已将此问题报告给 Google。见code.google.com/p/android/issues/detail?id=224319。尽管我礼貌地要求他们让我知道这是不是一个问题,即使他们不能立即修复它,但到目前为止,没有任何回应承认这是一个错误或其他问题。
  • @pbm 你能解决你的问题吗?如果有帮助,请您选择正确的答案吗?

标签: android android-emulator android-7.0-nougat


【解决方案1】:

这不是安卓的问题; 在方法 decodestream(); 中使用输入流后,输入流变为空; 如果你想多次使用输入流,你应该每次都重置它使用它的 .reset() 函数。

【讨论】:

  • 为什么我才找到这个答案....我花了一整夜来解决这个问题。好伤心。
【解决方案2】:

一旦您从输入流中读取数据(例如在 BitmapFatory.decodeStream 中),您就无法再次备份到流的开头。可以把它想象成从一个字节数组中读取,其中数组的读取索引对您不可用 - 每次读取时,您都会在上次读取之后获得字节。

当通过 myInputStream = getActivity().getAssets().open("images/" + imageName) 将输入流初始化为资产的开头时,一旦调用 BitmapFatory.decodeStream(),输入流就会有效指向资产之外。如果您尝试再次使用它,它将无法正常工作。在这种情况下,您必须在每次调用 BitmapFatory.decodeStream() 之前初始化输入流。

【讨论】:

    猜你喜欢
    • 2017-01-11
    • 1970-01-01
    • 2015-11-14
    • 1970-01-01
    • 2021-08-28
    • 2021-01-07
    • 2014-05-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多