android缓存工具类

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import android.graphics.Bitmap;
 
/**
  * <p>Bitmap缓存池</p>
  *
  * <p>基于2Q改进算法缓存</p>
  * <p>http://www.vldb.org/conf/1994/P439.PDF</p>
  *
  * 使用:
  *    LCache static lCache = new LCache();
  *   
  *    ...
  *   
  *   
  *    String imgUrl = "http://monstar.ch/uploads/img/201212/22085340_Zun9.jpg";
  *    if(lCache.isCached(imgUrl)){
  *        Bitmap tBitmap = lCache.get(imgUrl);
  *    }else{
  *        //从服务端获取图像
  *        Bitmap tBitmap = 服务端获取的Bitmap
  *        
  *        lCache.put(imgUrl,tBitmap);
  *    }
  *
  * @author lei.guoting
  */
public class LCache{
        private static final int DEFAULT_MAX_SIZE = ( int )( 1024 * 1024 * 3 .5f);       //默认缓存池大小  3.5M
        private static final int DEFAULT_IN_QUEUE_MAX_SIZE = 40 ;                     //fInCacheQue队列默认大小
        private static final int DEFAULT_OUT_QUEUE_MAX_SIZE = 60 ;                   //fOutCacheQue队列默认大小
        private static final int DEFAULT_CACHE_QUEUE_MAX_SIZE = 0 ;                   //finalCacheQue队列默认大小
         
        private final HashMap<String,Ref> cache;            //缓存池
    private final Queue<String> fInCacheQue;            //一级缓存,Ain
    private final Queue<String> fOutCacheQue;          //清楚一级缓存记录,Aout
    private final Queue<String> finalCacheQue;          //最终缓存,Am
     
    private final int cacheMaxSize;
    private int size;
    private int curBitmapSize;
         
        /**
          * 构建默认大小的Cache
          */
        public LCache() {
                this (DEFAULT_MAX_SIZE);
        }
         
        /**
          * 构建指定大小的Cache
          *
          * @param cacheMaxSize Cache最大容量
          */
        public LCache( int cacheMaxSize){
                if ( 0 >= cacheMaxSize){
                        throw new IllegalArgumentException( "cacheMaxSize must be greater than 0" );
                }
                 
                this .cacheMaxSize = cacheMaxSize;
                this .cache = new HashMap<String,Ref>();
                this .fInCacheQue = new Queue<String>(DEFAULT_IN_QUEUE_MAX_SIZE);
                this .fOutCacheQue = new Queue<String>(DEFAULT_OUT_QUEUE_MAX_SIZE);
                this .finalCacheQue = new Queue<String>(DEFAULT_CACHE_QUEUE_MAX_SIZE);
        }
         
        /**
          *
          * @param key key值
          * <a href="\"http://www.eoeandroid.com/home.php?mod=space&uid=7300\"" target="\"_blank\"">@return</a>  true-key对应的Bitmap在该缓存池中
          *          false-key对应的Bitmap不在该缓存池中
          */
        public synchronized boolean isCached(String key){
                return this .cache.containsKey(key);
        }
         
        /**
          * 获取缓存池中Bitmap
          *
          * @param key key值
          * @return   Bitmap
          */
        public Bitmap get(String key){
                if ( null == key){
                        throw new NullPointerException( "The key can not be null" );
                }
                 
                if ( "" .equals(key)){
                        throw new IllegalArgumentException( "The key dons't value" );
                }
                 
                return this .getFromCache(key);
        }
         
        /**
          * 将Bitmap缓存到该缓存池中
          *
          * @param key
          * @param mBitmap
          */
    public synchronized void put(String key,Bitmap mBitmap){
            if ( this .cache.containsKey(key)){
                    return ;
            }
             
         if ( this .fOutCacheQue.contains(key)){
                this .finalCacheQue.addToHead(key);
                this .fOutCacheQue.remove(key);
                this .reclaimCache(key,mBitmap);
         }
         
         else {
                this .fInCacheQue.addToHead(key);
                this .reclaimCache(key,mBitmap);
                if ( this .fInCacheQue.isOverflow()){
                        String tKey = this .fInCacheQue.removeFromTail();
                        this .clearCache(tKey);
                        this .fOutCacheQue.addToHead(tKey);
                        this .fOutCacheQue.trim();
                }
         }
    }
     
    private void reclaimCache(String key, Bitmap mBitmap){
            if ( this .hasFreeCache(mBitmap)){
             this .putIntoCache(key, mBitmap);
            }
             
            else if ( this .fInCacheQue.isOverflow()){
                    do {
                            String tKey = this .fInCacheQue.removeFromTail();
                            this .clearCache(tKey);
                            this .fOutCacheQue.addToHead(key);
                    } while ( this .cacheMaxSize < ( this .size + this .curBitmapSize));                   
                    this .fOutCacheQue.trim();
                    this .putIntoCache(key, mBitmap);                   
            }
             
            else {
                    do {
                            String tKey = this .finalCacheQue.removeFromTail();
                            this .clearCache(tKey);
                    } while ( this .cacheMaxSize < ( this .size + this .curBitmapSize));                    
                    this .putIntoCache(key, mBitmap);
            }
    }
     
    private void putIntoCache(String key, Bitmap mBitmap){
            this .cache.put(key, new Ref(mBitmap, this .curBitmapSize));
                this .size += this .curBitmapSize;
                this .curBitmapSize = 0 ;
    }
     
    private boolean hasFreeCache(Bitmap mBitmap){
            boolean hasFreeCache = true ;
            this .curBitmapSize = this .sizeOf(mBitmap);
            if ( this .cacheMaxSize < ( this .size + this .curBitmapSize)){
                    hasFreeCache = false ;
            }
             
            return hasFreeCache;
    }
     
    private void clearCache(String key){
            Ref  tRef = this .cache.remove(key);
         if ( null != tRef){
                this .size -= tRef.getSize();
                if ( null != tRef.getBitmap()){
                    tRef.getBitmap().recycle();       
                }
         }
    }
     
    private Bitmap getFromCache(String key){
            Bitmap tBitmap = null ;
            synchronized ( this ){
                    if ( this .finalCacheQue.contains(key)){
                        this .finalCacheQue.moveToHead(key);
                }
                    tBitmap = this .cache.get(key).getBitmap();
            }
             
            return   tBitmap;
    }
         
        /**
          * Bitmap 存储大小
          *
          * @param mBitmap
          * @return
          */
        private int sizeOf (Bitmap mBitmap){
                int weight = 0 ;
                switch (mBitmap.getConfig()){
                case ALPHA_8 :
                        weight = 1 ;
                        break ;
                case ARGB_4444 :
                        weight = 2 ;
                        break ;
                case ARGB_8888 :
                        weight = 4 ;
                        break ;
                case RGB_565 :
                        weight = 2 ;
                        break ;
                default :
                        weight = 1 ;
                        break ;
                }
 
                return (mBitmap.getWidth() * mBitmap.getHeight() * weight);
        }
         
        public synchronized void destory(){
                this .cache.clear();
                this .finalCacheQue.clear();
                this .fInCacheQue.clear();
                this .fOutCacheQue.clear();
        }
         
         
        /**
          * 队列
          */
        class Queue<T>{
             private int capacity;
                 
             private final List<T> list;
             
             /**
              * @param capacity  队列最大容量,可为0;如果capacity为0,当前队列无大小限制
              */
                public Queue( int capacity){
                        this .capacity = capacity;
                        if ( 0 < this .capacity){
                                this .list = new ArrayList<T>( this .capacity);
                        } else {
                                this .list = new LinkedList<T>();
                        }
                         
                }
                 
                /**
                  * 队列容量
                  *
                  * @return 队列容量
                  */
                public int capacity(){
                        return this .capacity;
                }
                 
                /**
                  * 队列当前大小
                  *
                  * @return 队列大小
                  */
                public int size(){
                        return this .list.size();
                }
                 
                /**
                  * 该队列中是否有key值
                  *
                  * @param key
                  * @return true 存在key值,false 不存在key值
                  */
                public boolean contains(T key){
                        return this .list.contains(key);
                }
                 
                /**
                  * 队列是否溢出
                  *
                  * @return
                  */
                public boolean isOverflow(){
                        if ( 0 == capacity){
                                return false ;
                        }
                         
                        else {
                                return ( this .list.size() > this .capacity);       
                        }
                }
                 
                /**
                  * 将队列中key移动到队列头
                  *
                  * @param key 值
                  */
                public void moveToHead(T key){
                        this .list.remove(key);
                        this .list.add(key);
                }
                 
                /**
                  * 将key添加到队列头
                  *
                  * @param key 值
                  */
                public void addToHead(T key){
                        this .list.add(key);
                }
                 
                /**
                  * 删除队列最后一个值
                  *
                  * @return 当前删除队列值
                  */
                public T removeFromTail(){
                        T tKey = null ;
                        if ( 0 < this .list.size()){
                                tKey = this .list.remove( 0 );
                        }
                        return tKey;
                }
                 
                /**
                  * 删除队列中key值
                  *
                  * @param key  key值
                  * @return   删除成功返回当前key,删除失败返回null
                  */
                public T remove(T key){
                        if ( this .list.remove(key)){
                                return key;
                        }
                        return null ;
                }
                 
                /**
                  * 将Queue中超过capacity的长度截取掉
                  *      如果list.size <= capacity, 什么都不做
                  */
                public void trim(){
                        if (( 0 == capacity) || ( this .list.size() <= this .capacity)){
                                return ;
                        }
                         
                        int tNum = this .list.size() - this .capacity;
                        for ( int idx = 0 ; idx < tNum; idx ++){
                                this .removeFromTail();
                        }
                }
                 
                public void clear(){
                        this .list.clear();
                }
        }
         
        class Ref{
                //private SoftReference<Bitmap> softReference;
                private Bitmap mBitmap;
                private int size;
                 
                public Ref(Bitmap mBitmap, int size){
                        //this.softReference = new SoftReference<Bitmap>(mBitmap);
                        this .mBitmap = mBitmap;
                        this .size = size;
                }
                 
                public int getSize(){
                        return size;
                }
                 
                public Bitmap getBitmap(){
                        //return softReference.get();
                        return this .mBitmap;
                }
        }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值