关于引用本地资源图片 造成OOM的解决方案

来源:互联网 发布:阿里云免费域名注册 编辑:程序博客网 时间:2024/04/29 17:20

情景

在实际开发中,我们会常常使用到本地的UI,这些是固定功能的导航索引,例如一个GridView的导航界面。
最近的一个项目就出现了这样的情况,在不使用第三方图片框架的情况下,解决这个问题.

解决方案:


  1. 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();    }

本文仅限于学习交流,不足之处,请踊跃指出,欢迎来喷.

0 0
原创粉丝点击