Android之Fresco框架(二)--ImagePipeline基本内容和配置

先附上官网的介绍:

Image pipeline 负责完成加载图像,变成Android设备可呈现的形式所要做的每个事情。

大致流程如下:

  1. 检查内存缓存,如有,返回
  2. 后台线程开始后续工作
  3. 检查是否在未解码内存缓存中。如有,解码,变换,返回,然后缓存到内存缓存中。
  4. 检查是否在磁盘缓存中,如果有,变换,返回。缓存到未解码缓存和内存缓存中。
  5. 从网络或者本地加载。加载完成后,解码,变换,返回。存到各个缓存中。


从上面的讲述可以看出,ImagePipiline中主要有三个缓存,一个是DiskCache,一个是未解码Bitmap缓存,还有一个是已解码的Bitmap缓存。下面通过源码观察下这些缓存及缓存算法如何实现,以及如果对图片进行缓存和读取。

ImagePipelineFactory

这里采用了工厂模式来进行实现,通过在ImagePipelineFactory对各种信息进行配置和初始化。在Fresco.initialize()方法中就对ImagePipelineFactroy进行了初始化:

if (imagePipelineConfig == null) {
      ImagePipelineFactory.initialize(context);
    } else {
      ImagePipelineFactory.initialize(imagePipelineConfig);
    }

这里可以看到,我们在初始化的时候是可以传入一个imagePipelineConfig的,这也是方便我们对ImagePipelineFactory进行自定义。我们先看一下imagePipelineConfig中定义了那些配置信息:

//对Bitmap的信息进行配置,主要是决定每个pixel用多个byte存储以及颜色的存储
private final Bitmap.Config mBitmapConfig;
//已解码的Bitmap缓存策略信息
private final Supplier<MemoryCacheParams> mBitmapMemoryCacheParamsSupplier;
//存储缓存修剪策略的信息,在不同Android系统中,缓存需要进行相应的修剪,用于未解码的Bitmap缓存中
private final CountingMemoryCache.CacheTrimStrategy mBitmapMemoryCacheTrimStrategy;
//缓存文件生成的CacheKey策略
private final CacheKeyFactory mCacheKeyFactory; 
private final Context mContext;
private final boolean mDownsampleEnabled;
//DiskCache工厂,用于获得DiskCache实例
private final FileCacheFactory mFileCacheFactory;
//未解码的Bitmap缓存策略信息
private final Supplier<MemoryCacheParams> mEncodedMemoryCacheParamsSupplier;
//获取线程池,为CPU绑定操作提供一个线程池,为IO绑定操作提供另一个线程池。
private final ExecutorSupplier mExecutorSupplier;
//图片缓存操作的跟踪接口,会组合到MemoryCache中,可以方便我们监听图片缓存操作,默认无任何操作
private final ImageCacheStatsTracker mImageCacheStatsTracker;
//图片解码,对图片进行解码生成一个实现了Closeable的image实例,方便用于释放资源
@Nullable private final ImageDecoder mImageDecoder;
//默认返回true
private final Supplier<Boolean> mIsPrefetchEnabledSupplier;
//DiskCache配置信息
private final DiskCacheConfig mMainDiskCacheConfig;
//观察者模式,保存其他注册的类,用于通知系统内存事件,不自行定义的话默认没有任何操作
private final MemoryTrimmableRegistry mMemoryTrimmableRegistry;
//定义pipeline使用的network fetcher,默认使用HttpURLConnection类
private final NetworkFetcher mNetworkFetcher;
//用于平台优化的Bitmap工厂
@Nullable private final PlatformBitmapFactory mPlatformBitmapFactory;
//创建各种pool的工厂  
private final PoolFactory mPoolFactory;
//渐进式JPEG配置
private final ProgressiveJpegConfig mProgressiveJpegConfig;
//ImageRequest的监听器
private final Set<RequestListener> mRequestListeners;
//是否允许缩放和旋转
private final boolean mResizeAndRotateEnabledForNetwork;
//对小图缓存的配置,默认和DiskCache配置信息相同
private final DiskCacheConfig mSmallImageDiskCacheConfig;
//ImageDecoder的信息配置 
@Nullable private final ImageDecoderConfig mImageDecoderConfig;
//对处于experimental state的ImagePipelineConfig的其他元素进行封装,不建议从默认值进行修改
private final ImagePipelineExperiments mImagePipelineExperimens;

可以看到里面配置了三级缓存,图片网络请求,图片解码相关的信息,我们可以对这些信息进行自定义。这个我们后面再说。先来看一下这些信息是怎么应用到ImagePipelineFactory中。首先先来看一下ImagePipelineFactory中又包含了哪些信息:

//single instance模式
private static ImagePipelineFactory sInstance = null;
//一旦从已解码的Bitmap缓存中读取失败,将图片的其他请求操作交付到新的线程(防止UI线程阻塞)
private final ThreadHandoffProducerQueue mThreadHandoffProducerQueue;
private final ImagePipelineConfig mConfig;
//利用LRU算法对缓存元素的管理,查找,写入,根据trim()方法实现不同策略的回收
private CountingMemoryCache<CacheKey, CloseableImage> mBitmapCountingMemoryCache;
//组合了CountingMemetyCache和ImageCacheStatsTracker(监听接口)
private MemoryCache<CacheKey, CloseableImage> mBitmapMemoryCache;
private CountingMemoryCache<CacheKey, PooledByteBuffer> mEncodedCountingMemoryCache;
private MemoryCache<CacheKey, PooledByteBuffer> mEncodedMemoryCache;
//在BufferedDiskCache中存储了一个StagingArea用于存储写入缓存的值,以便可以高速并行的get返回
private BufferedDiskCache mMainBufferedDiskCache;
//DiskStrorageCache,采用synchroinzed方式实现文件的读写
private FileCache mMainFileCache;
//将EncodeImage转为CloseableImage
private ImageDecoder mImageDecoder;
//ImagePipeline实例
private ImagePipeline mImagePipeline;
//Producer工厂
private ProducerFactory mProducerFactory;
//PruducerSequence工厂
private ProducerSequenceFactory mProducerSequenceFactory;
//小图磁盘缓存的配置信息
private BufferedDiskCache mSmallImageBufferedDiskCache;
private FileCache mSmallImageFileCache;
/*
下面几个暂时不知道用途
*/
private MediaVariationsIndex mMediaVariationsIndex;
//为平台优化的位图工厂
private PlatformBitmapFactory mPlatformBitmapFactory;
private PlatformDecoder mPlatformDecoder;
//图像的动画效果
private AnimatedFactory mAnimatedFactory;

在这些配置信息中,除了最后几个之外,其他的可以大致分为这两种:用于设置三级缓存的相关信息,用于图像请求的管道化实现的Producer和ProducerSequence信息。其中第二部分等到下一篇文章再来讲。这里先看以下三级缓存的配置。

在ImagePipelineFactory中,以上变量的初始化都是采用的懒加载,所以ImagePipelineFactory不是线程安全的。这里为啥可以不用线程安全呢,这个我们待会再看。我们先看看一下三级缓存:

Decoded Bitmap Cache:

 public CountingMemoryCache<CacheKey, CloseableImage> getBitmapCountingMemoryCache() {
    if (mBitmapCountingMemoryCache == null) {
      mBitmapCountingMemoryCache =
          BitmapCountingMemoryCacheFactory.get(
              mConfig.getBitmapMemoryCacheParamsSupplier(),
              mConfig.getMemoryTrimmableRegistry(),
              getPlatformBitmapFactory(),
              mConfig.getExperiments().isExternalCreatedBitmapLogEnabled(),
              mConfig.getBitmapMemoryCacheTrimStrategy());
    }
    return mBitmapCountingMemoryCache;
  }

  public MemoryCache<CacheKey, CloseableImage> getBitmapMemoryCache() {
    if (mBitmapMemoryCache == null) {
      mBitmapMemoryCache =
          BitmapMemoryCacheFactory.get(
              getBitmapCountingMemoryCache(),
              mConfig.getImageCacheStatsTracker());
    }
    return mBitmapMemoryCache;
  }

Encoded Bitmap Cache:

  public CountingMemoryCache<CacheKey, PooledByteBuffer> getEncodedCountingMemoryCache() {
    if (mEncodedCountingMemoryCache == null) {
      mEncodedCountingMemoryCache =
          EncodedCountingMemoryCacheFactory.get(
              mConfig.getEncodedMemoryCacheParamsSupplier(),
              mConfig.getMemoryTrimmableRegistry(),
              getPlatformBitmapFactory());
    }
    return mEncodedCountingMemoryCache;
  }

  public MemoryCache<CacheKey, PooledByteBuffer> getEncodedMemoryCache() {
    if (mEncodedMemoryCache == null) {
      mEncodedMemoryCache =
          EncodedMemoryCacheFactory.get(
              getEncodedCountingMemoryCache(),
              mConfig.getImageCacheStatsTracker());
    }
    return mEncodedMemoryCache;
  }

基本上是一毛一样的代码,这里面主要涉及到CountingMemoryCache类和MemoryCache类,大致看一下这两个的源码

CountingMemoryCache

// How often the cache checks for a new cache configuration.
  @VisibleForTesting
  static final long PARAMS_INTERCHECK_INTERVAL_MS = TimeUnit.MINUTES.toMillis(5);

  // Contains the items that are not being used by any cl
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值