图片的三级缓存

图片的网址

package com.example.mybitmap;

/**
 * Created by 李倩 on 2017/12/11.
 */

public class ImageDataUtils {
    public static String[] ImagesUtils=new String[]{
            "http://tupian.enterdesk.com/2012/0615/gha/15/1337566102yPLeJh.jpg",
            "http://d.hiphotos.baidu.com/zhidao/pic/item/9358d109b3de9c8252c0eeac6e81800a19d8436f.jpg",
            "http://d.hiphotos.baidu.com/zhidao/pic/item/503d269759ee3d6d8ef6e5e641166d224f4adeef.jpg",
            "http://e.hiphotos.baidu.com/zhidao/pic/item/ca1349540923dd54ea2076a4d309b3de9d8248af.jpg",
            "http://img2.duitang.com/uploads/item/201302/02/20130202212707_4isX8.jpeg",
            "http://f.hiphotos.baidu.com/zhidao/pic/item/cf1b9d16fdfaaf51be2f8bc9885494eef11f7af3.jpg",
            "http://www.fosss.org/Images/2012ZhuFu/images/nmamtf_39.png",
            "http://www.fosss.org/Images/2012ZhuFu/images/nmamtf_40.png",
            "http://e.hiphotos.baidu.com/zhidao/pic/item/f9198618367adab4aef507b98ad4b31c8701e427.jpg",
            "http://img5.imgtn.bdimg.com/it/u=334903364,3746159163&fm=21&gp=0.jpg",
            "http://i1.sinaimg.cn/gm/t/i/2010-03-09/U1782P115T41D188006F756DT20100309143541.jpg",
            "http://cdn.pcbeta.attachment.inimc.com/data/attachment/forum/201210/03/0028387ggklg56eel5s5es.jpg",
            "http://image.tianjimedia.com/uploadImages/2012/236/S406C8D0TG39.jpg",
            "http://imgsrc.baidu.com/baike/pic/item/0b46f21fbe096b6329270c190c338744ebf8acb9.jpg",
            "http://www.fosss.org/Images/2012ZhuFu/images/nmamtf_27.png",
            "http://i2.sinaimg.cn/gm/t/i/2011-04-14/U1782P115T41D229872F756DT20110414152419.jpg",
            "http://e.hiphotos.baidu.com/zhidao/pic/item/f9dcd100baa1cd119664989dbb12c8fcc2ce2db9.jpg"
    };
}

自定义的bitmap工具类

package com.example.mybitmap.bitmap;
/**
 *
 * 一个懂得了编程乐趣的小白,希望自己
 * 能够在这个道路上走的很远,也希望自己学习到的
 * 知识可以帮助更多的人,分享就是学习的一种乐趣
 *
 */

import android.graphics.Bitmap;
import android.widget.ImageView;

/**
 * 自定义的bitmap工具类
 */
public class MyBitmapUtils {
    /**
     * 网络缓存
     */
    public NetCacheUtils mNetCacheUtils;

    /**
     * 本地缓存
     */
    public SDcardCacheUtils mSdCacheUtils;

    /**
     * 内存缓存
     */
    public MemoryCacheUtils mMemoryCacheUtils;


    public MyBitmapUtils() {
        mSdCacheUtils = new SDcardCacheUtils();
        mMemoryCacheUtils = new MemoryCacheUtils();
        mNetCacheUtils = new NetCacheUtils(mSdCacheUtils, mMemoryCacheUtils);
    }

    /**
     * 展示图片的方法
     *
     * @param image
     * @param url
     */
    public void display(ImageView image, String url) {


        //从内存中读取
        Bitmap fromMemroy = mMemoryCacheUtils.getFromMemroy(url);
        //如果内存中有的h话就直接返回,从内存中读取
        if (fromMemroy != null) {
            image.setImageBitmap(fromMemroy);

            return;
        }


        //从本地SD卡读取
        Bitmap fromSd = mSdCacheUtils.getFromSd(url);
        if (fromSd != null) {
            image.setImageBitmap(fromSd);

            mMemoryCacheUtils.setToMemory(url, fromSd);

            return;
        }
        //从网络中读取
        mNetCacheUtils.getDataFromNet(image, url);

    }
}

MemoryCacheUtils 内存缓存

package com.example.mybitmap.bitmap;

/**
 * Created by 李倩 on 2017/12/11.
 */

import android.graphics.Bitmap;
import android.util.Log;
import android.util.LruCache;

/**
 * 内存缓存
 */
public class MemoryCacheUtils {
    /**
     * LinkedHashMap<>(10,0.75f,true);
     * <p/>
     * 10是最大致   0.75f是加载因子   true是访问排序   false插入排序
     *
     */
    //private LinkedHashMap<String,Bitmap> mMemoryCache = new LinkedHashMap<>(5,0.75f,true);
    private LruCache<String, Bitmap> mLruCache;

    public MemoryCacheUtils() {
        long maxMemory = Runtime.getRuntime().maxMemory();//最大内存  默认是16兆  运行时候的
        mLruCache = new LruCache<String, Bitmap>((int) (maxMemory / 8)) {
            @Override
            protected int sizeOf(String key, Bitmap value) {
                //int byteCount = value.getByteCount();
                //得到图片字节数
                // @return number of bytes between rows of the native bitmap pixels.
                int byteCount = value.getRowBytes() * value.getWidth();
                return byteCount;
            }
        };
    }

    /**
     * 从内存中读取
     *
     * @param url
     */
    public Bitmap getFromMemroy(String url) {

        Log.d("MyBitmapUtils", "从内存中加载图片");
        return mLruCache.get(url);
    }

    /**
     * 写入到内存中
     *
     * @param url
     * @param bitmap
     */
    public void setToMemory(String url, Bitmap bitmap) {
        mLruCache.put(url, bitmap);
    }
}

NetCacheUtils网络缓存工具类

package com.example.mybitmap.bitmap;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.ImageView;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * 网络缓存工具类
 */
public class NetCacheUtils {


    /**
     * 图片
     */
    private ImageView mImageView;

    /**
     * 图片地址
     */
    private String mUrl;

    /**
     * 本地缓存
     */
    private SDcardCacheUtils mDcardCacheUtils;


    /**
     * 内存缓存
     */
    private MemoryCacheUtils mMemoryCacheUtils;


    public NetCacheUtils(SDcardCacheUtils dcardCacheUtils, MemoryCacheUtils memoryCacheUtils) {
        mDcardCacheUtils = dcardCacheUtils;
        mMemoryCacheUtils = memoryCacheUtils;
    }

    /**
     * 从网络中下载图片
     *
     * @param image
     * @param url
     */
    public void getDataFromNet(ImageView image, String url) {
        new MyAsyncTask().execute(image, url);  //启动Asynctask,传入的参数到对应doInBackground()
    }


    /**
     * 异步下载
     * <p/>
     * 第一个泛型 : 参数类型  对应doInBackground()
     * 第二个泛型 : 更新进度   对应onProgressUpdate()
     * 第三个泛型 : 返回结果result   对应onPostExecute
     */
    class MyAsyncTask extends AsyncTask<Object, Void, Bitmap> {

        /**
         * 后台下载  子线程
         *
         * @param params
         * @return
         */
        @Override
        protected Bitmap doInBackground(Object... params) {

            //拿到传入的image
            mImageView = (ImageView) params[0];

            //得到图片的地址
            mUrl = (String) params[1];
            //将imageview和url绑定,防止错乱
            mImageView.setTag(mUrl);

            Bitmap bitmap = downLoadBitmap(mUrl);

            return bitmap;
        }


        /**
         * 进度更新   UI线程
         *
         * @param values
         */
        @Override
        protected void onProgressUpdate(Void... values) {
            super.onProgressUpdate(values);
        }

        /**
         * 回调结果,耗时方法结束后,主线程
         *
         * @param bitmap
         */
        @Override
        protected void onPostExecute(Bitmap bitmap) {
            if (bitmap != null) {
                //得到图片的tag值
                String url = (String) mImageView.getTag();
                //确保图片设置给了正确的image
                if (url.equals(mUrl)) {
                    mImageView.setImageBitmap(bitmap);

                    /**
                     * 当从网络上下载好之后保存到sdcard中
                     */
                    mDcardCacheUtils.savaSd(mUrl, bitmap);

                    /**
                     *  写入到内存中
                     */
                    mMemoryCacheUtils.setToMemory(mUrl, bitmap);
                    Log.d("MyBitmapUtils", "我是从网络缓存中读取的图片啊");
                }
            }
        }
    }

    /**
     * 下载图片
     *
     * @param url 下载图片地址
     * @return
     */
    private Bitmap downLoadBitmap(String url) {

        //连接
        HttpURLConnection conn = null;
        try {
            conn = (HttpURLConnection) new URL(url)
                    .openConnection();

            //设置读取超时
            conn.setReadTimeout(5000);
            //设置请求方法
            conn.setRequestMethod("GET");
            //设置连接超时连接
            conn.setConnectTimeout(5000);
            //连接
            conn.connect();

            //响应码
            int code = conn.getResponseCode();

            if (code == 200) {  //请求正确的响应码是200
                //得到响应流
                InputStream inputStream = conn.getInputStream();
                //得到bitmap对象
                Bitmap bitmap = BitmapFactory.decodeStream(inputStream);

                return bitmap;
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            conn.disconnect();
        }

        return null;
    }
}

SDcardCacheUtils 本地缓存

package com.example.mybitmap.bitmap;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Environment;
import android.util.Log;


import com.example.mybitmap.MD5Encoder;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

/**
 * 本地缓存
 */
public class SDcardCacheUtils {

    /**
     * 我们读取内存的绝对路径
     */
    public static final String CACHE_PATH = Environment
            .getExternalStorageDirectory().getAbsolutePath() + "/aixuexi";

    /**
     * 从本地读取
     * @param url
     */
    public Bitmap getFromSd(String url){
        String fileName = null;
        try {
            //得到图片的url的md5的文件名
            fileName = MD5Encoder.encode(url);
        } catch (Exception e) {
            e.printStackTrace();
        }
        File file = new File(CACHE_PATH,fileName);

        //如果存在,就通过bitmap工厂,返回的bitmap,然后返回bitmap
        if (file.exists()){
            try {
                Bitmap bitmap = BitmapFactory.decodeStream(new FileInputStream(file));
                Log.d("MyBitmapUtils", "从本地读取图片啊");
                return bitmap;
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * 向本地缓存
     *
     * @param url   图片地址
     * @param bitmap   图片
     */
    public void savaSd(String url,Bitmap bitmap){
        String fileName = null;
        try {
            //我们对图片的地址进行MD5加密,作为文件名
            fileName = MD5Encoder.encode(url);
        } catch (Exception e) {
            e.printStackTrace();
        }

        /**
         * 以CACHE_PATH为文件夹  fileName为文件名
         */
        File file = new File(CACHE_PATH,fileName);

        //我们首先得到他的符文剑
        File parentFile = file.getParentFile();
        //查看是否存在,如果不存在就创建
        if (!parentFile.exists()){
            parentFile.mkdirs(); //创建文件夹
        }

        try {
            //将图片保存到本地
            /**
             * @param format   The format of the compressed image   图片的保存格式
             * @param quality  Hint to the compressor, 0-100. 0 meaning compress for
             *                 small size, 100 meaning compress for max quality. Some
             *                 formats, like PNG which is lossless, will ignore the
             *                 quality setting
             *                 图片的保存的质量    100最好
             * @param stream   The outputstream to write the compressed data.
             */
            bitmap.compress(Bitmap.CompressFormat.JPEG,100,new FileOutputStream(file));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}

MD5Encoder 加密

package com.example.mybitmap;

import java.security.MessageDigest;

/**
 * Created by 李倩 on 2017/12/11.
 */

public class MD5Encoder {
    public static String encode(String string) throws Exception {
        byte[] hash = MessageDigest.getInstance("MD5").digest(string.getBytes("UTF-8"));
        StringBuilder hex = new StringBuilder(hash.length * 2);
        for (byte b : hash) {
            if ((b & 0xFF) < 0x10) {
                hex.append("0");
            }
            hex.append(Integer.toHexString(b & 0xFF));
        }
        return hex.toString();
    }
}

MainActivity

package com.example.mybitmap;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;

import com.example.mybitmap.bitmap.MyBitmapUtils;

public class MainActivity extends AppCompatActivity {

    private String[] mImageViews;

    private ListView mListView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mImageViews = ImageDataUtils.ImagesUtils;
        mListView = (ListView) findViewById(R.id.listview);
        mListView.setAdapter(new PhotoAdapter());
    }

    /**
     * ListView的适配器
     */
    class PhotoAdapter extends BaseAdapter {

     // private BitmapUtils mBitmapUtils;

        private MyBitmapUtils utils;
        public PhotoAdapter() {
            //mBitmapUtils = new BitmapUtils(MainActivity.this);
            // mBitmapUtils.configDefaultLoadingImage(R.mipmap.defaut);
            utils = new MyBitmapUtils();
        }

        @Override
        public int getCount() {
            return mImageViews.length;
        }

        @Override
        public Object getItem(int position) {
            return mImageViews[position];
        }

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

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {

            ViewHolder holder = null;
            if (convertView == null){
                holder = new ViewHolder();
                convertView = View.inflate(parent.getContext(),R.layout.photo_item_list,null);
                holder.tvImage = (ImageView) convertView.findViewById(R.id.image);
                convertView.setTag(holder);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }

            //PhotoData.PhotoInfo photoInfo = getItem(position);
            // holder.tvTitle.setText(photoInfo.title);
            //mBitmapUtils.display(holder.tvImage,mImageViews[position]);
            utils.display(holder.tvImage,mImageViews[position]);
            return convertView;
        }
    }

    static class ViewHolder{
        ImageView tvImage;
    }
}

布局main

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" tools:context="com.example.mybitmap.MainActivity">

    <ListView
        android:id="@+id/listview"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </ListView>

</RelativeLayout>

子布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ImageView
        android:id="@+id/image"
        android:layout_width="match_parent"
        android:layout_height="220dp"
        android:src="@mipmap/t012ea2b182c5bbbc35"/>
</LinearLayout>
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值