Android图片加载的缓存类

本文为大家分享了Android图片加载的缓存类,供大家参考,具体内容如下

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 && !bmp.isRecycled()) {
      LogHelper.e("ImageLoaderEngine","一级缓存获取:"+id);
      return bmp;
    }
    // 2. 从二级缓存中获取
    bmp = getFromSecondLevelCache(id);
    if (bmp != null && !bmp.isRecycled()) {
      LogHelper.e("ImageLoaderEngine","二级缓存获取:"+id);
      return bmp;
    } 

    if(bmp != null && 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 && !bmp.isRecycled()) {
      LogHelper.e("ImageLoaderEngine","一级缓存获取:"+id);
      return bmp;
    }
    // 2. 从二级缓存中获取
    bmp = getFromSecondLevelCache(id);
    if (bmp != null && !bmp.isRecycled()) {
      LogHelper.e("ImageLoaderEngine","二级缓存获取:"+id);
      return bmp;
    }
    // 3. 从SD卡缓存中获取
    bmp = getFromSDCache(moment, photoTag);
    if (bmp != null && !bmp.isRecycled()) {
      LogHelper.e("ImageLoaderEngine","SD卡缓存获取:"+id);
      return bmp;
    }
    // 4. 从网络中获取
    loadImageByMoment(moment, photoTag);
//    LogHelper.e("ImageLoaderEngine","本地获取图片失败:"+moment.id+"="+moment.getPicture()); 

    if(bmp != null && bmp.isRecycled()) {
      return null;
    } else {
      return bmp;
    }
  } 

  public Bitmap getImage(String key,String url) {
    Bitmap bmp = null;
    // 1. 从一级缓存中获取
    bmp = getFromFirstLevelCache(key);
    if (bmp != null && !bmp.isRecycled()) {
      return bmp;
    }
    // 2. 从二级缓存中获取
    bmp = getFromSecondLevelCache(key);
    if (bmp != null && !bmp.isRecycled()) {
      return bmp;
    }
    // 3. 从SD卡缓存中获取
    bmp = getFromSDCacheByKey(key,0);
    if (bmp != null && !bmp.isRecycled()) {
      return bmp;
    }
    // 4. 从网络中获取
    loadImageByUrl(key, url,0); 

    if(bmp != null && 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() && !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() && 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() && 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;
  }
}

以上就是一个完整的Android图片加载缓存类,希望对大家的学习有所帮助。

(0)

相关推荐

  • Android中使用Bitmap类将矩形图片转为圆形的方法

    一般要做正圆形图片,只能是正方形的基础上才能实现,否则就变成椭圆了,下面说说如何使长方形的图片生成正圆形图片 废话不多说,没图没真相,先上图吧: 原图: 变成正圆后: 下面上代码: public static Bitmap makeRoundCorner(Bitmap bitmap) { int width = bitmap.getWidth(); int height = bitmap.getHeight(); int left = 0, top = 0, right = width, bot

  • Android实现从缓存中读取图片与异步加载功能类

    本文实例讲述了Android实现从缓存中读取图片与异步加载功能类.分享给大家供大家参考,具体如下: 在新浪微博的微博列表中的图片,为了加速其显示也为了加快程序的响应,可以参考该图片异步加载类实现. public class AsyncImageLoader { //SoftReference是软引用,是为了更好的为了系统回收变量 private HashMap<String, SoftReference<Drawable>> imageCache; public AsyncImag

  • Android TextView显示Html类解析的网页和图片及自定义标签用法示例

    本文实例讲述了Android TextView显示Html类解析的网页和图片及自定义标签.分享给大家供大家参考,具体如下: Android系统显示HTML网页的最佳控件为WebView,有时候为了满足特定需求,需要在TextView中显示HTML网页.图片及解析自定义标签. 1.TextView显示Html类解析的网页 CharSequence richText = Html.fromHtml("<strong>萝卜白菜的博客</strong>--<a href='

  • Android中使用BitmapShader类来制作各种图片的圆角

    public   BitmapShader(Bitmap bitmap,Shader.TileMode tileX,Shader.TileMode tileY) 调用这个类来产生一个画有一个位图的渲染器(Shader). bitmap:在渲染器内使用的位图 (1)tileX:The tiling mode for x to draw the bitmap in.   在位图上X方向花砖模式 (2)tileY:The tiling mode for y to draw the bitmap in.

  • android图片类型之间相互转换实现代码

    本文实例讲述了android图片类型之间相互转换实现代码.分享给大家供大家参考.具体如下: android在处理一写图片资源的时候,会进行一些类型的转换,现在有空整理一下: 1.Drawable → Bitmap Java代码如下: public static Bitmap drawableToBitmap(Drawable drawable) { Bitmap bitmap = Bitmap .createBitmap( drawable.getIntrinsicWidth(), drawab

  • android中写一个内部类来选择文件夹中指定的图片类型实例说明

    复制代码 代码如下: /**本类是用来选择文件夹中是.jpg类型的图片*/ private class JpgFileFilter implements FilenameFilter{ @Override public boolean accept(File dir, String filename) { // TODO Auto-generated method stub return filename.endsWith(".jpg"); } }

  • 非常实用的Android图片工具类

    本文实例为大家分享了Android图片工具类的具体代码,供大家参考,具体内容如下 import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import android.content.Context; import android.grap

  • Android图片加载的缓存类

    本文为大家分享了Android图片加载的缓存类,供大家参考,具体内容如下 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.SoftReferenc

  • 一起动手编写Android图片加载框架

    开发一个简洁而实用的Android图片加载缓存框架,并在内存占用与加载图片所需时间这两个方面与主流图片加载框架之一Universal Image Loader做出比较,来帮助我们量化这个框架的性能.通过开发这个框架,我们可以进一步深入了解Android中的Bitmap操作.LruCache.LruDiskCache,让我们以后与Bitmap打交道能够更加得心应手.若对Bitmap的大小计算及inSampleSize计算还不太熟悉,请参考这里:高效加载Bitmap.由于个人水平有限,叙述中必然存在

  • Android图片加载框架Coil的详细使用总结

    目录 简介 简单使用 高斯模糊 圆角 圆形 灰色变换 GrayscaleTransformation Gif 监听下载过程 取消下载 替换 okhttp 实例 自定义 Coil 源码分析 总结 简介 Coil 是一个 Android 图片加载库,通过 Kotlin 协程的方式加载图片.特点如下: 更快: Coil 在性能上有很多优化,包括内存缓存和磁盘缓存,把缩略图存保存在内存中,循环利用 bitmap,自动暂停和取消图片网络请求等. 更轻量级: Coil 只有2000个方法(前提是你的 APP

  • Flutter图片加载与缓存机制的深入探究

    目录 前言 图片控件 图片解析 缓存管理 ​新增缓存 缓存清理 图片加载 滑动中处理 总结 前言 今天来学习一下 Flutter 自身是如何加载图片和管理图片的. Flutter 提供了一个图片控件 Image,Image 定义了若干中加载图片的方式,包括 Image.asset.Image.file.Image.network.Image.memory. Image内部维护了一个 ImageProvider对象,ImageProvider则真正维护整个图片加载的工作.Widget 本身内部是体

  • Android图片加载库Glide用法

    目录 Glide介绍 Android SDK 要求 使用前的准备 基本用法 在 ListView 和 RecyclerView 中的使用 占位符 选项 过渡动画 变换效果 使用示例 Glide介绍 Glide是一个快速高效的Android图片加载库,注重于平滑的滚动.Glide提供了易用的API,高性能.可扩展的图片解码管道,以及自动的资源池技术.Glide 的主要目标是让任何形式的图片列表的滚动尽可能地变得更快.更平滑. Android SDK 要求 Min Sdk Version - 使用

  • Android开发中ImageLoder进行图片加载和缓存

    图片处理类: package com.longfei.admin.imageloder_text; import android.app.Application; import android.graphics.Bitmap; import android.os.Environment; import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiscCache; import com.nostra13.universa

  • Android图片加载缓存框架Glide

    Glide开源框架是Google推荐的图片加载和缓框架,其在Github上的开源地址是:https://github.com/bumptech/glide 当然一个Google推荐的框架肯定就是Volley啦. 目前Android主流开发工具是AndroidStudio,在AndroidStudio如何使用Glide,https://github.com/bumptech/glide上有详细的介绍说明. 因为刚换新工作不久,公司和的还是Eclipse,所以学习Glide我暂时还用的Eclipse

  • 设计简单的Android图片加载框架

    目前Android 发展至今优秀的图片加载框架太多,例如: Volley ,Picasso,Imageloader,Glide等等.但是作为程序猿,懂得其中的实现原理还是相当重要的,只有懂得才能更好地使用.于是乎,今天我就简单设计一个网络加载图片框架.主要就是熟悉图片的网络加载机制. 一般来说,一个优秀的 图片加载框架(ImageLoader) 应该具备如下功能: 图片压缩 内存缓存 磁盘缓存 图片的同步加载 图片的异步加载 网络拉取 那我们就从以上几个方面进行介绍: 1.图片压缩(有效的降低O

  • Android图片加载利器之Picasso基本用法

    今天开始我们来学习一下Picasso,计划包括以下几方面的内容: 图片加载利器之Picasso进阶 图片加载利器之Picasso源码解析 目前市场上比较流行的图片加载框架主要有UniversalImageLoader,Picasso,Glide,Fresco. 下面简单介绍一下这几个框架: UniversalImageLoader:这个可以说是非常非常经典的一个了,相信每个app的开发人员都使用过,只可惜作者已经停止该项目的维护了,所以不太推荐使用. Picasso:是Square公司出品的图片

  • Android图片加载利器之Picasso源码解析

    看到了这里,相信大家对Picasso的使用已经比较熟悉了,本篇博客中将从基本的用法着手,逐步的深入了解其设计原理. Picasso的代码量在众多的开源框架中算得上非常少的一个了,一共只有35个class文件,但是麻雀虽小,五脏俱全.好了下面跟随我的脚步,出发了. 基本用法 Picasso.with(this).load(imageUrl).into(imageView); with(this)方法 public static Picasso with(Context context) { if

随机推荐