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

2019-12-10 18:16:05王冬梅

     经过以上的步骤,我们已经成功地将图片写入了文件系统。 

(3)获取缓存对象
    我们使用DiskLruCache的get方法从中获取缓存对象,这个方法的大致源码如下:

public synchronized Snapshot get(String key) throws IOException {
    checkNotClosed();
    validateKey(key);
    Entry entry = lruEntries.get(key);
    if (entry == null) {
      return null;
    }
 
    if (!entry.readable) {
      return null;
    }
 
    /*
     * Open all streams eagerly to guarantee that we see a single published
     * snapshot. If we opened streams lazily then the streams could come
     * from different edits.
     */
    InputStream[] ins = new InputStream[valueCount];19     ... 
    return new Snapshot(key, entry.sequenceNumber, ins);
 }

    我们可以看到,这个方法最终返回了一个Snapshot对象,并以我们要获取的缓存对象的key作为构造参数之一。Snapshot是DiskLruCache的内部类,它包含一个getInputStream方法,通过这个方法可以获取相应缓存对象的输入流,得到了这个输入流,我们就可以进一步获取到Bitmap对象了。在获取缓存的Bitmap时,我们通常都要对它进行一些预处理,主要就是通过设置inSampleSize来适当的缩放图片,以防止出现OOM。我们之前已经介绍过如何高效加载Bitmap,在那篇文章里我们的图片来源于Resources。尽管现在我们的图片来源是流对象,但是计算inSampleSize的方法是一样的,只不过我们不再使用decodeResource方法而是使用decodeFileDescriptor方法。

相关的代码如下:

Bitmap bitmap = null;
String key = getKeyFromUrl(url);
DiskLruCache.Snapshot snapShot = mDiskLruCache.get(key);
if (snapShot != null) {
  FileInputStream fileInputStream = (FileInputStream) snapShot.getInputStream(0); //参数表示索引,同之前的newOutputStream一样
  FileDescriptor fileDescriptor = fileInputStream.getFD();
  bitmap = decodeSampledBitmapFromFD(fileDescriptor, dstWidth, dstHeight);
  if (bitmap != null) {
    addBitmapToMemoryCache(key, bitmap);
  }
}