欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

图片三级缓存

程序员文章站 2022-07-02 09:48:55
...

图片的三级缓存

何为图片的三级缓存?

  1. 内存缓存(优先加载,加载速度最快,不耗费流量)
  2. 本地缓存(次优先加载,加载速度稍块,不耗费流量)
  3. 网络缓存(最后加载,加载速度最慢,耗费流量)

内存缓存

package bitmap;

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

import android.graphics.Bitmap;
import android.support.v4.util.LruCache;

//内存缓存
public class MemoryCacheUtils {
private LruCache<String, Bitmap>mMemoryCacheUtils;
public MemoryCacheUtils(){
    long maxMemory=Runtime.getRuntime().maxMemory()/8;  //模拟器默认16M
    mMemoryCacheUtils=new LruCache<String, Bitmap>((int) maxMemory){
        @Override
        protected int sizeOf(String key, Bitmap value) {
            int byteCount=value.getRowBytes()*value.getHeight();
            return byteCount;
        }
    };
}
//从内存读
public Bitmap getBitmapFromMemory(String url){  
    return mMemoryCacheUtils.get(url) ;
}
//写入内存
public void setBitmapToMemory(String url,Bitmap bitmap){
    mMemoryCacheUtils.put(url,bitmap);
    }
}

本地缓存

package bitmap;

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

import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.os.Environment;

//本地缓存
public class LocalCacheUtils {

public static final String CACHE_PATH=Environment.
        getExternalStorageDirectory().getAbsolutePath()+"/getPhoto";
//从本地sdcard读取图片
public Bitmap getBitmapFromLocal(String url) {

    try {
        String fileName = MD5Encoder.encode(url);
        File file=new File(CACHE_PATH,fileName);
        if(file.exists()){
            Bitmap bitmap=BitmapFactory.decodeStream(new FileInputStream(file));
            return bitmap;
        }
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return null;

}

//向sdcard写图片
public void setBitmapToLocal(String url,Bitmap bitmap){

    try {
        String fileName=MD5Encoder.encode(url);

        File file=new File(CACHE_PATH,fileName);

        File parentFile=file.getParentFile();
        if(!parentFile.exists()){  //如果文件夹不存在
            parentFile.mkdirs();
        }

        //将图片保存到本地
        bitmap.compress(CompressFormat.JPEG, 100, new FileOutputStream(file));
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
}

网络缓存

package bitmap;

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

import com.lidroid.xutils.bitmap.callback.BitmapLoadFrom;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.widget.ImageView;

//网络缓存
public class NetCacheUtils {
LocalCacheUtils mLocalCacheUtils;
MemoryCacheUtils mMemoryCacheUtils;
public NetCacheUtils(LocalCacheUtils mLocalCacheUtils,MemoryCacheUtils mMemoryCacheUtils) {
    this.mLocalCacheUtils=mLocalCacheUtils;
    this.mMemoryCacheUtils=mMemoryCacheUtils;
}

//从网络下载图片
public void getBitmapFromNet(ImageView ivPic, String url) {
    new BitmapTask().execute(ivPic,url);  //启动AsyncTask
}

//Handler和线程池的封装
//第一个泛型:参数类型  第二个泛型:更新进度的泛型,第三个泛型:onPostExecute的返回结果

class BitmapTask extends AsyncTask<Object,Void,Bitmap>{

    private ImageView ivPic;
    private String url;
    /**
     * 后台耗时方法在此执行, 子线程
     */
    @Override
    protected Bitmap doInBackground(Object... params) {
        ivPic=(ImageView)params[0];
        url=(String)params[1];

        ivPic.setTag(url);  //将url和imageView绑定
        return downloadBitmap(url);

    }
    //更新进度,主线程
    @Override
    protected void onProgressUpdate(Void... values) {
        // TODO Auto-generated method stub
        super.onProgressUpdate(values);
    }
    /**
     * 耗时方法结束后,执行该方法, 主线程
     */
    @Override
    protected void onPostExecute(Bitmap result) {
        if(result!=null){
            String bindUrl=(String) ivPic.getTag();
            if(url.equals(bindUrl)){   //确保图片给了正确的Imageview

                ivPic.setImageBitmap(result);

                mLocalCacheUtils.setBitmapToLocal(url, result);  //将图片保存到本地

                mMemoryCacheUtils.setBitmapToMemory(url, result);//将图片保存到内存

                System.out.println("从网络读取了。。。");

            }
        }
    }
}

//下载图片
private Bitmap downloadBitmap(String url){

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

        conn.setConnectTimeout(5000);  //设置连接时间
        conn.setReadTimeout(5000);
        conn.setRequestMethod("GET");
        conn.connect();

        int responseCode=conn.getResponseCode();
        if(responseCode==200){
            InputStream inputStream=conn.getInputStream();

            //图片压缩处理
            BitmapFactory.Options option=new BitmapFactory.Options();
            option.inSampleSize=2;  //宽高都压缩为原来的二分之一,根据图片要展示的大小来设置
            option.inPreferredConfig=Bitmap.Config.RGB_565; //设置图片格式

            Bitmap bitmap=BitmapFactory.decodeStream(inputStream,null,option);
            //Bitmap bitmap=BitmapFactory.decodeStream(inputStream);
            return bitmap;
        }

    } catch (IOException e) {

        e.printStackTrace();
    }finally{
        conn.disconnect();
    }
    return null;
}

}

使用方法

//声明图片加载工具类
private MyBitmapUtils utils;
    public TopNewsAdapter() {
        utils = new MyBitmapUtils();
    }

然后在getView()方法中,使用工具类中的display()方法就可以了
//display(ImageView image,String url)
utils.display(image, banner.pic);

以上就是三级缓存的方法以及使用。