Android Open Source - webimageloader Pending Requests






From Project

Back to project page webimageloader.

License

The source code is released under:

Apache License

If you think the Android project webimageloader listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.webimageloader.loader;
//from  w  w w .  j  a  v  a 2  s .  c  o m
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;

import com.webimageloader.ImageLoader;
import com.webimageloader.ImageLoader.Logger;
import com.webimageloader.util.BitmapUtils;
import com.webimageloader.util.InputSupplier;

import android.graphics.Bitmap;
import android.util.Log;

public class PendingRequests {
    private static final String TAG = "PendingRequests";

    private MemoryCache memoryCache;

    // Don't remove tags at all, this means both of these should be weakhashmaps
    //
    private Map<Object, PendingListeners> pendingTags;
    private Map<LoaderRequest, PendingListeners> pendingRequests;

    public PendingRequests(MemoryCache memoryCache) {
        this.memoryCache = memoryCache;

        // Use WeakHashMap to ensure tags can be GC'd
        pendingTags = new WeakHashMap<Object, PendingListeners>();
        pendingRequests = new HashMap<LoaderRequest, PendingListeners>();
    }

    public synchronized Bitmap getBitmap(Object tag, LoaderRequest request) {
        if (memoryCache != null) {
            MemoryCache.Entry entry = memoryCache.get(request);
            if (entry != null) {
                // We got this bitmap, cancel old pending work
                cancelPotentialWork(tag);
                return entry.bitmap;
            }
        }

        return null;
    }

    public synchronized LoaderWork addRequest(Object tag, final LoaderRequest request, LoaderManager.Listener listener) {
        if (tag != null && stillPending(tag, request)) {
            return null;
        }

        if (tag != null) {
            cancelPotentialWork(tag);
        }

        PendingListeners listeners = pendingRequests.get(request);
        LoaderWork work = null;

        if (listeners == null) {
            work = new LoaderWork(new RequestListener(request), new ImageLoader.ProgressListener() {
                @Override
                public void onProgress(float value) {
                    publishProgress(request, value);
                }
            });

            listeners = new PendingListeners(request, tag, listener, work);
            pendingRequests.put(request, listeners);
        } else {
            if (Logger.VERBOSE) Log.v(TAG, "Reusing request: " + request);
            listeners.add(tag, listener);
        }

        if (tag != null) {
            pendingTags.put(tag, listeners);
        }

        return work;
    }

    public synchronized void cancel(Object tag) {
        cancelPotentialWork(tag);
    }

    protected synchronized void publishProgress(LoaderRequest request, float value) {
        PendingListeners listeners = pendingRequests.get(request);
        if (listeners != null) {
            listeners.publishProgress(value);
        }
    }

    protected synchronized void deliverResult(LoaderRequest request, Bitmap b, Metadata metadata) {
        PendingListeners listeners = removeRequest(request);
        if (listeners != null) {
            saveToMemoryCache(request, b, metadata);

            listeners.deliverResult(b);
        }
    }

    protected synchronized void deliverError(LoaderRequest request, Throwable t) {
        PendingListeners listeners = removeRequest(request);
        if (listeners != null) {
            listeners.deliverError(t);
        }
    }

    private PendingListeners removeRequest(LoaderRequest request) {
        PendingListeners listeners = pendingRequests.remove(request);
        if (listeners == null) {
            if (Logger.VERBOSE) Log.v(TAG, "Request no longer pending: " + request);
        } else {
            pendingTags.keySet().removeAll(listeners.getTags());
        }

        return listeners;
    }

    private void cancelPotentialWork(Object tag) {
        PendingListeners listeners = pendingTags.remove(tag);
        if (listeners == null) {
            return;
        }

        listeners.remove(tag);
        if (listeners.isEmpty()) {
            LoaderRequest request = listeners.getRequest();
            pendingRequests.remove(request);
            listeners.cancel();
        }
    }

    private void saveToMemoryCache(LoaderRequest request, Bitmap b, Metadata metadata) {
        if (memoryCache != null) {
            memoryCache.put(request, b, metadata);
        }
    }

    private boolean stillPending(Object tag, LoaderRequest request) {
        PendingListeners listeners = pendingTags.get(tag);

        return listeners != null && request.equals(listeners.getRequest());
     }

    private class RequestListener implements Loader.Listener {
        private LoaderRequest request;

        public RequestListener(LoaderRequest request) {
            this.request = request;
        }

        @Override
        public void onStreamLoaded(InputSupplier input, Metadata metadata) {
            try {
                InputStream is = input.getInput();
                
                try {
                    Bitmap b = BitmapUtils.decodeStream(is);
                    
                    onBitmapLoaded(b, metadata);
                } finally {
                    is.close();
                }
            } catch (IOException e) {
                onError(e);
            }
        }

        @Override
        public void onBitmapLoaded(Bitmap b, Metadata metadata) {
            deliverResult(request, b, metadata);
        }

        @Override
        public void onNotModified(Metadata metadata) {
            // Nothing changed, we don't need to notify any listeners
            memoryCache.updateMetadata(request, metadata);
        }

        @Override
        public void onError(Throwable t) {
            deliverError(request, t);
        }
    }

    private static class PendingListeners {
        private LoaderRequest request;
        private Map<Object, LoaderManager.Listener> listeners;
        private List<LoaderManager.Listener> extraListeners;
        private LoaderWork work;

        public PendingListeners(LoaderRequest request, Object tag, LoaderManager.Listener listener, LoaderWork work) {
            this.request = request;
            this.work = work;

            // Use a WeakHashMap to ensure tags can be GC'd, also use 1 a initial
            // capacity as we expect a low number of listeners per request
            listeners = new WeakHashMap<Object, LoaderManager.Listener>(1);
            extraListeners = new ArrayList<LoaderManager.Listener>(1);

            add(tag, listener);
        }

        public void add(Object tag, LoaderManager.Listener listener) {
            if (tag == null) {
                extraListeners.add(listener);
            } else {
                listeners.put(tag, listener);
            }
        }

        public void remove(Object tag) {
            listeners.remove(tag);
        }

        public boolean isEmpty() {
            return listeners.isEmpty() && extraListeners.isEmpty();
        }

        public void cancel() {
            work.cancel();
        }

        public LoaderRequest getRequest() {
            return request;
        }

        public Set<Object> getTags() {
            return listeners.keySet();
        }

        public void publishProgress(float value) {
            for (LoaderManager.Listener listener : listeners.values()) {
                listener.onProgress(value);
            }

            for (LoaderManager.Listener listener : extraListeners) {
                listener.onProgress(value);
            }
        }

        public void deliverResult(Bitmap b) {
            for (LoaderManager.Listener listener : listeners.values()) {
                listener.onLoaded(b);
            }

            for (LoaderManager.Listener listener : extraListeners) {
                listener.onLoaded(b);
            }
        }

        public void deliverError(Throwable t) {
            for (LoaderManager.Listener listener : listeners.values()) {
                listener.onError(t);
            }

            for (LoaderManager.Listener listener : extraListeners) {
                listener.onError(t);
            }
        }


    }
}




Java Source Code List

com.webimageloader.ConnectionFactory.java
com.webimageloader.ConnectionHandler.java
com.webimageloader.Constants.java
com.webimageloader.ImageLoaderImpl.java
com.webimageloader.ImageLoader.java
com.webimageloader.Request.java
com.webimageloader.content.ContentURLConnection.java
com.webimageloader.content.ContentURLStreamHandler.java
com.webimageloader.ext.ImageHelper.java
com.webimageloader.ext.ImageLoaderApplication.java
com.webimageloader.loader.BackgroundLoader.java
com.webimageloader.loader.DiskLoader.java
com.webimageloader.loader.LoaderManager.java
com.webimageloader.loader.LoaderRequest.java
com.webimageloader.loader.LoaderWork.java
com.webimageloader.loader.Loader.java
com.webimageloader.loader.MemoryCache.java
com.webimageloader.loader.MemoryLoader.java
com.webimageloader.loader.Metadata.java
com.webimageloader.loader.NetworkLoader.java
com.webimageloader.loader.PendingRequests.java
com.webimageloader.loader.SimpleBackgroundLoader.java
com.webimageloader.loader.TransformingLoader.java
com.webimageloader.sample.AsyncLoader.java
com.webimageloader.sample.ExampleApplication.java
com.webimageloader.sample.FastImageView.java
com.webimageloader.sample.MainActivity.java
com.webimageloader.sample.numbers.NumberDetailsActivity.java
com.webimageloader.sample.numbers.NumbersActivity.java
com.webimageloader.sample.patterns.PatternDetailsActivity.java
com.webimageloader.sample.patterns.PatternsActivity.java
com.webimageloader.sample.patterns.PatternsListFragment.java
com.webimageloader.sample.progress.ProgressActivity.java
com.webimageloader.transformation.ScaleTransformation.java
com.webimageloader.transformation.SimpleTransformation.java
com.webimageloader.transformation.Transformation.java
com.webimageloader.util.AbstractImageLoader.java
com.webimageloader.util.Android.java
com.webimageloader.util.BitmapUtils.java
com.webimageloader.util.FlushedInputStream.java
com.webimageloader.util.Hasher.java
com.webimageloader.util.HeaderParser.java
com.webimageloader.util.IOUtil.java
com.webimageloader.util.InputSupplier.java
com.webimageloader.util.ListenerFuture.java
com.webimageloader.util.LruCache.java
com.webimageloader.util.PriorityThreadFactory.java
com.webimageloader.util.WaitFuture.java