图片下载缓存处理基础篇

      给大家介绍一个自己整理的图片下载缓存的工具类。


整体思路:

一,首先使用异步任务去下载图片,下载完成(可在本地保存),调用LruCache的put 方法将图片加入内存缓存中。

二,当第二次查看图片时,先通过调用LruCache,get(key),获取内存缓存中的图片,如果没有,再去查看本地图片是否存在,如果存在,加入内存缓存,如果不存在,就去下载,下载完成加入内存缓存,并保存本地。这样就形成了一个闭环。

在上代码之前先说下LruCache使用步骤:

(1)要设置缓存图片的内存大小

手机内存的获取方式:int MAXMEMONRY = (int) (Runtime.getRuntime() .maxMemory());

(2)LruCache里面的键值对分别是URL和对应的图片
(3)重写sizeOf方法,返回图片数量。


 private final static int maxMemory = (int) Runtime.getRuntime().maxMemory();// 获取当前应用程序所分配的最大内存
    private final static int cacheSize = maxMemory / 5;// 只分5分之一用来做图片缓存
    private static LruCache<String, Bitmap> mLruCache = new LruCache<String, Bitmap>(
            cacheSize) {
        protected int sizeOf(String key, Bitmap value) {
            return value.getRowBytes() * value.getHeight() / 1024;
        };
    };

//===================下面为具体代码实现=========

具体分三个工具类,代码注释比较详细,就不在多说、、

/**

*第一步通过url判断内存中是否有此图片,然后执行相应的操作

*/

public class BitmapCache {  
    
    private final static int maxMemory = (int) Runtime.getRuntime().maxMemory();// 获取当前应用程序所分配的最大内存
    private final static int cacheSize = maxMemory / 5;// 只分5分之一用来做图片缓存

    //缓存处理类

    private static LruCache<String, Bitmap> mLruCache = new LruCache<String, Bitmap>(
            cacheSize) {
        protected int sizeOf(String key, Bitmap value) {
            return value.getRowBytes() * value.getHeight() / 1024;
        };
    };
    /**
     * @param urlStr所需要加载的图片的url,以String形式传进来,可以把这个url作为缓存图片的key
     * @param image ImageView 控件
     */
    public static void loadBitmap(String urlStr, ImageView image){
        AsyncImageLoader asyncLoader = new AsyncImageLoader(image,
                mLruCache);
        Bitmap bitmap = asyncLoader.getBitmapFromMemoryCache(urlStr);// 首先从内存缓存中获取图片
        if (bitmap != null) {// 如果缓存中存在这张图片则直接设置给ImageView
            image.setImageBitmap(bitmap);
        }
        else {// 否则先设置成默认的图片, 然后执行异步任务AsycnTask 下载图片
            image.setImageResource(R.drawable.pic_default_image);
            asyncLoader.execute(urlStr);
        }
    }
}  
//==============下载图片异步任务类=========

/**
 * 异步任务类,区下载图片,在内存中缓存。
 */
public class AsyncImageLoader extends AsyncTask<String, Void, Bitmap>{

     private ImageView image;  
     private LruCache<String, Bitmap> lruCache;  
     public AsyncImageLoader(ImageView image, LruCache<String, Bitmap> lruCache) {  
            super();  
            this.image = image;  
            this.lruCache = lruCache;  
        }  
       @Override  
       protected Bitmap doInBackground(String... params) {  
            Bitmap bitmap = null;
            //通过url下载图片
            bitmap = LoadImageUtil.getBitmap(params[0]); 
            if(bitmap==null){//图片加载失败,可能url不正确等等
                return null;
            }else{  //添加内部缓存
                addBitmapToMemoryCache(params[0], bitmap);  
                return bitmap;
            }
        }  
      
        @Override  
        protected void onPostExecute(Bitmap bitmap) {  
            if(bitmap!=null){
                 image.setImageBitmap(bitmap);  
            }
           
        }  
       //调用LruCache的put 方法将图片加入内存缓存中
        private void addBitmapToMemoryCache(String key, Bitmap bitmap){  
            if (getBitmapFromMemoryCache(key) == null) {  
                lruCache.put(key, bitmap);  
            }  
        }  
        //调用Lrucache的get 方法从内存缓存中去图片  
        public Bitmap getBitmapFromMemoryCache(String key) {  
            return lruCache.get(key);  
        }  
    } 

//=============具体下载图片类工具===========

public classLoadImageUtil{

/**
     * 通过url获取Bitmap
     *
     * @param 该图片的网络路径
     */
    public static Bitmap getBitmap(String urlPath) {
        Bitmap bitmap = null;
        String fullName = getImageFullName(urlPath);// 本地保存图片的文件名
        Log.i(TAG, "fullName" + fullName);
        if (judgeExists(fullName)) {
            bitmap = BitmapFactory.decodeFile(fullName);
        } else {
            bitmap = downloadAndSaveBitmap(urlPath, fullName); // 下载保存图片
        }
        return bitmap;
    }

    /**
     * 判断文件是否存在
     *
     * @param 文件在本地的完整名
     * @return
     */
    private static boolean judgeExists(String fullName) {

        File file = new File(fullName);

        return file.exists();
    }

    /**
     * 拼接一个完整的本地文件名
     *
     * @param 文件的网络路径
     * @return
     */
    private static String getImageFullName(String name) {
        return FileUtil.PATH_IMAGE+File.separator+ getLastName(name);
    }
    /**
     * 获取最后的‘/’后的文件名,在当地保存
     *
     * @param name
     * @return
     */
    private static String getLastName(String name) {
        int lastIndexOf = 0;
        lastIndexOf = name.lastIndexOf('/');
        String sub=name.substring(lastIndexOf, name.length());
        return sub;
    }

    /**
     * 下载保存图片
     *
     * @param urlPath
     *            下载路径
     * @param fullName
     *            文件保存路径+文件名
     * @return
     */
    private static Bitmap downloadAndSaveBitmap(String urlPath, String fullName) {

        Bitmap bitmap = downloadImage(urlPath); // 下载图片
        /* 首先判断是否挂载了sdcard */
        boolean sdCardExist = Environment.getExternalStorageState().equals(
                android.os.Environment.MEDIA_MOUNTED); // 判断sd卡是否存在
        if (sdCardExist) {
            if (bitmap != null) {
                saveBitmap(fullName, bitmap);
            }
        } else {
            Log.e(TAG, "没有sdcard无法保存图片");
        }

        return bitmap;
    }

    /**
     * 保存图片
     *
     * @param fullName图片本地保存的文件夹名
     * @param bitmap图片
     */
    private static void saveBitmap(String fullName, Bitmap bitmap) {

        if (bitmap != null) {

            try {
                File file = new File(fullName);//文件夹
                if (!file.exists()) {
                    creatFolder(fullName);
                    file.createNewFile();
                }
                FileOutputStream fos = new FileOutputStream(file);
                bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
                fos.flush();
            } catch (IOException e) {
                e.printStackTrace();
    
            }
        } else {

        }
    }

    /**
     * 创建保存文件的文件夹
     *
     * @param fullName
     *            带文件名的文件路径
     * @return
     */
    private static void creatFolder(String fullName) {
        if (getLastName(fullName).contains(".")) {
            String newFilePath = fullName.substring(0,
                    fullName.lastIndexOf('/'));
            File file = new File(newFilePath);
            file.mkdirs();
        }
    }

    /**
     * 下载图片
     *
     * @param urlPath
     * @return
     */
    public static Bitmap downloadImage(String urlPath) {

        try {
            byte[] byteData = getImageByte(urlPath);
            if (byteData == null) {
                Log.e(TAG, "没有得到图片的byte,问题可能是path:" + urlPath);
                return null;
            }
            int len = byteData.length;
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inPreferredConfig = Bitmap.Config.RGB_565;
            options.inPurgeable = true;
            options.inInputShareable = true;
            options.inJustDecodeBounds = false;
            if (len > 200000) {// 大于200K的进行压缩处理
                options.inSampleSize = 2;
            }
            return BitmapFactory.decodeByteArray(byteData, 0, len);
        } catch (Exception e) {
            e.printStackTrace();
            Log.e(TAG, "图片下载失败,异常信息是:" + e.toString());
            return null;
        }
    }

    /**
     * 获取图片的byte数组
     *
     * @param urlPath
     * @return
     */
    private static byte[] getImageByte(String urlPath) {
        InputStream in = null;
        byte[] result = null;
        try {
            URL url = new URL(urlPath);
            HttpURLConnection httpURLconnection = (HttpURLConnection) url
                    .openConnection();
            httpURLconnection.setDoInput(true);
            httpURLconnection.connect();
            if (httpURLconnection.getResponseCode() == 200) {
                in = httpURLconnection.getInputStream();
                result = readInputStream(in);
                in.close();
            } else {
                Log.e(TAG, "下载图片失败,状态码是:" + httpURLconnection.getResponseCode());
            }
        } catch (Exception e) {
            Log.e(TAG, "下载图片失败,原因是:" + e.toString());
            e.printStackTrace();
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }
    /**
     * 将输入流转为byte数组
     *
     * @param in
     * @return
     * @throws Exception
     */
    private static byte[] readInputStream(InputStream in) throws Exception {

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len = -1;
        while ((len = in.read(buffer)) != -1) {
            baos.write(buffer, 0, len);
        }
        baos.close();
        in.close();
        return baos.toByteArray();
    }
}













 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

流转的年华

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值