我使用小资源图像(最大25kb,最大256x256),并使用picasso从互联网加载一些较大的图像。直到现在,毕加索的装载从未失败。但资源镜像加载有时确实如此。
对于资源映像,我使用附加的代码(setBitmap
),但尽管我缩小了映像的规模,但在某些设备上,我的应用程序在调用BitmapFactory.decodeResource
时仍然会生成OutOfMemoryError
。有人知道下一步该去哪里吗?
private static void setBitmap(final ImageView iv, final int resId)
{
iv.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener()
{
public boolean onPreDraw()
{
iv.getViewTreeObserver().removeOnPreDrawListener(this);
iv.setImageBitmap(decodeSampledBitmapFromResource(iv.getContext().getResources(), resId, iv.getMeasuredWidth(), iv.getMeasuredHeight()));
return true;
}
});
}
private static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int w, int h)
{
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
options.inSampleSize = calculateInSampleSize(options, w, h);
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
private static int calculateInSampleSize(BitmapFactory.Options options, int w, int h)
{
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > h || width > w)
{
final int halfHeight = height / 2;
final int halfWidth = width / 2;
while ((halfHeight / inSampleSize) > h && (halfWidth / inSampleSize) > w)
{
inSampleSize *= 2;
}
}
L.d(ImageTools.class, "inSampleSize | height | width: " + inSampleSize + " | " + height + " | " + width);
return inSampleSize;
}
如果你有一个列表ImageViews,你可以实现一个缓存:http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html
您可以在清单中使用android:largeHeap="true"
作为最后一个选项。但是,我不建议使用此功能,因为它会使您的应用程序速度变慢。
您可以使用请求更多的memory
android:largeHeap="true"
清单中。
此外,您可以使用本机内存(NDK&JNI),因此实际上可以绕过堆大小限制。
以下是一些关于它的帖子:
-
如何将位图缓存到本机内存
-
JNI位图操作,用于在使用大图像时帮助避免OOM
这里有一个为它制作的图书馆:
- https://github.com/AndroidDeveloperLB/AndroidJniBitmapOperations
快乐编码
关于maven