android ListView 多线程异步加载Url图片

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();  
						}
					}
				}
			}
    	}
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值