package com.dusk.lin.biz;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
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.Log;
import android.widget.ImageView;
import com.dusk.lin.constant.MConstant;
/**
* @author Dusk
* @version 1.0
*
* */
public class ImageLoaderBiz {
//定义出一个LruCache作为第一重图片数据的加载源:String 图片的网络路径作为key, bitmap 图片作为值
private static LruCache<String, Bitmap> lruCache;
static{
int cacheSize = 1024*1024*4;
lruCache = new LruCache<String, Bitmap>(cacheSize ){
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getByteCount();
}
};
}
/**
* 该方法向外部直接返回指定网络路径的图片
* */
public static Bitmap getImage(String imageUrl){
Bitmap bitmap;
if(imageUrl == null){
Log.d("TAG:getimage", "imageUrl为空");
return null;
}
//先判断LruCache中是否存在指定图片:存在返回该图片,不存在,向下刷选本地内存
if((bitmap = getImageFromLruCache(imageUrl)) != null){
return bitmap;
}
//判断手机内存中的Cache文件夹下是否缓存过指定图片:有,则返回该图片;没有,向下执行异步的网络图片下载
if((bitmap = getImageFromCacheFile(imageUrl)) != null ){
return bitmap;
}
//异步加载网络图片
asyncGetImageByHttpURLConnection(imageUrl);
return b;
}
/**
* 该方法可以直接设定指定imageview的src图片
*
* */
public static void setImage(String imageUrl, ImageView imageAvatar){
Bitmap bitmap;
if(imageUrl == null){
Log.d("TAG:getimage", "imageUrl为空");
return;
}
if((bitmap = getImageFromLruCache(imageUrl)) != null){
imageAvatar.setImageBitmap(bitmap);
return ;
}
if((bitmap = getImageFromCacheFile(imageUrl)) != null ){
imageAvatar.setImageBitmap(bitmap);
return ;
}
asyncGetImageByHttpURLConnection(imageUrl, imageAvatar);
}
private static void asyncGetImageByHttpURLConnection(String imageUrl,
final ImageView imageAvatar) {
new MyImageLoadAsyncTask(new ImageLoadAsyncListener() {
@Override
public void onImageLoadEnd(Bitmap bitmap) {
imageAvatar.setImageBitmap(bitmap);
}
}).execute(imageUrl);
}
private static Bitmap b = null;
private static void asyncGetImageByHttpURLConnection(final String imageUrl) {
new MyImageLoadAsyncTask(new ImageLoadAsyncListener() {
@Override
public void onImageLoadEnd(Bitmap bitmap) {
b = bitmap;
}
}).execute(imageUrl);
}
protected static void saveImageToCacheFile(Bitmap b2, String path) {
//拿到手机内存中的cache目录
File fileCache = MConstant.context.getCacheDir();
if(!fileCache.exists()){
fileCache.mkdirs();
}
//文件名酌情而定
String fileName = path.substring(path.indexOf("/")+1);
File file = new File(fileCache, fileName);
try {
OutputStream out = new FileOutputStream(file);
b2.compress(CompressFormat.JPEG, 100, out);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
private static class MyImageLoadAsyncTask extends AsyncTask<String, Void, Bitmap>{
private ImageLoadAsyncListener listener;
public MyImageLoadAsyncTask(ImageLoadAsyncListener listener) {
this.listener = listener;
}
@Override
protected Bitmap doInBackground(String... params) {
// TODO Auto-generated method stub
Bitmap bitmap = null;
String imageUrl = params[0];
String path = MConstant.ROOT + imageUrl;
URL url = null;
InputStream in = null;
HttpURLConnection conn = null;
try {
url= new URL(path);
conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(5000);
conn.setRequestMethod("GET");
conn.setDoInput(true);
conn.connect();
int status = conn.getResponseCode();
if(status == 200){
in = conn.getInputStream();
if(in != null){
//先压缩图片
bitmap = compressImage(in);
//再分别在缓存和内存中备份
lruCache.put(imageUrl, bitmap);
saveImageToCacheFile(bitmap, imageUrl);
}else{
Log.e("TAG:imageloadByAsync", "数据库响应数据流为空");
}
}else{
Log.e("TAG:imageloadByAsync", "数据库响应异常:"+status);
}
} catch (IOException e) {
e.printStackTrace();
}finally{
conn.disconnect();
if(in != null){
in = null;
}
}
return bitmap;
}
@Override
protected void onPostExecute(Bitmap result) {
super.onPostExecute(result);
listener.onImageLoadEnd(result);
}
}
public interface ImageLoadAsyncListener{
public void onImageLoadEnd(Bitmap bitmap);
}
private static Bitmap getImageFromCacheFile(String imageUrl) {
String fileName = imageUrl.substring(imageUrl.lastIndexOf("/")+1);
Bitmap bitmap = null;
File cacheFile = MConstant.context.getCacheDir();
if(cacheFile != null){
File[] files = cacheFile.listFiles();
for(File f : files){
if(f.isFile() && f.getName().equals(fileName)){
bitmap = BitmapFactory.decodeFile(f.getAbsolutePath());
}
}
}else{
Log.e("TAG:getImageFromCacheFile", "cacheFile=null");
}
return bitmap;
}
public static Bitmap compressImage(InputStream in) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int len = 0;
byte[] buffer = new byte[1024];
try {
while((len = in.read(buffer)) != -1){
baos.write(buffer, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
}
byte[] data = baos.toByteArray();
Options opts = new Options();
opts.inJustDecodeBounds = true;
BitmapFactory.decodeByteArray(data, 0, data.length, opts );
int width = opts.outWidth;
int height = opts.outHeight;
int wCompress = 60;
int hCompress = 60;
int wScale = width/wCompress;
int hScale = height/hCompress;
int scale = Math.max(wScale, hScale);
if(scale <= 0){
scale = 1;
}
opts.inJustDecodeBounds = false;
opts.inSampleSize = scale;
return BitmapFactory.decodeByteArray(data, 0, data.length, opts);
}
private static Bitmap getImageFromLruCache(String imageUrl) {
return lruCache.get(imageUrl);
}
}