ImageCache

public class ImageCache extends LinkedHashMap{
	/**
		 */
	private static final long serialVersionUID = 1L;
	private int mMaxEntries = 0;
	
	private static final float DEFAULT_LOAD_FACTOR = 0.75f;
	private boolean mNeedRecycle = true;
	protected Object mLock = new Object();
	/**
	 * 文件缓存目录
	 */
	private String mDiskCacheDirectory;
	
	public ImageCache(String dir, int maxCapacity) {
        super(maxCapacity, DEFAULT_LOAD_FACTOR, true);
        this.mMaxEntries = maxCapacity;
    	
    	this.mDiskCacheDirectory = dir;
    	File outFile = new File(mDiskCacheDirectory);
    	if(!outFile.exists()){
    		// 文件夹不存在的话就创建文件夹
    		outFile.mkdirs();
    	}
    }
	
	//LinkedHashMap不是同步的,在clear和get同时的时候有可能出现错误:
	//at java.util.LinkedHashMap.makeTail(LinkedHashMap.java:271)
	//由于这个接口性能要求较高,故不做成同步的,采用捕获该异常方式
	@Override
	public Bitmap get(Object key) {
		try {
			return super.get(key);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	@Override
	public void clear(){
		synchronized(mLock){
			if(mNeedRecycle){
				Iterator iter = this.entrySet().iterator();
				while(iter.hasNext()){
					Entry entry = (Entry)iter.next();
					Bitmap bmp = entry.getValue();
					if(bmp != null && !bmp.isRecycled()){
						bmp.recycle();
					}
					else{
					}				
				}
			}
			super.clear();
		}
	}
	@Override
	protected boolean removeEldestEntry(Entry entry) {
		if(size()>mMaxEntries){
			if(mNeedRecycle){
				Bitmap bmp = entry.getValue();
                if(bmp != null && !bmp.isRecycled()){
                    bmp.recycle();
                }
			}
			return true;
		}
		return false;
	}
	
	/**
	 * 从文件缓存中删除一个文件
	 * @param key 文件名
	 * @return 是否删除成功
	 * @author wiizhang
	 */
	public boolean removeFromDiskCache(String key){
         File file = new File(key);
         if (file.exists()) {
        	 return file.delete();
         }
         return false;
	}
	
	/**
     * 从文件缓存中读取图片
     * 
     * @param key
     * @return
     */
    public Bitmap readFromDiskCache(String key) {
        Bitmap b = null;
        synchronized (mLock) {
            ByteArrayOutputStream baos = null;
            FileInputStream fis = null;
            try {
                File file = new File(key);
                if (!file.exists()) {
                    // 没找到缓存对应的文件
                    return null;
                }
                baos = new ByteArrayOutputStream();
                fis = new FileInputStream(file);
                byte[] buf = new byte[1024];
                while (true) {
                    int numread = fis.read(buf);
                    if (numread == -1) {
                        break;
                    }
                    baos.write(buf, 0, numread);
                }
                buf = baos.toByteArray();
                try {
                    baos.close();
                    fis.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                b = null;
                if (b == null) {
                    ObjectInputStream istream = null;
                    try {
                        istream = new ObjectInputStream(new FileInputStream(file));
                        byte[] imageData = (byte[]) istream.readObject();
                        b = null;
                    } catch (Exception e) {
                        e.printStackTrace();
                    } finally {
                        if (istream != null) {
                            try {
                                istream.close();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                    }


                }
            } catch (StreamCorruptedException e) {
                e.printStackTrace();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (baos != null) {
                        baos.close();
                    }
                    if (fis != null) {
                        fis.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return b;
    }
    
    /**
     * 将内存缓存里的图片写入到文件缓存
     * @param keypath
     * @return
     */
    public boolean cache2Disk(String keypath,Bitmap bitmap){
        if(bitmap == null){     // 内存缓存中获取不到资源的话表示写入失败
            return false;
        }
        synchronized (mLock){
            File file = new File(keypath);
            if(file.exists() && file.length() > 0){
                // 文件已存在的话,说明图片已经下载过了,不用再保存
                return true;
            }else{
                try {
                    file.createNewFile();
                    FileOutputStream fos = new FileOutputStream(file);
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();     
                    bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
                    baos.writeTo(fos);
                    try{
                        baos.close();
                        fos.close();
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                    return true;
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } finally{
                    
                }
            }
        }
        return false;
    }
    
    /**
     * 将字节流数据写入到文件缓存
     * 

baos 从外部来,不要close baos      * @param baos,字节流数据      * @param keypath      * @return      */     public boolean cache2Disk(ByteArrayOutputStream baos,String keypath){         if(baos == null){                    return false;         }         synchronized (mLock){             File file = new File(keypath);             if(file.exists() && file.length() > 0){                 // 文件已存在的话,说明图片已经下载过了,不用再保存                 return true;             }else{                 try {                     file.createNewFile();                     FileOutputStream fos = new FileOutputStream(file);                     baos.writeTo(fos);                     try{                         baos.close();                         fos.close();                     }catch (Exception e){                         e.printStackTrace();                     }                     return true;                 } catch (FileNotFoundException e) {                     e.printStackTrace();                 } catch (IOException e) {                     e.printStackTrace();                 } finally{                                      }             }         }         return false;     }      //    @Override //    public Bitmap get(Object key) { //        synchronized (mLock) { //            return super.get(key); //        } //    }     @Override     public Bitmap put(String key, Bitmap value) {         synchronized (mLock) {             return super.put(key, value);         }     }     /**      * 文件形式直接保存      * @param is      * @param keypath      * @return      */     public boolean cache2Disk(InputStream is, String keypath) {     synchronized (mLock) {     try {         File f = new File(keypath);         if(f.exists() && f.length() > 0){                      // 文件已存在的话,说明图片已经下载过了,不用再保存                      return true;                  }         f.createNewFile();     FileOutputStream fos = new FileOutputStream(f);         byte[] buf = new byte[1024 * 4];         int len = 0;         while((len = is.read(buf)) > 0) {         fos.write(buf, 0, len);         }         fos.flush();         fos.close();         return true;     } catch (Throwable e) {     e.printStackTrace();     }     }     return false;     }          public String getCachePath(String url){         return mDiskCacheDirectory + File.separator + getFileNameForKey(url);     }          public String getFileNameForKey(String url) {         return "";//MD5.toMD5(url);     }          public String getDiskCacheDirectory(){         return mDiskCacheDirectory;     } }

你可能感兴趣的:(android)