zoukankan      html  css  js  c++  java
  • Fresco 源码分析(三) Fresco服务端处理(3) DataSource到Producer的适配器逻辑以及BitmapMemoryCacheProducer处理的逻辑

    4.3.1.2.1 Producer和DataSource之间适配器处理的逻辑

    还是从程序的入口开始说吧

    CloseableProducerToDataSourceAdapter.create() 源码

    此处看到无非是创建了一个新的数据适配器而已CloseableProducerToDataSourceAdapter

      public static <T> DataSource<CloseableReference<T>> create(
          Producer<CloseableReference<T>> producer,
          SettableProducerContext settableProducerContext,
          RequestListener listener) {
        return new CloseableProducerToDataSourceAdapter<T>(
            producer, settableProducerContext, listener);
      }
    

    继续跟踪

    CloseableProducerToDataSourceAdapter构造的过程

    看到这里,发现并没有做什么特殊的操作,只是调用了父类构造而已

      private CloseableProducerToDataSourceAdapter(
          Producer<CloseableReference<T>> producer,
          SettableProducerContext settableProducerContext,
          RequestListener listener) {
        super(producer, settableProducerContext, listener);
      }
    

    AbstractProducerToDataSourceAdapter构造的过程
    寻找了这么久,终于找到了核心的逻辑,在这里,

    1. 初始化Adapter的参数
    2. 通知外界的mRequestListener已经开始了请求
    3. 生产者producer开始了生产数据(核心逻辑)
      protected AbstractProducerToDataSourceAdapter(
      Producer producer,
      SettableProducerContext settableProducerContext,
      RequestListener requestListener) {
      mSettableProducerContext = settableProducerContext;
      mRequestListener = requestListener;
      mRequestListener.onRequestStart(
      settableProducerContext.getImageRequest(),
      mSettableProducerContext.getCallerContext(),
      mSettableProducerContext.getId(),
      mSettableProducerContext.isPrefetch());
      producer.produceResults(createConsumer(), settableProducerContext);
      }

       其他无关部分,我们先不关心了,直接看看,核心逻辑的操作

    1. 创建了一个消费者
    2. 传递给生产者来生产结果

    打开我们的producer.producerResults,发现这只是个接口,这个其实就是面向接口的编程嘛,无论我们的请求需要做什么操作,这里只是通知生产者要开始生产工作了而已.

       前面我们已经提到了网络数据的producer是如何一步一步包装,然后创建的,我们还是以第一次网络请求的数据做参照,但是涉及到的producer也是比较多的,我们就挑选最先处理的producer和最后处理的producer和中间有代表性的一两个producer来做说明

       再来回顾一下,producer的相关过程,网络获取数据的producer会一步步包装,最后包装给BitmapMemoryCacheGetProducer,就是内存获取的producer,因而最终的producer就是BitmapMemoryCacheGetProducer,即这个调用的producer就是我们的BitmapMemoryCacheGetProducer
    那么现在就可以从BitmapMemoryCacheGetProducer的produceResult来入手了

    BitmapMemoryCacheGetProducer的继承体系

    Producer
    
        --| BitmapMemoryCacheProducer
    
            --| BitmapMemoryCacheGetProducer
    

    BitmapMemoryCacheGetProducer只是一个负责从内存中获取对应的数据的producer,查看其源码,发现没有复写produceResult方法,那就查看基类的produceResult

    BitmapMemoryCacheProducer.produceResults() 源码

    从类的名字,便可以知道,这个只是用于内存存取的producer,因而在producerResult的时候,会先从自己的内存中获取一下,查看是否存在于内存中,如果存在,直接获取到通知consumer即可,如果内存中不存在,才会去通知下一个处理器来处理这些事情,下个处理器在处理完成这些数据后,还是会通知消费者即回调的方式,来完成后续的操作,这就是生成处理完成的数据,处理完的结果如何应该保存到内存中呢?肯定是要生成一个key,然后将这个key保存到内存中.

     @Override
      public void produceResults(
          final Consumer<CloseableReference<CloseableImage>> consumer,
          final ProducerContext producerContext) {
    
        final ProducerListener listener = producerContext.getListener();
        final String requestId = producerContext.getId();
        listener.onProducerStart(requestId, getProducerName());
        final ImageRequest imageRequest = producerContext.getImageRequest();
        final CacheKey cacheKey = mCacheKeyFactory.getBitmapCacheKey(imageRequest);
    
        CloseableReference<CloseableImage> cachedReference = mMemoryCache.get(cacheKey);
    
        if (cachedReference != null) {
          boolean isFinal = cachedReference.get().getQualityInfo().isOfFullQuality();
          if (isFinal) {
            listener.onProducerFinishWithSuccess(
                requestId,
                getProducerName(),
                listener.requiresExtraMap(requestId) ? ImmutableMap.of(VALUE_FOUND, "true") : null);
            consumer.onProgressUpdate(1f);
          }
          consumer.onNewResult(cachedReference, isFinal);
          cachedReference.close();
          if (isFinal) {
            return;
          }
        }
    
        if (producerContext.getLowestPermittedRequestLevel().getValue() >=
            ImageRequest.RequestLevel.BITMAP_MEMORY_CACHE.getValue()) {
          listener.onProducerFinishWithSuccess(
              requestId,
              getProducerName(),
              listener.requiresExtraMap(requestId) ? ImmutableMap.of(VALUE_FOUND, "false") : null);
          consumer.onNewResult(null, true);
          return;
        }
    
        Consumer<CloseableReference<CloseableImage>> wrappedConsumer = wrapConsumer(consumer, cacheKey);
        listener.onProducerFinishWithSuccess(
            requestId,
            getProducerName(),
            listener.requiresExtraMap(requestId) ? ImmutableMap.of(VALUE_FOUND, "false") : null);
        mNextProducer.produceResults(wrappedConsumer, producerContext);
      }
    

    消费者是如何处理这个回调呢
    BitmapMemoryCacheProducer.wrapConsumer() 源码

     protected Consumer<CloseableReference<CloseableImage>> wrapConsumer(
          final Consumer<CloseableReference<CloseableImage>> consumer,
          final CacheKey cacheKey) {
        return new DelegatingConsumer<
            CloseableReference<CloseableImage>,
            CloseableReference<CloseableImage>>(consumer) {
          @Override
          public void onNewResultImpl(CloseableReference<CloseableImage> newResult, boolean isLast) {
            // ignore invalid intermediate results and forward the null result if last
            if (newResult == null) {
              if (isLast) {
                getConsumer().onNewResult(null, true);
              }
              return;
            }
            // stateful results cannot be cached and are just forwarded
            if (newResult.get().isStateful()) {
              getConsumer().onNewResult(newResult, isLast);
              return;
            }
            // if the intermediate result is not of a better quality than the cached result,
            // forward the already cached result and don't cache the new result.
            if (!isLast) {
              CloseableReference<CloseableImage> currentCachedResult = mMemoryCache.get(cacheKey);
              if (currentCachedResult != null) {
                try {
                  QualityInfo newInfo = newResult.get().getQualityInfo();
                  QualityInfo cachedInfo = currentCachedResult.get().getQualityInfo();
                  if (cachedInfo.isOfFullQuality() || cachedInfo.getQuality() >= newInfo.getQuality()) {
                    getConsumer().onNewResult(currentCachedResult, false);
                    return;
                  }
                } finally {
                  CloseableReference.closeSafely(currentCachedResult);
                }
              }
            }
            // cache and forward the new result
            CloseableReference<CloseableImage> newCachedResult =
                mMemoryCache.cache(cacheKey, newResult);
            try {
              if (isLast) {
                getConsumer().onProgressUpdate(1f);
              }
              getConsumer().onNewResult(
                  (newCachedResult != null) ? newCachedResult : newResult, isLast);
            } finally {
              CloseableReference.closeSafely(newCachedResult);
            }
          }
        };
      }
    

    在这里用到了代理设计模式,因为呢,每个producer都会调用consumer的方法,但是不同的producer需要在原有consumer的基础上处理自己的一些逻辑,这里呢?就需要将原来的consumer进行代理,调用时,先处理自己的逻辑,然后调用原有consumer的相关方法即可.

    这里我们看到消费者是在产生新的结果时会缓存这个结果,但是这个只是基类BitmapMemoryCacheProducer的wrapConsumer的方法,我们这个实现类BitmapMemoryCacheGetProducer只是用于内存获取而已,所以,不会涉及到内存缓存这块,只是获取,所以BitmapMemoryCacheGetProducer的wrapConsumer只是返回方法中的consumer.

    看完了这个内存缓存的producer后,我们再看看最后的producer,即网络数据获取的相关producer:NetworkFetchProducer

  • 相关阅读:
    PowerShell脚本自动设置安卓手机wifi代理
    Python写一个Windows下的android设备截图工具
    Auty框架表现篇——python flask框架实践
    服务器端查看log的shell脚本
    软件测试体系划分与职业素养
    Python Locust性能测试框架实践
    一步一步教你编写与搭建自动化测试框架——python篇
    Auty自动化测试框架第七篇——添加动作库和常量文件库
    Auty自动化测试框架第六篇——垃圾代码回收、添加suite支持
    Auty自动化测试框架第四篇——生成测试结果报告
  • 原文地址:https://www.cnblogs.com/pandapan/p/4784423.html
Copyright © 2011-2022 走看看