Android Open Source - WebImageView Image Loader






From Project

Back to project page WebImageView.

License

The source code is released under:

MIT License

If you think the Android project WebImageView 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.rsv.comp;
/*from w  ww .  jav  a  2 s. c o m*/
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import org.apache.http.client.ClientProtocolException;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

import com.rsv.cache.LmtSizeMemCache;
import com.rsv.cache.LmtSpaceFileCache;
import com.rsv.config.ConfigReader;
import com.rsv.utils.HttpClientUtils;
import com.rsv.utils.LogUtils;
import com.rsv.utils.StorageUtils;

/**
 * 
 * Fetch the image data and cache
 * 
 */
public class ImageLoader {

  private static final Map<Context, ImageLoader> pool = Collections
      .synchronizedMap(new HashMap<Context, ImageLoader>());

  private static final Map<String, Object> imgUrlLock = Collections
      .synchronizedMap(new HashMap<String, Object>());

  private final LmtSpaceFileCache fileCache;

  private final LmtSizeMemCache<Bitmap> memCache;

  private final String userAgent;

  public synchronized static ImageLoader getImageLoader(final Context cxt) throws Exception {

    final Context appContext = cxt.getApplicationContext();

    ImageLoader obj = pool.get(appContext);

    if (obj == null) {

      String subdir = ConfigReader.getImageCacheDir(appContext);

      File cacheDir;

      switch (ConfigReader.getImageCacheStorage(appContext)) {

        case INTERNAL:
          cacheDir = new File(appContext.getApplicationContext().getCacheDir(), subdir);
          break;

        default:
          if (StorageUtils.isExternalStorageWritable()) {

            cacheDir = StorageUtils.getExternalCacheDirectory(appContext
                .getApplicationContext().getPackageName(), subdir);

          } else {
            throw new Exception("ExternalStorage is not writable");
          }
      }

      if (!cacheDir.exists()) {
        cacheDir.mkdirs();
      }

      if (!cacheDir.canWrite()) {
        throw new Exception("WebImageCache dir is not writable: "
            + cacheDir.getCanonicalPath());
      }

      obj = new ImageLoader(appContext, cacheDir.getCanonicalPath());

      pool.put(appContext, obj);

    }
    return obj;

  }

  private ImageLoader(final Context context, final String dir) {

    int cacheSpace = (int) (ConfigReader.getImageCacheSpaceInMB(context) * 1024 * 1024);

    int memorySizeLimit = ConfigReader.getImageMemorySizeLimit(context);

    this.userAgent = ConfigReader.getUseragentForImageLoader(context);

    this.fileCache = new LmtSpaceFileCache(new File(dir), cacheSpace);

    this.memCache = new LmtSizeMemCache<Bitmap>(memorySizeLimit);

    LogUtils.i(this, String.format(
        "ImageLoader: memsize:%d, filespace:%d, dir: %s, useragent:%s", memorySizeLimit,
        cacheSpace, dir, this.userAgent));
  }

  private Bitmap loadImgFromMem(String url) {
    Bitmap bm = memCache != null ? memCache.get(url) : null;

    if (bm != null) {
      LogUtils.i(this, "memcache got: " + url);
    }

    return bm;
  }

  /**
   * Clear from memory
   */
  public void clearMemcache() {
    if (this.memCache != null)
      this.memCache.clear();
  }

  /**
   * Clear file cache
   * 
   */
  public void clearFilecache() {
    this.fileCache.clear();
  }

  /**
   * Download an image to the file cache dir
   * 
   * @param url
   * @param downloadProgressListener
   * @return
   * @throws IOException
   */
  public Bitmap downloadImg(final String url, long expireInSecs,
      final IProgressListener downloadProgressListener) throws IOException {

    Bitmap bm;

    bm = this.tryGetFromMem(url, expireInSecs, downloadProgressListener);

    if (bm != null)
      return bm;

    Object urlLock = getUrlLock(url);

    synchronized (urlLock) {

      try {

        bm = this.doFetchImage(url, expireInSecs, downloadProgressListener);

      } finally {

        removeUrlLock(url);
      }
    }

    return bm;
  }

  private static void removeUrlLock(String url) {
    imgUrlLock.remove(url);
  }

  private static synchronized Object getUrlLock(String url) {

    if (imgUrlLock.containsKey(url))
      return imgUrlLock.get(url);

    Object lock = new Object();

    imgUrlLock.put(url, lock);

    return lock;
  }

  /**
   * Get the image from file cache or just download
   * 
   * @param url
   * @param downloadProgressListener
   * @return
   * @throws ClientProtocolException
   * @throws IOException
   */
  private Bitmap doFetchImage(final String url, long expireInSecs,
      final IProgressListener downloadProgressListener) throws ClientProtocolException,
      IOException {

    Bitmap bm = this.tryGetFromMem(url, expireInSecs, downloadProgressListener);

    if (bm != null)
      return bm;

    // get the file
    File file = fileCache.get(url);

    if (file != null) {

      if (expireInSecs >= 0
          && System.currentTimeMillis() - file.lastModified() > expireInSecs * 1000) {

        LogUtils.i(this, "file expired: " + url);

        file = null;
      }
    }

    if (file == null) {

      file = fileCache.getTargetFile(url);

      if (HttpClientUtils.downloadToFile(url, file, this.userAgent, downloadProgressListener)) {

        fileCache.put(url, file);

      }

    } else {
      LogUtils.i(this, "filecache got: " + url);
    }

    if (file != null && file.exists()) {

      FileInputStream is = null;

      try {
        is = new FileInputStream(file);

        bm = BitmapFactory.decodeStream(is);

      } catch (FileNotFoundException e) {
        LogUtils.logException(e);

        throw e;

      } finally {
        if (is != null) {
          try {
            is.close();
          } catch (IOException e) {
            LogUtils.logException(e);
          }
        }
      }
    }

    if (bm != null) {
      if (memCache != null) {

        // only cache the one never expired
        if (expireInSecs < 0) {
          memCache.put(url, bm);
        }
      }
    }

    return bm;
  }

  /**
   * Try get the image data from memory
   * 
   * @param url
   * @param downloadProgressListener
   * @return
   */
  public Bitmap tryGetFromMem(final String url, long expireInSecs,
      final IProgressListener downloadProgressListener) {

    // no mem cache if expireInSecs set
    if (expireInSecs >= 0)
      return null;

    Bitmap bm = this.loadImgFromMem(url);

    if (bm != null) {

      if (downloadProgressListener != null)
        downloadProgressListener.reportProgress(100);

      return bm;
    }

    return bm;
  }
}




Java Source Code List

com.rsv.cache.BaseFileCache.java
com.rsv.cache.BaseMemCache.java
com.rsv.cache.LmtSizeMemCache.java
com.rsv.cache.LmtSpaceFileCache.java
com.rsv.comp.IProgressListener.java
com.rsv.comp.ImageLoader.java
com.rsv.config.ConfigReader.java
com.rsv.config.Constants.java
com.rsv.utils.FileUtils.java
com.rsv.utils.HttpClientUtils.java
com.rsv.utils.IOUtils.java
com.rsv.utils.ImgUtils.java
com.rsv.utils.LogUtils.java
com.rsv.utils.OSUtils.java
com.rsv.utils.StorageUtils.java
com.rsv.widget.WebImageView.java