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

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

android下载网络图片并缓存的更多相关文章

  1. android 下载网络图片并缓存

    异步下载网络图片,并提供是否缓存至内存或外部文件的功能 异步加载类AsyncImageLoader public void downloadImage(final String url, final ...

  2. Android 下载网络图片保存到本地

    通过网络地址获取网络图片,点击下载将图片显示出来,然后点击图片将图片保存到本地. 首先需要在manifest上添加一些权限: <!-- 访问网络的权限 --> <uses-permi ...

  3. android下载网络图片,设置宽高,等比缩放

    使用Picasso组件去下载图片会发现图片宽高会变形不受等比缩放控制,即使设置了图片的 scaleType,可能是对Picasso的api没有用对, Picasso.with(this.activit ...

  4. Android开发-下载网络图片并显示到本地

    Android下载网络图片的流程是: 发送网络请求->将图片以流的形式下载下来->将流转换为Bitmap并赋给ImageView控件. 注意点 最新的Android系统不可以在主线程上请求 ...

  5. wemall app商城源码Android之ListView异步加载网络图片(优化缓存机制)

    wemall-mobile是基于WeMall的android app商城,只需要在原商城目录下上传接口文件即可完成服务端的配置,客户端可定制修改.本文分享wemall app商城源码Android之L ...

  6. Android异步下载图片并且缓存图片到本地

    Android异步下载图片并且缓存图片到本地 在Android开发中我们经常有这样的需求,从服务器上下载xml或者JSON类型的数据,其中包括一些图片资源,本demo模拟了这个需求,从网络上加载XML ...

  7. (14)[Xamarin.Android] 异步的网络图片下载

    原文 [Xamarin.Android] 异步的网络图片下载 在设计要从网络上接大量数据并且显示在Android Listview中,而这些资料是利用Json格式传送并且数据中包含这图片档案. 那在X ...

  8. (BUG已修改,最优化)安卓ListView异步加载网络图片与缓存软引用图片,线程池,只加载当前屏之说明

    原文:http://blog.csdn.net/java_jh/article/details/20068915 迟点出更新的.这个还有BUG.因为软引应不给力了.2.3之后 前几天的原文有一个线程管 ...

  9. Android之网络图片加载的5种基本方式

    学了这么久,最近有空把自己用到过的网络加载图片的方式总结了出来,与大家共享,希望对你们有帮助. 此博客包含Android 5种基本的加载网络图片方式,包括普通加载HttpURLConnection.H ...

随机推荐

  1. 云栖大会上宣布即将开源的手淘Atlas什么来头?

    在刚刚过去的云栖大会上,手淘宣布其移动容器化框架Atlas将于2017年年初开源,对这个框架,在过去团队对外部做过一些分享,外界也一直对其十分关注,到现在它终于即将开源了. 本文将介绍Atlas的设计 ...

  2. C# Dictionary<TKey,TValue>如何添加键重复的内容

    这里以Dictionary<string,string>为例 当我们实例化Dictionary<string,string>集合时,其中有一个重载构造方法如下: // // 摘 ...

  3. 偷懒啦!button多了,这样写既简洁又高效

    在日常的项目中,我最喜欢用button了,但是button多了,写起来又枯燥又费时,今天学到一方法,绝对简单高效! 看看以前: 看吧,这还只是声明,接下来还有: 等等……,是不是很麻烦?现在找到新方法 ...

  4. 临时和永久关闭Selinux

    临时关闭: [root@localhost ~]# getenforceEnforcing [root@localhost ~]# setenforce 0[root@localhost ~]# ge ...

  5. 微软BI 之SSIS 系列 - 变量查询语句引起列输出顺序不一致的解决方法

    开篇介绍 这个问题来自于 天善BI社区,看了一下比较有意思,因为我自己认为在 SSIS中处理各种类型文件的经验还比较丰富(有一年的时间几乎所有ETL都跟文件相关),但是这个问题确实之前没有特别考虑过. ...

  6. [javase学习笔记]-6.2 类与对象的关系

    这一节我们来看一下类与对象之间的关系. 我们学习java语言,目的就是用java语言对现实生活中的事物进行描写叙述.那么我们如何来描写叙述呢.这就引出了类,我们在实际实现时,是通过类的形式来体现的. ...

  7. java 除法运算只保留整数位的3种方式

      1.情景展示 根据提供的毫秒数进行除法运算,如果将毫秒数转换成小时,小时数不为0,则只取整数位,依此类推... 2.情况分析 可以使用3个函数实现 Math.floor(num)  只保留整数位 ...

  8. 使用Ubuntu

    一.ubuntu把文件夹名称改为中文 vim ~/.config/user-dirs.dirs 修改文件内容为: XDG_DESKTOP_DIR="$HOME/Desktop" X ...

  9. mark 阿里支付

    开源软件企业版特惠高校版博客 我的码云 ·· 8月18日(周六)成都源创会火热报名中,四位一线行业大牛与你面对面,探讨区块链技术热潮下的冷思考. 开源项目 > WEB应用开发 > Web开 ...

  10. SNF快速开发平台MVC-表格单元格合并组件

    1.   表格单元格合并组件 1.1.      效果展示 1.1.1.    页面展现表格合并单元格 图 4.1 1.1.2.    导出excel合并单元格 图 4.2 1.2.      调用说 ...