BitmapFactory.decodeStream 来自 Assets 的 Android 有时会失败 Android 7
BitmapFactory.decodeStream from Assets sometimes fails on Android 7
我刚从 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不为空,因此找到了资产。方法 decodeStream() returns null.
为了进一步调试,我将代码更改为以下内容。此代码有效 - BitmapFactory.decodeStream() returns 有效位图。
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 );
使用调试器,我进入了 API 24 源码 BitMapFactory.decodeStream()。问题是由于调用 nativeDecodeAsset() 失败。它总是在第二次使用相同的输入资产调用时失败。我的猜测是我使用的是正确的本机库,但它有一个错误,或者我使用的库是错误的。
正如我之前提到的,我在真实设备上没有看到这个问题 运行 API 19 和 21。我只在 Android Studio 的模拟器上看到它 Galaxy_S6_API_24 和 Genymotion API 24 模拟器。
我不清楚如何调试它。我在哪里可以获得与我的构建匹配的本机库的源代码?你能提出一个解决方案或者我还应该检查什么来解决这个问题吗?我想证明我的代码可以在 Android 7.0 上运行,而无需使用真实设备!
这不是 android 的问题;
在方法 decodestream() 中使用输入流后,输入流变为空;
如果您想多次使用输入流,您应该每次使用它的 .reset() 函数重置它。
一旦您从输入流中读取(例如在 BitmapFatory.decodeStream 中),您将无法再次返回到流的开头。可以把它想象成从一个字节数组中读取,其中数组中的读取索引对您不可用 - 每次读取时都会获得上次读取后的字节。
当输入流通过 myInputStream = getActivity().getAssets().open("images/" + imageName) 初始化为资产的开始时,一旦您调用了 BitmapFatory.decodeStream()输入流有效地指向资产之外。如果您尝试再次使用它,它将无法正常工作。在这种情况下,您必须在每次调用 BitmapFatory.decodeStream().
之前初始化输入流
我刚从 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不为空,因此找到了资产。方法 decodeStream() returns null.
为了进一步调试,我将代码更改为以下内容。此代码有效 - BitmapFactory.decodeStream() returns 有效位图。
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 );
使用调试器,我进入了 API 24 源码 BitMapFactory.decodeStream()。问题是由于调用 nativeDecodeAsset() 失败。它总是在第二次使用相同的输入资产调用时失败。我的猜测是我使用的是正确的本机库,但它有一个错误,或者我使用的库是错误的。
正如我之前提到的,我在真实设备上没有看到这个问题 运行 API 19 和 21。我只在 Android Studio 的模拟器上看到它 Galaxy_S6_API_24 和 Genymotion API 24 模拟器。
我不清楚如何调试它。我在哪里可以获得与我的构建匹配的本机库的源代码?你能提出一个解决方案或者我还应该检查什么来解决这个问题吗?我想证明我的代码可以在 Android 7.0 上运行,而无需使用真实设备!
这不是 android 的问题; 在方法 decodestream() 中使用输入流后,输入流变为空; 如果您想多次使用输入流,您应该每次使用它的 .reset() 函数重置它。
一旦您从输入流中读取(例如在 BitmapFatory.decodeStream 中),您将无法再次返回到流的开头。可以把它想象成从一个字节数组中读取,其中数组中的读取索引对您不可用 - 每次读取时都会获得上次读取后的字节。
当输入流通过 myInputStream = getActivity().getAssets().open("images/" + imageName) 初始化为资产的开始时,一旦您调用了 BitmapFatory.decodeStream()输入流有效地指向资产之外。如果您尝试再次使用它,它将无法正常工作。在这种情况下,您必须在每次调用 BitmapFatory.decodeStream().
之前初始化输入流