Volley 에서 사용 하 는 캐 시

이 글 을 보기 전에 곽 림 대 신의 블 로 그 를 읽 어 보 는 게 좋 을 것 같 아 요. http://blog.csdn.net/guolin_blog / article / details / 17482095 모두 4 편 입 니 다. 자세히 보 세 요.
  다음은 제 가 그 안에 사용 하 는 imageloader 의 cache 를 확장 하 는 것 입 니 다.
안 드 로 이 드 슈퍼 portV 4 에서 제공 하 는 LRuCache (하 드 참조, 소프트 참조, sdcard 로 컬 캐 시 포함) 를 계승 하 는 bitmapcache 클래스 를 새로 만 듭 니 다. 코드 는 다음 과 같 습 니 다.
public class BitmapCache extends LruCache<String, Bitmap> implements ImageCache {
	private static final int SOFT_CACHE_SIZE = 15; //        
	static int maxSize = 10 * 1024 * 1024;
	private static BitmapCache instance = null;//      
	private static LinkedHashMap<String, SoftReference<Bitmap>> mSoftCache; //      

	public static BitmapCache getInstance() {
		if (instance == null) {
			instance = new BitmapCache(maxSize);
			mSoftCache = new LinkedHashMap<String, SoftReference<Bitmap>>(
					SOFT_CACHE_SIZE, 0.75f, true) {
				private static final long serialVersionUID = 6040103833179403725L;

				@Override
				protected boolean removeEldestEntry(
						Entry<String, SoftReference<Bitmap>> eldest) {
					if (size() > SOFT_CACHE_SIZE) {
						return true;
					}
					return false;
				}
			};
		}
		return instance;
	}

	private BitmapCache(int maxSize) {
		super(maxSize);
		initLocalFileManager();
	}

	private void initLocalFileManager() {

	}

	@Override
	protected int sizeOf(String key, Bitmap value) {
		return value.getRowBytes() * value.getHeight();
	}

	@Override
	protected void entryRemoved(boolean evicted, String key, Bitmap oldValue,
			Bitmap newValue) {
		if (oldValue != null)
			//            ,   LRU                     
			mSoftCache.put(key, new SoftReference<Bitmap>(oldValue));
	}

	@Override
	public Bitmap getBitmap(String url) {
		//       
		Bitmap tbm = get(url);
		if (tbm == null) {
			//            ,        
			synchronized (mSoftCache) {
				SoftReference<Bitmap> bitmapReference = mSoftCache.get(url);
				if (bitmapReference != null) {
					tbm = bitmapReference.get();
					if (tbm != null) {
						//         
						put(url, tbm);
						mSoftCache.remove(url);
						return tbm;
					} else {
						mSoftCache.remove(url);
					}
				}
			}
		}
		if (tbm == null) {
			tbm = ImageFileCache.getInstance().getBitmap(url);
			if (tbm != null) {
				put(url, tbm);
			}
		}
		return tbm;
	}

	@Override
	public void putBitmap(String url, Bitmap bitmap) {
		put(url, bitmap);
		//         
		ImageFileCache.getInstance().saveBitmap(bitmap, url);
	}

	public void clearCache() {
		mSoftCache.clear();
	}
}

이전 클래스 에 ImageFileCache 를 사 용 했 습 니 다. 코드 는 다음 과 같 습 니 다.
public class ImageFileCache {
	//sdcard     
	private static final String CACHDIR = "/image";
	private static final String WHOLESALE_CONV = ".cache";

	private static final int MB = 1024 * 1024;
	private static final int FREE_SD_SPACE_NEEDED_TO_CACHE = 10;

	private static ImageFileCache mInstance;

	private ImageFileCache() {
	}

	public static ImageFileCache getInstance() {
		if (mInstance == null) {
			mInstance = new ImageFileCache();
		}
		return mInstance;
	}

	/**
	 *         
	 * 
	 * @param url
	 * @return
	 */
	public synchronized Bitmap getBitmap(final String url) {
		final String path = getDirectory() + "/" + convertUrlToFileName(url);
		File file = new File(path);
		if (file.exists()) {
			Bitmap bmp = BitmapFactory.decodeFile(path);
			if (bmp == null) {
				file.delete();
			} else {
				updateFileTime(path);
				return bmp;
			}
		}
		return null;
	}

	/**
	 *          
	 * 
	 * @param bm
	 *                   
	 * @param url
	 *               url  
	 */
	public void saveBitmap(Bitmap bm, String url) {
		if (bm == null) {
			return;
		}
		//   sdcard    
		if (FREE_SD_SPACE_NEEDED_TO_CACHE > freeSpaceOnSd()) {
			// SD    
			return;
		}
		String filename = convertUrlToFileName(url);

		String dir = getDirectory();
		File dirFile = new File(dir);
		if (!dirFile.exists())
			dirFile.mkdirs();
		File file = new File(dir + "/" + filename);
		try {
			file.createNewFile();
			OutputStream outStream = new FileOutputStream(file);
			bm.compress(Bitmap.CompressFormat.PNG, 100, outStream);
			outStream.flush();
			outStream.close();
		} catch (FileNotFoundException e) {
			Log.w("ImageFileCache", "FileNotFoundException");
		} catch (IOException e) {
			Log.w("ImageFileCache", "IOException");
		}
	}

	/**
	 *            
	 * 
	 * @param path
	 *                
	 */
	public void updateFileTime(String path) {
		File file = new File(path);
		long newModifiedTime = System.currentTimeMillis();
		file.setLastModified(newModifiedTime);
	}

	/**
	 *   SD      
	 * 
	 * @return
	 */
	@SuppressWarnings("deprecation")
	private int freeSpaceOnSd() {
		StatFs stat = new StatFs(Environment.getExternalStorageDirectory()
				.getPath());
		double sdFreeMB = ((double) stat.getAvailableBlocks() * (double) stat
				.getBlockSize()) / MB;
		return (int) sdFreeMB;
	}

	/**
	 *  url        
	 * 
	 * @param url
	 * @return
	 */
	private String convertUrlToFileName(String url) {
		String[] strs = url.split("/");
		return strs[strs.length - 1] + WHOLESALE_CONV;
	}

	/**
	 *          
	 * 
	 * @return
	 */
	public String getDirectory() {
		// String dir = getSDPath() + "/" + CACHDIR;
		String dir = CommonUtils.getExternalCacheDir() + CACHDIR;
		return dir;
	}

	/**
	 *   SDCard   
	 * 
	 * @return
	 */
	@SuppressWarnings("unused")
	private String getSDPath() {
		File sdDir = null;
		boolean sdCardExist = Environment.getExternalStorageState().equals(
				android.os.Environment.MEDIA_MOUNTED); //   sd     
		if (sdCardExist) {
			sdDir = Environment.getExternalStorageDirectory(); //      
		}
		if (sdDir != null) {
			return sdDir.toString();
		} else {
			return "";
		}
	}

}
이렇게 볼 리 가 사용 하 는 캐 시 를 만 들 었 습 니 다.
volley 이미지 로드 는 이미지 Request, imageLoader, NetworkImageView 등 세 가지 방법 을 제공 합 니 다.
세 번 째 NetworkImageView 는 사용 이 간단 합 니 다. 절 차 는 다음 과 같 습 니 다. (일반적으로 adapter 의 getview 에서 사용 합 니 다)
1. RequestQueue 대상 을 만 듭 니 다.
RequestQueue mQueue = Volley.newRequestQueue(context);  
2. ImageLoader 대상 을 만 듭 니 다.
mImageLoader = new ImageLoader(mQueue, BitmapCache.getInstance());
3. 레이아웃 파일 에 NetworkImageView 컨트롤 을 추가 합 니 다.
4. 코드 에서 이 컨트롤 의 인 스 턴 스 를 가 져 옵 니 다.5. 불 러 올 그림 주 소 를 설정 합 니 다.
img.setDefaultImageResId(R.drawable.item_default_img);//img        NetWorkImageView  
			img.setErrorImageResId(R.drawable.item_default_img_err);
			img.setImageUrl(getItem(position).getImgFile(), mImageLoader);

좋은 웹페이지 즐겨찾기