偶遇DiskLruCache(缓存策略解析)
根据郭神的博客写了个小demo,详细的方法都卸载注释里了,先上效果图:
布局代码:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.example.disklrucache.MainActivity" > <ScrollView android:layout_width="fill_parent" android:layout_height="wrap_content" > <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical" > <TextView android:id="@+id/showSize" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="25sp" /> <Button android:id="@+id/read" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="缓存图片" /> <Button android:id="@+id/remove" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="移除缓存图片" /> <Button android:id="@+id/delete" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="删除全部缓存(包括日志文件)"/> <Button android:id="@+id/show" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="显示图片" /> <ImageView android:id="@+id/img" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> </ScrollView> </LinearLayout>
主Activity代码
package com.example.disklrucache; 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.MalformedURLException; import java.net.URL; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import libcore.io.DiskLruCache; import android.app.Activity; import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager.NameNotFoundException; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Bundle; import android.os.Environment; import android.view.View; import android.view.View.OnClickListener; import android.view.Window; import android.widget.Button; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends Activity { String imageUrl = "http://img.my.csdn.net/uploads/201309/01/1378037235_7476.jpg"; private DiskLruCache lruCache = null ; private TextView showSize ; //缓存区的大小 private ImageView img ; private Button read,show ; //读取,与现实在屏幕上 private Button remove ; //移除缓存文件但是保留操作日志 private Button delete ; //删除缓存 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE) ; setContentView(R.layout.activity_main); this.read = (Button)findViewById(R.id.read) ; this.remove = (Button)findViewById(R.id.remove) ; this.show = (Button)findViewById(R.id.show) ; this.delete = (Button)findViewById(R.id.delete) ; this.showSize = (TextView) findViewById(R.id.showSize) ; img = (ImageView) findViewById(R.id.img) ; File file = getDiskCacheDir(MainActivity.this, "bitmap") ; if(!file.exists()) { file.mkdirs() ; } try { lruCache = DiskLruCache.open(file, getAppVersion(MainActivity.this), 1, 10*1024*1024) ; } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } this.show.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub getCacheBitmap(); showSize.setText("当前缓存尺寸:"+lruCache.size()); } }); this.read.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub String key = hashKeyForDisk(imageUrl) ; //生成key DiskLruCache.Editor editor; try { editor = lruCache.edit(key); if(editor != null) { OutputStream out = editor.newOutputStream(0) ; if(downUrlToStream(imageUrl, out)) { editor.commit(); } else { editor.abort(); } } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } //将key传入editor } }).start(); } }); this.remove.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub try { String key = hashKeyForDisk(imageUrl); lruCache.remove(key); } catch (IOException e) { e.printStackTrace(); } } }); this.delete.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub try { lruCache.delete(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }); //getCacheBitmap(); //读取下载的图片 } /* * 缓存的读取,主要借助get方法 */ public void getCacheBitmap() { try { String key = hashKeyForDisk(imageUrl); DiskLruCache.Snapshot snapShot = lruCache.get(key); if (snapShot != null) { InputStream is = snapShot.getInputStream(0); Bitmap bitmap = BitmapFactory.decodeStream(is); img.setImageBitmap(bitmap); } } catch (IOException e) { e.printStackTrace(); } } /* * 根据传入的url下载一张图片,并且将图片写入本地 */ private boolean downUrlToStream(String url,OutputStream outputStream) { HttpURLConnection httpurlcon = null ; BufferedInputStream in = null ; BufferedOutputStream out = null ; URL mUrl; try { mUrl = new URL(url); httpurlcon = (HttpURLConnection)mUrl.openConnection() ; in = new BufferedInputStream(httpurlcon.getInputStream(),8*1024) ; out = new BufferedOutputStream(outputStream,1024*8) ; int b ; while((b = in.read()) != -1) { out.write(b); } return true ; } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (final IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { if(httpurlcon != null) { httpurlcon.disconnect(); } try { if(in != null) in.close(); if(out != null) { out.close(); } }catch(IOException e) { e.printStackTrace(); } } return false ; } /* * 调用MD5编码算法生成唯一的key */ public String hashKeyForDisk(String key) { String cacheKey ; try { final MessageDigest mDigest = MessageDigest.getInstance("MD5") ; mDigest.update(key.getBytes()); cacheKey = bytesToHexString(mDigest.digest()) ; } catch (NoSuchAlgorithmException e) { cacheKey = String.valueOf(key.hashCode()) ; } return cacheKey ; } private String bytesToHexString(byte[] bytes) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < bytes.length; i++) { String hex = Integer.toHexString(0xFF & bytes[i]); if (hex.length() == 1) { sb.append('0'); } sb.append(hex); } return sb.toString(); } /* * 用以获取cache目录,处理当内存卡有异常(如不在或者不可用) */ public File getDiskCacheDir(Context context, String uniqueName) { String cachePath; 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); } /* * 得到应用程序的版本号,作为参数传入DiskLruCache的open方法,DiskLruCache默认 * 程序版本号发生变化时移除全部缓存数据 */ public int getAppVersion(Context context) { PackageInfo version; try { version = context.getPackageManager().getPackageInfo(context.getPackageName(), 0); return version.versionCode ; } catch (NameNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } return 1 ; //程序发生异常时返回初始版本号1.0 } @Override protected void onPause() { // TODO Auto-generated method stub try { lruCache.flush(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } super.onPause(); } @Override protected void onDestroy() { // TODO Auto-generated method stub try { lruCache.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } super.onDestroy(); } }
最后不要忘了声明权限
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。