一、 我们建立一个简单的项目去体会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

results matching ""

    No results matching ""