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.       
    转自:http://blog.csdn.net/liliang497/article/details/7221110
  • 相关阅读:
    Linux 发展历史
    购物车0612版登陆与购物功能
    Linux 基本命令
    MySQL练习
    购物车登陆购物版
    MySQL阅读目录
    输入打印之佛祖辟邪
    mysql存储引擎
    函数对象、函数嵌套、名称空间与作用域、装饰器
    【计算机网络】哈尔滨工业大学MOOC-计算机网络 第2周 计算机网络概述(下) 作业2
  • 原文地址:https://www.cnblogs.com/pricks/p/3921611.html
Copyright © 2011-2022 走看看