圖片三級緩存

圖片的三級緩存

何爲圖片的三級緩存?

  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);

以上就是三級緩存的方法以及使用。

發佈了23 篇原創文章 · 獲贊 8 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章