All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.webimageloader.ImageLoaderImpl Maven / Gradle / Ivy

package com.webimageloader;

import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.concurrent.ExecutionException;

import android.graphics.Bitmap;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;

import com.webimageloader.loader.LoaderManager;
import com.webimageloader.loader.MemoryCache;
import com.webimageloader.transformation.Transformation;
import com.webimageloader.util.AbstractImageLoader;
import com.webimageloader.util.WaitFuture;

class ImageLoaderImpl extends AbstractImageLoader {
    private LoaderManager loaderManager;
    private HandlerManager handlerManager;

    ImageLoaderImpl(LoaderManager loaderManager) {
        this.loaderManager = loaderManager;

        handlerManager = new HandlerManager();
    }

    @Override
    public MemoryCache.DebugInfo getMemoryCacheInfo() {
        MemoryCache memoryCache = loaderManager.getMemoryCache();

        if (memoryCache != null) {
            return memoryCache.getDebugInfo();
        } else {
            return null;
        }
    }

    @Override
    public MemoryCache getMemoryCache() {
        return loaderManager.getMemoryCache();
    }

    @Override
    public Bitmap loadBlocking(Request request) throws IOException {
        final WaitFuture future = new WaitFuture();

        Bitmap b = loadInternal(null, request, new LoaderManager.Listener() {
            @Override
            public void onLoaded(Bitmap b) {
                future.set(b);
            }

            @Override
            public void onError(Throwable t) {
                future.setException(t);
            }
        });

        if (b != null) {
            return b;
        }

        boolean interrupted = false;

        try {
            while (true) {
                try {
                    return future.get();
                } catch (ExecutionException e) {
                    Throwable cause = e.getCause();

                    // Rethrow as original exception if possible
                    if (cause instanceof IOException) {
                        throw (IOException) cause;
                    } else {
                        throw new IOException("Failed to fetch image", e.getCause());
                    }
                } catch (InterruptedException e) {
                    // Fall through and retry
                    interrupted = true;
                }
            }
        } finally {
            if (interrupted) {
                Thread.currentThread().interrupt();
            }
        }
    }

    public void preload(Request request) {
        loadInternal(null, request, null);
    }

    public  Bitmap load(T tag, Request request, Listener listener) {
        return loadInternal(tag, request, handlerManager.getListener(tag, listener));
    }

    @Override
    public  void cancel(T tag) {
        handlerManager.cancel(tag);
        loaderManager.cancel(tag);
    }

    private Bitmap loadInternal(Object tag, Request request, LoaderManager.Listener listener) {
        return loaderManager.load(tag, request.toLoaderRequest(), listener);
    }

    @Override
    public void destroy() {
        loaderManager.close();
    }

    private static class HandlerManager {
        private Handler handler;

        public HandlerManager() {
            handler = new Handler(Looper.getMainLooper());
        }

        public  LoaderManager.Listener getListener(T tag, Listener listener) {
            if (tag != null) {
                // It's possible there is already a callback in progress for this tag
                // so we'll remove it
                handler.removeCallbacksAndMessages(tag);

                return new TagListener(tag, listener);
            } else {
                return new TagListener(listener);
            }
        }

        public void cancel(Object tag) {
            handler.removeCallbacksAndMessages(tag);
        }

        private class TagListener implements LoaderManager.Listener {
            private Listener listener;
            private WeakReference reference;

            public TagListener(Listener listener) {
                this.listener = listener;
            }

            public TagListener(T tag, Listener listener) {
                this.listener = listener;
                this.reference = new WeakReference(tag);
            }

            @Override
            public void onLoaded(final Bitmap b) {
                final T tag = getTag();

                post(tag, new Runnable() {
                    @Override
                    public void run() {
                        listener.onSuccess(tag, b);
                    }
                });
            }

            @Override
            public void onError(final Throwable t) {
                final T tag = getTag();

                post(tag, new Runnable() {
                    @Override
                    public void run() {
                        listener.onError(tag, t);
                    }
                });
            }

            private T getTag() {
                T tag = null;

                if (reference != null) {
                    tag = reference.get();
                    if (tag == null) {
                        throw new RuntimeException("Listener called but tag was GC'ed");
                    }
                }

                return tag;
            }

            private void post(T tag, Runnable r) {
                Message m = Message.obtain(handler, r);
                m.obj = tag;
                handler.sendMessage(m);
            }
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy