欢迎访问悦橙教程(wld5.com),关注java教程。悦橙教程  java问答|  每日更新
页面导航 : > > 文章正文

Android图片加载的缓存类,, import j

来源: javaer 分享于  点击 28136 次 点评:280

Android图片加载的缓存类,, import j


    import java.io.File;      import java.io.FileInputStream;      import java.io.FileNotFoundException;      import java.io.FileOutputStream;      import java.io.IOException;      import java.io.InputStream;      import java.lang.ref.SoftReference;      import java.net.HttpURLConnection;      import java.net.URL;      import java.util.LinkedHashMap;      import java.util.concurrent.ConcurrentHashMap;      import java.util.concurrent.ExecutorService;      import java.util.concurrent.Executors;      import android.graphics.Bitmap;      import android.graphics.BitmapFactory;      import android.os.Build;      import android.os.Handler;      import android.text.TextUtils;      /**      * 图片加载器,主要功能是从网络中下载图片并缓存。这里之所以另写一个功能类似重复的原因是 之前旧的图片加载逻辑感觉非常复杂,我这里写个轻量级的      *       * @author H3c      *       */      public class ImageLoaderEngine {          public static final int LOAD_IMG_SUCCESS = 2010;          private final int MAX_CAPACITY = Build.VERSION.SDK_INT > Build.VERSION_CODES.GINGERBREAD_MR1 ? 50 : 10;// 一级缓存缓存图片数          private static ImageLoaderEngine instance;          private static Handler mHandler;          private ExecutorService pool;// 后台线程池          // 这里用LinkedHashMap不用LruCache的原因是LruCache直接申请内存大小而不是图片个数。此App已经有一个全局的LruCache了,重复申请内存大小对应用不利          private LinkedHashMap<String, Bitmap> mFirstLevelCache;// <momentId>一级缓存,硬链接bitmap,只保留最近用的图片。          private ConcurrentHashMap<String, SoftReference<Bitmap>> mSecondLevelCache;// <momentId>          public static ImageLoaderEngine getInstance(Handler handler) {              if (instance == null) {                  instance = new ImageLoaderEngine();              }              if(handler != null) {                  mHandler = handler;              }              return instance;          }          private ImageLoaderEngine() {              pool = Executors.newFixedThreadPool(4);// 默认线程池大小为6              initCache();          }          private void initCache() {              mFirstLevelCache = new LinkedHashMap<String, Bitmap>(MAX_CAPACITY / 2,                      0.75f, true) {                  private static final long serialVersionUID = 1L;                  protected boolean removeEldestEntry(Entry<String, Bitmap> eldest) {                      if (size() > MAX_CAPACITY) {// 超过一级缓存大小后会挪到二级缓存中                          mSecondLevelCache.put(eldest.getKey(),                                  new SoftReference<Bitmap>(eldest.getValue()));                          return true;                      }                      return false;                  };              };              mSecondLevelCache = new ConcurrentHashMap<String, SoftReference<Bitmap>>();// <momentId>          }          /**          * 移除缓存          * @param key          */          public void deleteCacheByKey(String key) {              String sdCacheingPath = IOHelper.getCachedPicturePath(                      Global.packageName, key);              String sdCacheedPath = sdCacheingPath +".png";              File file = new File(sdCacheingPath);              if(file.exists()) {                  file.delete();              }              file = new File(sdCacheedPath);              if(file.exists()) {                  file.delete();              }              mFirstLevelCache.remove(key);              mSecondLevelCache.remove(key);          }          /**          * 释放资源          */          public void recycleImageLoader() {              new Thread(new Runnable() {                  @Override                  public void run() {                      if (pool != null) {                          pool.shutdownNow();                      }                      if (mFirstLevelCache != null) {                          for (Bitmap bmp : mFirstLevelCache.values()) {                              if (bmp != null) {                                  bmp.recycle();                                  bmp = null;                              }                          }                          mFirstLevelCache.clear();                          mFirstLevelCache = null;                      }                      if (mSecondLevelCache != null) {                          mSecondLevelCache.clear();                      }                      mHandler = null;                  }              }).start();          }          /**          * 后台请求图片          *           * @param item          */          public void loadImageByMoment(final NMoment moment,String photoTag) {              if (moment.isPicture()                      || moment.isVideo()) {                  String id = moment.id + photoTag;                  loadImageByUrl(id+"", moment.getPicture(Global.widthPixels/3*2),moment.orientation);              }          }          /**          * 后台请求图片          * @param key          * @param url          */          public void loadImageByUrl(final String key,final String url,final int orientation) {                  pool.submit(new Runnable() {                      public void run() {                          LogHelper.e("ImageLoaderEngine","从网络中下载");                          // 如果内存中有就算了                          if (mFirstLevelCache.get(key) != null                                  || mSecondLevelCache.get(key) != null) {// 如果图片已经缓存了                              LogHelper.e("ImageLoaderEngine","下载图片错误 1");                              return;                          }                          // 如果SD卡缓存中有就算了                          final String sdCacheingPath = IOHelper.getCachedPicturePath(                                  Global.packageName, key);                          File cacheingFile = new File(sdCacheingPath);                          if (cacheingFile.exists()) {// 如果正在缓存就算了                              long currentTime = System.currentTimeMillis();                              if((currentTime - cacheingFile.lastModified()) >2 * 60 * 1000) {                                  LogHelper.e("ImageLoaderEngine","2分钟都还没下载完,准备删除它.."+currentTime+"="+cacheingFile.lastModified());                                  cacheingFile.delete();                              } else {                                  getBitmapFromNetworkAndAddToMemory(url, key, orientation);                                  LogHelper.e("ImageLoaderEngine","第二次进来应该走这里..");                                  return;                              }                          }                          String sdCacheedPath = sdCacheingPath + ".png";// 缓存完成后会改名字,否则会导致缓存错误,图片变黑                          File cacheedFile = new File(sdCacheedPath);                          if (cacheedFile.exists()) {// 如果缓存了就算了                              LogHelper.e("ImageLoaderEngine","下载图片错误 2");                              return;                          }                          getBitmapFromNetworkAndAddToMemory(url, key, orientation);                      }                  });          }          private void getBitmapFromNetworkAndAddToMemory(String url,String key,int orientation) {              Bitmap bmp = getBitmapFromUrl(url);              if(bmp!= null) {                  LogHelper.e("ImageLoaderEngine","下载网络图片成功");                  if(key.endsWith("_DetailDaily")) {                      bmp = scaledBitmap(bmp, Global.getThumbWidth());                  }                  if(orientation != 0) {                      mFirstLevelCache.put(key, ViewHelper.rotateBitmap(orientation, bmp));// 从网络下载后直接显示                  } else {                      mFirstLevelCache.put(key, bmp);// 从网络下载后直接显示                  }                  if (mHandler != null) {                      mHandler.removeMessages(LOAD_IMG_SUCCESS);                      mHandler.sendEmptyMessageDelayed(                              LOAD_IMG_SUCCESS, 600);// 延时提示没有数据了                  }                  final String sdCacheingPath = IOHelper.getCachedPicturePath(                          Global.packageName, key);                  saveBitmapToFile(sdCacheingPath, bmp);              } else {                  LogHelper.e("ImageLoaderEngine","下载网络图片失败...");              }          }          /**          * 直接从网络中获取          * @param url          * @return          */          public Bitmap getBitmapFromUrl(String url) {              URL myFileUrl = null;              Bitmap bitmap = null;              InputStream is = null;              try {                  if (!UIUtils.isNetworkAvailable(MyApplication.getInstance())) {                      return null;                  }                  myFileUrl = new URL(url);                  HttpURLConnection conn = (HttpURLConnection) myFileUrl                          .openConnection();                  conn.setDoInput(true);                  conn.connect();                  is = conn.getInputStream();                  bitmap = BitmapFactory.decodeStream(is);              } catch (Exception e) {                  try {                      if(is != null) {                          is.close();                      }                  } catch (IOException e1) {                      e1.printStackTrace();                  }                  e.printStackTrace();              }              return bitmap;          }          public Bitmap getImageInMemory(NMoment moment) {              return getImageInMemory(moment, "");          }          /**          * 新增接口,可以根据tag重新标识Moment,这样可以扩展应用场景,比如首页需要大图,进入相集页需要小图          * @param moment          * @param photoTag          * @return          */          public Bitmap getImageInMemory(NMoment moment, String photoTag) {              String id = moment.id + photoTag;              Bitmap bmp = null;              // 1. 从一级缓存中获取              bmp = getFromFirstLevelCache(id);              if (bmp != null &amp;&amp; !bmp.isRecycled()) {                  LogHelper.e("ImageLoaderEngine","一级缓存获取:"+id);                  return bmp;              }              // 2. 从二级缓存中获取              bmp = getFromSecondLevelCache(id);              if (bmp != null &amp;&amp; !bmp.isRecycled()) {                  LogHelper.e("ImageLoaderEngine","二级缓存获取:"+id);                  return bmp;              }              if(bmp != null &amp;&amp; bmp.isRecycled()) {                  return null;              } else {                  return bmp;              }          }          public void setImage(String key,Bitmap picture) {              mFirstLevelCache.put(key, picture);          }          /**          * 获取图片          */          public Bitmap getImage(NMoment moment) {              return getImage(moment, "");          }          public Bitmap getImage(NMoment moment, String photoTag) {              String id = moment.id + photoTag;              Bitmap bmp = null;              // 1. 从一级缓存中获取              bmp = getFromFirstLevelCache(id);              if (bmp != null &amp;&amp; !bmp.isRecycled()) {                  LogHelper.e("ImageLoaderEngine","一级缓存获取:"+id);                  return bmp;              }              // 2. 从二级缓存中获取              bmp = getFromSecondLevelCache(id);              if (bmp != null &amp;&amp; !bmp.isRecycled()) {                  LogHelper.e("ImageLoaderEngine","二级缓存获取:"+id);                  return bmp;              }              // 3. 从SD卡缓存中获取              bmp = getFromSDCache(moment, photoTag);              if (bmp != null &amp;&amp; !bmp.isRecycled()) {                  LogHelper.e("ImageLoaderEngine","SD卡缓存获取:"+id);                  return bmp;              }              // 4. 从网络中获取              loadImageByMoment(moment, photoTag);       //        LogHelper.e("ImageLoaderEngine","本地获取图片失败:"+moment.id+"="+moment.getPicture());              if(bmp != null &amp;&amp; bmp.isRecycled()) {                  return null;              } else {                  return bmp;              }          }          public Bitmap getImage(String key,String url) {              Bitmap bmp = null;              // 1. 从一级缓存中获取              bmp = getFromFirstLevelCache(key);              if (bmp != null &amp;&amp; !bmp.isRecycled()) {                  return bmp;              }              // 2. 从二级缓存中获取              bmp = getFromSecondLevelCache(key);              if (bmp != null &amp;&amp; !bmp.isRecycled()) {                  return bmp;              }              // 3. 从SD卡缓存中获取              bmp = getFromSDCacheByKey(key,0);              if (bmp != null &amp;&amp; !bmp.isRecycled()) {                  return bmp;              }              // 4. 从网络中获取              loadImageByUrl(key, url,0);              if(bmp != null &amp;&amp; bmp.isRecycled()) {                  return null;              } else {                  return bmp;              }          }          /**          * 一级缓存获取图片          *           * @param imgId          * @return          */          private Bitmap getFromFirstLevelCache(String imgId) {              Bitmap bitmap = null;              synchronized (mFirstLevelCache) {                  bitmap = mFirstLevelCache.get(imgId);                  if (bitmap != null) {                      mFirstLevelCache.remove(imgId);                      mFirstLevelCache.put(imgId, bitmap);                  }              }              return bitmap;          }          /**          * 二级缓存获取图片          *           * @param url          * @return          */          private Bitmap getFromSecondLevelCache(String imgId) {              Bitmap bitmap = null;              SoftReference<Bitmap> softReference = mSecondLevelCache.get(imgId);              if (softReference != null) {                  bitmap = softReference.get();                  if (bitmap == null) {                      mSecondLevelCache.remove(imgId);                  }              }              return bitmap;          }          /**          * 从SD卡缓存获取图片,并放入一级缓存中          *           * @param moment          * @return          * @throws IOException          */          private Bitmap getFromSDCache(final NMoment moment,final String photoTag) {              Bitmap drawable = null;              String id = moment.id + photoTag;              String sdCacheingPath = IOHelper.getCachedPicturePath(Global.packageName,                      id);              String sdCacheedPath = sdCacheingPath + ".png";              if(moment.isLocal){                  if(moment.isVideo()) {                      //获取本地路径                      sdCacheedPath = moment.getPicture(Global.widthPixels/3*2);                  } else {                      sdCacheedPath = moment.local_res_path;                  }              }              File cacheFile = new File(sdCacheedPath);              if (!cacheFile.exists()) {// 如果没有缓存完成就退出                  LogHelper.e("ImageLoaderEngine","找不到缓存文件:"+sdCacheedPath);                  if(!TextUtils.isEmpty(moment.local_res_path)) {// 如果本地有图片,就先用本地图片代替                      sdCacheedPath = moment.local_res_path;                      cacheFile = new File(sdCacheedPath);                      if (cacheFile.exists() &amp;&amp; !GlobalData.PHONE_MANUFACTURER.equalsIgnoreCase("samsung")) {                          LogHelper.e("ImageLoaderEngine","AK47...:"+GlobalData.PHONE_MANUFACTURER);// 先从本地找替代图片..                          new Thread(new Runnable() {// 从网络下载                              @Override                              public void run() {                                  loadImageByMoment(moment, photoTag);                               }                          }).start();                          return getFitPhoto(sdCacheedPath, moment, cacheFile);                      } else {                          return null;                      }                  } else {                      return null;                  }              }              drawable = getFitPhoto(sdCacheedPath, moment, cacheFile);              if (drawable != null) {                  if (moment.orientation != 0) {                      drawable = ViewHelper                              .rotateBitmap(moment.orientation, drawable);                  }                  if(mFirstLevelCache != null) {                      mFirstLevelCache.put(id, drawable);                  }              } else {                  cacheFile.delete();              }              return drawable;          }          private Bitmap getFitPhoto(String sdCacheedPath,NMoment moment,File cacheFile) {              FileInputStream fs = null;              Bitmap result;              try {                  BitmapFactory.Options options = new BitmapFactory.Options();                  options.inJustDecodeBounds = true;                  BitmapFactory.decodeFile(sdCacheedPath, options);                  int hRatio = (int) Math.ceil(options.outHeight                          / (float) moment.picture_height); // 算高度                  int wRatio = (int) Math.ceil(options.outWidth                          / (float) Global.widthPixels); // 算宽度                  if (hRatio > 1 || wRatio > 1) {                      if (hRatio > wRatio) {                          options.inSampleSize = hRatio;                      } else                          options.inSampleSize = wRatio;                  }                  options.inPurgeable = true;                  options.inInputShareable = true;                  options.inDither = false;                  options.inJustDecodeBounds = false;                  try {                      fs = new FileInputStream(cacheFile);                  } catch (FileNotFoundException e) {                      e.printStackTrace();                  }                  result = BitmapFactory.decodeFileDescriptor(fs.getFD(), null,                          options);              } catch (Exception e) {                  throw new RuntimeException(e);              } finally {                  if (fs != null) {                      try {                          fs.close();                      } catch (IOException e) {                          e.printStackTrace();                      }                  }              }              return result;          }          private Bitmap getFromSDCacheByKey(String key,int orientation) {              Bitmap drawable = null;              FileInputStream fs = null;              String sdCacheedPath = IOHelper.getCachedPicturePath(                      Global.packageName, key) + ".png";              File cacheFile = new File(sdCacheedPath);              if (!cacheFile.exists()) {// 如果没有缓存完成就退出                  return null;              }              try {                  BitmapFactory.Options options = new BitmapFactory.Options();                  options.inJustDecodeBounds = true;                  BitmapFactory.decodeFile(sdCacheedPath, options);                  int wRatio = (int) Math.ceil(options.outWidth                          / (float) Global.widthPixels); // 算宽度                  options.inSampleSize = wRatio;                  options.inPurgeable = true;                  options.inInputShareable = true;                  options.inDither = false;                  options.inJustDecodeBounds = false;                  try {                      fs = new FileInputStream(cacheFile);                  } catch (FileNotFoundException e) {                      e.printStackTrace();                  }                  drawable = BitmapFactory.decodeFileDescriptor(fs.getFD(), null,                          options);                  if (drawable != null) {                      if(orientation != 0) {                          drawable = ViewHelper.rotateBitmap(orientation, drawable);                      }                      mFirstLevelCache.put(key, drawable);                  } else {                      cacheFile.delete();                  }              } catch (Exception e) {                  throw new RuntimeException(e);              } finally {                  if (fs != null) {                      try {                          fs.close();                      } catch (IOException e) {                          e.printStackTrace();                      }                  }              }              return drawable;          }          /**          * 创建一个灰色的默认图          * @param moment          * @return          */          public Bitmap getDefaultBitmap(NMoment moment) {              return ImageHelper.createBitmap(moment.picture_width, moment.picture_height,                      R.color.image_bg_daily);          }          /**          * 保存Bitmap文件到sd卡,传入jpg结尾的路径          * @param filePath          * @param mBitmap          */          public void saveBitmapToFile(String filePath, Bitmap mBitmap) {              try {                  File file = new File(filePath);                  if (!file.getParentFile().exists()) {                      file.getParentFile().mkdirs();                  }                  if (file.exists() &amp;&amp; file.length() > 0) {                      long currentTime = System.currentTimeMillis();                      if ((currentTime - file.lastModified()) > 2 * 60 * 1000) {                          LogHelper.e("ImageLoaderEngine",                                  "2分钟都还没下载完,准备删除它.." + currentTime + "="                                          + file.lastModified());                          file.delete();                      } else {                          return;                      }                  } else {                      file.createNewFile();                  }                  FileOutputStream fOut = null;                  fOut = new FileOutputStream(file);                  mBitmap.compress(Bitmap.CompressFormat.JPEG, 80, fOut);                  fOut.flush();                  fOut.close();                  file.renameTo(new File(filePath+".png"));              } catch (Exception e) {                  e.printStackTrace();                  LogHelper.e("ImageLoaderEngine","保存图片错误:"+e);              }              LogHelper.e("ImageLoaderEngine","保存网络图片成功"+filePath+".png");          }          /**          * 保存文件至缓存,这里重写而不用IOHelper里面的原因是IOHelper里面过于复杂          *           * @param url          * @param filePath          * @return          */          public boolean saveUrlBitmapToFile(String url, String filePath) {                  if (TextUtils.isEmpty(filePath)) {                      return false;                  }              File iconFile = new File(filePath);              if (iconFile.getParentFile() == null) {                      return false;              }              if (!iconFile.getParentFile().exists()) {                  iconFile.getParentFile().mkdirs();              }              if (iconFile.exists() &amp;&amp; iconFile.length() > 0) {                  long currentTime = System.currentTimeMillis();                  if((currentTime - iconFile.lastModified()) >2 * 60 * 1000) {                      LogHelper.e("ImageLoaderEngine","2分钟都还没下载完,准备删除它.."+currentTime+"="+iconFile.lastModified());                      iconFile.delete();                  } else {                      return true;                  }              }              FileOutputStream fos = null;              InputStream is = null;              try {                  fos = new FileOutputStream(filePath);                  is = new URL(url).openStream();                  int data = is.read();                  while (data != -1) {                      fos.write(data);                      data = is.read();                  }              } catch (IOException e) {                  LogHelper.e("ImageLoaderEngine", "ImageLoaderEngine 下载图片错误" + e);                  iconFile.delete();                  e.printStackTrace();                  return false;              } finally {                  try {                      if (is != null) {                          is.close();                      }                      if (fos != null) {                          fos.close();                      }                  } catch (IOException e) {                      e.printStackTrace();                  }              }              iconFile.renameTo(new File(filePath+".png"));              return true;          }          /**          * 缩放bitmap          * @param bmp          * @param scaledValue缩放值          * @return          */          public Bitmap scaledBitmap(Bitmap bmp,int scaledValue) {              int bmpWidth = bmp.getWidth();              int bmpHeight = bmp.getHeight();              if(bmpWidth >= bmpHeight) {// 横图                  bmpWidth = (bmpWidth *  scaledValue / bmpHeight);                  bmpHeight = scaledValue;              } else {                  bmpHeight = (bmpHeight *  scaledValue / bmpWidth);                  bmpWidth = scaledValue;              }              Bitmap scaledBmp = Bitmap.createScaledBitmap(bmp,bmpWidth,bmpHeight,true);              bmp.recycle();              bmp = null;              return scaledBmp;          }      }  

来自:http://blog.csdn.net/h3c4lenovo/article/details/27060505

相关栏目:

用户点评