【安卓筆記】硬碟緩衝工具類的編寫,安卓工具類

來源:互聯網
上載者:User

【安卓筆記】硬碟緩衝工具類的編寫,安卓工具類

DiskLruCache(https://github.com/JakeWharton/DiskLruCache)想必大家都很熟悉。(不熟悉的請看這裡),它是jakewharton大神寫的一個開源庫,提供了硬碟緩衝的方案。

       但是該庫的API比較簡單,有時候並不能滿足我們使用。比如說如果你想把緩衝中的資料以Bitmap的形式返回,API並沒有提供這樣的方法,我們必須通過DiskLruCache#get方法返回來的Snapshot獲得輸入資料流,然後將流轉化為Bitmap。另外,構建DiskLruCache時必須要傳入VersionCode,CachePath等變數,而實際開發中,Versioncode通常是應用版本號碼,Cachepath也相對固定(要麼是sd的緩衝目錄要麼是本地的緩衝目錄),每次構建DiskLruCache都要寫擷取版本號碼等等重複的代碼實在是太枯燥了。再比如說,寫緩衝時需要指定key,而這個key在項目中通常是url,而url中可能有特殊字元,這將導致寫緩衝失敗,我們最好將url進行編碼,然後使用編碼後的key,而在API中並沒有提供類似的方法。鑒於此,我寫了一個基於DiskLruCache的工具類,進一步簡化快取作業。    這個工具類主中的方法全部是靜態,可直接調用。它的功能有:1.構建緩衝對象;2.讀緩衝。將緩衝讀為String/流/Bitmap;3.寫緩衝。可以將String/File/流/Bitmap寫入緩衝,並支援非同步寫入。
   說了這麼多,下面來看這個工具類是怎樣寫的吧。
package com.jakewharton.disklrucache;import java.io.BufferedInputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import android.content.Context;import android.content.pm.PackageManager;import android.content.pm.PackageManager.NameNotFoundException;import android.graphics.Bitmap;import android.graphics.Bitmap.CompressFormat;import android.graphics.BitmapFactory;import android.os.Environment;import android.text.TextUtils;/** * @author Rowandjj * *DiskLruCache的協助工具輔助類(DiskLruCache:http://jakewharton.github.io/DiskLruCache) * 提供建立/讀取/寫入緩衝的方法,並支援非同步緩衝寫入. */public class DiskLruCacheHelper{private static final long DEFAULT_MAX_SIZE = 10*1024*1024;private static ExecutorService service = null;/** *  * 建立DiskLruCache執行個體,預設版本號碼為當前應用版本號碼,緩衝位置由getDiskCacheDir指定 * @param context 上下文 * @param cacheDirName 快取檔案夾名稱 * @param maxSize 緩衝最大值,單位是byte * @return 建立成功返回DiskLruCache執行個體否則返回null */public static DiskLruCache createCache(Context context,String cacheDirName,long maxSize){DiskLruCache cache = null;try{ cache = DiskLruCache.open(getDiskCacheDir(cacheDirName, context), getAppVersion(context),1, maxSize);} catch (IOException e){e.printStackTrace();}return cache;}/** * 返回一個具有預設大小的DiskLruCache執行個體,預設大小為10Mb * @param context * @param cacheDirName * @return 建立成功返回DiskLruCache執行個體否則返回null */public static DiskLruCache createCache(Context context,String cacheDirName){return createCache(context, cacheDirName, DEFAULT_MAX_SIZE);}/** * 將圖片寫入緩衝 */public static boolean writeBitmapToCache(DiskLruCache cache,Bitmap bitmap,String url){return writeBitmapToCache(cache, bitmap, url, CompressFormat.JPEG,100);}/** * 非同步地將圖片寫入緩衝。將不會不會寫入結果。 * @param cache * @param bitmap * @param url */public static void asyncWriteBitmapToCache(final DiskLruCache cache,final Bitmap bitmap,final String url){if(service == null)service = Executors.newSingleThreadExecutor();service.execute(new Runnable(){@Overridepublic void run(){writeBitmapToCache(cache, bitmap, url);}});}/** * 將圖片寫入緩衝 * @param cache 緩衝對象 * @param bitmap 圖片對象 * @param url 用於標識bitmap的唯一名稱,通常為圖片url * @return true表示寫入緩衝成功否則為false */public static boolean writeBitmapToCache(DiskLruCache cache,Bitmap bitmap,String url,CompressFormat format, int quality){if(cache == null || bitmap == null || url == null || TextUtils.isEmpty(url))return false;try{DiskLruCache.Editor editor = cache.edit(generateKey(url));if(editor != null){OutputStream out = editor.newOutputStream(0);if(bitmap.compress(format,quality, out)){editor.commit();return true;}else{editor.abort();}}} catch (IOException e){e.printStackTrace();}return false;}/** * 非同步地將圖片寫入緩衝。將不會不會寫入結果。 */public static void asyncWriteBitmapToCache(final DiskLruCache cache,final Bitmap bitmap,final String url,final CompressFormat format, final int quality){if(service == null)service = Executors.newSingleThreadExecutor();service.execute(new Runnable(){@Overridepublic void run(){writeBitmapToCache(cache, bitmap, url,format,quality);}});}/** * 非同步地將inputStram流寫入緩衝,將不會返回寫入結果。 */public static void asyncWriteStreamToCache(final DiskLruCache cache,final InputStream in,final String url){if(service == null)service = Executors.newSingleThreadExecutor();service.execute(new Runnable(){@Overridepublic void run(){asyncWriteStreamToCache(cache, in, url);}});}/** * 將inputStram流寫入緩衝 * @param cache * @param in * @param url * @return */public static boolean writeStreamToCache(DiskLruCache cache,InputStream in,String url){if(cache == null || in == null || url == null|| TextUtils.isEmpty(url))return false;DiskLruCache.Editor editor = null;try{editor = cache.edit(generateKey(url));if(editor != null){OutputStream out = editor.newOutputStream(0);BufferedInputStream bin = new BufferedInputStream(in);byte[] buffer = new byte[1024];int len = 0;while((len = bin.read(buffer)) != -1){out.write(buffer, 0, len);out.flush();}editor.commit();return true;}} catch (IOException e){e.printStackTrace();}return false;}/** * 非同步地將檔案寫入緩衝,將不會返回寫入結果。 */public static void asyncWriteFileToCache(final DiskLruCache cache,final File file,final String url){if(service == null)service = Executors.newSingleThreadExecutor();service.execute(new Runnable(){@Overridepublic void run(){writeFileToCache(cache, file, url);}});}/** * 將檔案寫入緩衝 * @return true表示寫入成功否則寫入失敗 */public static boolean writeFileToCache(DiskLruCache cache,File file,String url){if(cache == null || file == null || url == null || !file.exists() || TextUtils.isEmpty(url)){return false;}FileInputStream fin = null;try{fin = new FileInputStream(file);} catch (FileNotFoundException e){e.printStackTrace();}return writeStreamToCache(cache, fin, url);}/** * 非同步地將字串寫入緩衝,將不會返回寫入結果 */public static void asyncWriteStringToCache(final DiskLruCache cache,final String str,final String url){if(service == null)service = Executors.newSingleThreadExecutor();service.execute(new Runnable(){@Overridepublic void run(){writeStringToCache(cache, str, url);}});}/** * 將字串寫入緩衝 * @param cache * @param str * @param url * @return */public static boolean writeStringToCache(DiskLruCache cache,String str,String url){if(cache == null || str == null || url == null || TextUtils.isEmpty(url) || TextUtils.isEmpty(str)){return false;}DiskLruCache.Editor editor = null;try{editor = cache.edit(generateKey(url));if(editor != null){OutputStream out = editor.newOutputStream(0);out.write(str.getBytes());out.flush();}editor.commit();return true;} catch (IOException e){e.printStackTrace();}return false;}/** * 停止內部正在寫緩衝的線程, * 這將導致部分寫緩衝任務不能進行。 */public static void stop(){if(service != null)service.shutdownNow();}/** *  * 根據url擷取緩衝,並將結果以String形式返回 * @param cache * @param url * @return 成功則返回String否則返回null */public static String readCacheToString(DiskLruCache cache,String url){if(cache == null || url == null || TextUtils.isEmpty(url))return null;String key = generateKey(url);DiskLruCache.Snapshot snapshot = null;try{snapshot = cache.get(key);if(snapshot != null){InputStream in = snapshot.getInputStream(0);StringBuilder builder = new StringBuilder(1024*2);int len = 0;byte[] buffer = new byte[1024];while((len = in.read(buffer)) != -1){builder.append(new String(buffer,0,len));}return builder.toString();}} catch (Exception e){e.printStackTrace();}return null;}/** * 根據url擷取緩衝,並將緩衝以InputStream形式返回 *  * @param cache DiskLruCache執行個體 * @param url 緩衝名 * @return 命中則返回InputStream流否則返回null */public static InputStream readCacheToInputStream(DiskLruCache cache,String url){if(cache == null || url == null || TextUtils.isEmpty(url))return null;String key = generateKey(url);DiskLruCache.Snapshot snapshot = null;try{snapshot = cache.get(key);} catch (IOException e){e.printStackTrace();}if(snapshot != null)return snapshot.getInputStream(0);return null;}/** * 根據url擷取緩衝,並將緩衝以Bitmap形式返回 * @param cache * @param url * @return 成功返回bitmap,否則返回null */public static Bitmap readCacheToBitmap(DiskLruCache cache,String url){InputStream in = readCacheToInputStream(cache, url);if(in != null)return BitmapFactory.decodeStream(in);return null;}/** * 擷取快取檔案路徑(優先選擇sd卡) * @param cacheDirName 快取檔案夾名稱 * @param context 上下文 * @return */public static File getDiskCacheDir(String cacheDirName,Context context){String cacheDir;if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)&&!Environment.isExternalStorageRemovable()){cacheDir = getExternalCacheDir(context);if(cacheDir == null)//部分機型返回了nullcacheDir = getInternalCacheDir(context);}else{cacheDir = getInternalCacheDir(context);}File dir =  new File(cacheDir,cacheDirName);if(!dir.exists())dir.mkdirs();return dir;}/** * 擷取當前app版本號碼 * @param context 上下文 * @return 當前app版本號碼 */public static int getAppVersion(Context context){PackageManager manager = context.getPackageManager();int code = 1;try{code = manager.getPackageInfo(context.getPackageName(),0).versionCode;} catch (NameNotFoundException e){e.printStackTrace();}return code;}/** * 根據指定的url移除指定緩衝 * Note:請不要是使用DiskLruCache.remove() *  * @param cache * @param url * @return */public static boolean remove(DiskLruCache cache,String url){if(cache == null || url == null || TextUtils.isEmpty(url)){return false;}try{return cache.remove(generateKey(url));} catch (IOException e){e.printStackTrace();}return false;}/** * 根據原始鍵產生新鍵,以保證鍵的名稱的合法性 * @param key 原始鍵,通常是url * @return */public static String generateKey(String key){String cacheKey;try{MessageDigest digest = MessageDigest.getInstance("md5");digest.update(key.getBytes());cacheKey = bytesToHexString(digest.digest());} catch (NoSuchAlgorithmException e){e.printStackTrace();cacheKey = String.valueOf(key.hashCode());  }return cacheKey;}private static String bytesToHexString(byte[] bytes){StringBuilder builder = new StringBuilder();for(int i = 0; i < bytes.length; i++){String hex = Integer.toHexString(0xff&bytes[i]);if(hex.length() == 1)builder.append('0');builder.append(hex);}return builder.toString();}private static String getExternalCacheDir(Context context){File dir = context.getExternalCacheDir();if(dir == null)return null;if(!dir.exists())dir.mkdirs();return dir.getPath();}private static String getInternalCacheDir(Context context){File dir = context.getCacheDir();if(!dir.exists())dir.mkdirs();return dir.getPath();}}
代碼比較簡單,而且都有注釋,我就不過多解釋了。以後在開發中,如果需要構建DiskLruCache,調用DiskLruCacheHelper.createCache,取緩衝調用DiskLruCacheHelper.readCacheToXX,寫緩衝調用DiskLruCacheHelper.writeXXtoCache,非同步寫調用DiskLruCacheHelper.asyncWriteXXtoCache,移除指定緩衝調用DiskLruCacheHelper.remove。是不是很方便?
github地址:https://github.com/Rowandjj/DiskLruCacheHelper

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.