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
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 下载网络图片并缓存相关推荐
- Android下载网络图片到本地
Android下载网络图片到本地sdcard中 1.方法调用: imageDownload(https://www.baidu.com/img/bdlogo.png); 2.图片下载: private ...
- Android 下载网络图片保存到本地
通过网络地址获取网络图片,点击下载将图片显示出来,然后点击图片将图片保存到本地. 首先需要在manifest上添加一些权限: <!-- 访问网络的权限 --> <uses-permi ...
- 安卓 Android 下载网络图片保存到本地
通过网络地址获取网络图片,点击下载将图片显示出来,然后点击图片将图片保存到本地. 首先需要在manifest上添加一些权限: <!-- 访问网络的权限 --> <uses-permi ...
- Android 下载网络图片保存到相册
下载类,可以url下载到相册,记得在清单加权限,6.0代码动态加权限判断,下载图片要在子线程中下载,下载完后广播更新相册 在清单文件里面添加权限: <!--网络--><uses-pe ...
- Android下载网络图片并保存到相册
下载类,可以url下载到相册,记得在清单加权限,6.0代码动态加权限判断,下载图片要在子线程中下载,下载完后广播更新相册 在清单文件里面添加权限: <!--网络--><uses-pe ...
- Android开发-下载网络图片并显示到本地
Android下载网络图片的流程是: 发送网络请求->将图片以流的形式下载下来->将流转换为Bitmap并赋给ImageView控件. 注意点 最新的Android系统不可以在主线程上请求 ...
- android 设置系统壁纸,Android HttpURLConnection下载网络图片设置系统壁纸
需求: 壁纸是url链接,get就能请求到,所以就用get请求到图片,把图片转化为bitmap,然后设置壁纸. 代码: 这里我封装了工具类 package xxxxx.utils; import an ...
- Android HttpURLConnection下载网络图片,设置系统壁纸
需求: 壁纸是url链接,get就能请求到,所以就用get请求到图片,把图片转化为bitmap,然后设置壁纸. 代码: 这里我封装了工具类 package xxxxx.utils;import and ...
- Android异步下载网络图片(其三:ExecutorService)
在第一节中,我们使用Handler.Thread/Runnable .URL.HttpURLConnection等等来进行异步下载网络图片.然后第二节中换了AsyncTask方式.那么这一节我们再应用 ...
- Android异步下载网络图片(其二:AsyncTask)
在上一节中,我们使用Handler.Thread/Runnable .URL.HttpURLConnection等等来进行异步下载网络图片. 但是采用这种方式有一些缺点,如下: 线程的开销较大,如果每 ...
最新文章
- jfinal js 拦截_jfinal全局数据拦截器
- Linux学习:目录操作函数
- 【QuotationTool】主要数据结构
- 搞定系统设计 00:开篇
- Oracle 之 管理
- 高阶函数 实现sum(2)(3) 柯里化
- Hbase二级索引+CDH+Lily
- 思科(Cisco)IOS 12.3特性分析[ZT]
- python文件打开的合法方式-用python与文件进行交互的方法
- LeetCode刷题——343. 整数拆分
- Verilog:三段式状态机(数字钟)
- 2345浏览器兼容模式怎么设置
- 高仿QQ游戏大厅-支持换肤和控件切换动画
- eggs和egg是什么意思_egg是什么
- Blast中文手册(1)
- 汉字转拼音,用户表增加拼音字段,并将汉字姓名对应的拼音赋值给拼音字段
- [补充内容]关于使用matlab进行方程组求解的线性代数相关知识补充——n维向量
- form表单数据回填
- 如何驯服野生论文 | EndNote
- 给你的钥匙贴个标签,就不用担心找不到了