android下载网络图片并缓存

来源:互联网 发布:软件使用说明 编辑:程序博客网 时间:2024/06/05 19:37

异步下载网络图片,并提供是否缓存至内存或外部文件的功能
异步加载类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

public class AsyncImageLoader {  //保存正在下载的图片URL集合,避免重复下载用  private static HashSet<String> sDownloadingSet;  //软引用内存缓存  private static Map<String,SoftReference<Bitmap>> sImageCache;   //图片三种获取方式管理者,网络URL获取、内存缓存获取、外部文件缓存获取  private static LoaderImpl impl;  //线程池相关  private static ExecutorService sExecutorService;  //通知UI线程图片获取ok时使用  private Handler handler;   /**  * 异步加载图片完毕的回调接口  */  public interface ImageCallback{      /**      * 回调函数      * @param bitmap: may be null!      * @param imageUrl       */      public void onImageLoaded(Bitmap bitmap, String imageUrl);  }  static{      sDownloadingSet = new HashSet<String>();      sImageCache = new HashMap<String,SoftReference<Bitmap>>();      impl = new LoaderImpl(sImageCache);  }  public AsyncImageLoader(Context context){      handler = new Handler();      startThreadPoolIfNecessary();      String defaultDir = context.getCacheDir().getAbsolutePath();      setCachedDir(defaultDir);  }  /**  * 是否缓存图片至/data/data/package/cache/目录  * 默认不缓存  */  public void setCache2File(boolean flag){      impl.setCache2File(flag);  }  /**  * 设置缓存路径,setCache2File(true)时有效  */  public void setCachedDir(String dir){      impl.setCachedDir(dir);  }  /**开启线程池*/  public static void startThreadPoolIfNecessary(){      if(sExecutorService == null || sExecutorService.isShutdown() || sExecutorService.isTerminated()){          sExecutorService = Executors.newFixedThreadPool(3);          //sExecutorService = Executors.newSingleThreadExecutor();      }  }  /**  * 异步下载图片,并缓存到memory中  * @param url     * @param callback  see ImageCallback interface  */  public void downloadImage(final String url, final ImageCallback callback){      downloadImage(url, true, callback);  }  /**  *   * @param url  * @param cache2Memory 是否缓存至memory中  * @param callback  */  public void downloadImage(final String url, final boolean cache2Memory, final ImageCallback callback){      if(sDownloadingSet.contains(url)){          Log.i("AsyncImageLoader", "###该图片正在下载,不能重复下载!");          return;      }      Bitmap bitmap = impl.getBitmapFromMemory(url);      if(bitmap != null){          if(callback != null){              callback.onImageLoaded(bitmap, url);          }      }else{          //从网络端下载图片          sDownloadingSet.add(url);          sExecutorService.submit(new Runnable(){              @Override              public void run() {                  final Bitmap bitmap = impl.getBitmapFromUrl(url, cache2Memory);                  handler.post(new Runnable(){                      @Override                      public void run(){                          if(callback != null)                              callback.onImageLoaded(bitmap, url);                          sDownloadingSet.remove(url);                      }                  });              }          });      }  }  /**  * 预加载下一张图片,缓存至memory中  * @param url   */  public void preLoadNextImage(final String url){      //将callback置为空,只将bitmap缓存到memory即可。      downloadImage(url, null);  }  }  

2.LoaderImpl.java

    /**              *               * @author Administrator              * @desc 异步加载图片管理器              *              */  public class LoaderImpl {  //内存中的软应用缓存  private Map<String, SoftReference<Bitmap>> imageCache;  //是否缓存图片至本地文件  private boolean cache2FileFlag = false;  //缓存目录,默认是/data/data/package/cache/目录  private String cachedDir;  public LoaderImpl(Map<String, SoftReference<Bitmap>> imageCache){      this.imageCache = imageCache;  }  /**  * 是否缓存图片至外部文件  * @param flag   */  public void setCache2File(boolean flag){      cache2FileFlag = flag;  }  /**  * 设置缓存图片到外部文件的路径  * @param cacheDir  */  public void setCachedDir(String cacheDir){      this.cachedDir = cacheDir;  }  /**  * 从网络端下载图片  * @param url 网络图片的URL地址  * @param cache2Memory 是否缓存(缓存在内存中)  * @return bitmap 图片bitmap结构  *   */  public Bitmap getBitmapFromUrl(String url, boolean cache2Memory){      Bitmap bitmap = null;      try{          URL u = new URL(url);          HttpURLConnection conn = (HttpURLConnection)u.openConnection();            InputStream is = conn.getInputStream();          bitmap = BitmapFactory.decodeStream(is);          if(cache2Memory){              //1.缓存bitmap至内存软引用中              imageCache.put(url, new SoftReference<Bitmap>(bitmap));              if(cache2FileFlag){                  //2.缓存bitmap至/data/data/packageName/cache/文件夹中                  String fileName = getMD5Str(url);                  String filePath = this.cachedDir + "/" +fileName;                  FileOutputStream fos = new FileOutputStream(filePath);                  bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);              }          }          is.close();          conn.disconnect();          return bitmap;      }catch(IOException e){          e.printStackTrace();          return null;      }  }  /**  * 从内存缓存中获取bitmap  * @param url  * @return bitmap or null.  */  public Bitmap getBitmapFromMemory(String url){      Bitmap bitmap = null;      if(imageCache.containsKey(url)){          synchronized(imageCache){              SoftReference<Bitmap> bitmapRef = imageCache.get(url);              if(bitmapRef != null){                  bitmap = bitmapRef.get();                  return bitmap;              }          }      }      //从外部缓存文件读取      if(cache2FileFlag){          bitmap = getBitmapFromFile(url);          if(bitmap != null)              imageCache.put(url, new SoftReference<Bitmap>(bitmap));      }      return bitmap;  }  /**  * 从外部文件缓存中获取bitmap  * @param url  * @return  */  private Bitmap getBitmapFromFile(String url){      Bitmap bitmap = null;      String fileName = getMD5Str(url);      if(fileName == null)          return null;      String filePath = cachedDir + "/" + fileName;      try {          FileInputStream fis = new FileInputStream(filePath);          bitmap = BitmapFactory.decodeStream(fis);      } catch (FileNotFoundException e) {          e.printStackTrace();          bitmap = null;      }      return bitmap;  }  /**    * MD5 加密    */     private static String getMD5Str(String str) {         MessageDigest messageDigest = null;         try {             messageDigest = MessageDigest.getInstance("MD5");             messageDigest.reset();             messageDigest.update(str.getBytes("UTF-8"));         } catch (NoSuchAlgorithmException e) {             System.out.println("NoSuchAlgorithmException caught!");             return null;      } catch (UnsupportedEncodingException e) {             e.printStackTrace();          return null;      }         byte[] byteArray = messageDigest.digest();         StringBuffer md5StrBuff = new StringBuffer();         for (int i = 0; i < byteArray.length; i++) {                         if (Integer.toHexString(0xFF & byteArray[i]).length() == 1)                 md5StrBuff.append("0").append(Integer.toHexString(0xFF & byteArray[i]));             else                 md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i]));         }         return md5StrBuff.toString();     }    /**    * MD5 加密   private static String getMD5Str(Object...objects){     StringBuilder stringBuilder=new StringBuilder();     for (Object object : objects) {         stringBuilder.append(object.toString());     }     return getMD5Str(stringBuilder.toString()); }*/   }  

3.测试Activity

public class MainActivity extends Activity {  /** Called when the activity is first created. */  @Override  public void onCreate(Bundle savedInstanceState) {      super.onCreate(savedInstanceState);      setContentView(R.layout.main);      final ImageView iv = (ImageView)findViewById(R.id.iv);      //网络图片地址      String imgUrl = "http://...";      //for test      AsyncImageLoader loader = new AsyncImageLoader(getApplicationContext());      //将图片缓存至外部文件中      loader.setCache2File(true); //false      //设置外部缓存文件夹      loader.setCachedDir(this.getCacheDir().getAbsolutePath());      //下载图片,第二个参数是否缓存至内存中      loader.downloadImage(imgUrl, true/*false*/, new AsyncImageLoader.ImageCallback() {          @Override          public void onImageLoaded(Bitmap bitmap, String imageUrl) {              if(bitmap != null){                  iv.setImageBitmap(bitmap);              }else{                  //下载失败,设置默认图片              }          }      });  }  }  
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 出隧道口限速40超速了怎么办 社保交了五年后断交以后该怎么办 躺椅折叠椅坐的地方坏了怎么办 苹果手机锁频密码忘了怎么办 客户要货公司不给进怎么办 高铁23:00买的票怎么办 带电子手刹的车刹车失灵怎么办 下坡刹车失灵遇行人不看车怎么办 跟大车后面看不见红灯闯了怎么办 跟着大货车后面闯了红灯怎么办 如果用工单位不发放加班工资怎么办 事故家属要司机向医院多交钱怎么办 在大学里和室友关系弄僵怎么办 房产证办出来房产局不给证怎么办 单位全员竞聘老员工没岗位怎么办 快件被快递公司签收了没给送怎么办 总公司跑路了分公司代理法人怎么办 大使馆领的结婚证现在离婚怎么办 日本签证照片被使馆贴错了怎么办 在菲律宾护照和签证丢了怎么办 新疆工地上班老板不肯发工资怎么办 德国大使馆签证如果拒签了怎么办 护照在大使馆办签证期间出国怎么办 法院两次判决不准离婚我该怎么办? 法院判决不准离婚妻子不回来怎么办 被告人在不调解的情况下怎么办 知道弟兄的孩子是别人的怎么办? 办居住证的回执单丢了怎么办 领取居住证的回执单丢了怎么办 北京居住证网上申报信息填错怎么办 买家退回来的货有问题怎么办 居转户过程中生的小孩户口怎么办 人才引进申请上海户口被拒怎么办 网络购高铁票身份证没有验证怎么办 高速遇到很浓的团雾怎么办 对于大巴不按座位坐的人该怎么办 火车上遇到占座不让的人怎么办 滁州婴儿打疫苗的绿本子怎么办 检查四维说宝宝嘴巴显示不清怎么办 携程订票付款成功一直没出票怎么办 手机微信支付密码忘了怎么办