图片的三级缓存机制(尝鲜版)

来源:互联网 发布:php cookie写入数据库 编辑:程序博客网 时间:2024/05/21 08:37

在上个公司的项目中涉及到了图片的缓存技术,当时限于个人技术的问题,度了很久,参考了很多范文。于是自己写了这个案例来练练手。这个案例很简单粗暴的实现了初级的三级缓存机制。可以给初学者们参考学习。

1.什么是三级缓存?

一级缓存:手机内存(相当于台式机的内存条):

一般的,当我们的应用需要去联网请求数据时,最好的效果就是第一次访问就能将图片缓存下来,以达到减少流量的使用。当图片缓存再内存中时,这时的读取速度是最快的,效率也是最高德。当内存中不存在图片的数据时,这是就会从SDCard中获取数据。

二级缓存:手机本地的SDCard

当图片缓存到SDCard时,图片就已经保存在了SDcard中,可以通过BitmapFactory.decodeFile(File file)的方式获取到图片的引用。当SDcard中不存在该图片时,就应该考虑从网络上下载该图片的数据了。

三级缓存:网络缓存

当一二级缓存中都不存在数据时,就需要通过网络请求来获取数据了,当请求成功后,需要把对应的数据保存中一二级缓存中。


下面是实现三级缓存的大概步骤:

/**
* Created by Avater on 2016/9/9 0009.
*/

public class MyImageLoader {

private Context context;  //上下文对象
private int loaddPic;  //异步任务下载时显示的图片
private int err_pic ;//下载失败时显示的图片

//一级缓存,由图片的下载路径作为String(KEY),Bitmap作为Value

private Map<String,Bitmap>map = new HashMap<String, Bitmap>();

/**
* Created by Avater on 2016/9/9 0009.

* 构造函数,接收参数

*/


public MyImageLoader(Context context, int loaddPic, int err_pic) {
this.context = context;
this.loaddPic = loaddPic;
this.err_pic = err_pic;
}

//获取图片的方法,并绑定数据

public void loadImageViewPic(String path, ImageView imageView_ID){
imageView_ID.setTag(path);

imageView_ID.setTag(path);

//TODO 进行一级缓存的操作
Bitmap bitmap = fromFirstCaush(path);
if(bitmap!=null){
imageView_ID.setImageBitmap(bitmap);
return;
}
//TODO 进行二级缓存的操作
bitmap = fromSecondCaush(path);
if(bitmap!=null){
imageView_ID.setImageBitmap(bitmap);
return ;
}
//TODO 进行三级缓存
FromThridCaush(path,imageView_ID);

}

/**
* 一级缓存,读取bitmap
* @param path
* @return
*/
private Bitmap fromFirstCaush(String path){
Log.i("TAG","一级缓存------------》取");
return map.get(path);
}


/**
* 一级缓存,写入内存的操作
* @param path
* @param bitmap
*/
private void putFirstCaush(String path,Bitmap bitmap){
Log.i("TAG","一级缓存------------》存");
map.put(path,bitmap);
}


/**
* 二建缓存,读取bitmap的操作
* @param path
* @return
*/
private Bitmap fromSecondCaush(String path){
String fileName=path.substring(path.lastIndexOf("/")+1);
String filePath=context.getExternalFilesDir(null)+"/"+fileName;
File file=new File(filePath);
if(file.exists()){
Log.i("TAG","二级缓存------------》取");
return BitmapFactory.decodeFile(file.getAbsolutePath());
}
return null;
}


/**
* 二级缓存,保存的操作
* @param path
* @throws IOException
*/
private Bitmap putSecondCaush(String path,Bitmap bitmap)throws IOException {
Log.i("TAG","二级缓存------------》存");
String fileName=path.substring(path.lastIndexOf("/")+1);
String filePath=context.getExternalFilesDir(null)+"/"+fileName;
FileOutputStream fos = new FileOutputStream(filePath);
bitmap.compress(Bitmap.CompressFormat.JPEG,100,fos);
fos.close();
return bitmap;
}


/**
* 三级缓存的方法,主要用异步任务下载图片的方法
* @param path
* @param imageView_id
*/
private void FromThridCaush(final String path, final ImageView imageView_id) {
new AsyncTask<Void, Void, Bitmap>(){

@Override
protected void onPreExecute() {
imageView_id.setImageResource(loaddPic);
}

@Override
protected Bitmap doInBackground(Void... params) {
Log.i("TAG","三级缓存------------》取");
String currentPath= (String) imageView_id.getTag();
if(!currentPath.equals(path)){
return null;
}

HttpURLConnection conn =null;
InputStream inputStream =null;
try {
URL url = new URL(path);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
conn.setReadTimeout(5000);
conn.connect();
if(conn.getResponseCode()==200){
inputStream = conn.getInputStream();
Bitmap bitmap=BitmapFactory.decodeStream(inputStream);
putFirstCaush(path,bitmap);//TODO 保存至一级缓存
putSecondCaush(path,bitmap);//TODO 保存至二级缓存

return bitmap;
}else{
//TODO 响应异常
return null;
}
}catch (Exception e){
e.printStackTrace();
//TODO 网络链接异常
}finally {
if(conn!=null) {
conn.disconnect();
}if(inputStream!=null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

return null;
}

@Override
protected void onPostExecute(Bitmap bitmap) {
String currentPath= (String) imageView_id.getTag();
if(!currentPath.equals(path)){
return;
}

if(bitmap!=null){
imageView_id.setImageBitmap(bitmap);
}else{
imageView_id.setImageResource(err_pic);
}
}
}.execute();
}

}


0 0