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

异步加载类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. Redis集群简记

    Redis集群 http://doc.redisfans.com/topic/cluster-tutorial.html redis 集群是为了多个节点之间数据的共享和集群高可用的保证. redis ...

  2. 如何在Windows 10上访问NFS的share

    大致过程是: 1. 开启名为"Services for NFS"的Windows Feature. 2. 如果需要拥有写权限,需要修改注册表. 3. Mount即可. 具体步骤详见 ...

  3. MDX Step by Step 读书笔记(七) - Performing Aggregation 聚合函数之 Max, Min, Count , DistinctCount 以及其它 TopCount, Generate

    MDX 中最大值和最小值 MDX 中最大值和最小值函数的语法和之前看到的 Sum 以及 Aggregate 等聚合函数基本上是一样的: Max( {Set} [, Expression]) Min( ...

  4. python3用BeautifulSoup用字典的方法抓取a标签内的数据

    # -*- coding:utf-8 -*- #python 2.7 #XiaoDeng #http://tieba.baidu.com/p/2460150866 #标签操作 from bs4 imp ...

  5. .Net可扩展的单据编号生成器-SNF.CodeRule--SNF快速开发平台3.2

    1.背景 在企业应用中单据编号的自定义是一个很常见的需求,如工号.业务单据编码等,能不能抽象一个通用的框架呢? 2.思路 这里的难点在于实现"解释器",比如将"前缀&qu ...

  6. C++ 重载运算符和重载函数

    C++ 重载运算符和重载函数 C++ 允许在同一作用域中的某个函数和运算符指定多个定义,分别称为函数重载和运算符重载. 重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明,但是 ...

  7. unity, 在image effect shader中用_CameraDepthTexture重建世界坐标

    --------------更新 更简单的方法: //depth: raw depth, nonlinear, 0 at near plane, 1 at far plan   float4 scre ...

  8. SpringMVC(Springboot)返回文件方法

    https://blog.csdn.net/Lynn_coder/article/details/79953977 ****************************************** ...

  9. [转载][IoC容器Unity]第二回:Lifetime Managers生命周期

    1.引言 Unity的生命周期是注册的类型对象的生命周期,而Unity默认情况下会自动帮我们维护好这些对象的生命周期,我们也可以显示配置对象的生命周期,Unity将按照配置自动管理,非常方便,下面就介 ...

  10. InstallShield:卸载时文字叠加,文字乱码

    问题: InstallShield2010打包的程序.如果程序正在运行,卸载程序,提示关闭程序,然后消息界面出现文字叠加. 定位问题: 新建Installshield项目,依次修改SetupType, ...