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

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

2.LoaderImpl.java

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

3.测试Activity

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

转载于:https://www.cnblogs.com/sunfb/p/3844364.html

android 下载网络图片并缓存相关推荐

  1. Android下载网络图片到本地

    Android下载网络图片到本地sdcard中 1.方法调用: imageDownload(https://www.baidu.com/img/bdlogo.png); 2.图片下载: private ...

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

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

  3. 安卓 Android 下载网络图片保存到本地

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

  4. Android 下载网络图片保存到相册

    下载类,可以url下载到相册,记得在清单加权限,6.0代码动态加权限判断,下载图片要在子线程中下载,下载完后广播更新相册 在清单文件里面添加权限: <!--网络--><uses-pe ...

  5. Android下载网络图片并保存到相册

    下载类,可以url下载到相册,记得在清单加权限,6.0代码动态加权限判断,下载图片要在子线程中下载,下载完后广播更新相册 在清单文件里面添加权限: <!--网络--><uses-pe ...

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

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

  7. android 设置系统壁纸,Android HttpURLConnection下载网络图片设置系统壁纸

    需求: 壁纸是url链接,get就能请求到,所以就用get请求到图片,把图片转化为bitmap,然后设置壁纸. 代码: 这里我封装了工具类 package xxxxx.utils; import an ...

  8. Android HttpURLConnection下载网络图片,设置系统壁纸

    需求: 壁纸是url链接,get就能请求到,所以就用get请求到图片,把图片转化为bitmap,然后设置壁纸. 代码: 这里我封装了工具类 package xxxxx.utils;import and ...

  9. Android异步下载网络图片(其三:ExecutorService)

    在第一节中,我们使用Handler.Thread/Runnable .URL.HttpURLConnection等等来进行异步下载网络图片.然后第二节中换了AsyncTask方式.那么这一节我们再应用 ...

  10. Android异步下载网络图片(其二:AsyncTask)

    在上一节中,我们使用Handler.Thread/Runnable .URL.HttpURLConnection等等来进行异步下载网络图片. 但是采用这种方式有一些缺点,如下: 线程的开销较大,如果每 ...

最新文章

  1. jfinal js 拦截_jfinal全局数据拦截器
  2. Linux学习:目录操作函数
  3. 【QuotationTool】主要数据结构
  4. 搞定系统设计 00:开篇
  5. Oracle 之 管理
  6. 高阶函数 实现sum(2)(3) 柯里化
  7. Hbase二级索引+CDH+Lily
  8. 思科(Cisco)IOS 12.3特性分析[ZT]
  9. python文件打开的合法方式-用python与文件进行交互的方法
  10. LeetCode刷题——343. 整数拆分
  11. Verilog:三段式状态机(数字钟)
  12. 2345浏览器兼容模式怎么设置
  13. 高仿QQ游戏大厅-支持换肤和控件切换动画
  14. eggs和egg是什么意思_egg是什么
  15. Blast中文手册(1)
  16. 汉字转拼音,用户表增加拼音字段,并将汉字姓名对应的拼音赋值给拼音字段
  17. [补充内容]关于使用matlab进行方程组求解的线性代数相关知识补充——n维向量
  18. form表单数据回填
  19. 如何驯服野生论文 | EndNote
  20. 给你的钥匙贴个标签,就不用担心找不到了

热门文章

  1. webvector将html转为svg或者png图片的工具
  2. opencv调用摄像头
  3. 在MFC中通过opencv显示摄像头视频或者文件视频
  4. 搞科研身体才是革命的本钱。
  5. 基于VS2015的C#的GDAl环境配置
  6. 决策树系列(三)——ID3
  7. 鸿蒙比苹果流畅,华为鸿蒙应用恢复率优于苹果iOS,无惧老化36个月持续流畅
  8. java合同到期提醒_合同到期提醒,你会操作吗?
  9. Flink Forward Asia 2020 -- Keynote 总结
  10. python数据库操作——连接Oracle