Android Open Source - GreenDroid Image Loader






From Project

Back to project page GreenDroid.

License

The source code is released under:

Apache License

If you think the Android project GreenDroid 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

/*
 * Copyright (C) 2010 Cyril Mottier (http://www.cyrilmottier.com)
 *// w w w.j  a  v a2s .c o m
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package greendroid.image;

import greendroid.util.Config;
import greendroid.util.GDUtils;

import java.io.InputStream;
import java.net.URL;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;

import android.content.Context;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Message;
import android.os.Process;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;

/**
 * An ImageLoader asynchronously loads image from a given url. Client may be
 * notified from the current image loading state using the
 * {@link ImageLoaderCallback}.
 * <p>
 * <em><strong>Note: </strong>You normally don't need to use the {@link ImageLoader}
 * class directly in your application. You'll generally prefer using an
 * {@link ImageRequest} that takes care of the entire loading process.</em>
 * </p>
 * 
 * @author Cyril Mottier
 */
public class ImageLoader {

    private static final String LOG_TAG = ImageLoader.class.getSimpleName();

    /**
     * @author Cyril Mottier
     */
    public static interface ImageLoaderCallback {

        void onImageLoadingStarted(ImageLoader loader);

        void onImageLoadingEnded(ImageLoader loader, Bitmap bitmap);

        void onImageLoadingFailed(ImageLoader loader, Throwable exception);
    }

    private static final int ON_START = 0x100;
    private static final int ON_FAIL = 0x101;
    private static final int ON_END = 0x102;
    
    private static ImageCache sImageCache;
    private static ExecutorService sExecutor;
    private static BitmapFactory.Options sDefaultOptions;
    private static AssetManager sAssetManager;

    public ImageLoader(Context context) {
        if (sImageCache == null) {
            sImageCache = GDUtils.getImageCache(context);
        }
        if (sExecutor == null) {
            sExecutor = GDUtils.getExecutor(context);
        }
        if (sDefaultOptions == null) {
          sDefaultOptions = new BitmapFactory.Options();
          sDefaultOptions.inDither = true;
          sDefaultOptions.inScaled = true;
          sDefaultOptions.inDensity = DisplayMetrics.DENSITY_MEDIUM;
          sDefaultOptions.inTargetDensity = context.getResources().getDisplayMetrics().densityDpi;
        }
        sAssetManager = context.getAssets();
    }

    public Future<?> loadImage(String url, ImageLoaderCallback callback) {
        return loadImage(url, callback, null);
    }

    public Future<?> loadImage(String url, ImageLoaderCallback callback, ImageProcessor bitmapProcessor) {
        return loadImage(url, callback, bitmapProcessor, null);
    }
    
    public Future<?> loadImage(String url, ImageLoaderCallback callback, ImageProcessor bitmapProcessor, BitmapFactory.Options options) {
        return sExecutor.submit(new ImageFetcher(url, callback, bitmapProcessor, options));
    }

    private class ImageFetcher implements Runnable {

        private String mUrl;
        private ImageHandler mHandler;
        private ImageProcessor mBitmapProcessor;
        private BitmapFactory.Options mOptions;

        public ImageFetcher(String url, ImageLoaderCallback callback, ImageProcessor bitmapProcessor, BitmapFactory.Options options) {
            mUrl = url;
            mHandler = new ImageHandler(url, callback);
            mBitmapProcessor = bitmapProcessor;
            mOptions = options;
        }

        public void run() {

            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);

            final Handler h = mHandler;
            Bitmap bitmap = null;
            Throwable throwable = null;

            h.sendMessage(Message.obtain(h, ON_START));

            try {

                if (TextUtils.isEmpty(mUrl)) {
                    throw new Exception("The given URL cannot be null or empty");
                }
                
                InputStream inputStream = null;
                
                if (mUrl.startsWith("file:///android_asset/")) {
                    inputStream = sAssetManager.open(mUrl.replaceFirst("file:///android_asset/", ""));
                } else {
                    inputStream = new URL(mUrl).openStream();
                }

                // TODO Cyril: Use a AndroidHttpClient?
                bitmap = BitmapFactory.decodeStream(inputStream, null, (mOptions == null) ? sDefaultOptions : mOptions);
                
                if (mBitmapProcessor != null && bitmap != null) {
                    final Bitmap processedBitmap = mBitmapProcessor.processImage(bitmap);
                    if (processedBitmap != null) {
                        bitmap = processedBitmap;
                    }
                }

            } catch (Exception e) {
                // An error occured while retrieving the image
                if (Config.GD_ERROR_LOGS_ENABLED) {
                    Log.e(LOG_TAG, "Error while fetching image", e);
                }
                throwable = e;
            }

            if (bitmap == null) {
                if (throwable == null) {
                    // Skia returned a null bitmap ... that's usually because
                    // the given url wasn't pointing to a valid image
                    throwable = new Exception("Skia image decoding failed");
                }
                h.sendMessage(Message.obtain(h, ON_FAIL, throwable));
            } else {
                h.sendMessage(Message.obtain(h, ON_END, bitmap));
            }
        }
    }

    private class ImageHandler extends Handler {

        private String mUrl;
        private ImageLoaderCallback mCallback;

        private ImageHandler(String url, ImageLoaderCallback callback) {
            mUrl = url;
            mCallback = callback;
        }

        @Override
        public void handleMessage(Message msg) {

            switch (msg.what) {

                case ON_START:
                    if (mCallback != null) {
                        mCallback.onImageLoadingStarted(ImageLoader.this);
                    }
                    break;

                case ON_FAIL:
                    if (mCallback != null) {
                        mCallback.onImageLoadingFailed(ImageLoader.this, (Throwable) msg.obj);
                    }
                    break;

                case ON_END:

                    final Bitmap bitmap = (Bitmap) msg.obj;
                    sImageCache.put(mUrl, bitmap);

                    if (mCallback != null) {
                        mCallback.onImageLoadingEnded(ImageLoader.this, bitmap);
                    }
                    break;

                default:
                    super.handleMessage(msg);
                    break;
            }
        };
    }

}




Java Source Code List

com.cyrilmottier.android.gdcatalog.AboutActivity.java
com.cyrilmottier.android.gdcatalog.ActionBarActivity.java
com.cyrilmottier.android.gdcatalog.AsyncImageViewListActivity.java
com.cyrilmottier.android.gdcatalog.BasicItemActivity.java
com.cyrilmottier.android.gdcatalog.CatalogActivity.java
com.cyrilmottier.android.gdcatalog.CatalogApplication.java
com.cyrilmottier.android.gdcatalog.InfoTabActivity.java
com.cyrilmottier.android.gdcatalog.MapPinMapActivity.java
com.cyrilmottier.android.gdcatalog.PagedViewActivity.java
com.cyrilmottier.android.gdcatalog.QuickActionActivity.java
com.cyrilmottier.android.gdcatalog.SegmentedActivity.java
com.cyrilmottier.android.gdcatalog.SimpleAsyncImageViewActivity.java
com.cyrilmottier.android.gdcatalog.TabbedActionBarActivity.java
com.cyrilmottier.android.gdcatalog.TweakedItemViewActivity.java
com.cyrilmottier.android.gdcatalog.WebContentActivity.java
com.cyrilmottier.android.gdcatalog.XmlItemActivity.java
com.cyrilmottier.android.gdcatalog.widget.HeadedTextItemView.java
com.cyrilmottier.android.gdcatalog.widget.HeadedTextItem.java
greendroid.app.ActionBarActivity.java
greendroid.app.GDActivity.java
greendroid.app.GDApplication.java
greendroid.app.GDExpandableListActivity.java
greendroid.app.GDListActivity.java
greendroid.app.GDMapActivity.java
greendroid.app.GDTabActivity.java
greendroid.graphics.drawable.ActionBarDrawable.java
greendroid.graphics.drawable.DrawableStateSet.java
greendroid.graphics.drawable.MapPinDrawable.java
greendroid.image.ChainImageProcessor.java
greendroid.image.ImageCache.java
greendroid.image.ImageLoader.java
greendroid.image.ImageProcessor.java
greendroid.image.ImageRequest.java
greendroid.image.MaskImageProcessor.java
greendroid.image.ScaleImageProcessor.java
greendroid.util.Config.java
greendroid.util.GDUtils.java
greendroid.util.Md5Util.java
greendroid.util.Time.java
greendroid.widget.ActionBarHost.java
greendroid.widget.ActionBarItem.java
greendroid.widget.ActionBar.java
greendroid.widget.AsyncImageView.java
greendroid.widget.ItemAdapter.java
greendroid.widget.LoaderActionBarItem.java
greendroid.widget.NormalActionBarItem.java
greendroid.widget.PageIndicator.java
greendroid.widget.PagedAdapter.java
greendroid.widget.PagedView.java
greendroid.widget.QuickActionBar.java
greendroid.widget.QuickActionGrid.java
greendroid.widget.QuickActionWidget.java
greendroid.widget.QuickAction.java
greendroid.widget.SegmentedAdapter.java
greendroid.widget.SegmentedBar.java
greendroid.widget.SegmentedHost.java
greendroid.widget.item.DescriptionItem.java
greendroid.widget.item.DrawableItem.java
greendroid.widget.item.Item.java
greendroid.widget.item.LongTextItem.java
greendroid.widget.item.ProgressItem.java
greendroid.widget.item.SeparatorItem.java
greendroid.widget.item.SubtextItem.java
greendroid.widget.item.SubtitleItem.java
greendroid.widget.item.TextItem.java
greendroid.widget.item.ThumbnailItem.java
greendroid.widget.itemview.DescriptionItemView.java
greendroid.widget.itemview.DrawableItemView.java
greendroid.widget.itemview.ItemView.java
greendroid.widget.itemview.LongTextItemView.java
greendroid.widget.itemview.ProgressItemView.java
greendroid.widget.itemview.SeparatorItemView.java
greendroid.widget.itemview.SubtextItemView.java
greendroid.widget.itemview.SubtitleItemView.java
greendroid.widget.itemview.TextItemView.java
greendroid.widget.itemview.ThumbnailItemView.java