加载自定义图片时出现内存不足错误。我阅读https://developer.android.com/training/displaying-bitmaps/load-bitmap.html寻求帮助。
我正在按照示例解码流以首先获取大小信息,然后解码。仍然在第一次解码时崩溃。有办法解决这个问题吗?
ava.lang.OutOfMemoryError:无法分配带有16776928个空闲字节的48771084字节分配和25MB直到OOM BackgroundImageManager.java,第84行
dalvik.system.VMRuntime.newNonMovableArray原生方法 2 android.graphics.BitmapFactory.nativeDecodeStream Native方法 3 android.graphics.BitmapFactory.decodeStreamInternal BitmapFactory.java,第882行 4 android.graphics.BitmapFactory.decodeStream BitmapFactory.java,第858行 5 android.graphics.BitmapFactory.decodeStream BitmapFactory.java,第896行 6 com.myapp.Utils.BackgroundImageManager.background BackgroundImageManager.java,第8行
public class BackgroundImageManager {
private final static String TAG = BackgroundImageManager.class.getSimpleName();
private static InputStream currentBackgroundImage;
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;
}
}
Log.v("Biscuit-Sample", String.valueOf(inSampleSize));
if (inSampleSize < 4) {
inSampleSize = 4;
}
return inSampleSize;
}
public static Drawable background(Context context, Store store) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
String bgUri = null;
int bgId = 0;
if (store != null) {
bgUri = store.backgroundImageURI;
bgId = store.backgroundImageNumber;
}
if (currentBackgroundImage != null) {
try {
currentBackgroundImage.close();
Log.v(TAG, "Current background image closed.");
} catch (IOException e) {
Log.e(TAG, "Could not close background image.", e);
}
}
if(bgUri != null && !bgUri.isEmpty()) {
try {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
Activity activity = (Activity) context;
Display display = activity.getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;
BitmapFactory.decodeStream( context.getContentResolver().openInputStream(Uri.parse(bgUri)) );
options.inSampleSize = BackgroundImageManager.calculateInSampleSize(options, width, height);
Bitmap bitmap = BitmapFactory.decodeStream( context.getContentResolver().openInputStream(Uri.parse(bgUri)) );
Drawable d = new BitmapDrawable(context.getResources(), bitmap);
return d;
} catch (FileNotFoundException e) {
Log.e(TAG, "Custom background image file could not be found.", e);
} catch (IOException e) {
Log.e(TAG, "Could not close custom background image after creating drawable", e);
}
}
if(bgId != 0) {
try {
return context.getResources().getDrawable(bgId);
} catch (Exception e) {
e.printStackTrace();
}
}
return context.getResources().getDrawable(R.drawable.bg_default);
}
答案 0 :(得分:1)
要处理bitmpas,您可以使用众多可用的开源库之一。 E.g Fresco
问题:
首先,您要对相同的位图进行两次解码。
BitmapFactory.decodeStream( context.getContentResolver().openInputStream(Uri.parse(bgUri)) );
options.inSampleSize = BackgroundImageManager.calculateInSampleSize(options, width, height);
Bitmap bitmap = BitmapFactory.decodeStream( context.getContentResolver().openInputStream(Uri.parse(bgUri)) );
这可能是错误的复制/粘贴。在第一行中,位图是解码而不使用。删除第一个BitmapFactory.decodeStream
问题出在这里
Bitmap bitmap = BitmapFactory.decodeStream( context.getContentResolver().openInputStream(Uri.parse(bgUri)) );
应该是
Bitmap bitmap = BitmapFactory.decodeStream( context.getContentResolver().openInputStream(Uri.parse(bgUri)), null, options);
该选项的对象必须是该方法调用的一部分才能被使用。
答案 1 :(得分:0)
管理图像的更好方法是使用Picasso库,因为它管理缓存和内存,因此可以避免OutOfMemory
崩溃。
示例:Picasso.with(Context).load("your_url").into(yourImageView);
更多信息: Picasso library