package com.egov.service;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import com.egov.http.MD5;
import android.graphics.drawable.Drawable;
import android.os.Environment;
import android.os.Handler;
import android.util.Log;
public class SyncImageLoaderService {
final Handler handler = new Handler();
/**
* 下载Image的线程池
*/
private ExecutorService mImageThreadPool = null;
private String sdCardDir = Environment.getExternalStorageDirectory() + "";
/**
* SD信息对应表
*/
boolean sdCardExist = Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);
public HashMap<String, SoftReference<Drawable>> imageCache = new HashMap<String, SoftReference<Drawable>>();
/**
* 获取线程池的方法,因为涉及到并发的问题,加上同步锁
* @return
*/
public ExecutorService getThreadPool(){
if(mImageThreadPool == null){
synchronized(ExecutorService.class){
if(mImageThreadPool == null){
// 为了下载图片更加的流畅,我们用了3个线程来下载图片
mImageThreadPool = Executors.newFixedThreadPool(10);
}
}
}
return mImageThreadPool;
}
public interface OnImageLoadListener {
public void onImageLoad(Integer t, Drawable drawable);
public void onError(Integer t);
}
public void loadImage(Integer t, String imageUrl,
OnImageLoadListener listener) {
final OnImageLoadListener mListener = listener;
final String mImageUrl = imageUrl;
final Integer mt = t;
// 如果缓存存在
if (imageCache.containsKey(mImageUrl)) {
loadImageFromCache(mImageUrl, mt, mListener);
} else {
// 从线程池中获取线程加载图片,减少服务器压力
getThreadPool().execute(new Runnable() {
@Override
public void run() {
Log.i("Thread", "软引用缓存不存在,调用" + mImageUrl);
loadImage(mImageUrl, mt, mListener);
}
});
}
}
public void loadImageFromCache(final String mImageUrl,final Integer mt,final OnImageLoadListener mListener) {
Log.i("Thread", "软引用缓存图片已经存在" + mImageUrl);
SoftReference<Drawable> softReference = imageCache.get(mImageUrl);
final Drawable d = softReference.get();
if (d != null) {
handler.post(new Runnable() {
@Override
public void run() {
mListener.onImageLoad(mt, d);
}
});
return;
}
}
private void loadImage(final String mImageUrl,final Integer mt,final OnImageLoadListener mListener){
// 如果缓存不存在
try {
final Drawable d = loadImageFromUrl(mImageUrl);
if(d != null){
// 加入缓存
Log.i("Thread", mImageUrl + "加入软引用缓存" + mImageUrl);
imageCache.put(mImageUrl, new SoftReference<Drawable>(d));
handler.post(new Runnable() {
@Override
public void run() {
mListener.onImageLoad(mt, d);
}
});
judgeDeleteCacheFile();
}
} catch (IOException e) {
handler.post(new Runnable() {
@Override
public void run() {
mListener.onError(mt);
}
});
e.printStackTrace();
}
}
public Drawable loadImageFromUrl(String url) throws IOException {
// 本地SD卡是否存在
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
// 获取SDcard路径
File sdCardDir = Environment
.getExternalStorageDirectory();
// SDCard目录:/mnt/sdcard
String sdcardPath = sdCardDir.getAbsolutePath();
File baseDir = new File(Environment.getExternalStorageDirectory()+"/DJKS/");
if(!baseDir.exists()) {
baseDir.mkdir();
}
File baseImageDir = new File(Environment.getExternalStorageDirectory()+"/DJKS/" + "cacheImages/");
if(!baseImageDir.exists()) {
baseImageDir.mkdir();
}
File f = new File(Environment.getExternalStorageDirectory()+"/DJKS/" + "cacheImages/" + MD5.getMD5(url));
if (f.exists()) {
Log.i("Thread", "所需要图片在SD卡存在" + url);
f.setLastModified(System.currentTimeMillis());
FileInputStream fis = new FileInputStream(f);
Drawable d = Drawable.createFromStream(fis, "src");
return d;
}
URL m = new URL(url);
InputStream i = (InputStream) m.getContent();
Drawable d;
if(i == null) {
Log.i("InputStream爆出异常", "i == null");
return null;
}
try {
DataInputStream in = new DataInputStream(i);
FileOutputStream out = new FileOutputStream(f);
f.setLastModified(System.currentTimeMillis());
byte[] buffer = new byte[1024];
int byteread=0;
// 图片信息写入SD卡
while ((byteread = in.read(buffer)) != -1) {
out.write(buffer, 0, byteread);
}
in.close();
out.close();
d = Drawable.createFromStream(i, "src");
} catch (Exception e) {
// TODO: handle exception
Log.i("爆出异常", "爆出异常");
return null;
}
return d;
}else{
// 访问URL获取图片
URL m = new URL(url);
InputStream i = (InputStream) m.getContent();
Drawable d = Drawable.createFromStream(i, "src");
return d;
}
}
public void judgeDeleteCacheFile() {
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
TreeMap<Long,File> tm = new TreeMap<Long,File>();
File baseDir = new File(Environment.getExternalStorageDirectory()+"/DJKS/" + "cacheImages/");
if (baseDir.isDirectory()) {
File subFile[] = baseDir.listFiles();
int fileNum = subFile.length;
if (fileNum > 30) {
Log.i("judgeDeleteCacheFile", "判断是否需要删除文件SD卡图片数量 大于30 需要删除" + fileNum);
for (int i = 0; i < fileNum; i++) {
Long tempLong = new Long(subFile[i].lastModified());
tm.put(tempLong, subFile[i]);
}
Set<Long> set = tm.keySet();
Iterator<Long> it = set.iterator();
int index = -1;
while (it.hasNext()) {
index ++;
Object key = it.next();
if(index > 30) {
Object objValue = tm.get(key);
File tempFile = (File) objValue;
Log.i("deleteFile", tempFile.getName());
new File(baseDir, tempFile.getName()).delete();
}
}
}
}
}
}
}