通过uri将图像设置为imageView时出现OOM
OOM comes up when setting image to imageView by the uri
我已将图像保存到文件中,当我想读取文件并将图像设置到 imageView 时,遇到 OOM 异常。
这是我的代码:
File tempImageFile = new File(Environment.getExternalStorageDirectory().getPath()
+ "/AHOORATempImage");
FileOutputStream fileOutputStream = new FileOutputStream(tempImageFile);
fileOutputStream.write(data);
fileOutputStream.flush();
fileOutputStream.close();
imageView.setImageURI(Uri.fromFile(tempImageFile));
并且这是 logCat 中错误的一部分:
java.lang.OutOfMemoryError: Failed to allocate a 7680012 byte allocation with 2074372 free bytes and 2025KB until OOM
at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
at android.graphics.BitmapFactory.decodeStreamInternal(BitmapFactory.java:677)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:653)
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:486)
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:993)
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:959)
at android.graphics.drawable.Drawable.createFromStream(Drawable.java:945)
at android.widget.ImageView.resolveUri(ImageView.java:769)
at android.widget.ImageView.setImageURI(ImageView.java:429)
at androidx.appcompat.widget.AppCompatImageView.setImageURI(AppCompatImageView.java:120)
at com.jsibbold.zoomage.ZoomageView.setImageURI(ZoomageView.java:395)
at com.apd.atxhider.allGalleryOpenImage.onCreate(allGalleryOpenImage.java:57)
at android.app.Activity.performCreate(Activity.java:6100)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1112)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2468)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2601)
at android.app.ActivityThread.access0(ActivityThread.java:178)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1470)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5637)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:960)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
谢谢!
尝试缓冲 reader 2k 左右并循环。当你完成后,你应该做的最后一件事就是冲水。然后你会读一些,写一些等等......只使用像 2k。然后flush得到最后一部分要写出来。
如果图片很大,可以使用带选项的BitmapFactory
请参考以下URL.
https://developer.android.com/topic/performance/graphics/load-bitmap
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
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;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) >= reqHeight
&& (halfWidth / inSampleSize) >= reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
public static Bitmap decodeSampledBitmapFromResource(String filePath,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filePath, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(filePath, options);
}
String filePath = tempImageFile.getAbsolutePath();
imageView.setImageBitmap(decodeSampledBitmapFromResource(filePath, 100, 100));
我已将图像保存到文件中,当我想读取文件并将图像设置到 imageView 时,遇到 OOM 异常。
这是我的代码:
File tempImageFile = new File(Environment.getExternalStorageDirectory().getPath()
+ "/AHOORATempImage");
FileOutputStream fileOutputStream = new FileOutputStream(tempImageFile);
fileOutputStream.write(data);
fileOutputStream.flush();
fileOutputStream.close();
imageView.setImageURI(Uri.fromFile(tempImageFile));
并且这是 logCat 中错误的一部分:
java.lang.OutOfMemoryError: Failed to allocate a 7680012 byte allocation with 2074372 free bytes and 2025KB until OOM
at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
at android.graphics.BitmapFactory.decodeStreamInternal(BitmapFactory.java:677)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:653)
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:486)
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:993)
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:959)
at android.graphics.drawable.Drawable.createFromStream(Drawable.java:945)
at android.widget.ImageView.resolveUri(ImageView.java:769)
at android.widget.ImageView.setImageURI(ImageView.java:429)
at androidx.appcompat.widget.AppCompatImageView.setImageURI(AppCompatImageView.java:120)
at com.jsibbold.zoomage.ZoomageView.setImageURI(ZoomageView.java:395)
at com.apd.atxhider.allGalleryOpenImage.onCreate(allGalleryOpenImage.java:57)
at android.app.Activity.performCreate(Activity.java:6100)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1112)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2468)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2601)
at android.app.ActivityThread.access0(ActivityThread.java:178)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1470)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5637)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:960)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
谢谢!
尝试缓冲 reader 2k 左右并循环。当你完成后,你应该做的最后一件事就是冲水。然后你会读一些,写一些等等......只使用像 2k。然后flush得到最后一部分要写出来。
如果图片很大,可以使用带选项的BitmapFactory
请参考以下URL.
https://developer.android.com/topic/performance/graphics/load-bitmap
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
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;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) >= reqHeight
&& (halfWidth / inSampleSize) >= reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
public static Bitmap decodeSampledBitmapFromResource(String filePath,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filePath, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(filePath, options);
}
String filePath = tempImageFile.getAbsolutePath();
imageView.setImageBitmap(decodeSampledBitmapFromResource(filePath, 100, 100));