android网络相册(带磁盘缓存DiskLruCache 和内存缓存LruCache)

涉及的技术: Volley & DiskLruCache & LruCache

效果图(主要是因为缓存在内存里面, 所以滑动的时候比较顺畅. 而且网络图片会缓存到磁盘, 所以相册可以离线使用)


NetHelper.java(单例获取Volley的RequestQueue)

public class NetHelper {
    private volatile static NetHelper netHelper;
    private RequestQueue requestQueue;
    static public NetHelper getInstance(Context context) {
        if (netHelper==null){
            synchronized (NetHelper.class){
                if (netHelper==null){
                    netHelper=new NetHelper(context.getApplicationContext());
                }
            }
        }
        return netHelper;
    }
    public NetHelper(Context context){
        requestQueue=Volley.newRequestQueue(context);
    }
    public RequestQueue getRequestQueue(){
        return requestQueue;
    }
}
MainActivity.java

public class MainActivity extends Activity {

    private int screenWidth;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_imageloader_main);
        WindowManager wm = this.getWindowManager();
        screenWidth = wm.getDefaultDisplay().getWidth();
        GridView gridView= (GridView) findViewById(R.id.gridview);
        gridView.setAdapter(new MyAdapter(getApplicationContext()));
    }
    class MyAdapter extends BaseAdapter{
        private final Context context;
        LayoutInflater lf;
        public MyAdapter(Context context){
            this.context=context;
            lf=LayoutInflater.from(context);
        }
        @Override
        public int getCount() {
            return imageThumbUrls.length;
        }

        @Override
        public Object getItem(int position) {
            return null;
        }

        @Override
        public long getItemId(int position) {
            return 0;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ImageView imageView=null;
            if (convertView==null){
                convertView=lf.inflate(R.layout.item_gridview,parent,false);
                imageView= (ImageView) convertView.findViewById(R.id.imageview);
                ViewGroup.LayoutParams layoutParams=imageView.getLayoutParams();
                layoutParams.width=layoutParams.height=screenWidth/3;
                imageView.setLayoutParams(layoutParams);
            }
            if (imageView==null) imageView= (ImageView) convertView.findViewById(R.id.imageview);
            ImageHelper.setImageViewByUrl(context,imageView,imageThumbUrls[position]);
            return convertView;
        }
    }

    public final static String[] imageThumbUrls = new String[] {
            "https://img-my.csdn.net/uploads/201407/26/1406383299_1976.jpg",
            "https://img-my.csdn.net/uploads/201407/26/1406383291_6518.jpg",
           ...(省略n个图片地址)
            "https://img-my.csdn.net/uploads/201407/26/1406383290_1042.jpg",
            "https://img-my.csdn.net/uploads/201407/26/1406383275_3977.jpg",
            "https://img-my.csdn.net/uploads/201407/26/1406383265_8550.jpg",
            "https://img-my.csdn.net/uploads/201407/26/1406383264_3954.jpg",
            "https://img-my.csdn.net/uploads/201407/26/1406383264_4787.jpg",
            "https://img-my.csdn.net/uploads/201407/26/1406383264_8243.jpg",
            "https://img-my.csdn.net/uploads/201407/26/1406383248_3693.jpg",
            "https://img-my.csdn.net/uploads/201407/26/1406383243_5120.jpg"
    };
}

ImageHelper.java

public class ImageHelper {
    private volatile static ImageHelper imageHelper;
    private final int screenWidth;
    ImageLoader imageLoader;
    private ImageHelper(final Context context) throws IOException {
        WindowManager wm =  (WindowManager) context
                .getSystemService(Context.WINDOW_SERVICE);
        screenWidth = wm.getDefaultDisplay().getWidth();
        //
        final File cacheFile=new File(getDiskCacheDir(context)+File.separator);
        if (!cacheFile.exists()) cacheFile.mkdirs();
        ImageLoader.ImageCache imageCache= new ImageLoader.ImageCache() {
            DiskLruCache diskLruCache=DiskLruCache.open(cacheFile,1,1,32*1024*1024);
            LruCache<String,Bitmap> lruCache=new LruCache<String,Bitmap>((int)(Runtime.getRuntime().maxMemory()/8)){
                @Override
                protected int sizeOf(String key, Bitmap bm) {
                    return bm.getByteCount();
                }
            };
            //getBitmap返回null才调用putBitmap
            @Override
            public Bitmap getBitmap(String key) {
                key=fixKey(key);
                //get cache from memory
                Bitmap bm=lruCache.get(key);
                //get cache from disk
                FileInputStream fileInputStream=null;
                if (bm==null){
//                    Log.e("getBitmap","disk cache: "+key);
                    try {
                        DiskLruCache.Snapshot snapshot=diskLruCache.get(key);
                        if (snapshot != null) {
                            fileInputStream=(FileInputStream) snapshot.getInputStream(0);
                            bm= BitmapFactory.decodeFileDescriptor(fileInputStream.getFD());
                            Log.e("getBitmap",bm.getWidth()+" "+bm.getHeight()+" "+bm.getByteCount());
                            //write to memory cache
                            lruCache.put(key, bm);
                        }else{
                            //没有磁盘缓存
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    } finally {
                        if (fileInputStream!=null){
                            try {
                                fileInputStream.close();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }else{
//                    Log.e("getBitmap","mem cache");
                }
                return bm;
            }

            @Override
            public void putBitmap(String key, Bitmap bitmap) {
                key=fixKey(key);
                //scale bitmap
                //volley 有些图片基本没怎么压缩, 所以要手动干这事情
                Matrix matrix = new Matrix();
                matrix.postScale(screenWidth/3.0f/bitmap.getWidth(),screenWidth/3.0f/bitmap.getHeight()); //长和宽放大缩小的比例
                Bitmap resizeBmp = Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(),bitmap.getHeight(),matrix,true);
                //write memory cache
                lruCache.put(key, resizeBmp);
                Log.e("putBitmap", "men cache");
                //write disk cache
                OutputStream out=null;
                try {
                    if (diskLruCache.get(key)!=null) return;
                    Log.e("putBitmap","disk cache");
                    DiskLruCache.Editor editor=diskLruCache.edit(key);
                    out=editor.newOutputStream(0);
                    resizeBmp.compress(Bitmap.CompressFormat.PNG, 50,out );
                    out.flush();
                    editor.commit();
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    if (out!=null){
                        try {
                            out.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        };
        imageLoader=new ImageLoader(NetHelper.getInstance(context).getRequestQueue(),imageCache);
    }



    public static String getDiskCacheDir(Context context) {
        String cachePath=null;
        if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())
                || !Environment.isExternalStorageRemovable()) {
            cachePath = context.getExternalCacheDir().getPath();
        } else {
            cachePath = context.getCacheDir().getPath();
        }
        return cachePath;
    }
    static public ImageHelper getInstance(final Context context) {
        if (imageHelper==null){
            synchronized (ImageHelper.class){
                if (imageHelper==null){
                    try {
                        imageHelper=new ImageHelper(context.getApplicationContext());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        return imageHelper;
    }
    public static void setImageViewByUrl(Context context, ImageView imageView, String url) {
        long beg=System.currentTimeMillis();
        getInstance(context).imageLoader.get(url,
                ImageLoader.getImageListener(imageView, R.mipmap.ic_launcher, R.mipmap.ic_launcher));
//        Log.e("time", System.currentTimeMillis() - beg + "");
    }
    public static String fixKey(String key) {
        char hexDigits[]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
        try {
            byte[] btInput = key.getBytes();
            // 获得MD5摘要算法的 MessageDigest 对象
            MessageDigest mdInst = MessageDigest.getInstance("MD5");
            // 使用指定的字节更新摘要
            mdInst.update(btInput);
            // 获得密文
            byte[] md = mdInst.digest();
            // 把密文转换成十六进制的字符串形式
            int j = md.length;
            char str[] = new char[j * 2];
            int k = 0;
            for (int i = 0; i < j; i++) {
                byte byte0 = md[i];
                str[k++] = hexDigits[byte0 >>> 4 & 0xf];
                str[k++] = hexDigits[byte0 & 0xf];
            }
            String res=new String(str);
            return res;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}

主要思路是, 先检查内存有没有图片的缓存, 如果没有再检查磁盘的缓存, 还是没有就用Volley获取图片

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值