I think we are in the same boat. My team was stuck in this problem for a while, like you.
The problem seems to be in BitmapFactory.cpp ( https://android.googlesource.com/platform/frameworks/base.git/+/master/core/jni/android/graphics/BitmapFactory.cpp ). In Android 7.0, some code was added and a problem arose.
// Create the codec. NinePatchPeeker peeker; std::unique_ptr<SkAndroidCodec> codec(SkAndroidCodec::NewFromStream(streamDeleter.release(), &peeker)); if (!codec.get()) { return nullObjectReturn("SkAndroidCodec::NewFromStream returned null"); }
And I found out that the BitmapFactory.decodeStream method BitmapFactory.decodeStream not create a bitmap after we set inJustDecodeBounds=false , but when I try to create a bitmap without bound decoding. It is working! The problem is that BitmapOptions is that the InputStream is not updated when we call BitmapFactory.decodeStream again.
So, I reset that InputStream before decoding again
private Bitmap getBitmapFromAssets(Context context, String fileName, int width, int height) { AssetManager asset = context.getAssets(); InputStream is; try { is = asset.open(fileName); } catch (IOException e) { return null; } BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeStream(is, null, options); try { is.reset(); } catch (IOException e) { return null; } options.inSampleSize = calculateInSampleSize(options, width, height); options.inJustDecodeBounds = false; return BitmapFactory.decodeStream(is, null, options); } public 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 halfHeight = height / 2; final int halfWidth = width / 2; while ((halfHeight / inSampleSize) >= reqHeight && (halfWidth / inSampleSize) >= reqWidth) { inSampleSize *= 2; } } return inSampleSize; }
It looks like we should reset InputStream every time before reusing it.
source share