源码分析之Fresco(1)

com.facebook.imagepipeline.core/ImagePipeline.java

 
[1]取图片从BitmapCache
>public DataSource<CloseableReference<CloseableImage>> fetchImageFromBitmapCache( ImageRequest imageRequest, Object callerContext)
>> submitFetchRequest() 
>>>CloseableProducerToDataSourceAdapter.create()生产者到数据源的一个适配器

该适配器目录com.facebook.imagepipeline.datasource/CloseableProducerToDataSourceAdapter.java

@看看定义
CloseableProducerToDataSourceAdapter<T> extends AbstractProducerToDataSourceAdapter<CloseableReference<T>>

@跟踪create方法
create()---> super(producer, settableProducerContext, listener)父类的构造方法
           >>producer.produceResults(createConsumer(), settableProducerContext)
执行父类构造方法,父类开始 告诉 生成者 开始生产作业了produceResults();


@那么这个producer生产者是谁呢?
:::::: producerSequence这玩意
>  Producer<CloseableReference<CloseableImage>> producerSequence =
                    mProducerSequenceFactory.getDecodedImageProducerSequence(imageRequest);
                                                         ^
@mProducerSequenceFactory工厂产生生产者
                                                         ^
   public Producer<CloseableReference<CloseableImage>> getDecodedImageProducerSequence(ImageRequest imageRequest) {
        Producer<CloseableReference<CloseableImage>> pipelineSequence =
                getBasicDecodedImageSequence(imageRequest);
        if (imageRequest.getPostprocessor() != null) {
            return getPostprocessorSequence(pipelineSequence);
        } else {
            return pipelineSequence;
        }
    }
@看看pipelineSequence怎么得来:

private Producer<CloseableReference<CloseableImage>> getBasicDecodedImageSequence(ImageRequest imageRequest) {
        Preconditions.checkNotNull(imageRequest);//判空

        Uri uri = imageRequest.getSourceUri();//图片地址
        Preconditions.checkNotNull(uri, "Uri is null.");//判空
        if (UriUtil.isNetworkUri(uri)) {//网络地址
            return getNetworkFetchSequence();
        } else if (UriUtil.isLocalFileUri(uri)) {//本地文件地址
            if (MediaUtils.isVideo(MediaUtils.extractMime(uri.getPath()))) {
                return getLocalVideoFileFetchSequence();
            } else {
                return getLocalImageFileFetchSequence();
            }
        } else if (UriUtil.isLocalContentUri(uri)) {//content地址 如 content://sms/inbox
            return getLocalContentUriFetchSequence();
        } else if (UriUtil.isLocalAssetUri(uri)) {//本地Asset地址
            return getLocalAssetFetchSequence();
        } else if (UriUtil.isLocalResourceUri(uri)) {//本地Resource地址
            return getLocalResourceFetchSequence();
        } else if (UriUtil.isDataUri(uri)) {
            return getDataFetchSequence();
        } else {
            String uriString = uri.toString();
            if (uriString.length() > 30) {
                uriString = uriString.substring(0, 30) + "...";
            }
            throw new RuntimeException("Unsupported uri scheme! Uri is: " + uriString);
        }
    }

根据uri类型 来返回 不同的 Producer生产者.

@继续跟代码
1、如果是网络地址 getNetworkFetchSequence();
                  > mNetworkFetchSequence = newBitmapCacheGetToDecodeSequence(getCommonNetworkFetchToEncodedMemorySequence());
                                                 
                  >>
    private Producer<CloseableReference<CloseableImage>> newBitmapCacheGetToDecodeSequence(Producer<EncodedImage> inputProducer) {
        DecodeProducer decodeProducer = mProducerFactory.newDecodeProducer(inputProducer);
        return newBitmapCacheGetToBitmapCacheSequence(decodeProducer);
    }

    com.facebook.imagepipeline.core/ProducerFactory.java
    先是 调用工厂类 ProducerFactory.newDecodeProducer得到一个DecodeProducer解码生产者

    

   newBitmapCacheGetToBitmapCacheSequence(inputProducer)做了啥?
   :ProducerFactory生了BitmapMemoryCacheProducer,进化成BitmapMemoryCacheKeyMultiplexProducer,再次进化ThreadHandoffProducer【这货后面有用到】
   然并卵 
   return mProducerFactory.newBitmapMemoryCacheGetProducer(threadHandoffProducer);
   >                              ||
          public BitmapMemoryCacheGetProducer newBitmapMemoryCacheGetProducer(
                Producer<CloseableReference<CloseableImage>> inputProducer) {
                 return new BitmapMemoryCacheGetProducer(mBitmapMemoryCache, mCacheKeyFactory, inputProducer);
           }

   最后超级进化成 @BitmapMemoryCacheGetProducer

   @2大工厂 @ProducerSequenceFactory 和 @ProducerFactory  前面又字面意思可以理解 一系列工厂,肯定是总厂,下面很多分厂;

   回到主线 producer.produceResults(createConsumer(), settableProducerContext); 找到了 生产者就要开始生产了!!!
   主角是 BitmapMemoryCacheGetProducer 官方注释是 只读的生产者,暂时有点懵逼
   主角父亲是BitmapMemoryCacheProducer这货

   @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());//告诉listener开始生产
        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()) {//最低请求等级判断 ,BITMAP_MEMORY_CACHE是最高等级
            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);
        mInputProducer.produceResults(wrappedConsumer, producerContext);//再次生产
    }
   
    @RequestLevel.java  是com.facebook.imagepipeline.request.ImageRequest的内部类
    
    /* Fetch (from the network or local storage) */
    FULL_FETCH(1),
    /* Disk caching */
    DISK_CACHE(2),
    /* Encoded memory caching */
    ENCODED_MEMORY_CACHE(3),
    /* Bitmap caching */
    BITMAP_MEMORY_CACHE(4);

      
    mInputProducer是谁呢? 另一个生产者闪亮登场了 ThreadHandoffProducer 这货
    这货是 怎么 产生的?
    ThreadHandoffProducer<CloseableReference<CloseableImage>> threadHandoffProducer =
                mProducerFactory.newBackgroundThreadHandoffProducer(bitmapKeyMultiplexProducer, mThreadHandoffProducerQueue);
    还是离不开ProducerFactory工厂类
    参数2:mThreadHandoffProducerQueue ,它里面 有一个Executor 线程执行器 和 ArrayList<Runnable>容器;
    其实 就是 一个 线程池吧。
    //ThreadHandoffProducer开始生产
    @Override
    public void produceResults(final Consumer<T> consumer, final ProducerContext context) {
        final ProducerListener producerListener = context.getListener();
        final String requestId = context.getId();
        final StatefulProducerRunnable<T> statefulRunnable = new StatefulProducerRunnable<T>(
                consumer, producerListener, PRODUCER_NAME, requestId) {
            @Override
            protected void onSuccess(T ignored) {
                producerListener.onProducerFinishWithSuccess(requestId, PRODUCER_NAME, null);
                mInputProducer.produceResults(consumer, context);//关键是 这句代码
            }

            @Override
            protected void disposeResult(T ignored) {
            }

            @Override
            protected T getResult() throws Exception {
                return null;
            }
        };
        context.addCallbacks(new BaseProducerContextCallbacks() {
                    @Override
                    public void onCancellationRequested() {
                        statefulRunnable.cancel();
                        mThreadHandoffProducerQueue.remove(statefulRunnable);
                    }
                });
        mThreadHandoffProducerQueue.addToQueueOrExecute(statefulRunnable); //丢到线程池 执行
    }
    
    
    在 onSuccess()回调方法里 ThreadHandoffProducer的mInputProducer开始 登场,
    此mInputProducer引用的对象是 BitmapMemoryCacheKeyMultiplexProducer bitmapKeyMultiplexProducer =
                mProducerFactory.newBitmapMemoryCacheKeyMultiplexProducer(bitmapMemoryCacheProducer);
    顺藤摸瓜 跟到BitmapMemoryCacheKeyMultiplexProducer的父类 MultiplexProducer
    >produceResults()
    >>startInputProducerIfHasAttachedConsumers()
    >>>mInputProducer.produceResults(forwardingConsumer, multiplexProducerContext);
    最后 又把任务交给 另一个生产者mInputProducer
    BitmapMemoryCacheProducer bitmapMemoryCacheProducer =
                mProducerFactory.newBitmapMemoryCacheProducer(inputProducer);
    看看 BitmapMemoryCacheProducer 的 
        @Override
    public void produceResults(final Consumer<CloseableReference<CloseableImage>> consumer,
            final ProducerContext producerContext) {
        ......
        Consumer<CloseableReference<CloseableImage>> wrappedConsumer = wrapConsumer(consumer, cacheKey);
        listener.onProducerFinishWithSuccess(
                requestId,
                getProducerName(),
                listener.requiresExtraMap(requestId) ? ImmutableMap.of(VALUE_FOUND, "false") : null);
        mInputProducer.produceResults(wrappedConsumer, producerContext);
    }
    哭笑不得 又交给 另一个生产者mInputProducer
    只能往回看代码了 :
    DecodeProducer decodeProducer = mProducerFactory.newDecodeProducer(inputProducer);
    解码生产者 
    @Override
    public void produceResults(final Consumer<CloseableReference<CloseableImage>> consumer,
            final ProducerContext producerContext) {
        final ImageRequest imageRequest = producerContext.getImageRequest();
        ProgressiveDecoder progressiveDecoder;
        if (!UriUtil.isNetworkUri(imageRequest.getSourceUri())) {//不是网络地址
            progressiveDecoder = new LocalImagesProgressiveDecoder(consumer, producerContext);
        } else { //是网络图片地址
            ProgressiveJpegParser jpegParser = new ProgressiveJpegParser(mByteArrayPool);
            progressiveDecoder = new NetworkImagesProgressiveDecoder(consumer,
                    producerContext,
                    jpegParser,
                    mProgressiveJpegConfig);
        }
        mInputProducer.produceResults(progressiveDecoder, producerContext);
    }

    继续跟 这个 mInputProducer,找源头吧 
    private synchronized Producer<CloseableReference<CloseableImage>> getNetworkFetchSequence() {
        if (mNetworkFetchSequence == null) {
            mNetworkFetchSequence = newBitmapCacheGetToDecodeSequence(getCommonNetworkFetchToEncodedMemorySequence());
        }
        return mNetworkFetchSequence;
    }
    到这里 getCommonNetworkFetchToEncodedMemorySequence()返回生产者

     /**
     * multiplex -> encoded cache -> disk cache -> (webp transcode) -> network fetch.
     */
    private synchronized Producer<EncodedImage> getCommonNetworkFetchToEncodedMemorySequence() {
        if (mCommonNetworkFetchToEncodedMemorySequence == null) {
            Producer<EncodedImage> inputProducer = newEncodedCacheMultiplexToTranscodeSequence(
                            mProducerFactory.newNetworkFetchProducer(mNetworkFetcher)); //这里是生存者 源头 
            mCommonNetworkFetchToEncodedMemorySequence =
                    ProducerFactory.newAddImageTransformMetaDataProducer(inputProducer);

            if (mResizeAndRotateEnabledForNetwork && !mDownsampleEnabled) { //需要调整大小 和 旋转 
                mCommonNetworkFetchToEncodedMemorySequence = mProducerFactory.newResizeAndRotateProducer(
                                mCommonNetworkFetchToEncodedMemorySequence);
            }
        }
        return mCommonNetworkFetchToEncodedMemorySequence;
    }

    直接看源头NetworkFetchProducer 网络获取生产者(从网络获取图片呗)
      @Override
  public void produceResults(Consumer<EncodedImage> consumer, ProducerContext context) {
    context.getListener()
            .onProducerStart(context.getId(), PRODUCER_NAME);
    final FetchState fetchState = mNetworkFetcher.createFetchState(consumer, context);
    mNetworkFetcher.fetch(fetchState, new NetworkFetcher.Callback() {
              @Override
              public void onResponse(InputStream response, int responseLength) throws IOException {
                NetworkFetchProducer.this.onResponse(fetchState, response, responseLength);
              }

              @Override
              public void onFailure(Throwable throwable) {
                NetworkFetchProducer.this.onFailure(fetchState, throwable);
              }

              @Override
              public void onCancellation() {
                NetworkFetchProducer.this.onCancellation(fetchState);
              }
            });
  }

  mNetworkFetcher是 由 ImagePipelineConfig 初始化的 时候配置的 
  mNetworkFetcher = builder.mNetworkFetcher == null ?
            new HttpUrlConnectionNetworkFetcher() : builder.mNetworkFetcher;
  默认配置下ImagePipelineConfig.Builder类的 mNetworkFetcher为 null;
  mNetworkFetcher 指向的 就是  HttpUrlConnectionNetworkFetcher,Fresco默认的网络连接用的是HttpUrlConnection;
  HttpUrlConnectionNetworkFetcher的 fetch() 方法里
  @Override
    public void fetch(final FetchState fetchState, final Callback callback) {
        final Future<?> future = mExecutorService.submit(new Runnable() {
                    @Override
                    public void run() {
                        fetchSync(fetchState, callback);
                    }
                });//开了个线程执行下载图片操作
         ......
    }
   
   void fetchSync(FetchState fetchState, Callback callback) {
        HttpURLConnection connection = null;
        try {
            connection = downloadFrom(fetchState.getUri(), MAX_REDIRECTS);//终于要下载了
            if (connection != null) {
                callback.onResponse(connection.getInputStream(), -1);
            }
        } catch (IOException e) {
            callback.onFailure(e);
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
        }

    }
以上是网络加载图片步骤...
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容