一、Android中的缓存策略
一般来说,缓存策略主要包含缓存的添加、获取和删除这三类操作。如何添加和获取缓存这个比较好理解,那么为什么还要删除缓存呢?这是因为不管是内存缓存还是硬盘缓存,它们的缓存大小都是有限的。当缓存满了之后,再想其添加缓存,这个时候就需要删除一些旧的缓存并添加新的缓存。
因此LRU(Least Recently Used)缓存算法便应运而生,LRU是近期最少使用的算法,它的核心思想是当缓存满时,会优先淘汰那些近期最少使用的缓存对象。采用LRU算法的缓存有两种:LrhCache和DisLruCache,分别用于实现内存缓存和硬盘缓存,其核心思想都是LRU缓存算法。
二、LruCache的实现原理
最近最少使用算法,LruCache的核心思想很好理解,就是要维护一个缓存对象列表,其中对象列表的排列方式是按照访问顺序实现的,即一直没访问的对象,将放在队尾,即将被淘汰。而最近访问的对象将放在队头,最后被淘汰。
三、LruCache的使用
工具类 ImageDownloader
package com.zhh.app;
import android.graphics.Bitmap;
import android.util.LruCache;
import com.orhanobut.logger.Logger;
/**
* 工具类
*/
public class ImageDownloader {
private static final String TAG = "TextDownload";
private LruCache<String, Bitmap> lruCache;
/**
* 实例化对象
*/
public ImageDownloader() {
long maxMemory = Runtime.getRuntime().maxMemory();
int cacheSize = (int) (maxMemory / 8);
lruCache = new LruCache<String, Bitmap>(cacheSize) {
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getByteCount();
}
};
}
/**
* 把Bitmap对象加入到缓存中
*
*/
public void addBitmapToMemory(String key, Bitmap bitmap) {
if (getBitmapFromMemCache(key) == null) {
lruCache.put(key, bitmap);
}
}
/**
* 从缓存中得到Bitmap对象
*/
public Bitmap getBitmapFromMemCache(String key) {
Logger.t("111").d("lrucache size: " + lruCache.size());
return lruCache.get(key);
}
/**
* 从缓存中删除指定的Bitmap
*/
public void removeBitmapFromMemory(String key) {
lruCache.remove(key);
}
}
在 MainActivity 中使用
package com.zhh.app;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import com.orhanobut.logger.Logger;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
public class MainActivity extends Activity {
// imageDownloader 对象
private ImageDownloader imageDownloader;
// imageView图片
private ImageView imageView;
// 按钮
private Button button;
// 上下文
private Context context;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initOnclick();
}
/**
* 初始化控件
*/
private void initView() {
imageView = (ImageView) findViewById(R.id.imageView);
button = (Button) findViewById(R.id.button);
imageDownloader = new ImageDownloader();
context = MainActivity.this;
}
/**
* 点击事件
*/
private void initOnclick() {
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 获取图片
getBitmap();
}
});
}
/**
* 显示网络上拿到的图片
*/
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 1:
Bitmap bitmap = (Bitmap) msg.obj;
imageView.setImageBitmap(bitmap);
break;
}
}
};
/**
* 先从内存缓存中拿图片
* 如果没有,网络获取
*/
public void getBitmap() {
Bitmap bitmap = imageDownloader.getBitmapFromMemCache("bitmap");
if (bitmap == null) {
httpPicture("http://img4.imgtn.bdimg.com/it/u=1210092829,3173610289&fm=11&gp=0.jpg");
Logger.t("111").d("网络获取");
} else {
imageView.setImageBitmap(bitmap);
Logger.t("111").d("内存缓存中获取");
}
}
/**
* 开线程访问网络
*
* @param bitmapUrl
*/
private void httpPicture(final String bitmapUrl) {
new Thread() {
@Override
public void run() {
Log.i("111", "run: " + Thread.currentThread().getName());
Bitmap bitmap = null;
HttpURLConnection connection = null;
InputStream inputStream = null;
try {
URL url = new URL(bitmapUrl);
connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(5000);
connection.setRequestMethod("GET");
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
inputStream = connection.getInputStream();
bitmap = BitmapFactory.decodeStream(inputStream);
}
// 保存图片
imageDownloader.addBitmapToMemory("bitmap", bitmap);
// 显示图片
Message message = handler.obtainMessage();
message.obj = bitmap;
message.what = 1;
handler.sendMessage(message);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect();
}
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}.start();
}
}
activity_main.xml
<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"
tools:context=".MainActivity"
android:orientation="vertical"
>
<Button
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="显示图片"
/>
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
添加权限
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
参考文章:
https://www.jianshu.com/p/b49a111147ee
源码下载:
huancun----app
https://download.csdn.net/download/zhaihaohao1/10752735