package com.wuxiaolong.androidsamples.disklrucache; import android.app.Activity; import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Bundle; import android.os.Environment; import android.util.Log; import android.view.View; import android.widget.ImageView; import android.widget.TextView; import com.jakewharton.disklrucache.DiskLruCache; import com.wuxiaolong.androidsamples.R; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; /** * https://github.com/JakeWharton/DiskLruCache */ public class DiskLruCacheActivity extends Activity { private DiskLruCache mDiskLruCache; private String IMGIP = "http://f.hiphotos.baidu.com/image/pic/item/58ee3d6d55fbb2fbfe951a134d4a20a44623dc71.jpg"; ImageView imageView; TextView cacheSize; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_disk_lru_cache); imageView = (ImageView) findViewById(R.id.imageView); cacheSize = (TextView) findViewById(R.id.cacheSize); initDiskLruCache(); } private void initDiskLruCache() { try { File cacheDir = getDiskCacheDir(this, "bitmap"); if (!cacheDir.exists()) { cacheDir.mkdirs(); } mDiskLruCache = DiskLruCache.open(cacheDir, getAppVersion(this), 1, 10 * 1024 * 1024); } catch ( IOException e ) { e.printStackTrace(); } } public void onCache(View view) { switch (view.getId()) { case R.id.cacheImageView: cacheImageView(); break; case R.id.showCacheImageView: showCacheImageView(); break; case R.id.deleteCacheImageView: clearCache(); break; case R.id.deleteAllCacheImageView: deleteAll(); break; } } private void getCacheSize() { cacheSize.setText(mDiskLruCache.size() + ""); } private void cacheImageView() { new Thread(new Runnable() { @Override public void run() { String key = MD5Util.md5(IMGIP); Log.d("wxl", "key=" + key); try { DiskLruCache.Editor editor = mDiskLruCache.edit(key); if (editor != null) { OutputStream out = editor.newOutputStream(0); if (downloadImg(IMGIP, out)) { //提交 editor.commit(); } else { //撤销操作 editor.abort(); } } /** * 这个方法用于将内存中的操作记录同步到日志文件(也就是journal文件)当中。 * 这个方法非常重要,因为DiskLruCache能够正常工作的前提就是要依赖于journal文件中的内容。 * 并不是每次写入缓存都要调用一次flush()方法的,频繁地调用并不会带来任何好处, * 只会额外增加同步journal文件的时间。 * 比较标准的做法就是在Activity的onPause()方法中去调用一次flush()方法就可以了 */ mDiskLruCache.flush(); } catch (Exception e) { e.printStackTrace(); } } }).start(); } private void showCacheImageView() { String key = MD5Util.md5(IMGIP); try { DiskLruCache.Snapshot snapShot = mDiskLruCache.get(key); if (snapShot != null) { InputStream is = snapShot.getInputStream(0); Bitmap bitmap = BitmapFactory.decodeStream(is); imageView.setImageBitmap(bitmap); getCacheSize(); } } catch (Exception e) { e.printStackTrace(); } } private void clearCache() { String key = MD5Util.md5(IMGIP); try { mDiskLruCache.remove(key); getCacheSize(); } catch (Exception e) { e.printStackTrace(); } } private void deleteAll() { /** * 这个方法用于将所有的缓存数据全部删除,比如说网易新闻中的那个手动清理缓存功能, * 其实只需要调用一下DiskLruCache的delete()方法就可以实现了。 * 会删除包括日志文件在内的所有文件 */ try { mDiskLruCache.delete(); getCacheSize(); } catch (Exception e) { e.printStackTrace(); } } private File getDiskCacheDir(Context context, String uniqueName) { String cachePath; //如果sd卡存在并且没有被移除 if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) || !Environment.isExternalStorageRemovable()) { cachePath = context.getExternalCacheDir().getPath(); } else { cachePath = context.getCacheDir().getPath(); } return new File(cachePath + File.separator + uniqueName); } private int getAppVersion(Context context) { try { PackageInfo info = context.getPackageManager().getPackageInfo( context.getPackageName(), 0); return info.versionCode; } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } return 1; } private boolean downloadImg(final String urlStr, final OutputStream outputStream) { HttpURLConnection conn = null; BufferedOutputStream out = null; BufferedInputStream in = null; try { URL url = new URL(urlStr); conn = (HttpURLConnection) url.openConnection(); in = new BufferedInputStream(conn.getInputStream(), 8 * 1024); out = new BufferedOutputStream(outputStream, 8 * 1024); int len = 0; while ((len = in.read()) != -1) { out.write(len); } return true; } catch (IOException e) { e.printStackTrace(); } finally { if (conn != null) conn.disconnect(); try { if (out != null) out.close(); } catch (IOException e) { e.printStackTrace(); } try { if (in != null) in.close(); } catch (IOException e) { e.printStackTrace(); } } return false; } @Override protected void onPause() { super.onPause(); try { mDiskLruCache.flush(); } catch (Exception e) { e.printStackTrace(); } } @Override protected void onDestroy() { super.onDestroy(); /** * 这个方法用于将DiskLruCache关闭掉,是和open()方法对应的一个方法。 * 关闭掉了之后就不能再调用DiskLruCache中任何操作缓存数据的方法, * 通常只应该在Activity的onDestroy()方法中去调用close()方法。 */ try { mDiskLruCache.close(); } catch (Exception e) { e.printStackTrace(); } } }