public interface BitmapCallback extends HttpCallback<Bitmap> {
} public interface FileCallback extends HttpCallback<File> {
} public abstract class GsonCallback<T> implements HttpCallback<T> {
    public final Type type;
    public final Gson gson;

    public GsonCallback(final Class<T> clazz) {
        this(clazz, null);
    }

    public GsonCallback(final Class<T> clazz, final Gson gson) {
        this.type = clazz;
        this.gson = gson;
    }

    public GsonCallback(final Type type) {
        this(type, null);
    }

    public GsonCallback(Type type, final Gson gson) {
        this.type = type;
        this.gson = gson;
    }

} public interface HttpCallback<T> {

    void handleResponse(T response);

    boolean handleException(Throwable throwable);
} public interface ResponseCallback extends HttpCallback<NextResponse> {
} public interface StringCallback extends HttpCallback<String> {
} public class HttpException extends Exception {

    public final NextResponse response;

    public HttpException(final NextResponse response) {
        super(response.message());
        this.response = response;
    }

    @Override
    public String toString() {
        return super.toString() + " {" + response + '}';
    }
} public class HttpJob<T> {

    public final NextRequest request;
    public final HttpTransformer<T> transformer;
    public final HttpCallback<T> callback;
    public final Object caller;
    private List<HttpProcessor<T>> processors;

    public HttpJob(final NextRequest request,
                   final HttpTransformer<T> transformer,
                   final HttpCallback<T> callback,
                   final Object caller) {
        this(request, transformer, callback, null, caller);
    }

    public HttpJob(final NextRequest request,
                   final HttpTransformer<T> transformer,
                   final HttpCallback<T> callback,
                   final List<HttpProcessor<T>> processors,
                   final Object caller) {
        AssertUtils.notNull(request, "request must not be null.");
        AssertUtils.notNull(transformer, "transformer must not be null.");
        AssertUtils.notNull(caller, "caller must not be null.");
        this.request = request;
        this.transformer = transformer;
        this.callback = callback;
        this.caller = caller;
        if (processors != null) {
            this.processors = processors;
        } else {
            this.processors = new ArrayList<HttpProcessor<T>>(2);
        }
    }

    public HttpJob<T> addProcessor(HttpProcessor<T> processor) {
        if (processor != null) {
            this.processors.add(processor);
        }
        return this;
    }

    public List<HttpProcessor<T>> getProcessors() {
        return processors;
    }

    public String execute(final HttpQueue queue) {
        return queue.add(this);
    }

    public String execute() {
        return HttpQueue.getDefault().add(this);
    }

    @Override
    public String toString() {
        return "HttpJob{" +
                "request=" + request +
                ", transformer=" + transformer +
                ", callback=" + callback +
                ", processors=" + processors +
                ", caller=" + caller +
                '}';
    }
} public interface HttpProcessor<T> {

    void process(T response);
} public class BitmapTransformer implements HttpTransformer<Bitmap> {
    @Override
    public Bitmap transform(final NextResponse response) throws IOException {
        return BitmapFactory.decodeStream(response.stream());
    }
} public class FileTransformer implements HttpTransformer<File> {

    private File file;

    public FileTransformer(final File file) {
        this.file = file;
    }


    @Override
    public File transform(final NextResponse response) throws IOException {
        boolean saved = response.writeTo(file);
        if (saved) {
            return file;
        }
        throw new IOException("can not save file: " + file);
    }
} public class GsonTransformer<T> implements HttpTransformer<T> {
    private Gson gson;
    private Type type;

    public GsonTransformer(final Gson gson, final Class<T> clazz) {
        this.gson = gson;
        this.type = clazz;
    }

    public GsonTransformer(final Gson gson, final Type type) {
        this.gson = gson;
        this.type = type;
    }

    @SuppressWarnings("unchecked")
    @Override
    public T transform(final NextResponse response) throws IOException {
        // ugly hack for runtime type for gson
        if (type instanceof Class) {
            return gson.fromJson(response.reader(), (Class<T>) type);
        } else {
            return gson.fromJson(response.reader(), type);
        }
    }
} public interface HttpTransformer<T> {

    T transform(NextResponse response) throws IOException;
} public class ResponseTransformer implements HttpTransformer<NextResponse> {
    @Override
    public NextResponse transform(final NextResponse response) throws IOException {
        return response;
    }
} public class StringTransformer implements HttpTransformer<String> {
    @Override
    public String transform(final NextResponse response) throws IOException {
        return response.string();
    }
} public class SimpleTaskCallback<Result> implements TaskCallback<Result> {

    @Override
    public void onTaskStarted(String name, Bundle extras) {

    }

    @Override
    public void onTaskFinished(String name, Bundle extras) {

    }

    @Override
    public void onTaskCancelled(String name, Bundle extras) {

    }

    @Override
    public void onTaskSuccess(Result result, Bundle extras) {

    }

    @Override
    public void onTaskFailure(Throwable ex, Bundle extras) {

    }
} public interface TaskCallback<Result> {
    String TASK_THREAD = "task_thread";
    String TASK_GROUP = "task_group";
    String TASK_NAME = "task_name";
    String TASK_SEQUENCE = "task_sequence";
    String TASK_DELAY = "task_delay";
    String TASK_DURATION = "task_duration";

    /**
     * 任务开始
     * 注意：此方法默认运行于主线程，可通过 TaskBuilder.dispatch(handler)更改
     *
     * @param name   TASK NAME
     * @param extras 附加结果，需要返回多种结果时会用到
     */
    void onTaskStarted(String name, Bundle extras);

    /**
     * 任务完成
     * 注意：此方法默认运行于主线程，可通过 TaskBuilder.dispatch(handler)更改
     *
     * @param name   TASK NAME
     * @param extras 附加结果，需要返回多种结果时会用到
     */
    void onTaskFinished(String name, Bundle extras);

    /**
     * 任务取消
     * 注意：此方法默认运行于主线程，可通过 TaskBuilder.dispatch(handler)更改
     *
     * @param name   TASK NAME
     * @param extras 附加结果，需要返回多种结果时会用到
     */
    void onTaskCancelled(String name, Bundle extras);

    /**
     * 回调，任务执行完成
     * 注意：此方法默认运行于主线程，可通过 TaskBuilder.dispatch(handler)更改
     *
     * @param result 执行结果
     * @param extras 附加结果，需要返回多种结果时会用到
     */
    void onTaskSuccess(Result result, Bundle extras);

    /**
     * 回调，任务执行失败
     * 注意：此方法默认运行于主线程，可通过 TaskBuilder.dispatch(handler)更改
     *
     * @param ex     失败原因，异常
     * @param extras 附加结果，需要返回额外的信息时会用到
     */
    void onTaskFailure(Throwable ex, Bundle extras);


} public abstract class TaskQueue implements ITaskQueue {

    static final class SingletonHolder {
        static final TaskQueue INSTANCE = TaskFactory.createQueue(0);
    }

    public static TaskQueue getDefault() {
        return SingletonHolder.INSTANCE;
    }

    public static TaskQueue concurrent(int maxThreads) {
        return TaskFactory.createQueue(maxThreads);
    }

    public static TaskQueue concurrent() {
        return TaskFactory.createQueue(0);
    }

    public static TaskQueue singleThread() {
        return TaskFactory.createQueue(1);
    }

    public static void setDebug(boolean debug) {
        Config.DEBUG = debug;
    }

    abstract <Result> String execute(final Callable<Result> callable,
                                     final TaskCallback<Result> callback,
                                     final Object caller);

    abstract String execute(final Task task);

    abstract void remove(final TaskFuture task);


    /**
     * 取消TAG对应的任务
     *
     * @param task 任务
     * @return 任务是否存在
     */
    abstract boolean cancel(final TaskFuture task);


}
import android.os.Bundle;
import android.os.SystemClock;
import android.util.Pair;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.mcxiaoke.next.http.callback.BitmapCallback;
import com.mcxiaoke.next.http.callback.FileCallback;
import com.mcxiaoke.next.http.callback.GsonCallback;
import com.mcxiaoke.next.http.callback.HttpCallback;
import com.mcxiaoke.next.http.callback.ResponseCallback;
import com.mcxiaoke.next.http.callback.StringCallback;
import com.mcxiaoke.next.http.exception.HttpException;
import com.mcxiaoke.next.http.job.HttpJob;
import com.mcxiaoke.next.http.processor.HttpProcessor;
import com.mcxiaoke.next.http.transformer.BitmapTransformer;
import com.mcxiaoke.next.http.transformer.FileTransformer;
import com.mcxiaoke.next.http.transformer.GsonTransformer;
import com.mcxiaoke.next.http.transformer.HttpTransformer;
import com.mcxiaoke.next.http.transformer.ResponseTransformer;
import com.mcxiaoke.next.http.transformer.StringTransformer;
import com.mcxiaoke.next.task.SimpleTaskCallback;
import com.mcxiaoke.next.task.TaskCallable;
import com.mcxiaoke.next.task.TaskCallback;
import com.mcxiaoke.next.task.TaskQueue;
import com.mcxiaoke.next.utils.LogUtils;
import okhttp3.OkHttpClient;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
package com.mcxiaoke.next.http;



/**
 * User: mcxiaoke
 * Date: 15/8/21
 * Time: 10:42
 */
public class HttpQueue {

    static class SingletonHolder {
        public static final HttpQueue INSTANCE = new HttpQueue();
    }

    public static HttpQueue getDefault() {
        return SingletonHolder.INSTANCE;
    }

    private static final String TAG = HttpQueue.class.getSimpleName();
    private static final int NUM_THREADS_DEFAULT = 0;

    private TaskQueue mQueue;
    private NextClient mClient;
    private Gson mGson;
    private boolean mDebug;

    public HttpQueue() {
        this(createQueue(), new NextClient());
    }

    public HttpQueue(final OkHttpClient client) {
        this(createQueue(), new NextClient(client));
    }

    public HttpQueue(final NextClient client) {
        this(createQueue(), client);
    }

    public HttpQueue(final TaskQueue queue) {
        this(queue, new NextClient());
    }

    public HttpQueue(final TaskQueue queue, final NextClient client) {
        mGson = new GsonBuilder().setPrettyPrinting().create();
        mQueue = queue;
        mClient = client;
    }

    public void setDebug(final boolean debug) {
        mDebug = debug;
        mClient.setDebug(debug);
        TaskQueue.setDebug(true);
    }

    public void setQueue(final TaskQueue queue) {
        mQueue = queue;
    }

    public void setClient(final NextClient client) {
        mClient = client;
    }

    public void setGson(final Gson gson) {
        mGson = gson;
    }

    public NextClient getClient() {
        return mClient;
    }

    public TaskQueue getQueue() {
        return mQueue;
    }

    public Gson getGson() {
        return mGson;
    }

    public void cancelAll(Object caller) {
        mQueue.cancelAll(caller);
    }

    public void cancel(String name) {
        if (name != null) {
            mQueue.cancel(name);
        }
    }

    public void cancelAll() {
        mQueue.cancelAll();
    }

    public <T> String add(final HttpJob<T> job) {
        return enqueue(job);
    }

    public <T> String add(final NextRequest request,
                          final HttpTransformer<T> transformer,
                          final HttpCallback<T> callback,
                          final HttpProcessor<T> processor,
                          final Object caller) {
        final HttpJob<T> job = new HttpJob<T>(request, transformer, callback, caller);
        job.addProcessor(processor);
        return enqueue(job);
    }

    public <T> String add(final NextRequest request,
                          final HttpTransformer<T> transformer,
                          final HttpCallback<T> callback,
                          final Object caller) {
        final HttpJob<T> job = new HttpJob<T>(request, transformer, callback, caller);
        return enqueue(job);
    }

    public String add(final NextRequest request,
                      final ResponseCallback callback,
                      final Object caller) {
        return add(request, new ResponseTransformer(), callback, caller);
    }

    public <T> String add(final NextRequest request,
                          final GsonCallback<T> callback,
                          Object caller) {
        final Gson gson = callback.gson == null ? mGson : callback.gson;
        final GsonTransformer<T> transformer;
        transformer = new GsonTransformer<T>(gson, callback.type);
        return add(request, transformer, callback, caller);
    }

    public String add(final NextRequest request,
                      final StringCallback callback,
                      final Object caller) {
        return add(request, new StringTransformer(), callback, caller);
    }

    public String add(final NextRequest request,
                      final BitmapCallback callback,