Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android本地緩存DiskLruCache完整詳細學習示例

Android本地緩存DiskLruCache完整詳細學習示例

編輯:關於Android編程

MainActivity如下:
package cc.vv;

import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;

import libcore.io.DiskLruCache;
import libcore.io.Utils;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.ImageView;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
/**
 * Demo描述:
 * DiskLruCache學習示例
 * 
 * DiskLruCache用於本地緩存.
 * 比如在網絡可用時加載一張網絡圖片,當網絡不可用時依然可以顯示該圖片。
 * 實現的原理是將圖片保存到本地;當網絡不可用時從本地加載圖片。
 * 在此簡單模擬該過程,步驟如下:
 * 1 從網絡下載圖片且保存至DiskLruCache
 * 2 從DiskLruCache中獲取緩存圖片進行顯示
 * 
 * 
 * 學習備注:
 * 1 DiskLruCache的本地緩存文件路徑為:
 *   /sdcard/Android/data//cache
 *   當應用被卸載時該文件亦會被刪除
 * 2 新聞類APP一般的做法.從新聞列表(ListView)中點擊某條新聞跳轉到詳細畫面.
 *   在詳細畫面一般有圖片和文字.此時可以將圖片和文字用同一個key存到不同的緩存文件夾下.
 *   在斷網時浏覽該新聞時候依據該key分別取出對應的圖片和文字即可.
 * 3 在示例中用到了DiskLruCache的存和取的相關API.在此對其余重要API簡要整理:
 *   3.1 remove(String key) 刪除某個已緩存的對象.
 *   3.2 size() 得到緩存路徑下緩存的總大小.這個很常見.許多APP都提示當前有多少緩存.
 *   3.3 flush() 將內存中的操作記錄同步到日志文件(也就是journal文件)中
 *       一般在Activity的onPause()中調用該方法.
 *   3.4 close() 關閉DiskLruCache.該方法與open方法對應.
 *       一般在Activity的onDestory()中調用該方法.
 *   3.5 delete() 將緩存數據全部刪除.
 *   
 * 
 * 學習資源:
 * http://blog.csdn.net/guolin_blog/article/details/28863651
 * Thank you very much
 */
public class MainActivity extends Activity {
	private ImageView mImageView;
    private DiskLruCache mDiskLruCache;
    private Context mContext;
    //DiskLruCache中對於圖片的最大緩存值.
    private int maxSize=20*1024*1024;
    private String mImagePath=http://www.baidu.com/img/bdlogo.png;
    private Handler mHandler;
    private final int FINISH=9527;
    
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		init();
	}
	
	private void init(){
		try {
			mHandler = new Handler() {
				@Override
				public void handleMessage(Message msg) {
					super.handleMessage(msg);
					if (msg.what==FINISH) {
						getDataFromDiskLruCache();
					}
				}
			};
			mContext=this;
			mImageView=(ImageView) findViewById(R.id.imageView);
			
			initDiskLruCache();
			
		} catch (Exception e) {
			// TODO: handle exception
		}
	}
	
	
	/**
	 * 初始化DiskLruCache
	 */
	private void initDiskLruCache(){
		try {
			File cacheDir=Utils.getDiskLruCacheDir(mContext, bitmap);
			if (!cacheDir.exists()) {
				cacheDir.mkdirs();
			}
			int versionCode=Utils.getAppVersionCode(mContext);
			mDiskLruCache=DiskLruCache.open(cacheDir, versionCode, 1, maxSize);
			
			saveDataToDiskLruCache();
			
		} catch (Exception e) {
			// TODO: handle exception
		}
	}
	
	
	// 將數據寫入DiskLruCache
	private void saveDataToDiskLruCache() {
		new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					//第一步:獲取將要緩存的圖片的對應唯一key值.
					String key = Utils.getStringByMD5(mImagePath);
					//第二步:獲取DiskLruCache的Editor
					DiskLruCache.Editor editor = mDiskLruCache.edit(key);
					if (editor!=null) {
						//第三步:從Editor中獲取OutputStream
						OutputStream outputStream=editor.newOutputStream(0);
						//第四步:下載網絡圖片且保存至DiskLruCache圖片緩存中
						boolean isSuccessfull=Utils.getBitmapFromNetWorkAndSaveToDiskLruCache(mImagePath, outputStream);
						if (isSuccessfull) {
							editor.commit();
							mHandler.sendEmptyMessage(FINISH);
						}else{
							editor.abort();
						}
						mDiskLruCache.flush();
					}
				} catch (Exception e) {
					
				}

			}
		}).start();
	}
	
	
	//從DiskLruCache中讀取數據
	private void getDataFromDiskLruCache(){
		try {
			//第一步:獲取已緩存的圖片的對應唯一key值.
			String key = Utils.getStringByMD5(mImagePath);
			//第二步:依據key獲取到其對應的snapshot
			DiskLruCache.Snapshot snapshot=mDiskLruCache.get(key);
			if (snapshot!=null) {
				//第三步:從snapshot中獲取到InputStream
				InputStream inputStream=snapshot.getInputStream(0);
				Bitmap bitmap=BitmapFactory.decodeStream(inputStream);
				mImageView.setImageBitmap(bitmap);
			}
		} catch (Exception e) {
			
		}
		
	}

}

Utils如下:

 

package libcore.io;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import org.apache.http.HttpStatus;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Environment;

public class Utils {

	/**
	 * 獲取DiskLruCache的緩存文件夾
	 * 注意第二個參數dataType
	 * DiskLruCache用一個String類型的唯一值對不同類型的數據進行區分.
	 * 比如bitmap,object等文件夾.其中在bitmap文件夾中緩存了圖片.
	 * 
	 * 緩存數據的存放位置為:
	 * /sdcard/Android/data//cache 
	 * 如果SD卡不存在時緩存存放位置為:
	 * /data/data//cache
	 * 
	 */
	public static File getDiskLruCacheDir(Context context, String dataType) {
		String dirPath;
		File cacheFile = null;
		if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) ||
			!Environment.isExternalStorageRemovable()) {
			dirPath=context.getExternalCacheDir().getPath();
		} else {
			dirPath=context.getCacheDir().getPath();
		}
		cacheFile=new File(dirPath+File.separator+dataType);
		return cacheFile;
	}
	
	
	
	/**
	 * 獲取APP當前版本號
	 * @param context
	 * @return
	 */
	public static int getAppVersionCode(Context context){
		int versionCode=1;
		try {
			String packageName=context.getPackageName();
			PackageManager packageManager=context.getPackageManager();
			PackageInfo packageInfo=packageManager.getPackageInfo(packageName, 0);
			versionCode=packageInfo.versionCode;
		} catch (NameNotFoundException e) {
			e.printStackTrace();
		}
		return versionCode;
	}
	
	
	/**
	 * 將字符串用MD5編碼.
	 * 比如在改示例中將url進行MD5編碼
	 */
	public static String getStringByMD5(String string) {
		String md5String = null;
		try {
			// Create MD5 Hash
			MessageDigest messageDigest = MessageDigest.getInstance(MD5);
			messageDigest.update(string.getBytes());
			byte messageDigestByteArray[] = messageDigest.digest();
			if (messageDigestByteArray == null || messageDigestByteArray.length == 0) {
				return md5String;
			}

			// Create hexadecimal String
			StringBuffer hexadecimalStringBuffer = new StringBuffer();
			int length = messageDigestByteArray.length;
			for (int i = 0; i < length; i++) {
				hexadecimalStringBuffer.append(Integer.toHexString(0xFF & messageDigestByteArray[i]));
			}
			md5String = hexadecimalStringBuffer.toString();
			return md5String;
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		return md5String;
	}
	
	
	/**
	 * 從網絡獲取圖片且保存至SD卡中的緩存
	 */
	public static boolean getBitmapFromNetWorkAndSaveToDiskLruCache(String imageUrl,OutputStream outputStream){
		boolean isSuccessfull=false;
		URL url=null;
		HttpURLConnection httpURLConnection=null;
		BufferedOutputStream bufferedOutputStream=null;
		InputStream inputStream=null;
		BufferedInputStream bufferedInputStream=null;
		try {
			url=new URL(imageUrl);
			httpURLConnection=(HttpURLConnection) url.openConnection();
			httpURLConnection.setConnectTimeout(5*1000);
			httpURLConnection.setReadTimeout(10*1000);
			httpURLConnection.setDoInput(true);
			httpURLConnection.setDoOutput(true);
			if (httpURLConnection.getResponseCode()==HttpStatus.SC_OK) {
				bufferedOutputStream=new BufferedOutputStream(outputStream);
				inputStream=httpURLConnection.getInputStream();
				bufferedInputStream=new BufferedInputStream(inputStream);
				int len=0;
				byte [] buffer=new byte[1024];
				while((len=bufferedInputStream.read(buffer))!=-1){
					bufferedOutputStream.write(buffer, 0, len);
					bufferedOutputStream.flush();
				}
				isSuccessfull=true;
			} else {
				isSuccessfull=false;
				System.out.println(圖片請求失敗);
			}
		} catch (Exception e) {
			    isSuccessfull=false;
			    System.out.println(e=+e.toString());
		}finally{
			try {
				if (bufferedOutputStream!=null) {
					bufferedOutputStream.close();
				}
				if (inputStream!=null) {
					inputStream.close();
				}
				if (bufferedInputStream!=null) {
					bufferedInputStream.close();
				}
				if (httpURLConnection!=null) {
					httpURLConnection.disconnect();
				}
			} catch (Exception e) {
				 System.out.println(e=+e.toString());
			}
		}
		
		return isSuccessfull;
		
	}

}

 

 

 



    




  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved