来自Assets的BitmapFactory.decodeStream有时会在Android 7上失败

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

我刚从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不为null,因此找到了资产。方法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!

android android-emulator android-7.0-nougat
2个回答
1
投票

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


0
投票

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

当输入流通过myInputStream = getActivity()初始化为资产的开始时.getAssets()。open(“images /”+ imageName),一旦调用了BitmapFatory.decodeStream(),输入流就会有效地指向资产。如果你再次尝试使用它就行不通。在这种情况下,您必须在每次调用BitmapFatory.decodeStream()之前初始化输入流。

© www.soinside.com 2019 - 2024. All rights reserved.