图片的三级缓存封装为library

package weeks.amiao.com.imageloader;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.DisplayMetrics;
import android.util.Log;
import android.widget.ImageView;
import android.widget.Toast;


import java.io.File;
import java.io.FileOutputStream;

import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.util.HashMap;

import cz.msebera.android.httpclient.HttpResponse;
import cz.msebera.android.httpclient.client.HttpClient;
import cz.msebera.android.httpclient.client.methods.HttpGet;
import cz.msebera.android.httpclient.impl.client.DefaultHttpClient;

/**
 *
 */

public class BitmapUtils {
    //建立一个图片缓存的文件夹
    private final  String filePath= Environment.getExternalStorageDirectory()+"/imagecache";
    File fileDir=new File(filePath);
    Handler hand=new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if(msg.what==0){
                ImageViewToBitmap ivp= (ImageViewToBitmap) msg.obj;
                 ivp.iv.setImageBitmap(ivp.bitmap);//将拿到对象取值bitmap赋值给控件

            }

        }
    };
    //建立一个缓存的对象
    HashMap<String,SoftReference<Bitmap>> map=new HashMap<>();

    //声明对象
    private Context context;
    private InputStream stream;
    private FileOutputStream fos;
    //1.构造器
    public BitmapUtils(Context context) {
        this.context=context;
        //进行判断
        if(!fileDir.exists()){
            fileDir.mkdirs();//创建文件夹
        }

    }
    //2.加载的三种方法
    public void disPlay(ImageView iv, String url) {
        //对内存进行缓存
        Bitmap bitmap = loadMemory(iv, url);
        if(bitmap!=null){
            iv.setImageBitmap(bitmap);
        }else{
            //对sd卡进行缓存
            Bitmap bitmap1 = loadSD(iv, url);
            if(bitmap1!=null){
                iv.setImageBitmap(bitmap1);
            }else{
                //进行网络图片的加载
                loadIntenetImage(iv,url);
            }
        }

 }
    //写个删除缓存的方法
    public void disCache(File root){
        File files[] = root.listFiles();
        if (files != null)
            for (File f : files) {
                if (f.isDirectory()) { // 判断是否为文件夹
                    disCache(f);
                    try {
                        f.delete();
                    } catch (Exception e) {
                    }
                } else {
                    if (f.exists()) { // 判断是否存在
                        disCache(f);
                        try {
                            f.delete();
                        } catch (Exception e) {
                        }
                    }
                }
            }
        Toast.makeText(context, "删除成功", Toast.LENGTH_SHORT).show();
    }

    //7.缓存到内存
    private Bitmap loadMemory(ImageView iv, String url) {
        SoftReference<Bitmap> softReference = map.get(url);
        //拿到软引用的对象
        if(softReference!=null){
            //拿到其中的对象
            Bitmap bitmap = softReference.get();
            return bitmap;

        }
           return null;
    }
    //6.缓存到sd卡
    private  Bitmap loadSD(ImageView iv, String url) {
        //缓存到sd卡,首先拿到缓存的路径和文件的名称
        String name=getFileName(url);
        File file=new File(fileDir,name);
        //进行写入sd卡中
        //需要对图片进行压缩,采用了二次采样的方法
        //获得BitmapFactory的选项对象
        if(file.exists()){
            BitmapFactory.Options options=new BitmapFactory.Options();
            //第一次采样,进行设置图片的宽高
            options.inJustDecodeBounds=true;
            //将图片的路径和选项进行编码
            BitmapFactory.decodeFile(name,options);
            //获得图片的宽高
            int width = options.outWidth;
            int height = options.outHeight;
            //获得屏幕的宽高,获得显示的度量
            DisplayMetrics metrics = context.getResources().getDisplayMetrics();
            int widthPixels = metrics.widthPixels;
            int heightPixels = metrics.heightPixels;
            //定义一个变量
            int scale=0;
            int scale_x=width/widthPixels;
            int scale_y=height/widthPixels;
            //三目运算符,如果判断的关系为真,就选择以x轴的比例
            scale=scale_x>scale_y?scale_x:scale_y;
             if(scale==0){
                 scale=1;
             }
            //进行第二次的采样,是对内容的裁剪
            options.inJustDecodeBounds=false;
             //将比值赋值给图片的尺寸
            options.inSampleSize=scale;
            //存入图片的绝对路径,和选项对象,返回一个bitmap对象
            Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath(), options);
           //拿到bitmap对象之后,需要将压缩好的图片放入内存的缓存中
            //因为内存大小是有限的,所以随时会被回收,就需要软引用
            //设置软引用的值
            SoftReference<Bitmap> soft=new SoftReference<Bitmap>(bitmap);
            map.put(name,soft);


            return bitmap;

        }
         return  null;
    }

    //3.网络加载图片
    private void loadIntenetImage(ImageView iv, String url) {
        //可以开启子线程进行联网操作
        new Thread(new DownLoadImage(iv,url)).start();

    }
    //写个类实现Runnable接口
    private class DownLoadImage implements Runnable{
        private ImageView iv;
        private  String url;
        public DownLoadImage(ImageView iv, String url) {
            this.iv=iv;
            this.url=url;

        }

        @Override
        public void run() {
            //进行解析
            HttpClient client=new DefaultHttpClient();
            HttpGet get=new HttpGet(url);
            Log.i("xxx",url+"");
            try {
                HttpResponse response = client.execute(get);
                if(response.getStatusLine().getStatusCode()==200){

                    stream = response.getEntity().getContent();
                     //获得图片的名称,写个方法
                    String name = getFileName(url);
                    Log.i("xxx",name+"");
                    //将文件夹放入,和图片的名称
                    File file=new File(fileDir,name);
                    //通过文件的输出流进行写入
                    fos = new FileOutputStream(file);
                    byte[] b=new byte[1024];
                    int len=0;
                    while((len= stream.read(b))!=-1){
                        fos.write(b,0,len);

                    }
                    fos.close();
                    stream.close();
                    //将图片缓存到sd卡中,拿到缓存的对象
                    Bitmap bitmap = loadSD(iv, url);
                    //将ImageView转换成Bitmap,原生的就是将ImageView通过BItmap的格式加载
                    //所以需要将ImageView转换为Bitmap
                    ImageViewToBitmap itb=new ImageViewToBitmap(iv,bitmap);
                    //通过Handler进行发送信息
                    Message message=Message.obtain(hand,0,itb);
                    message.sendToTarget();//发送消息


              }

            } catch (Exception e) {
                e.printStackTrace();
            }
            finally {
                /*try {

                } catch (IOException e) {
                    e.printStackTrace();
                }
*/
            }
        }
    }

    //4.获得图片的名称
    private String getFileName(String url) {
        return Md5Utils.encode(url)+".jpg";

    }
    //5.将ImageView转换为Bitmap对象
    private class ImageViewToBitmap {
        private ImageView iv;
        private  Bitmap bitmap;
        public ImageViewToBitmap(ImageView iv, Bitmap bitmap) {
            this.bitmap=bitmap;
            this.iv=iv;

        }
    }
}



//获得图片名称的工具类

package weeks.amiao.com.imageloader;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class Md5Utils {
    public static String encode(String password){
        try {
            MessageDigest digest = MessageDigest.getInstance("MD5");
            byte[] result = digest.digest(password.getBytes());
            StringBuffer sb = new StringBuffer();
            for(byte b : result){
                int number = (int)(b & 0xff) ;
                String str = Integer.toHexString(number);
                if(str.length()==1){
                    sb.append("0");
                }
                sb.append(str);
            }
            return sb.toString();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            //can't reach
            return "";
        }
    }
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值