[Android Notes] hard disk cache tools, Android tools
DiskLruCache (https://github.com/JakeWharton/DiskLruCache) should be familiar to everyone. (For details, refer to here) It is an open-source library written by jakewharton and provides a hard disk cache solution.
However, the API of this database is relatively simple and sometimes cannot meet our needs. For example, if you want to return data in the cache in the form of Bitmap, the API does not provide such a method, we must get the input stream through the Snapshot returned by the DiskLruCache # get method, then convert the flow to Bitmap. In addition, when constructing DiskLruCache, VersionCode, CachePath, and other variables must be passed in. In actual development, Versioncode is usually the application version number, cachepath is also relatively fixed (either the sd cache directory or the local cache directory). It is too boring to write duplicate code such as getting the version number every time you build DiskLruCache. For example, you need to specify the key when writing the cache, which is usually a url in the project, and the url may have special characters, which leads to write cache failure, we 'd better encode the url and then use the encoded key, but no similar method is provided in the API. In view of this, I wrote a tool Class Based on DiskLruCache to further simplify cache operations. All methods in this tool class are static and can be called directly. Its functions include: 1. Build cache objects; 2. Read cache. Read the cache as String/stream/Bitmap; 3. Write the cache. You can write String/File/stream/Bitmap to the cache and write data asynchronously.
After talking about this, let's take a look at how this tool class is written.
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. execut Ors; 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 helper tool class (DiskLruCache: http://jakewharton.github.io /DiskLruCache) * provides methods for creating, reading, and writing caches, and supports asynchronous cache writing. */public class DiskLruCacheHelper {private static final long DEFAULT_MAX_SIZE = 10*1024*1024; private static ExecutorService service = null;/*** create a DiskLruCache instance, the default version number is the current application version number. The cache location is specified by getDiskCacheDir * @ param context * @ param cacheDirName cache folder name * @ param maxSize Maximum Cache value, the Unit is byte * @ return. If the instance is created successfully, the system returns the DiskLruCache instance. Otherwise, the system returns null */public static DiskLruCache create. Cache (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;}/*** returns a DiskLruCache instance of the default size, the default size is 10 Mb * @ param context * @ param cacheDirName * @ return: The DiskLruCache instance is created successfully. Otherwise, null */public static DiskLruCache crea is returned. TeCache (Context context, String cacheDirName) {return createCache (context, cacheDirName, DEFAULT_MAX_SIZE);}/*** write the image to the cache */public static boolean writeBitmapToCache (DiskLruCache cache, bitmap bitmap, String url) {return writeBitmapToCache (cache, bitmap, url, CompressFormat. JPEG, 100);}/*** writes the image to the cache asynchronously. No results will be written. * @ 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(registry.service.exe cute (new Runnable () {@ Overridepublic void run () {writeBitmapToCache (cache, bitmap, url );}});} /*** write the image to the cache * @ param cache object * @ param bitmap image object * @ param url is used to identify the unique bitmap object. Name. Generally, the image url * @ return true indicates that the data is successfully written to the cache. Otherwise, it is 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;}/*** writes the image to the cache asynchronously. No results will be written. */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(registry.service.exe cute (new Runnable () {@ Overridepublic void run () {writeBitmapToCache (cache, bitmap, url, format, quality );}});} /*** write the inputStram stream to the cache asynchronously without returning the Write result. */Public static void asyncWriteStreamToCache (final DiskLruCache cache, final InputStream in, final String url) {if (service = null) service = executors.newsinglethreadexecutor({service.exe cute (new Runnable () {@ Overridepublic void run () {asyncWriteStreamToCache (cache, in, url );}});} /*** write the inputStram stream to the cache * @ param in * @ param url * @ return */public static boolean writeStreamToCache (DiskLru Cache 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;}/*** writes the file to the cache asynchronously without returning the Write result. */Public static void asyncWriteFileToCache (final DiskLruCache cache, final File file, final String url) {if (service = null) service = executors.newsinglethreadexecutor({service.exe cute (new Runnable () {@ Overridepublic void run () {writeFileToCache (cache, file, url );}});} /*** write the File to the cache * @ return true indicates that the write is successful or the write fails */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);}/*** write the string to the cache asynchronously, no write results will be returned */public static void asyncWriteStringToCache (final DiskLruCache cache, final String str, final String url) {if (service = null) service = Executors. newSingleThr Eadexecutor({{service.exe cute (new Runnable () {@ Overridepublic void run () {writeStringToCache (cache, str, url );}});} /*** write the String to the 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 ed Itor = 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;}/*** stop the internal write cache thread. * This will make some write cache tasks unavailable. */Public static void stop () {if (service! = Null) service. shutdownNow ();}/***** obtain the cache based on the url, return the result in String format * @ param cache * @ param url * @ return success. return String. Otherwise, return 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;}/*** obtain the cache based on the url, the cache is returned in the form of InputStream ** @ param cache DiskLruCache instance * @ param url cache name * @ return hit, the InputStream is returned; otherwise, the return value is null */public static InputStream readCacheToInputStream (DiskLruCache cache, string url) {if (cache = null | url = null | TextUtils. isEmpty (url) return n Ull; 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;}/*** obtain the cache based on the url, and return the * @ param cache * @ param url * @ return in the form of Bitmap to return bitmap, otherwise, null */public static Bitmap readCacheToBitmap (DiskLruCache cache, String url) {InputStream in = readCacheToInputStream (cache, url); if (in! = Null) return BitmapFactory. decodeStream (in); return null;}/*** obtain the cache file path (SD card is preferred) * @ param cacheDirName cache folder name * @ param context Context * @ return */public static File getDiskCacheDir (String cacheDirName, context) {String cacheDir; if (Environment. getExternalStorageState (). equals (Environment. MEDIA_MOUNTED )&&! Environment. isExternalStorageRemovable () {cacheDir = getExternalCacheDir (context); if (cacheDir = null) // some models return nullcacheDir = getInternalCacheDir (context );} else {cacheDir = getInternalCacheDir (context);} File dir = new File (cacheDir, cacheDirName); if (! Dir. exists () dir. mkdirs (); return dir;}/*** get the current app version * @ param context Context * @ return current app version */public static int getAppVersion (context) {PackageManager manager = context. getPackageManager (); int code = 1; try {code = manager. getPackageInfo (context. getPackageName (), 0 ). versionCode;} catch (NameNotFoundException e) {e. printStackTrace ();} return code;}/*** remove the specified cache based on the specified url * Note: Do not use 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;}/*** generate a new key based on the original key to ensure the validity of the key name * @ param key original key, usually the 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 ++) {St Ring 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 ();}}
The code is relatively simple, and there are comments, so I just want to explain it more. In future development, if you need to build DiskLruCache, call DiskLruCacheHelper. createCache: Call DiskLruCacheHelper to obtain the cache. readCacheToXX: The write cache calls DiskLruCacheHelper. writeXXtoCache, asynchronous write call DiskLruCacheHelper. asyncWriteXXtoCache: removes the specified cache and calls DiskLruCacheHelper. remove. Is it convenient?
Github address: https://github.com/Rowandjj/DiskLruCacheHelper