android - Assets 中的 BitmapFactory.decodeStream 在 Android 7 上有时会失败

标签 android android-emulator android-7.0-nougat

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

以下用于解码 Assets 的现有代码在 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 不为空,因此找到了 Assets 。方法 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() 的调用失败。它总是在第二次使用相同的输入 Assets 调用时失败。我的猜测是我使用的是正确的 native 库,但它有一个错误,或者我使用的库是错误的。

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

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

最佳答案

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

关于android - Assets 中的 BitmapFactory.decodeStream 在 Android 7 上有时会失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39824214/

相关文章:

java - Android Nougat 上的错误通知 : Couldn't expand RemoteViews for: StatusBarNotification.

android:libffmpeg-neon 库加载:致命信号 11

android-emulator - 如何将android模拟器连接到互联网

java - Android 致命信号错误 11 SIGSEGV 在不同版本的 JellyBean 上

android - 在模拟器上运行 APK : "Unfortunately, YourAPP has stopped."

android - 在我的例子中,在 Android 2.2 平台上(在 Android 4.0 上可以)更改应用程序中的语言环境

android - 移动设备是否将其从打瞌睡中唤醒

安卓牛轧糖 : Why do checkboxes on Fragment have incomplete state when selected programmatically (but look fine on Lollipop)

android - 别名具有相同名称的布局资源只是不同的屏幕限定符

android - 如何排除显示最近应用程序的我的应用程序屏幕截图