Fresco 源码分析(三) Fresco服务端处理(2) Producer具体实现的内容

我们以mProducerFactory.newNetworkFetchProducer()为例,因为这些创建新的producer的方式类似,区别在于是否有包装的处理器,即如果当前处理器中没有正在处理的数据或者等待处理的数据,便交给包装的处理器来处理

在查看NetworkFetchProducer的源码之前,先来看看producer的接口

Producer的源码

这个接口的功能其实看看类和方法的注释就知道了,就是用于产生结果的,这个使用与网络数据的获取,磁盘缓存,内存缓存,解码,编码和图片的变性处理等等
这种设计模式的特点的好处在于,将图片整体处理的逻辑打散为不同的区块处理,这样实现了模块化

/**
 * Building block for image processing in the image pipeline.
 *
 * <p> Execution of image request consists of multiple different tasks such as network fetch,
 * disk caching, memory caching, decoding, applying transformations etc. Producer<T> represents
 * single task whose result is an instance of T. Breaking entire request into sequence of
 * Producers allows us to construct different requests while reusing the same blocks.
 *
 * <p> Producer supports multiple values and streaming.
 *
 * @param <T>
 */
public interface Producer<T> {

  /**
   * Start producing results for given context. Provided consumer is notified whenever progress is
   * made (new value is ready or error occurs).
   * @param consumer
   * @param context
   */
  void produceResults(Consumer<T> consumer, ProducerContext context);
}

在继续分析Producer的处理逻辑之前,我们先把遗留的Q5问题解决: 即ProducerSequenceFactory.newBitmapCacheGetToDecodeSequence()的源码分析续
再来回顾一下:

ProducerSequenceFactory.newBitmapCacheGetToDecodeSequence()的源码
上篇已经提到了根据网络的请求的producer,然后生成了解码的producer,在根据这个解码的producer,生成newBitmapCacheGetToBitmapCacheSequence

  /**
     * Same as {@code newBitmapCacheGetToBitmapCacheSequence} but with an extra DecodeProducer.
     * @param nextProducer next producer in the sequence after decode
     * @return bitmap cache get to decode sequence
     */
    private Producer<CloseableReference<CloseableImage>> newBitmapCacheGetToDecodeSequence(
            Producer<EncodedImage> nextProducer) {
        DecodeProducer decodeProducer = mProducerFactory.newDecodeProducer(nextProducer);
        return newBitmapCacheGetToBitmapCacheSequence(decodeProducer);
    }

那么下面需要关注的就是newBitmapCacheGetToBitmapCacheSequence()的过程

** ProducerSequenceFactory.newBitmapCacheGetToBitmapCacheSequence()的源码 **

这段逻辑其实就是ImagePipeline最先处理逻辑的倒叙,就是从bitmapCacheCacheGetProducer到HandlerOff的处理,BitmapCache的生成的倒叙
将包装处理类一步步传递给上层处理器

  /**
   * Bitmap cache get -> thread hand off -> multiplex -> bitmap cache
   * @param nextProducer next producer in the sequence after bitmap cache
   * @return bitmap cache get to bitmap cache sequence
   */
  private Producer<CloseableReference<CloseableImage>> newBitmapCacheGetToBitmapCacheSequence(
      Producer<CloseableReference<CloseableImage>> nextProducer) {
    BitmapMemoryCacheProducer bitmapMemoryCacheProducer =
        mProducerFactory.newBitmapMemoryCacheProducer(nextProducer);
    BitmapMemoryCacheKeyMultiplexProducer bitmapKeyMultiplexProducer =
        mProducerFactory.newBitmapMemoryCacheKeyMultiplexProducer(bitmapMemoryCacheProducer);
    ThreadHandoffProducer<CloseableReference<CloseableImage>> threadHandoffProducer =
        mProducerFactory.newBackgroundThreadHandoffProducer(bitmapKeyMultiplexProducer);
    return mProducerFactory.newBitmapMemoryCacheGetProducer(threadHandoffProducer);
  }

由于初始化过程的类似,我们直接跳到这个方法最后的new过程,newBitmapMemoryCacheGetProducer()方法
直接看这个过程,发现

  public BitmapMemoryCacheGetProducer newBitmapMemoryCacheGetProducer(
      Producer<CloseableReference<CloseableImage>> nextProducer) {
    return new BitmapMemoryCacheGetProducer(mBitmapMemoryCache, mCacheKeyFactory, nextProducer);
  }


  public BitmapMemoryCacheGetProducer(
      MemoryCache<CacheKey, CloseableImage> memoryCache,
      CacheKeyFactory cacheKeyFactory,
      Producer<CloseableReference<CloseableImage>> nextProducer) {
    super(memoryCache, cacheKeyFactory, nextProducer);
  }

暂且先看到这里,做个标记,由于中间处理的逻辑大体相似,所以我们分析producer的一头一尾即可,知道中间的处理流程,一个是处理的头部BitmapMemoryCacheGetProducer, 另外一个是尾部NetworkFetchProducer,但是如果在深入分析,我们就会陷入细节,先将ImagePipeline的整体分析完后,我们再分析这里,标记为Q6:分析BitmapMemoryCacheGetProducer和NetworkFetchProducer

4.3.1.2 ImagePipeline.fetchDecodedImage() 源码分支2的处理

由于中间已经分析了producer的很多知识,所以我们先回顾一下ImagePipeline的fetchDecodedImage()的过程

ImagePipeline.fetchDecodedImage() 源码
1.获取到producer
2.根据生成的producer提交请求

 /**
   * Submits a request for execution and returns a DataSource representing the pending decoded
   * image(s).
   *
   * <p>The returned DataSource must be closed once the client has finished with it.
   * @param imageRequest the request to submit
   * @return a DataSource representing the pending decoded image(s)
   */
  public DataSource<CloseableReference<CloseableImage>> fetchDecodedImage(
      ImageRequest imageRequest,
      Object callerContext) {
    try {
      Producer<CloseableReference<CloseableImage>> producerSequence =
          mProducerSequenceFactory.getDecodedImageProducerSequence(imageRequest);
      return submitFetchRequest(
          producerSequence,
          imageRequest,
          ImageRequest.RequestLevel.FULL_FETCH,
          callerContext);
    } catch (Exception exception) {
      return DataSources.immediateFailedDataSource(exception);
    }
  }

分支1已经在4.3.1.1中分析,接下来分析producer的提交请求

ImagePipeline.submitFetchRequest()源码

  1. 计算出当前图片请求的最低的请求级别

  2. 创建一个SettableProducerContext

  3. 根据创建的settableProducerContext,再将利用Producer和DataSource中间的适配器,创建了一个DataSource(需要理解的核心部分)

     private <T> DataSource<CloseableReference<T>> submitFetchRequest(
           Producer<CloseableReference<T>> producerSequence,
           ImageRequest imageRequest,
           ImageRequest.RequestLevel lowestPermittedRequestLevelOnSubmit,
           Object callerContext) {
         try {
           ImageRequest.RequestLevel lowestPermittedRequestLevel =
               ImageRequest.RequestLevel.getMax(
                   imageRequest.getLowestPermittedRequestLevel(),
                   lowestPermittedRequestLevelOnSubmit);
           SettableProducerContext settableProducerContext = new SettableProducerContext(
               imageRequest,
               generateUniqueFutureId(),
               mRequestListener,
               callerContext,
               lowestPermittedRequestLevel,
             /* isPrefetch */ false,
               imageRequest.getProgressiveRenderingEnabled() ||
                   !UriUtil.isNetworkUri(imageRequest.getSourceUri()),
               imageRequest.getPriority());
           return CloseableProducerToDataSourceAdapter.create(
               producerSequence,
               settableProducerContext,
               mRequestListener);
         } catch (Exception exception) {
           return DataSources.immediateFailedDataSource(exception);
         }
       }
    

上面的逻辑看起来很简单,包涵的知识挺多的,咱们一个一个说

  1. 计算出当前图片请求的最低的请求级别

根据前一个方法的调用的参数,得知是与最低级别的ImageRequest.RequestLevel.BITMAP_MEMORY_CACHE,所以在提交请求时最低级别就是我们在请求中设置的级别
2. 创建一个SettableProducerContext

ProducerContext也是请求信息的一个上下文,这里包含了所有在producer处理过程中需要得知的信息,例如图片的请求信息,请求的优先级,请求的id,是否要预处理等等.

  1. 根据创建的settableProducerContext,再将利用Producer和DataSource中间的适配器,创建了一个DataSource(需要理解的核心部分),并且做了返回

过程1和过程2比较简单,这个可以自己看看哈,大概作用就是上面描述的,我们来看看过程3

CloseableProducerToDataSourceAdapter.create(
	          producerSequence,
	          settableProducerContext,
	          mRequestListener);

创建了一个可关闭的生产者到数据源的适配器,就是讲生产者和数据源进行了关联,这个类似于连接器的一个作用,其实发送请求的核心逻辑位于这个地方,因为Producer只是负责生产数据,需要有对应的Consumer来消费数据,数据源是DataSource,那么消费的数据如何得到这个通知呢?这个其实就是客户端的DataSubscriber(剧透一下),其实数据适配器就是做了这样的一个逻辑.算是剧透了,下面我们开始一步一步分析这个过程

安卓源码分析群: Android源码分析QQ1群号:164812238

安卓源码分析群: Android源码分析QQ1群号:164812238

posted @ 2015-09-06 08:42  Panda Pan  阅读(650)  评论(0编辑  收藏  举报