android下载网络图片并缓存

异步下载网络图片,并提供是否缓存至内存或外部文件的功能
异步加载类AsyncImageLoader
public void downloadImage(final String url, final ImageCallback callback);
public void downloadImage(final String url, final boolean cache2Memory, final ImageCallback callback);
public void setCache2File(boolean flag);
public void setCachedDir(String dir);
图片下载和缓存实现类LoaderImpl


1.AsyncImageLoader.java

public class AsyncImageLoader {  
//保存正在下载的图片URL集合,避免重复下载用  
private static HashSet<String> sDownloadingSet;  
//软引用内存缓存  
private static Map<String,SoftReference<Bitmap>> sImageCache;   
//图片三种获取方式管理者,网络URL获取、内存缓存获取、外部文件缓存获取  
private static LoaderImpl impl;  
//线程池相关  
private static ExecutorService sExecutorService;  

//通知UI线程图片获取ok时使用  
private Handler handler;   


/** 
 * 异步加载图片完毕的回调接口 
 */  
public interface ImageCallback{  
    /** 
     * 回调函数 
     * @param bitmap: may be null! 
     * @param imageUrl  
     */  
    public void onImageLoaded(Bitmap bitmap, String imageUrl);  
}  

static{  
    sDownloadingSet = new HashSet<String>();  
    sImageCache = new HashMap<String,SoftReference<Bitmap>>();  
    impl = new LoaderImpl(sImageCache);  
}  

public AsyncImageLoader(Context context){  
    handler = new Handler();  
    startThreadPoolIfNecessary();  

    String defaultDir = context.getCacheDir().getAbsolutePath();  
    setCachedDir(defaultDir);  
}  

/** 
 * 是否缓存图片至/data/data/package/cache/目录 
 * 默认不缓存 
 */  
public void setCache2File(boolean flag){  
    impl.setCache2File(flag);  
}  

/** 
 * 设置缓存路径,setCache2File(true)时有效 
 */  
public void setCachedDir(String dir){  
    impl.setCachedDir(dir);  
}  

/**开启线程池*/  
public static void startThreadPoolIfNecessary(){  
    if(sExecutorService == null || sExecutorService.isShutdown() || sExecutorService.isTerminated()){  
        sExecutorService = Executors.newFixedThreadPool(3);  
        //sExecutorService = Executors.newSingleThreadExecutor();  
    }  
}  

/** 
 * 异步下载图片,并缓存到memory中 
 * @param url    
 * @param callback  see ImageCallback interface 
 */  
public void downloadImage(final String url, final ImageCallback callback){  
    downloadImage(url, true, callback);  
}  

/** 
 *  
 * @param url 
 * @param cache2Memory 是否缓存至memory中 
 * @param callback 
 */  
public void downloadImage(final String url, final boolean cache2Memory, final ImageCallback callback){  
    if(sDownloadingSet.contains(url)){  
        Log.i("AsyncImageLoader", "###该图片正在下载,不能重复下载!");  
        return;  
    }  

    Bitmap bitmap = impl.getBitmapFromMemory(url);  
    if(bitmap != null){  
        if(callback != null){  
            callback.onImageLoaded(bitmap, url);  
        }  
    }else{  
        //从网络端下载图片  
        sDownloadingSet.add(url);  
        sExecutorService.submit(new Runnable(){  
            @Override  
            public void run() {  
                final Bitmap bitmap = impl.getBitmapFromUrl(url, cache2Memory);  
                handler.post(new Runnable(){  
                    @Override  
                    public void run(){  
                        if(callback != null)  
                            callback.onImageLoaded(bitmap, url);  
                        sDownloadingSet.remove(url);  
                    }  
                });  
            }  
        });  
    }  
}  

/** 
 * 预加载下一张图片,缓存至memory中 
 * @param url  
 */  
public void preLoadNextImage(final String url){  
    //将callback置为空,只将bitmap缓存到memory即可。  
    downloadImage(url, null);  
}  

}  

2.LoaderImpl.java

    /** 
             *  
             * @author Administrator 
             * @desc 异步加载图片管理器 
             * 
             */  
public class LoaderImpl {  
//内存中的软应用缓存  
private Map<String, SoftReference<Bitmap>> imageCache;  

//是否缓存图片至本地文件  
private boolean cache2FileFlag = false;  

//缓存目录,默认是/data/data/package/cache/目录  
private String cachedDir;  

public LoaderImpl(Map<String, SoftReference<Bitmap>> imageCache){  
    this.imageCache = imageCache;  
}  

/** 
 * 是否缓存图片至外部文件 
 * @param flag  
 */  
public void setCache2File(boolean flag){  
    cache2FileFlag = flag;  
}  

/** 
 * 设置缓存图片到外部文件的路径 
 * @param cacheDir 
 */  
public void setCachedDir(String cacheDir){  
    this.cachedDir = cacheDir;  
}  

/** 
 * 从网络端下载图片 
 * @param url 网络图片的URL地址 
 * @param cache2Memory 是否缓存(缓存在内存中) 
 * @return bitmap 图片bitmap结构 
 *  
 */  
public Bitmap getBitmapFromUrl(String url, boolean cache2Memory){  
    Bitmap bitmap = null;  
    try{  
        URL u = new URL(url);  
        HttpURLConnection conn = (HttpURLConnection)u.openConnection();    
        InputStream is = conn.getInputStream();  
        bitmap = BitmapFactory.decodeStream(is);  

        if(cache2Memory){  
            //1.缓存bitmap至内存软引用中  
            imageCache.put(url, new SoftReference<Bitmap>(bitmap));  
            if(cache2FileFlag){  
                //2.缓存bitmap至/data/data/packageName/cache/文件夹中  
                String fileName = getMD5Str(url);  
                String filePath = this.cachedDir + "/" +fileName;  
                FileOutputStream fos = new FileOutputStream(filePath);  
                bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);  
            }  
        }  

        is.close();  
        conn.disconnect();  
        return bitmap;  
    }catch(IOException e){  
        e.printStackTrace();  
        return null;  
    }  
}  

/** 
 * 从内存缓存中获取bitmap 
 * @param url 
 * @return bitmap or null. 
 */  
public Bitmap getBitmapFromMemory(String url){  
    Bitmap bitmap = null;  
    if(imageCache.containsKey(url)){  
        synchronized(imageCache){  
            SoftReference<Bitmap> bitmapRef = imageCache.get(url);  
            if(bitmapRef != null){  
                bitmap = bitmapRef.get();  
                return bitmap;  
            }  
        }  
    }  
    //从外部缓存文件读取  
    if(cache2FileFlag){  
        bitmap = getBitmapFromFile(url);  
        if(bitmap != null)  
            imageCache.put(url, new SoftReference<Bitmap>(bitmap));  
    }  

    return bitmap;  
}  

/** 
 * 从外部文件缓存中获取bitmap 
 * @param url 
 * @return 
 */  
private Bitmap getBitmapFromFile(String url){  
    Bitmap bitmap = null;  
    String fileName = getMD5Str(url);  
    if(fileName == null)  
        return null;  

    String filePath = cachedDir + "/" + fileName;  

    try {  
        FileInputStream fis = new FileInputStream(filePath);  
        bitmap = BitmapFactory.decodeStream(fis);  
    } catch (FileNotFoundException e) {  
        e.printStackTrace();  
        bitmap = null;  
    }  
    return bitmap;  
}  


/**   
 * MD5 加密   
 */     
private static String getMD5Str(String str) {     
    MessageDigest messageDigest = null;     
    try {     
        messageDigest = MessageDigest.getInstance("MD5");     
        messageDigest.reset();     
        messageDigest.update(str.getBytes("UTF-8"));     
    } catch (NoSuchAlgorithmException e) {     
        System.out.println("NoSuchAlgorithmException caught!");     
        return null;  
    } catch (UnsupportedEncodingException e) {     
        e.printStackTrace();  
        return null;  
    }     

    byte[] byteArray = messageDigest.digest();     
    StringBuffer md5StrBuff = new StringBuffer();     
    for (int i = 0; i < byteArray.length; i++) {                 
        if (Integer.toHexString(0xFF & byteArray[i]).length() == 1)     
            md5StrBuff.append("0").append(Integer.toHexString(0xFF & byteArray[i]));     
        else     
            md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i]));     
    }     

    return md5StrBuff.toString();     
}    

/**   
 * MD5 加密   
private static String getMD5Str(Object...objects){ 
    StringBuilder stringBuilder=new StringBuilder(); 
    for (Object object : objects) { 
        stringBuilder.append(object.toString()); 
    } 
    return getMD5Str(stringBuilder.toString()); 
}*/   
}  

3.测试Activity

public class MainActivity extends Activity {  
/** Called when the activity is first created. */  
@Override  
public void onCreate(Bundle savedInstanceState) {  
    super.onCreate(savedInstanceState);  
    setContentView(R.layout.main);  

    final ImageView iv = (ImageView)findViewById(R.id.iv);  
    //网络图片地址  
    String imgUrl = "http://...";  

    //for test  
    AsyncImageLoader loader = new AsyncImageLoader(getApplicationContext());  

    //将图片缓存至外部文件中  
    loader.setCache2File(true); //false  
    //设置外部缓存文件夹  
    loader.setCachedDir(this.getCacheDir().getAbsolutePath());  

    //下载图片,第二个参数是否缓存至内存中  
    loader.downloadImage(imgUrl, true/*false*/, new AsyncImageLoader.ImageCallback() {  
        @Override  
        public void onImageLoaded(Bitmap bitmap, String imageUrl) {  
            if(bitmap != null){  
                iv.setImageBitmap(bitmap);  
            }else{  
                //下载失败,设置默认图片  
            }  
        }  
    });  
}  

}  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值