// Path: restvolley/src/main/java/com/hujiang/restvolley/TaskScheduler.java
// public class TaskScheduler {
// 
//     private static Handler mHandler = new Handler(Looper.getMainLooper());
//     private static ThreadPool mThreadPool = new ThreadPool("com.hujiang.restvolley.task_scheduler");
// 
//     /**
//      * 以轻量级的方式执行一个异步任务.
//      * @param backgroundTaskRunnable 异步任务
//      */
//     public static void execute(final Runnable backgroundTaskRunnable) {
//         if (backgroundTaskRunnable != null) {
//             mThreadPool.addTask(backgroundTaskRunnable);
//         }
//     }
// 
//     /**
//      * execute a task.
//      * @param backgroundRunnable background task
//      * @param foregroundRunnable foreground task
//      */
//     public static void execute(final Runnable backgroundRunnable, final Runnable foregroundRunnable) {
//         mThreadPool.addTask(new Runnable() {
//             @Override
//             public void run() {
//                 if (backgroundRunnable != null) {
//                     backgroundRunnable.run();
//                 }
// 
//                 if (foregroundRunnable != null) {
//                     mHandler.post(foregroundRunnable);
//                 }
//             }
//         });
//     }
// 
//     /**
//      * execute a task.
//      * @param task {@link Task}
//      * @param <IT> in paramter's type
//      * @param <OT> out paramter's type
//      */
//     public static <IT, OT> void execute(final Task<IT, OT> task) {
//         exec(task);
//     }
// 
//     private static <IT, OT> void exec(final Task<IT, OT> task) {
//         if (task != null) {
//             mThreadPool.addTask(new Runnable() {
//                 @Override
//                 public void run() {
//                     final OT out = task.onDoInBackground(task.mInput);
//                     mHandler.post(new Runnable() {
//                         @Override
//                         public void run() {
//                             task.onPostExecuteForeground(out);
//                         }
//                     });
// 
//                 }
//             });
//         }
//     }
// }


import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;
import android.widget.ImageView;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.RequestFuture;
import com.hujiang.restvolley.R;
import com.hujiang.restvolley.TaskScheduler;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.LinkedList;
import java.util.Locale;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
    public ImageContainer load(String requestUri, final ImageListener listener) {
        return load(requestUri, listener, null);
    }

    /**
     * Issues a bitmap request with the given uri if that image is not available
     * in the cache, and returns a bitmap container that contains all of the data
     * relating to the request (as well as the default image if the requested
     * image is not available).
     * @param requestUri The uri of the remote image
     * @param imageListener The listener to call when the remote image is loaded
     * @param imageLoadOption image load option.
     * @return A container object that contains all of the properties of the request, as well as
     *     the currently available image (default if remote is not loaded).
     */
    public ImageContainer load(final String requestUri, final ImageListener imageListener, final ImageLoadOption imageLoadOption) {

        final int maxWidth = getMaxWidth(imageLoadOption);
        final int maxHeight = getMaxHeight(imageLoadOption);
        final ImageView.ScaleType scaleType = getScaleType(imageLoadOption);
        final boolean isCacheEnable = isCacheEnable(imageLoadOption);

        final String cacheKey = generateCacheKey(requestUri, maxWidth, maxHeight, scaleType);

        // The bitmap did not exist in the cache, fetch it!
        final ImageContainer imageContainer = new ImageContainer(null, requestUri, cacheKey, LoadFrom.UNKNOWN, imageListener);

        // Update the caller to let them know that they should use the default bitmap.
        responseOnUiThread(imageContainer, true, imageListener);

// Path: restvolley/src/main/java/com/hujiang/restvolley/TaskScheduler.java
// public class TaskScheduler {
// 
//     private static Handler mHandler = new Handler(Looper.getMainLooper());
//     private static ThreadPool mThreadPool = new ThreadPool("com.hujiang.restvolley.task_scheduler");
// 
//     /**
//      * 以轻量级的方式执行一个异步任务.
//      * @param backgroundTaskRunnable 异步任务
//      */
//     public static void execute(final Runnable backgroundTaskRunnable) {
//         if (backgroundTaskRunnable != null) {
//             mThreadPool.addTask(backgroundTaskRunnable);
//         }
//     }
// 
//     /**
//      * execute a task.
//      * @param backgroundRunnable background task
//      * @param foregroundRunnable foreground task
//      */
//     public static void execute(final Runnable backgroundRunnable, final Runnable foregroundRunnable) {
//         mThreadPool.addTask(new Runnable() {
//             @Override
//             public void run() {
//                 if (backgroundRunnable != null) {
//                     backgroundRunnable.run();
//                 }
// 
//                 if (foregroundRunnable != null) {
//                     mHandler.post(foregroundRunnable);
//                 }
//             }
//         });
//     }
// 
//     /**
//      * execute a task.
//      * @param task {@link Task}
//      * @param <IT> in paramter's type
//      * @param <OT> out paramter's type
//      */
//     public static <IT, OT> void execute(final Task<IT, OT> task) {
//         exec(task);
//     }
// 
//     private static <IT, OT> void exec(final Task<IT, OT> task) {
//         if (task != null) {
//             mThreadPool.addTask(new Runnable() {
//                 @Override
//                 public void run() {
//                     final OT out = task.onDoInBackground(task.mInput);
//                     mHandler.post(new Runnable() {
//                         @Override
//                         public void run() {
//                             task.onPostExecuteForeground(out);
//                         }
//                     });
// 
//                 }
//             });
//         }
//     }
// }


// Path: restvolley/src/main/java/com/hujiang/restvolley/image/ImageLoaderCompat.java
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;
import android.widget.ImageView;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.RequestFuture;
import com.hujiang.restvolley.R;
import com.hujiang.restvolley.TaskScheduler;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.LinkedList;
import java.util.Locale;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;

    public ImageContainer load(String requestUri, final ImageListener listener) {
        return load(requestUri, listener, null);
    }

    /**
     * Issues a bitmap request with the given uri if that image is not available
     * in the cache, and returns a bitmap container that contains all of the data
     * relating to the request (as well as the default image if the requested
     * image is not available).
     * @param requestUri The uri of the remote image
     * @param imageListener The listener to call when the remote image is loaded
     * @param imageLoadOption image load option.
     * @return A container object that contains all of the properties of the request, as well as
     *     the currently available image (default if remote is not loaded).
     */
    public ImageContainer load(final String requestUri, final ImageListener imageListener, final ImageLoadOption imageLoadOption) {

        final int maxWidth = getMaxWidth(imageLoadOption);
        final int maxHeight = getMaxHeight(imageLoadOption);
        final ImageView.ScaleType scaleType = getScaleType(imageLoadOption);
        final boolean isCacheEnable = isCacheEnable(imageLoadOption);

        final String cacheKey = generateCacheKey(requestUri, maxWidth, maxHeight, scaleType);

        // The bitmap did not exist in the cache, fetch it!
        final ImageContainer imageContainer = new ImageContainer(null, requestUri, cacheKey, LoadFrom.UNKNOWN, imageListener);

        // Update the caller to let them know that they should use the default bitmap.
        responseOnUiThread(imageContainer, true, imageListener);

        TaskScheduler.execute(new Runnable() {