imageview显示优化,二级缓存,以及软引用。
package com.app.util;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.widget.ImageView;
/**
* 异步加载图片并显示
图片(Bitmap)缓存:
1. 在内存中缓存图片对应的bitmap对象 (一级缓存)
2. 将图片保存在手机内部(二级缓存)
3. 服务器端
*/
public class ImageLoader2 {
private int defaultBitmapId;
private Context context;
//内存中缓存图片对象的集合
private Map cache = new HashMap();
public ImageLoader2(Context context, int defaultBitmapId) {
this.defaultBitmapId = defaultBitmapId;
this.context = context;
}
/**
* 根据图片路径加载图片并显示
* @param imagepath
* @param imageView
*/
public void loadImage(String imagepath, ImageView imageView) {
//保存标记
imageView.setTag(imagepath);
//从一级缓存中取bitmap对象
Bitmap bitmap = getFromFirstCache(imagepath);
if(bitmap!=null) { //如果有, 直接显示
imageView.setImageBitmap(bitmap);
return;
}
//从二级缓存中取bitmap对象
bitmap = getFromSecondCache(imagepath);
if(bitmap!=null) { //如果有, 直接显示
imageView.setImageBitmap(bitmap);
return;
}
//从服务器获取
//显示默认图片
imageView.setImageResource(R.drawable.shop_photo_frame);
loadImageFromNet(imagepath, imageView);
}
/**
* 从服务器端获取图片, 并显示
* @param imagepath
* @param imageView
*/
private void loadImageFromNet(final String imagepath, final ImageView imageView) {
new AsyncTask() {
@Override
protected Bitmap doInBackground(Void... params) {
String newPath = (String) imageView.getTag();
if(newPath!=imagepath)//如果不相同, 说明imageView已经被复用, 不用加载服务器端的图片
return null;
Bitmap bitmap = null;
try {
URL url = new URL(imagepath);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
connection.connect();
if(connection.getResponseCode()==200) {
InputStream is = connection.getInputStream(); //图片流
bitmap = BitmapFactory.decodeStream(is);
if(bitmap!=null) {
//缓存到一级缓存中
cache.put(imagepath, bitmap);
//缓存到二级缓存, 将bitmap保存为一张图片
String filename = imagepath.substring(imagepath.lastIndexOf("/")+1);
File cacheFile = context.getCacheDir();
bitmap.compress(CompressFormat.JPEG, 100, new FileOutputStream(new File(cacheFile, filename)));
}
}
} catch (Exception e) {
e.printStackTrace();
}
return bitmap;
}
@Override
protected void onPostExecute(Bitmap bitmap) {
String newPath = (String) imageView.getTag();
if(bitmap!=null && newPath==imagepath) {//只有ImageView没有被复用才能显示
imageView.setImageBitmap(bitmap);
}
}
}.execute();
}
/**
* 从二级缓存中取bitmap对象
* 图片缓存在: /data/data/packagename/cache/
* @param imagepath : http://.../f1.jpg
* @return
*/
private Bitmap getFromSecondCache(String imagepath) {
//得到图片的本地路径
String filename = imagepath.substring(imagepath.lastIndexOf("/")+1);
File cacheFile = context.getCacheDir();
String filePath = cacheFile.getAbsolutePath()+"/"+filename; // /data/data/packagename/cache/f1.jpg
//加载图片文件, 得到bitmap对象
Bitmap bitmap = BitmapFactory.decodeFile(filePath);
return bitmap;
}
/**
* 从一级缓存中取bitmap对象
* @param imagepath
* @return
*/
private Bitmap getFromFirstCache(String imagepath) {
Bitmap bitmap = cache.get(imagepath);
return bitmap;
}
}