ImageCache.java :  » Image » floatingimage » dk » nindroid » rss » Android Open Source

Android Open Source » Image » floatingimage 
floatingimage » dk » nindroid » rss » ImageCache.java
package dk.nindroid.rss;

import java.io.BufferedInputStream;
import java.io.DataInputStream;
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.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Bitmap.CompressFormat;
import android.os.Environment;
import android.util.Log;
import dk.nindroid.rss.data.FileDateReverseComparator;
import dk.nindroid.rss.data.ImageReference;

public class ImageCache {
  TextureBank bank;
  private final String   mExploreFolder;
  private final String   mExploreInfoFolder;
  List<File>        mFiles;
  Map<String, Integer>  mCached;
  Random           mRand;
  File           mExplore;
  File           mExploreInfo;
  byte[]          mBuf;
  Context          mContext;
  
  public ImageCache(Context context, TextureBank bank){
    this.bank = bank;
    this.mContext = context;
    mBuf = new byte[1024];
    String datafolder = mContext.getString(R.string.dataFolder);
    datafolder = Environment.getExternalStorageDirectory().getAbsolutePath() + datafolder;
    mExploreInfoFolder = datafolder + context.getString(R.string.exploreFolder);
    mExploreFolder = mExploreInfoFolder + "/bmp";
  }
  
  void setupImageCache(){
    mRand = new Random(new Date().getTime());
    mExploreInfo = new File(mExploreInfoFolder);
    mExplore = new File(mExploreFolder);
    mExploreInfo.mkdirs(); // Make dir if not exists
    mExplore.mkdirs(); // Make dir if not exists
    File[] exploreInfoArray = mExploreInfo.listFiles();
    if(exploreInfoArray == null) return;
    mFiles = new ArrayList<File>(exploreInfoArray.length);
    mCached = new HashMap<String, Integer>(exploreInfoArray.length);
    Log.v("Floating Image", exploreInfoArray.length + " files in cache.");
    for(int i = 0; i < exploreInfoArray.length; ++i){
      File f = exploreInfoArray[i];
      if(f == null) break;
      if(!f.isDirectory()){
        addFile(f);
      }
    }
  }
  
  /*
  public void run(){
    if(mExploreFiles == null) return;
    while(true){
      if(bank.stopThreads) return;
      while(bank.cached.size() < 5 && !mExploreFiles.isEmpty()){
        if(bank.stopThreads) return;
        bank.addOldBitmap(getRandomExplore());
      }
      try {
        synchronized (bank.cached) {
          bank.cached.wait();
        }
      } catch (InterruptedException e) {
        Log.v("Bitmap downloader", "*** Stopping asynchronous cache thread", e);
        return;
      }
    }
  }
  */
  // Will not delete directory, just fail when trying to...
  public void cleanCache(){
    try{
      int limit = 500;
      File[] files = mExploreInfo.listFiles();
      if(files == null || files.length < limit) return;
      
      Arrays.sort(files, new FileDateReverseComparator());
      int size = files.length;
      for(int i = size - 1; i > limit; --i){
        try{
          InputStream is_info = new FileInputStream(files[i]);
          BufferedInputStream bis_info = new BufferedInputStream(is_info, 64);
          DataInputStream dis = new DataInputStream(bis_info);
          File img = new File(dis.readLine());
          img.delete();
          files[i].delete();
          files[i] = null;
          dis.close();
          bis_info.close();
        }catch(NullPointerException e){
          Log.w("Floating Image", "Unexpected null pointer exception caught.", e);
          files[i].delete();
          files[i] = null;
        }
      }
      synchronized(mFiles){
        mFiles.clear();
      }
      int entries = Math.min(limit, files.length);
      synchronized(mFiles){
        for(int i = 0; i < entries; ++i){
          addFile(files[i]);
        }
      }
    }catch(Exception e){
      Log.w("Floating Image", "Error removing old images...", e);
    }
  }
  
  public void saveImage(ImageReference ir){
    if(mFiles == null){
      setupImageCache();
    }
    if(ir == null) return;
    String name = ir.getID();
    if(exists(name)) return;
    try {      
      File f = new File(mExplore.getPath() + "/" + name + ".jpg");
      FileOutputStream fos = new FileOutputStream(f);
      ir.getBitmap().compress(CompressFormat.JPEG, 85, fos);
      fos.flush();
      fos.close();
      File f_info = updateMeta(ir);
      if(f_info == null){
        f.delete();
      }else{
        synchronized(mFiles){
          addFile(f_info);
          mCached.put(f_info.getName(), mFiles.size() - 1);
        }
      }
    } catch (FileNotFoundException e) {
      Log.w("Floating Image", "Image could not be cached", e);
      return;
    } catch (IOException e) {
      Log.w("Floating Image", "Image could not be cached", e);
      return;
    }
  }
  
  public File updateMeta(ImageReference ir){
    try {
      String name = ir.getID();
      String thumbPath = mExplore.getPath() + "/" + name + ".jpg";
      File f_info = new File(mExploreInfo.getPath() + "/" + name + ".info");
      f_info.delete();
      FileOutputStream fos_info = new FileOutputStream(f_info);
      fos_info.write((thumbPath + "\n" + ir.getInfo()).getBytes());
      fos_info.flush();
      fos_info.close();
      return f_info;
    } catch (FileNotFoundException e) {
      Log.w("Floating Image", "Image could not be cached", e);
      return null;
    } catch (IOException e) {
      Log.w("Floating Image", "Image could not be cached", e);
      return null;
    }
  }
  
  protected void addFile(File file){
    mFiles.add(file);
    mCached.put(file.getName(), mFiles.size() - 1);
  }
  /*
  public ImageReference getRandomExplore(){
    if(mExploreFiles.size() == 0 || (!mActive || !Settings.useCache)){
      try {
        Thread.sleep(10000);   // Sleep for a bit, we're not doing anything anyway...
                    // TODO: Make this wait() instead!
      } catch (InterruptedException e) {
        Log.w("ImageCache", "We were interrupted!");
      }
      return null;
    }
    Log.v("Image cache", "Adding random cached image");
    return getFile(mRand.nextInt(mExploreFiles.size()));
  }
  */
  public ImageReference getFile(int index, ImageReference ir){
    File f_info = null;
    try {
      f_info = mFiles.get(index);
      int length = (int)f_info.length();
      InputStream is_info = new FileInputStream(f_info);
      if(mBuf.length < length){
        mBuf = new byte[length];
      }
      is_info.read(mBuf);
      is_info.close();
      String s = new String(mBuf, 0, length, "UTF-8");
      String[] tokens = s.split("\n");
      
      String bmpName = tokens[0];
      if(bmpName == null){
        f_info.delete();
        mCached.remove(mFiles.get(index));
        mFiles.set(index, null);
        //return getRandomExplore();
        return null;
      }
      // Read bitmap
      Bitmap bmp = BitmapFactory.decodeFile(bmpName);
      
      // Fill image reference
      ir.parseInfo(tokens, bmp);
      
      // Clean up
      return ir;
    } catch (FileNotFoundException e) {
      if(f_info != null){
        f_info.delete();
        synchronized(mFiles){
          mCached.remove(mFiles.get(index));
          mFiles.set(index, null);
        }
      }
      Log.w("Floating Image", "Image cache file not found: " + e);
    } catch (IOException e) {
      Log.w("Floating Image", "IOException reading Image cache!", e);
    }
    return null;
  }
  
  public boolean exists(String name){
    if(mFiles == null) return false;
    synchronized(mFiles){
      if(mCached.containsKey(name + ".info")){
        return true;
      }
      return false;
    }
  }
  
  public void addImage(ImageReference ir, boolean next){
    bank.addBitmap(getFile(mCached.get(ir.getID() + ".info"), ir), false, next);
  }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.