/**
三级缓存的操作:
是否在内存中 会把图片放置在一个集合里面
从硬盘中获取:sdcard
从网络加载
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpConnectionParams;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.os.AsyncTask;
import android.support.v4.util.LruCache;
import android.util.DisplayMetrics;
import android.widget.ImageView;
*AsyncTask :主要是封装了线程池 + Handler
*如果使用AsyncTask 去除线程池 Handler
*/
public class BitmapUtils {
private File dir;//存放图片的目录
//android在4.0添加的一个缓存支持类
int maxSize = (int) (Runtime.getRuntime().maxMemory()/8);
private LruCache<String, Bitmap> cache = new LruCache<String, Bitmap>(maxSize){
//返回图片的数据
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getRowBytes()*value.getHeight()/1024;
}
};//指定缓存的大小
//LruCache 自身有一套算法:移除里面使用频率低的对象
private Context context;
public BitmapUtils(Context context) {
this.context = context;
dir = new File("/mnt/sdcard/bitmapcache");
if(!dir.exists()){
dir.mkdirs();//创建目录
}
}
/**
* 显示图片
* @param iv
* @param url
*/
public void display(ImageView iv,String url){
Bitmap bitmap = null;//图片
//1从内存中获取
bitmap = fromCacheGetBitmap(url);
if(bitmap != null){
iv.setImageBitmap(bitmap);
return;
}
//2 从sdcard获取
bitmap = fromSdcardGetBitmap(url);
if(bitmap != null){
iv.setImageBitmap(bitmap);
return;
}
//3 从网络上获取图片
fromInternetGetBitmap(iv,url);
}
/**
* 从内存中获取图片:使用一个map集合来存储图片 oom异常 16M内存空间
* java里面有一个对象引用的机制
* 1 强引用: Object obj = new Object(); 只要在使用就不可能被垃圾回收器回收
* 2 不是强引用
* 2.1 软引用 :只保证该软件能够正常运行
* 2.2 弱引用 :当发现内存不足 马上就回收
* 2.3 虚引用 :只要回收器一运行马上回收
* @param url
* @return
*/
private Bitmap fromCacheGetBitmap(String url){
Bitmap bitmap = null;
bitmap = cache.get(url);
return bitmap;
}
/**
* 从sdcard里面获取图片
* @param url
* @return
*/
private Bitmap fromSdcardGetBitmap(String url){
Bitmap bitmap = null;
File file = new File(dir,getFileName(url));
bitmap = decodeFile(file);
if(bitmap != null){
//把图片存入内存集合
cache.put(url, bitmap);
}
return bitmap;
}
/**
* 从网络获取图片
* @param url
*/
private void fromInternetGetBitmap(ImageView iv,String url){
//AsyncTask 执行异步任务 每次都需要new
new MyAsyncTask().execute(new ImageViewURl(iv,url));
}
private class MyAsyncTask extends AsyncTask<ImageViewURl, Integer, ImageViewBitmap>{
//下载前调用
@Override
protected void onPreExecute() {
super.onPreExecute();
}
//下载
@Override
protected ImageViewBitmap doInBackground(ImageViewURl... params) {
try {
String url = params[0].url;
ImageView iv = params[0].iv;
HttpClient client = new DefaultHttpClient();
client.getParams().setParameter(HttpConnectionParams.CONNECTION_TIMEOUT, 3000);
HttpGet request = new HttpGet(url);
HttpResponse response = client.execute(request);
if(response.getStatusLine().getStatusCode() == 200){
InputStream inputStream = response.getEntity().getContent();
//把流处理成图片
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
//1 把bitmap放入集合
cache.put(url, bitmap);
//2 把bitmap放置在sdcard
File file = new File(dir,getFileName(url));
FileOutputStream stream = new FileOutputStream(file);
bitmap.compress(CompressFormat.JPEG, 100, stream);
return new ImageViewBitmap(iv, bitmap);
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
//下载完成
@Override
protected void onPostExecute(ImageViewBitmap result) {
super.onPostExecute(result);
result.iv.setImageBitmap(result.bitmap);
}
}
/**
* 使用AsyncTask去加载网络图片
* @author apple
*
*/
static class ImageViewURl{
ImageView iv;
String url;
public ImageViewURl(ImageView iv, String url) {
super();
this.iv = iv;
this.url = url;
}
}
/**
* 网络加载完成后的对象
* @author apple
*
*/
static class ImageViewBitmap{
ImageView iv;
Bitmap bitmap;
public ImageViewBitmap(ImageView iv, Bitmap bitmap) {
super();
this.iv = iv;
this.bitmap = bitmap;
}
}
/**
* 获取图片的名称
* @param url
* @return
*/
private String getFileName(String url){
return Md5Utils.encode(url);
}
/**
* OOM大图片处理
* @param file
* @return
*/
public Bitmap decodeFile(File file){
Options opts = new Options();
opts.inJustDecodeBounds = true;//只加载图片的宽度
opts.inPurgeable = true;//加载图片的像素点是可以清除
opts.inInputShareable = true;
BitmapFactory.decodeFile(file.getAbsolutePath(), opts);//此次加载就是为获取图片的宽高
opts.inSampleSize = calculatorSampleSize(opts);//设置缩放的比率
opts.inJustDecodeBounds = false;//加载整个图片的内容
return BitmapFactory.decodeFile(file.getAbsolutePath(), opts);
}
/*
* 计算缩放比率
*/
private int calculatorSampleSize(Options opts) {
int inSamleSize = 1;
int outWidth = opts.outWidth;
int outHeight = opts.outHeight;
//获取手机屏幕的宽高
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
int widthPixels = displayMetrics.widthPixels;
int heightPixels = displayMetrics.heightPixels;
//只有加载的图片大于屏幕的宽高
if(outWidth > widthPixels || outHeight > heightPixels){
int scaleX = outWidth/widthPixels;
int scaleY = outHeight/heightPixels;
inSamleSize = scaleX > scaleY?scaleX:scaleY;
}
return inSamleSize;
}
}