com.facebook.imagepipeline.backends.okhttp.OkHttpNetworkFetchProducer.java Source code

Java tutorial

Introduction

Here is the source code for com.facebook.imagepipeline.backends.okhttp.OkHttpNetworkFetchProducer.java

Source

/*
 * Copyright (c) 2015-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 */

package com.facebook.imagepipeline.backends.okhttp;

import java.io.IOException;

import android.net.Uri;

import com.facebook.common.logging.FLog;
import com.facebook.common.references.CloseableReference;
import com.facebook.imagepipeline.memory.ByteArrayPool;
import com.facebook.imagepipeline.memory.PooledByteBuffer;
import com.facebook.imagepipeline.memory.PooledByteBufferFactory;
import com.facebook.imagepipeline.producers.BaseProducerContextCallbacks;
import com.facebook.imagepipeline.producers.Consumer;
import com.facebook.imagepipeline.producers.NfpRequestState;
import com.facebook.imagepipeline.producers.NetworkFetchProducer;
import com.facebook.imagepipeline.producers.ProducerContext;

import com.squareup.okhttp.Call;
import com.squareup.okhttp.Callback;
import com.squareup.okhttp.CacheControl;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import com.squareup.okhttp.ResponseBody;

/**
 * Network fetch producer using OkHttp as a backend.
 *
 * <p> OkHttpNetworkFetchProducer supports request cancellation. This feature is enabled
 * via {@code cancellable} constructor parameter.
 */
public class OkHttpNetworkFetchProducer extends NetworkFetchProducer<NfpRequestState> {

    private static final String TAG = "OkHttpNetworkFetchProducer";

    private final OkHttpClient mOkHttpClient;
    private final boolean mCancellable;

    /**
     * @param okHttpClient client to use
     * @param cancellable whether to allow cancellation of submitted requests
     * @param pooledByteBufferFactory pooled byte buffer factory
     * @param byteArrayPool pool for stream input/ouptut buffering
     */
    public OkHttpNetworkFetchProducer(OkHttpClient okHttpClient, boolean cancellable,
            PooledByteBufferFactory pooledByteBufferFactory, ByteArrayPool byteArrayPool) {
        super(pooledByteBufferFactory, byteArrayPool);
        mOkHttpClient = okHttpClient;
        mCancellable = cancellable;
    }

    @Override
    protected NfpRequestState newRequestState(Consumer<CloseableReference<PooledByteBuffer>> consumer,
            ProducerContext context) {
        return new NfpRequestState(consumer, context);
    }

    @Override
    protected void fetchImage(final NfpRequestState requestState) {
        final Uri uri = requestState.getUri();
        final Request request = new Request.Builder().cacheControl(new CacheControl.Builder().noStore().build())
                .url(uri.toString()).get().build();
        final Call call = mOkHttpClient.newCall(request);

        if (mCancellable) {
            requestState.getContext().addCallbacks(new BaseProducerContextCallbacks() {
                @Override
                public void onCancellationRequested() {
                    call.cancel();
                }
            });
        }

        call.enqueue(new Callback() {
            @Override
            public void onResponse(Response response) {
                final ResponseBody body = response.body();
                try {
                    long contentLength = body.contentLength();
                    if (contentLength < 0) {
                        contentLength = 0;
                    }
                    processResult(requestState, body.byteStream(), (int) contentLength, false);
                } catch (IOException ioe) {
                    handleException(call, requestState, ioe);
                } finally {
                    try {
                        body.close();
                    } catch (IOException ioe) {
                        FLog.w(TAG, "Exception when closing response body", ioe);
                    }
                }
            }

            @Override
            public void onFailure(final Request request, final IOException e) {
                handleException(call, requestState, e);
            }
        });
    }

    /**
     * Handles IOExceptions.
     *
     * <p> OkHttp notifies callers of cancellations via an IOException. If IOException is caught
     * after request cancellation, then the exception is interpreted as successful cancellation
     * and onCancellation is called. Otherwise onFailure is called.
     */
    private void handleException(final Call call, final NfpRequestState requestState, final IOException ioe) {
        if (call.isCanceled()) {
            onCancellation(requestState, null);
        } else {
            onFailure(requestState, ioe, null);
        }
    }
}