Android Open Source - photogallery Thumbnail Downloader






From Project

Back to project page photogallery.

License

The source code is released under:

Apache License

If you think the Android project photogallery 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.donnemartin.android.photogallery;
/*from  w  w w  .  j av  a2s . c o  m*/
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import android.annotation.SuppressLint;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.util.Log;
import android.widget.ImageView;

public class ThumbnailDownloader extends HandlerThread {
    // Class to download thumbnails on demand to avoid isses when there is
    // a slow connection or a large number of thumbnails stored in memory
    // AsyncTask is the easiest way to get a background thread, but it is
    // not well suited for repetitive and long-running work.

    private static final String TAG = "ThumbnailDownloader";
    private static final int MESSAGE_DOWNLOAD = 0;

    Handler mHandler;
    // Synchronized hash map.  Using Token as a key, store and retrieve the
    // URL associated with a particular Token.
    Map<ImageView,String> requestMap =
            Collections.synchronizedMap(new HashMap<ImageView,String>());
    Handler mResponseHandler;
    Listener<ImageView> mListener;

    public interface Listener<ImageView> {
        // Add a Listener interface to communicate the responses with
        void onThumbnailDownloaded(ImageView imageView, Bitmap thumbnail);
    }

    public void setListener(Listener<ImageView> listener) {
        mListener = listener;
    }

    public ThumbnailDownloader(Handler responseHandler) {
        super(TAG);
        mResponseHandler = responseHandler;
    }

    // Suppress warnings about subclassing Handler.
    // The handler will be kept alive by its Looper.  If your handler is an
    // anonymous inner class, it is easy to leak memory accidentally through an
    // implicit object reference.  However, everything here is tied to the
    // HandlerThread so there is no danger of leaking anything
    @SuppressLint("HandlerLeak")
    @Override
    protected void onLooperPrepared() {
        // onLooperPrepared is called before the Looper checks the queue
        // for the first time, a good place to create a Handler implementation
        mHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                if (msg.what == MESSAGE_DOWNLOAD) {
                    // Necessary because Token is a generic class argument but
                    // Message.obj is an Object.  Type erasure makes it
                    // impossible to make this cast
                    @SuppressWarnings("unchecked")
                    ImageView imageView = (ImageView)msg.obj;
                    Log.i(TAG,
                      "Got a request for url: " + requestMap.get(imageView));
                    handleRequest(imageView);
                }
            }
        };
    }

    private void handleRequest(final ImageView imageView) {
        // Use FlickrConn to download bytes from the URL and turn them
        // into a bitmap
        try {
            final String url = requestMap.get(imageView);
            if (url != null) {
                byte[] bitmapBytes = new FlickrConn().getUrlBytes(url);

                // Create a BitmapFactory to construct a bitmap with the array
                // of bytes
                final Bitmap bitmap = BitmapFactory
                        .decodeByteArray(bitmapBytes, 0, bitmapBytes.length);

                // Send a custom message back to the main thread
                // When a Message has its callback field set, instead of being
                // rn by its Handler target, the Runnable in callback is run
                // instead.  Because mResponseHandler is associated with the
                // main thread's Looper, this UI update code will be run on the
                // main thread
                mResponseHandler.post(new Runnable() {
                    public void run() {
                        // Double check the requestMap because the GridView
                        // recycles its views to ensure the Token gets the
                        // correct image, even if another request has been
                        // made in the meantime
                        String urlStored = requestMap.get(imageView);
                        if (urlStored != null && urlStored.equals(url)) {
                            // Remove this token since we have handled it
                            requestMap.remove(imageView);
                            // Set the bitmap on the token
                            mListener.onThumbnailDownloaded(imageView, bitmap);
                        }
                    }
                });
            }
        } catch (IOException ioe) {
            Log.e(TAG, "Error downloading image", ioe);
        }
    }

    public void queueThumbnail(ImageView imageView, String url) {
        requestMap.put(imageView, url);

        // Build the message using obtainMessage rather than building it by hand
        // ObtainMessage pulls from a common recycling pool to avoid creating
        // new message objects
        mHandler
            .obtainMessage(MESSAGE_DOWNLOAD, imageView)
            .sendToTarget();
    }

    public void clearQueue() {
        // If the user rotates the screen, ThumbnailDownloader might have an
        // invalid ImageView.  Clean all requests out of the queue.
        mHandler.removeMessages(MESSAGE_DOWNLOAD);
        requestMap.clear();
    }
}




Java Source Code List

com.donnemartin.android.photogallery.Creds.java
com.donnemartin.android.photogallery.FlickrConn.java
com.donnemartin.android.photogallery.GalleryItem.java
com.donnemartin.android.photogallery.NotificationReceiver.java
com.donnemartin.android.photogallery.PhotoGalleryActivity.java
com.donnemartin.android.photogallery.PhotoGalleryFragment.java
com.donnemartin.android.photogallery.PhotoPageActivity.java
com.donnemartin.android.photogallery.PhotoPageFragment.java
com.donnemartin.android.photogallery.PollService.java
com.donnemartin.android.photogallery.SingleFragmentActivity.java
com.donnemartin.android.photogallery.StartupReceiver.java
com.donnemartin.android.photogallery.ThumbnailDownloader.java
com.donnemartin.android.photogallery.VisibleFragment.java