LRU是Least Recently Used 的缩写,即“最近最少使用”,说明LRU缓存算法的淘汰策略是将最近最少使用的数据移除,让出内存给最新读取的数据。
LRU缓存就是通过http请求网络上的图片文件,然后保存在缓存中。显示图片时,先从缓存中取,如果缓存中没有的话就发送请求向服务器取。
看下代码:
布局文件代码:
垂直线性布局中放置了两个按钮和一张图片。
当点击第一个下载显示按钮时,首先进行判断,如果缓存中没有就从网络上获取图片,如果缓存中有的话就优先从缓存中取就OK了;第二个按钮作用是清除缓存。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.shen.actionbar.MainActivity"> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="showPic" android:onClick="showPic"/> <Button android:layout_marginTop="20dp" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="removePic" android:onClick="removePic"/> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/ivPic" android:src="@mipmap/ic_launcher"/> </LinearLayout>
然后看关键代码:
public class MainActivity extends AppCompatActivity { private ImageView ivPic; private String imgUrl = "http://img.hb.aicdn.com/a4941f541c82ec07063ca886531ba0ccf0c0782544120-5Uz3Yi_fw580"; private ImageDownload imageDownload; private Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { if(msg.what == 1){ ivPic.setImageBitmap((Bitmap) msg.obj); } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ivPic = (ImageView) findViewById(R.id.ivPic); imageDownload = new ImageDownload(); } public void showPic(View view){//判断图片是否缓存过 Bitmap bitmap = imageDownload.get("cachePic"); if(bitmap == null){ Log.i("MABi","zouzhele++++++++++");//没有缓存过,则需要通过网络下载
//创建子线程 new Thread(new Runnable() { @Override public void run() { HttpURLConnection conn = null; InputStream is = null; try { URL url = new URL(imgUrl); conn = (HttpURLConnection) url.openConnection(); conn.setConnectTimeout(1000); conn.connect(); if(conn.getResponseCode() == 200){ Bitmap downloadBitmap = BitmapFactory.decodeStream(conn.getInputStream());//将新下载的图片加入至缓存中保存 imageDownload.add("cachePic",downloadBitmap); handler.obtainMessage(1,downloadBitmap).sendToTarget(); } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { if(conn != null){ conn.disconnect(); } if(is != null){ try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } } }).start(); }else{//缓存过,那就从缓存中取出该图片 ivPic.setImageBitmap(bitmap); } } public void removePic(View view){imageDownload.remove("cachePic");ivPic.setImageResource(R.mipmap.ic_launcher); } //定义一个缓存工具的内部类 class ImageDownload {//缓存数据的容器 private android.support.v4.util.LruCache<String, Bitmap> lruCache; public ImageDownload() {//取出内存大小的八分之一作为缓存的大小 long maxMemorySize = Runtime.getRuntime().maxMemory(); int cacheMemorySize = (int) (maxMemorySize / 8); lruCache = new android.support.v4.util.LruCache<String, Bitmap>(cacheMemorySize) { @Override protected int sizeOf(String key, Bitmap value) { return value.getByteCount(); } }; }//从缓存中取出缓存的数据 public Bitmap get(String key) { return lruCache.get("key"); }//添加新的数据至缓存中 public void add(String key,Bitmap bitmap){//判断之前是否缓存过 if(bitmap == null){ lruCache.put(key,bitmap); //Toast.makeText(MainActivity.this,"chenggong",Toast.LENGTH_SHORT).show(); Log.i("AHHAHAHHAHA",lruCache.get(key).toString()); } }//从缓存中删除数据 public void remove(String key){ lruCache.remove(key); } } }但是我发现有点儿不太对劲,按理说下载过一次就会有缓存的,然后断掉网络它会从缓存中取数据,但是我试了下并不能。。。求路过的解释一下,拜托啦