Android Open Source - RecyclingImageLoader Image Loader






From Project

Back to project page RecyclingImageLoader.

License

The source code is released under:

Apache License

If you think the Android project RecyclingImageLoader 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 2013 hellosky ye//w  w w .j  ava  2  s  .  co  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 com.hellosky.recyclingimageloader.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Collections;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.widget.ImageView;

import com.hellosky.recyclingimageloader.R;

public class ImageLoader {

  ImageMemoryCache memoryCache = new ImageMemoryCache();
  ImageFileCache fileCache;
  int stub_id = R.drawable.empty_photo;
  private Map<ImageView, String> imageViews = Collections
      .synchronizedMap(new WeakHashMap<ImageView, String>());
  ExecutorService executorService;
  private Context mContext;
  protected int mImageWidth;
    protected int mImageHeight;

  public ImageLoader(Context context) {
    fileCache = new ImageFileCache(context);
    executorService = Executors.newFixedThreadPool(5);
    mContext = context;
  }
  
  public void setLoadingImage(int resId) {
    stub_id = resId;
    }

  
  public void displayImage(String url, ImageView imageView) {
    try{
      imageViews.put(imageView, url);
      //get Drawable from memory cache
      BitmapDrawable bitmap = memoryCache.get(url);
      if (bitmap != null)
        imageView.setImageDrawable(bitmap);
      else {
        //download image 
        queuePhoto(url, imageView);
        imageView.setImageResource(stub_id);
      }
    }catch(OutOfMemoryError e){
      e.printStackTrace();
    }catch(Exception e){
      e.printStackTrace();
    }
  }
  
  public void setImageSize(int size) {
        setImageSize(size, size);
    }
  
  public void setImageSize(int width, int height) {
        mImageWidth = width;
        mImageHeight = height;
    }

  private void queuePhoto(String url, ImageView imageView) {
    PhotoToLoad p = new PhotoToLoad(url, imageView);
    executorService.submit(new PhotosLoader(p));
  }

  private BitmapDrawable getBitmap(String url) {
    if(url==null || url.length()==0)return null;
    File f = fileCache.getFile(url);

    BitmapDrawable drawable = null;
    // get Bitmap from local file
    Bitmap b = decodeSampledBitmapFromFile(f.getAbsolutePath(), mImageWidth, mImageHeight);//decodeFile(f);
    if (b != null) {
            drawable = new RecyclingBitmapDrawable(mContext.getResources(), b);
            return drawable;
        }

    //download file
    try {
      Bitmap bitmap = null;
      URL imageUrl = new URL(url);
      HttpURLConnection conn = (HttpURLConnection) imageUrl
          .openConnection();
      conn.setConnectTimeout(30000);
      conn.setReadTimeout(30000);
      conn.setInstanceFollowRedirects(true);
      InputStream is = conn.getInputStream();
      OutputStream os = new FileOutputStream(f);
      CopyStream(is, os);
      os.close();
      bitmap = decodeSampledBitmapFromFile(f.getAbsolutePath(), mImageWidth, mImageHeight);//decodeFile(f);
      if (bitmap != null) {
        drawable = new RecyclingBitmapDrawable(mContext.getResources(), bitmap);
            }
      return drawable;
    } catch (Exception ex) {
      ex.printStackTrace();
      return null;
    }
  }

  // Task for the queue
  private class PhotoToLoad {
    public String url;
    public ImageView imageView;

    public PhotoToLoad(String u, ImageView i) {
      url = u;
      imageView = i;
    }
  }

  class PhotosLoader implements Runnable {
    PhotoToLoad photoToLoad;

    PhotosLoader(PhotoToLoad photoToLoad) {
      this.photoToLoad = photoToLoad;
    }

    @Override
    public void run() {
      try{
        android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);
      }catch(Exception e){
        e.printStackTrace();
      }
      if (imageViewReused(photoToLoad))
        return;
      BitmapDrawable drawable = getBitmap(photoToLoad.url);
      if (memoryCache != null && drawable != null) {
              memoryCache.put(photoToLoad.url, drawable);
            }
      //memoryCache.put(photoToLoad.url, bmp);
      if (imageViewReused(photoToLoad))
        return;
      BitmapDisplayer bd = new BitmapDisplayer(drawable, photoToLoad);
      // show the image in UI thread
      Activity a = (Activity) photoToLoad.imageView.getContext();
      a.runOnUiThread(bd);
    }
  }

  boolean imageViewReused(PhotoToLoad photoToLoad) {
    String tag = imageViews.get(photoToLoad.imageView);
    if (tag == null || !tag.equals(photoToLoad.url))
      return true;
    return false;
  }

  class BitmapDisplayer implements Runnable {
    BitmapDrawable bitmap;
    PhotoToLoad photoToLoad;

    public BitmapDisplayer(BitmapDrawable b, PhotoToLoad p) {
      bitmap = b;
      photoToLoad = p;
    }

    public void run() {
      if (imageViewReused(photoToLoad))
        return;
      if (bitmap != null)
        photoToLoad.imageView.setImageDrawable(bitmap);
      else
        photoToLoad.imageView.setImageResource(stub_id);
    }
  }

  public void clearCache() {
    memoryCache.clear();
    fileCache.clear();
  }

  public static void CopyStream(InputStream is, OutputStream os) {
    final int buffer_size = 1024;
    try {
      byte[] bytes = new byte[buffer_size];
      for (;;) {
        int count = is.read(bytes, 0, buffer_size);
        if (count == -1)
          break;
        os.write(bytes, 0, count);
      }
    } catch (Exception ex) {
    }
  }
  
  public static synchronized Bitmap decodeSampledBitmapFromFile(
      String filename, int reqWidth, int reqHeight) {

    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(filename, options);

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth,
        reqHeight);

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeFile(filename, options);
  }
  
  public static int calculateInSampleSize(BitmapFactory.Options options,
      int reqWidth, int reqHeight) {
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;

    if (height > reqHeight || width > reqWidth) {
      if (width > height) {
        inSampleSize = Math.round((float) height / (float) reqHeight);
      } else {
        inSampleSize = Math.round((float) width / (float) reqWidth);
      }

      final float totalPixels = width * height;

      // Anything more than 2x the requested pixels we'll sample down
      // further.
      final float totalReqPixelsCap = reqWidth * reqHeight * 2;

      while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) {
        inSampleSize++;
      }
    }
    return inSampleSize;
  }
}




Java Source Code List

com.hellosky.recyclingimageloader.ImageDetailActivity.java
com.hellosky.recyclingimageloader.ImageDetailFragment.java
com.hellosky.recyclingimageloader.ImageGridActivity.java
com.hellosky.recyclingimageloader.ImageGridFragment.java
com.hellosky.recyclingimageloader.Images.java
com.hellosky.recyclingimageloader.SampleActivity.java
com.hellosky.recyclingimageloader.util.ImageFileCache.java
com.hellosky.recyclingimageloader.util.ImageLoader.java
com.hellosky.recyclingimageloader.util.ImageMemoryCache.java
com.hellosky.recyclingimageloader.util.RecyclingBitmapDrawable.java
com.hellosky.recyclingimageloader.util.Utils.java