zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    OpenStack网卡桥接问题
    Linux DD添加swap分区
    OpenStack KVM嵌套虚拟化的配置
    OpenStack KVM嵌套虚拟化的配置
    received packet with own address as source address
    mysql ERROR 1040 (08004): Too many connections
    openstack以其他tenant用户创建实例
    OpenStack Controller HA (3)
    OpenStack Controller HA (2)
    OpenStack controller HA
  • 原文地址:https://www.cnblogs.com/sunfb/p/3844364.html
Copyright © 2011-2022 走看看