异步下载网络图片,并提供是否缓存至内存或外部文件的功能

异步加载类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

  1. package com.imagecache;
  2. import java.lang.ref.SoftReference;
  3. import java.util.HashMap;
  4. import java.util.HashSet;
  5. import java.util.Map;
  6. import java.util.concurrent.ExecutorService;
  7. import java.util.concurrent.Executors;
  8. import android.content.Context;
  9. import android.graphics.Bitmap;
  10. import android.os.Handler;
  11. import android.util.Log;
  12. public class AsyncImageLoader {
  13. //保存正在下载的图片URL集合,避免重复下载用
  14. private static HashSet<String> sDownloadingSet;
  15. //软引用内存缓存
  16. private static Map<String,SoftReference<Bitmap>> sImageCache;
  17. //图片三种获取方式管理者,网络URL获取、内存缓存获取、外部文件缓存获取
  18. private static LoaderImpl impl;
  19. //线程池相关
  20. private static ExecutorService sExecutorService;
  21. //通知UI线程图片获取ok时使用
  22. private Handler handler;
  23. /**
  24. * 异步加载图片完毕的回调接口
  25. */
  26. public interface ImageCallback{
  27. /**
  28. * 回调函数
  29. * @param bitmap: may be null!
  30. * @param imageUrl
  31. */
  32. public void onImageLoaded(Bitmap bitmap, String imageUrl);
  33. }
  34. static{
  35. sDownloadingSet = new HashSet<String>();
  36. sImageCache = new HashMap<String,SoftReference<Bitmap>>();
  37. impl = new LoaderImpl(sImageCache);
  38. }
  39. public AsyncImageLoader(Context context){
  40. handler = new Handler();
  41. startThreadPoolIfNecessary();
  42. String defaultDir = context.getCacheDir().getAbsolutePath();
  43. setCachedDir(defaultDir);
  44. }
  45. /**
  46. * 是否缓存图片至/data/data/package/cache/目录
  47. * 默认不缓存
  48. */
  49. public void setCache2File(boolean flag){
  50. impl.setCache2File(flag);
  51. }
  52. /**
  53. * 设置缓存路径,setCache2File(true)时有效
  54. */
  55. public void setCachedDir(String dir){
  56. impl.setCachedDir(dir);
  57. }
  58. /**开启线程池*/
  59. public static void startThreadPoolIfNecessary(){
  60. if(sExecutorService == null || sExecutorService.isShutdown() || sExecutorService.isTerminated()){
  61. sExecutorService = Executors.newFixedThreadPool(3);
  62. //sExecutorService = Executors.newSingleThreadExecutor();
  63. }
  64. }
  65. /**
  66. * 异步下载图片,并缓存到memory中
  67. * @param url
  68. * @param callback  see ImageCallback interface
  69. */
  70. public void downloadImage(final String url, final ImageCallback callback){
  71. downloadImage(url, true, callback);
  72. }
  73. /**
  74. *
  75. * @param url
  76. * @param cache2Memory 是否缓存至memory中
  77. * @param callback
  78. */
  79. public void downloadImage(final String url, final boolean cache2Memory, final ImageCallback callback){
  80. if(sDownloadingSet.contains(url)){
  81. Log.i("AsyncImageLoader", "###该图片正在下载,不能重复下载!");
  82. return;
  83. }
  84. Bitmap bitmap = impl.getBitmapFromMemory(url);
  85. if(bitmap != null){
  86. if(callback != null){
  87. callback.onImageLoaded(bitmap, url);
  88. }
  89. }else{
  90. //从网络端下载图片
  91. sDownloadingSet.add(url);
  92. sExecutorService.submit(new Runnable(){
  93. @Override
  94. public void run() {
  95. final Bitmap bitmap = impl.getBitmapFromUrl(url, cache2Memory);
  96. handler.post(new Runnable(){
  97. @Override
  98. public void run(){
  99. if(callback != null)
  100. callback.onImageLoaded(bitmap, url);
  101. sDownloadingSet.remove(url);
  102. }
  103. });
  104. }
  105. });
  106. }
  107. }
  108. /**
  109. * 预加载下一张图片,缓存至memory中
  110. * @param url
  111. */
  112. public void preLoadNextImage(final String url){
  113. //将callback置为空,只将bitmap缓存到memory即可。
  114. downloadImage(url, null);
  115. }
  116. }

2.LoaderImpl.java

  1. package com.imagecache;
  2. import java.io.FileInputStream;
  3. import java.io.FileNotFoundException;
  4. import java.io.FileOutputStream;
  5. import java.io.IOException;
  6. import java.io.InputStream;
  7. import java.io.UnsupportedEncodingException;
  8. import java.lang.ref.SoftReference;
  9. import java.net.HttpURLConnection;
  10. import java.net.URL;
  11. import java.security.MessageDigest;
  12. import java.security.NoSuchAlgorithmException;
  13. import java.util.Map;
  14. import android.graphics.Bitmap;
  15. import android.graphics.BitmapFactory;
  16. /**
  17. *
  18. * @author Administrator
  19. * @desc 异步加载图片管理器
  20. *
  21. */
  22. public class LoaderImpl {
  23. //内存中的软应用缓存
  24. private Map<String, SoftReference<Bitmap>> imageCache;
  25. //是否缓存图片至本地文件
  26. private boolean cache2FileFlag = false;
  27. //缓存目录,默认是/data/data/package/cache/目录
  28. private String cachedDir;
  29. public LoaderImpl(Map<String, SoftReference<Bitmap>> imageCache){
  30. this.imageCache = imageCache;
  31. }
  32. /**
  33. * 是否缓存图片至外部文件
  34. * @param flag
  35. */
  36. public void setCache2File(boolean flag){
  37. cache2FileFlag = flag;
  38. }
  39. /**
  40. * 设置缓存图片到外部文件的路径
  41. * @param cacheDir
  42. */
  43. public void setCachedDir(String cacheDir){
  44. this.cachedDir = cacheDir;
  45. }
  46. /**
  47. * 从网络端下载图片
  48. * @param url 网络图片的URL地址
  49. * @param cache2Memory 是否缓存(缓存在内存中)
  50. * @return bitmap 图片bitmap结构
  51. *
  52. */
  53. public Bitmap getBitmapFromUrl(String url, boolean cache2Memory){
  54. Bitmap bitmap = null;
  55. try{
  56. URL u = new URL(url);
  57. HttpURLConnection conn = (HttpURLConnection)u.openConnection();
  58. InputStream is = conn.getInputStream();
  59. bitmap = BitmapFactory.decodeStream(is);
  60. if(cache2Memory){
  61. //1.缓存bitmap至内存软引用中
  62. imageCache.put(url, new SoftReference<Bitmap>(bitmap));
  63. if(cache2FileFlag){
  64. //2.缓存bitmap至/data/data/packageName/cache/文件夹中
  65. String fileName = getMD5Str(url);
  66. String filePath = this.cachedDir + "/" +fileName;
  67. FileOutputStream fos = new FileOutputStream(filePath);
  68. bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
  69. }
  70. }
  71. is.close();
  72. conn.disconnect();
  73. return bitmap;
  74. }catch(IOException e){
  75. e.printStackTrace();
  76. return null;
  77. }
  78. }
  79. /**
  80. * 从内存缓存中获取bitmap
  81. * @param url
  82. * @return bitmap or null.
  83. */
  84. public Bitmap getBitmapFromMemory(String url){
  85. Bitmap bitmap = null;
  86. if(imageCache.containsKey(url)){
  87. synchronized(imageCache){
  88. SoftReference<Bitmap> bitmapRef = imageCache.get(url);
  89. if(bitmapRef != null){
  90. bitmap = bitmapRef.get();
  91. return bitmap;
  92. }
  93. }
  94. }
  95. //从外部缓存文件读取
  96. if(cache2FileFlag){
  97. bitmap = getBitmapFromFile(url);
  98. if(bitmap != null)
  99. imageCache.put(url, new SoftReference<Bitmap>(bitmap));
  100. }
  101. return bitmap;
  102. }
  103. /**
  104. * 从外部文件缓存中获取bitmap
  105. * @param url
  106. * @return
  107. */
  108. private Bitmap getBitmapFromFile(String url){
  109. Bitmap bitmap = null;
  110. String fileName = getMD5Str(url);
  111. if(fileName == null)
  112. return null;
  113. String filePath = cachedDir + "/" + fileName;
  114. try {
  115. FileInputStream fis = new FileInputStream(filePath);
  116. bitmap = BitmapFactory.decodeStream(fis);
  117. } catch (FileNotFoundException e) {
  118. e.printStackTrace();
  119. bitmap = null;
  120. }
  121. return bitmap;
  122. }
  123. /**
  124. * MD5 加密
  125. */
  126. private static String getMD5Str(String str) {
  127. MessageDigest messageDigest = null;
  128. try {
  129. messageDigest = MessageDigest.getInstance("MD5");
  130. messageDigest.reset();
  131. messageDigest.update(str.getBytes("UTF-8"));
  132. } catch (NoSuchAlgorithmException e) {
  133. System.out.println("NoSuchAlgorithmException caught!");
  134. return null;
  135. } catch (UnsupportedEncodingException e) {
  136. e.printStackTrace();
  137. return null;
  138. }
  139. byte[] byteArray = messageDigest.digest();
  140. StringBuffer md5StrBuff = new StringBuffer();
  141. for (int i = 0; i < byteArray.length; i++) {
  142. if (Integer.toHexString(0xFF & byteArray[i]).length() == 1)
  143. md5StrBuff.append("0").append(Integer.toHexString(0xFF & byteArray[i]));
  144. else
  145. md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i]));
  146. }
  147. return md5StrBuff.toString();
  148. }
  149. /**
  150. * MD5 加密
  151. private static String getMD5Str(Object...objects){
  152. StringBuilder stringBuilder=new StringBuilder();
  153. for (Object object : objects) {
  154. stringBuilder.append(object.toString());
  155. }
  156. return getMD5Str(stringBuilder.toString());
  157. }*/
  158. }

3.测试Activity

    1. package com.imagecache;
    2. import android.app.Activity;
    3. import android.graphics.Bitmap;
    4. import android.os.Bundle;
    5. import android.widget.ImageView;
    6. public class MainActivity extends Activity {
    7. /** Called when the activity is first created. */
    8. @Override
    9. public void onCreate(Bundle savedInstanceState) {
    10. super.onCreate(savedInstanceState);
    11. setContentView(R.layout.main);
    12. final ImageView iv = (ImageView)findViewById(R.id.iv);
    13. //网络图片地址
    14. String imgUrl = "http://...";
    15. //for test
    16. AsyncImageLoader loader = new AsyncImageLoader(getApplicationContext());
    17. //将图片缓存至外部文件中
    18. loader.setCache2File(true); //false
    19. //设置外部缓存文件夹
    20. loader.setCachedDir(this.getCacheDir().getAbsolutePath());
    21. //下载图片,第二个参数是否缓存至内存中
    22. loader.downloadImage(imgUrl, true/*false*/, new AsyncImageLoader.ImageCallback() {
    23. @Override
    24. public void onImageLoaded(Bitmap bitmap, String imageUrl) {
    25. if(bitmap != null){
    26. iv.setImageBitmap(bitmap);
    27. }else{
    28. //下载失败,设置默认图片
    29. }
    30. }
    31. });
    32. }
    33. }

转自:http://blog.csdn.net/liliang497/article/details/7221110

最新文章

  1. iOS超全开源框架、项目和学习资料汇总(5)AppleWatch、经典博客、三方开源总结篇
  2. 【poj3522】 Slim Span
  3. IOS6学习笔记(一)
  4. 服务器重写技术:rewrite
  5. Android基础笔记(十四)- 内容提供者读取联系人
  6. JavaScript 鸭子模型
  7. 在win下,如何用bat看程序运行的时间
  8. NOIP2011-普及组复赛模拟试题-第一题-NBA总冠军
  9. 安装python2.7.13-64bit &amp; Pycharm在两个python版本之间切换
  10. Spring声明式事务总结
  11. Android Studio 不得不知的20大快捷键
  12. python 项目实例
  13. css3工具
  14. SAP 查询分析器,查询报表自动生成,SQL查询测试实现说明(转)
  15. SourceTree提交不了,报git -c diff.mnemonicprefix=false -c core.quotepath=false push -v --tags origin master:master
  16. windows环境python2.7安装MySQLdb
  17. angularjs1.x的directive中的link参数element见解
  18. Mysql 函数使用记录(一)——DATEDIFF、CONCAT
  19. spring框架之AspectJ的XML方式完成AOP的开发
  20. Oracle11g常用数据字典

热门文章

  1. nginx image_filter 配置记录
  2. pycharm如何设置python版本、设置国内pip镜像、添加第三方类库
  3. AngularJS中介者模式实例
  4. Android ecludeFromRecents
  5. How to chain a command after sudo su?
  6. Spring中通过Annotation来实现AOP
  7. 【Java】MyBatis与Spring框架整合(一)
  8. 高性能Javascript(1)
  9. linux删除软连接
  10. 云服务器 - 安装zookeeper单机环境