美文网首页
Android 图片缓存

Android 图片缓存

作者: 杰奎琳子 | 来源:发表于2020-06-13 08:33 被阅读0次

Android打开一张图片关闭,打开,再关闭,OOM了,GC也没用,发现是界面的图片资源没用释放掉;

GirdView和ListView可以自动回收子View但是如果自己动态加载图片的布局不合理,android就不会回收Bitmap;

可以使用 SoftReference软引用,也可以像下面这样复杂的方法回收自己的图片布局,图片控件会变白闪烁一下.

Android的OOM除了本身图片过大会OOM,需要进行bitmap.option或者thumb压缩以外(ps:google的压缩方法对图片高宽反着的图片是会崩溃的);

对于每个界面中的ImageView占用的Bitmap是要回收的.今天先发个回收界面中ImageView中图片的.

对于每个Activity来说,

只要在父Activity上使用Map recycleViews;

在动态创建的View上回收该View中的

ImageView;recycleViews.put(gridView, new int[]{R.id.iv_item_chooseimg_big,R.id.iv_item_chooseimg_small});

在合适的地方,比如返回的时候,处理这个对象就行了;

RecycleBitmap.recycle(recycleViews);

* @author intbird 20140225

 */

package core.tool;

import java.util.Iterator;

import java.util.LinkedHashMap;

import java.util.Map;

import android.graphics.Bitmap;

import android.graphics.drawable.BitmapDrawable;

import android.graphics.drawable.Drawable;

import android.view.View;

import android.view.ViewGroup;

import android.widget.AbsListView;

import android.widget.ImageView;

public class RecycleBitmap {

    /**

     * 清理map中的bitmap;

     * @param imgCache ImageCacheMap

     * @param maxSize 允许添加的最大图片数量

     * @param freeSize 释放掉图片的数量;

    */

    public static void recycleMapCache(LinkedHashMap<String, Bitmap> imgCache,int maxSize,int freeSize){

        //超出最大容量时清理

        if (imgCache.values().size() > maxSize) {

            synchronized(imgCache){

                Iterator<String> it = imgCache.keySet().iterator();

                while( it.hasNext()&&(imgCache.keySet().size()>freeSize)){

                    Bitmap bmp=imgCache.get(it.next());

                    if(bmp!=null&&!bmp.isRecycled()) {

                        bmp.recycle();

                        bmp=null;

                    }

                    it.remove();

                }

            }

            System.gc();

        }

    }

    /**

     * 清理View中的ImagView被BitMap占用的内存;

     * @param mapViews 一个View的合集

    */

    public static void recycle(Map<View,int[]> mapViews){

       synchronized(mapViews){

            Iterator<View> it = mapViews.keySet().iterator();

           while(it.hasNext()){

               //获取布局

                View view=it.next();

             if(view==null) return;

              //获取要布局内要回收的ids;

               int [] recycleIds=mapViews.get(view);

               //如果是listView,先找到每个布局文件.重要提示:每个ImagView在布局文件的第一层;

                 if ((view instanceof AbsListView)) {

                    recycleAbsList((AbsListView)view, recycleIds);

                }

                 //如果是ImageView,直接回收;

               else if(view instanceof ImageView){

                    recycleImageView(view);

                 }

                //如果是ViewGroup,重要提示:每个ImagView在ViewGroup的第二层;

               else if ((view instanceof ViewGroup)) {

                    recycleViewGroup((ViewGroup)view, recycleIds);

                }

            }

        }

        System.gc();

    }

    /**

     * 回收继承自AbsListView的类,如GridView,ListView等

     * @param absView

     * @param recycleIds 要清理的Id的集合;

     */

    public static void recycleAbsList(AbsListView absView,int[]recycleIds){

       if(absView==null) return;

        synchronized(absView){

            //回收当前显示的区域

           for (int index = absView.getFirstVisiblePosition(); index <= absView.getLastVisiblePosition(); index++) {

               //获取每一个显示区域的具体ItemView

                ViewGroup views = (ViewGroup) absView.getAdapter().getView(index, null, absView);

                for(int count=0;count<recycleIds.length;count++){

                   recycleImageView(views.findViewById(recycleIds[count]));

               }

            }

        }

   }

   /**

     * 回收继承自AbsListView的类,如GridView,ListView等

     * @param absView

    * @param recycleIds 要清理的Id的集合;

    */

    public static void recycleViewGroup(ViewGroup layout,int[]recycleIds){

        if(layout==null) return;

        synchronized(layout){

            for (int i = 0; i < layout.getChildCount(); i++) {

                View subView = layout.getChildAt(i);

                if (subView instanceof ViewGroup) {

                   for(int count=0;count<recycleIds.length;count++){

                       recycleImageView(subView.findViewById(recycleIds[count]));

                    }

                } else {

                    if (subView instanceof ImageView) {

                        recycleImageView((ImageView)subView);

                    }

                }

            }

        }

    }

    /**

     * 回收ImageView占用的图像内存;

     * @param view

     */

    public static void recycleImageView(View view){

        if(view==null) return;

        if(view instanceof ImageView){

            Drawable drawable=((ImageView) view).getDrawable();

            if(drawable instanceof BitmapDrawable){

                Bitmap bmp = ((BitmapDrawable)drawable).getBitmap();

                if (bmp != null && !bmp.isRecycled()){

                    ((ImageView) view).setImageBitmap(null);

                    bmp.recycle();

                    bmp=null;

                }

            }

        }

    }

}

相关文章

网友评论

      本文标题:Android 图片缓存

      本文链接:https://www.haomeiwen.com/subject/titgtktx.html