情景
在实际开发中,我们会常常使用到本地的UI,这些是固定功能的导航索引,例如一个GridView的导航界面。
最近的一个项目就出现了这样的情况,在不使用第三方图片框架的情况下,解决这个问题.
解决方案:
- BitmapFactory.decodeStream(InputStream, null, BitmapFactory.Options);
原先我们使用的ImageView.setBackgroundResource/setImageResource , 这些方法,都会使用Java层的createBitmap来创建一个Bitmap,意味着会消耗更多内存。
BitmapFactory.decodeStream,则是直接调用JNI nativeDecodeAsset(),而不再通过Java层,从而节省了Java层的内存空间,有效地防止了OOM的异常。
public static Bitmap getBitmapFromRecource(Context context, int resId) {
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inPreferredConfig = Bitmap.Config.RGB_565;
opt.inPurgeable = true;
opt.inInputShareable = true;
// 获取资源图片
InputStream is = context.getResources().openRawResource(resId);
return BitmapFactory.decodeStream(is, null, opt);
}
2.出现OOM的原因之一是使用过多资源,没有及时释放.
在当前Activity中,将使用到底Bitmap对象,存储到一个集合中,在该Activity销毁的时候,释放这些资源。
所以,我们可以重载该方法,List的创建:只有当你需要引用到多个ResourceDrawable的时候.
/**
* 根据ResourceId获取Bitmap对象,并插入到Bitmap集合中;
*
* @param context
* @param bitmapList
* @param resId
* @return
*/
public static Bitmap getBitmapFromRecource(Context context, List<Bitmap> bitmapList, int resId) {
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inPreferredConfig = Bitmap.Config.RGB_565;
opt.inPurgeable = true;
opt.inInputShareable = true;
// 获取资源图片
InputStream is = context.getResources().openRawResource(resId);
Bitmap bitmap = BitmapFactory.decodeStream(is, null, opt);
insertBitmap(bitmapList, bitmap);
return bitmap;
}
/**
* 将当前的Bitmap插入到List中
*
* @param bitmapList
* @param bitmap
* @return
*/
private static void insertBitmap(List<Bitmap> bitmapList, Bitmap bitmap) {
if (!bitmapList.contains(bitmap)) {
bitmapList.add(bitmap);
}
}
3.最后,在Activity销毁的时候,要对所有当前Activity使用到的Bitmap进行回收.
/**
* 当不再使用到的时候,回收所有的Bitmap
*
* @param bitmapList
*/
public static void recycleBitmapUnuseful(List<Bitmap> bitmapList) {
if (null != bitmapList && 0 != bitmapList.size()) {
for (Bitmap bitmap : bitmapList) {
bitmap.recycle();
}
bitmapList.clear();
bitmapList = null;
}
}
@Override
protected void onDestroy() {
recycleBitmapUnuseful(bitmapList);
super.onDestroy();
}