天天看點

緩存類型與自定義三級緩存1、緩存類型2、自定義三級緩存

1、緩存類型

(1)強引用

    程式崩潰也不會回收對象

    例:平時我們new出來的指向的引用就是強引用

(2)弱引用

    垃圾回收一跑,就很容易被回收

    應用:有些需要需要畫面一移出螢幕,就要回收該資源,這時我們可以用弱引用處理

    XUtils中BitmapUtils的緩存機制

(3)軟引用

    1、垃圾回收線程運作時,不會回收該引用

    2、隻有在程式記憶體溢出抛出OOM異常之前執行回收操作

    應用:三級緩存

(4)虛引用

    該引用很少用到

2、自定義三級緩存

/**
	 * 圖檔的三級緩存類
	 * 
	 * 
	 * 1. 記憶體擷取資料 2. 本地磁盤擷取資料 cache 3. 網絡擷取資料
	 * 
	 * @author Administrator
	 * 
	 */
	public class BitmapCacheUtils {
		private HomeActivity mContext;
	
		private int maxSize = (int) (Runtime.getRuntime().freeMemory() / 2);// 擷取可用記憶體的一半做為緩存容器大小
		private Map<ImageView,String> iv_urls = new HashMap<ImageView,String>();//記錄最後顯示想iv對應url
		private LruCache<String, Bitmap> mLruCaches = new LruCache<String, Bitmap>(
				maxSize) {
	
			@Override
			protected int sizeOf(String key, Bitmap value) {
				// TODO Auto-generated method stub
				return value.getRowBytes() * value.getHeight();// return
																// value.getByteCount();//擷取位元組的大小
			}
	
		};
	
		private ExecutorService mThreadPool;//線程池
	
		public BitmapCacheUtils(HomeActivity context) {
			mContext = context;
			mThreadPool = Executors.newFixedThreadPool(6); 
		}
	
		public void display(ImageView iv_temp, String url) {
	
			// 1. 記憶體擷取資料
			Bitmap bitmap = mLruCaches.get(url);
			if (bitmap != null) {
				PrintLog.print("從記憶體中擷取圖檔");
				// 緩存中有資料
				iv_temp.setImageBitmap(bitmap);
				return;
			}
			// 2. 本地磁盤擷取資料
			bitmap = getBitmapFromLocal(url);
			if (bitmap != null) {
				PrintLog.print("從本地擷取圖檔");
				// 本地有圖檔
				iv_temp.setImageBitmap(bitmap);
				
				//往記憶體中儲存一份
				writeBitmap2Memery(url, bitmap);
				
				return;
			}
	
			// 3. 網絡擷取資料
			iv_urls.put(iv_temp, url);
			getBitmapFromNet(iv_temp, url);
	
		}
	
		private void getBitmapFromNet(ImageView iv_temp, String url) {
			// 線程 線程池
			
			//new Thread(new BitmapFromNet(iv_temp, url)).start();
			mThreadPool.submit(new BitmapFromNet(iv_temp, url));
	
		}
	
		/**
		 * 網絡請求資料
		 * 
		 * @author Administrator
		 * 
		 */
		private class BitmapFromNet implements Runnable {
			private ImageView iv_bitmap;
			private String mUrl;
	
			public BitmapFromNet(ImageView iv_temp, String url) {
				// TODO Auto-generated constructor stub
				this.iv_bitmap = iv_temp;
				this.mUrl = url;
			}
	
			@Override
			public void run() {
				// 1. 請求網絡
				try {
					URL url = new URL(mUrl);
					HttpURLConnection con = (HttpURLConnection) url
							.openConnection();
					con.setConnectTimeout(7000);// 7秒逾時設定
					con.setRequestMethod("GET");// 請求方式
					int code = con.getResponseCode();
					if (code == 200) {
						// success
						InputStream is = con.getInputStream();
	
						// 把is 轉成 bitmap
						final Bitmap bitmap = BitmapFactory.decodeStream(is);
	
						// 1. 記憶體存放一份
						writeBitmap2Memery(mUrl, bitmap);
	
						// 2. 本地Cache目錄存放一份
						writeBitmap2Local(mUrl, bitmap);
	
						// 3. 顯示圖檔
						mContext.runOnUiThread(new Runnable() {
	
							@Override
							public void run() {
								//判斷目前url或者的圖檔是否是最新的
								if (iv_urls.get(iv_bitmap).equals(mUrl)) {
									//最新的url
									
									// 運作在主線程中
									iv_bitmap.setImageBitmap(bitmap);
									PrintLog.print("從網絡擷取圖檔。。。。。。。");
								} else {
									//網速慢造成的圖檔錯位 不顯示圖檔
								}
								
							}
						});
	
					}
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
	
			}
		}
	
		/**
		 * 往記憶體中儲存
		 * 
		 * @param url
		 * @param bitmap
		 */
		public void writeBitmap2Memery(String url, Bitmap bitmap) {
			// TODO Auto-generated method stub
			mLruCaches.put(url, bitmap);// 記憶體中儲存一份
		}
	
		/**
		 * 從本地擷取圖檔
		 * 
		 * @param url
		 * @return
		 */
		public Bitmap getBitmapFromLocal(String mUrl) {
			File file = new File(mContext.getCacheDir(), mUrl.substring(mUrl
					.lastIndexOf('/') + 1));
	
			Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
	
			return bitmap;
		}
	
		/**
		 * 往本地中儲存
		 * 
		 * @param mUrl
		 * @param bitmap
		 */
		public void writeBitmap2Local(String mUrl, Bitmap bitmap) {
			// cache
			File cacheDir = mContext.getCacheDir();
			File file = new File(cacheDir,
					mUrl.substring(mUrl.lastIndexOf('/') + 1));
	
			try {
				bitmap.compress(CompressFormat.JPEG, 100,
						new FileOutputStream(file));
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	
		}
	}