一、 我们建立一个简单的项目去体会LruCache的使用过程
通过http请求网络上的图片文件,然后保存在缓存中。显示图片时,先从缓存中取,如果没有,就发送请求向服务器取。项目结构如下:
二、 在AndroidManifest.xml文件中,加入网络权限的声明:
<uses-permission android:name="android.permission.INTERNET"/>
三、 创建一个图片加载的类,用于对缓存的一些操作,重写LruCache的sizeOf方法:
java代码:
import android.graphics.Bitmap;
import android.util.LruCache;
/**
* Created by huhx on 2016/4/12.
*/
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) { Log.i(TAG, "lrucache size: " + lruCache.size());
return lruCache.get(key);
}
// 从缓存中删除指定的Bitmap
public void removeBitmapFromMemory(String key) {
lruCache.remove(key);
}
}
kotlin代码:
import android.graphics.Bitmap
import android.util.Log
import android.util.LruCache
/**
* Created by Administrator on 2018/3/15 0015.
*/
class ImageDownLoader {
//用来存储缓存的数字
private var lruCache:LruCache<String,Bitmap>?=null
//初始化
init {
//获取运行的最大内存
val maxMemory=Runtime.getRuntime().maxMemory()
Log.d("获取运行的最大内存",maxMemory.toString())
//默认取缓存的八分之一
val cacheSize=(maxMemory/8).toInt()
lruCache=object :LruCache<String,Bitmap>(cacheSize){
override fun sizeOf(key: String?, value: Bitmap?): Int {
return value?.byteCount?:0
}
}
}
//把Bitmap对象加入到缓存中
fun addBitmapToMemory(key:String,bitmap:Bitmap){
if(getBitmapFromMemCache(key)==null){
lruCache?.put(key,bitmap)
}
}
//从缓存中取出数据
fun getBitmapFromMemCache(key:String):Bitmap?{
return lruCache?.get(key)
}
//从缓存中删除指定Bitmap
fun removeBitmapFromMemory(key: String){
lruCache?.remove(key)
}
companion object {
private val TAG="图片工具类ImageDownLoader"
}
}
四、 在MainActivity中使用并测试LruCache:showBitmap方法是先从缓存中取,如果没有就发送http请求取得。
java代码:
public void showBitmap(View view) {
Bitmap bitmap = imageDownloader.getBitmapFromMemCache("bitmap");
if (bitmap == null) {
new BitmapThread(bitmapUrl).start();
} else {
imageView.setImageBitmap(bitmap);
}
}
kotlin代码:
private fun showBitmap(key:String,view:View){
val bitmap=imageDownLoader.getBitmapFromMemCache(key)
if(bitmap==null){
BitmapThread(key,imageDownLoader,handler).start()
}else{
imageView.setImageBitmap(bitmap)
}
}
五、 BitmapThread的线程:从服务器拿到Bitmap对象,并加入到缓存中。
java代码
class BitmapThread extends Thread {
private String bitmapUrl;
BitmapThread(String bitmapUrl) {
this.bitmapUrl = bitmapUrl;
}
@Override
public void run() {
Log.i(TAG, "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);
handler.obtainMessage(DOWNLOAD_IMAGE, bitmap).sendToTarget();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect();
}
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
kotlin代码:
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.os.Handler
import android.util.Log
import java.io.InputStream
import java.net.HttpURLConnection
import java.net.URL
class BitmapThread(private val bitmapUrl: String,
private val imageDownLoader: ImageDownLoader,
private val handler: Handler) : Thread() {
override fun run() {
Log.i(TAG, "run:" + Thread.currentThread().name)
var bitmap: Bitmap? = null
var connection: HttpURLConnection? = null
var inputStram: InputStream? = null
try {
val url=URL(bitmapUrl)
connection= url.openConnection() as HttpURLConnection?
connection?.connectTimeout=5000
connection?.requestMethod="GET"
if(connection?.responseCode==HttpURLConnection.HTTP_OK){
inputStram=connection.inputStream
bitmap=BitmapFactory.decodeStream(inputStram)
}
if(bitmap!=null){
imageDownLoader.addBitmapToMemory(bitmapUrl,bitmap)
}
handler.obtainMessage(110,bitmap).sendToTarget()
}catch (e:Exception){
e.printStackTrace()
}finally {
connection?.disconnect()
inputStram?.close()
}
}
companion object {
private val TAG = "BitmapThread子线程下载"
}
}
六、 handler处理消息,并显示图片:
java代码
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
Log.i(TAG, "hanlder handleMessage: " + Thread.currentThread().getName());
switch (msg.what) {
case DOWNLOAD_IMAGE:
imageView.setImageBitmap((Bitmap) msg.obj);
break;
}
}
};
kotlin代码:
private val handler=object:Handler(){
override fun handleMessage(msg: Message?) {
Log.d(TAG,"handler handlerMessage:"+Thread.currentThread().name)
if(msg?.what==110){
imageView.setImageBitmap(msg?.obj as Bitmap?)
}
}
}
七、 从缓存中删除图片:
java代码:
public void remove(View view) {
imageDownloader.removeBitmapFromMemory("bitmap");
}
八、 输出日志结果如下:
第一次点击showBitmap:
04-12 19:51:21.768 15941-15941/com.example.linux.lrucachetest I/TextDownload: lrucache size: 0
04-12 19:51:21.771 15941-19434/com.example.linux.lrucachetest I/MainActivity: run: Thread-2264
04-12 19:51:21.816 15941-19434/com.example.linux.lrucachetest I/TextDownload: lrucache size: 0
04-12 19:51:21.817 15941-15941/com.example.linux.lrucachetest I/MainActivity: hanlder handleMessage: main
第二次点击showBitmap:
04-12 19:52:11.128 15941-15941/com.example.linux.lrucachetest I/TextDownload: lrucache size: 256000
点击remove之后,再点击showBitmap:
04-12 19:52:47.834 15941-15941/com.example.linux.lrucachetest I/TextDownload: lrucache size: 0
04-12 19:52:47.839 15941-20689/com.example.linux.lrucachetest I/MainActivity: run: Thread-2266
04-12 19:52:47.895 15941-20689/com.example.linux.lrucachetest I/TextDownload: lrucache size: 0
04-12 19:52:47.895 15941-15941/com.example.linux.lrucachetest I/MainActivity: hanlder handleMessage: main