Lrucache浅析

在应用程序的UI界面中加载图片是很常见的事情,但是当程序需要在界面上加载一大堆图片的时候,情况就变得复杂起来。在很多情况下,(比如使用ListView, GridView 或者 ViewPager 这样的组件),屏幕上显示的图片可以通过滑动屏幕等事件不断地增加,最终导致OOM。

为了保证内存的使用始终维持在一个合理的范围,通常需要回收被移除屏幕的图片。此时垃圾回收器也会认为你不再持有这些图片的引用,从而对这些图片进行GC操作。为了能让程序快速运行,在界面上迅速地加载图片,同时考虑到某些图片被回收之后,用户又将它重新滑入屏幕这种情况。这时重新去加载一遍刚刚加载过的图片无疑会造成性能丢失,需要想办法去避免这个情况的发生。因此使用内存缓存技术可以很好的解决这个问题,它可以让组件快速地重新加载和处理图片。内存缓存技术对那些大量占用应用程序宝贵内存的图片提供了快速访问的方法。其中最核心的类是LruCache (此类在android-support-v4的包中提供)

 

LruCache使用一个LinkedHashMap简单的实现内存的缓存,没有软引用,都是强引用。当新添加一个cache或者已有cache再次使用时会将他们放在双向线性列表的头部。如果添加的数据大于设置的最大值,就删除尾部的数据来调整内存。这样就保证了最近使用的被最后删除。这个排序是根据在创建LinkedHashMap时最后一个参数来设置是否有序排列。

 

下面是一个使用 LruCache 来缓存图片的例子:

private LruCache<String, Bitmap>mMemoryCache;  

@Override

protected void onCreate(Bundle savedInstanceState) { 

    // 获取到可用内存的最大值,使用内存超出这个值会引起OutOfMemory异常。 

    // LruCache通过构造函数传入缓存值,以KB为单位。 

    int maxMemory = (int)(Runtime.getRuntime().maxMemory() / 1024); 

    // 使用最大可用内存值的1/8作为缓存的大小。 

    int cacheSize = maxMemory / 8; 

    mMemoryCache = new LruCache<String, Bitmap>(cacheSize){ 

        @Override

        protected int sizeOf(String key, Bitmap bitmap) { 

            //重写此方法来衡量每张图片的大小,默认返回图片数量。 

            return bitmap.getByteCount() / 1024; 

        } 

    }; 

    

public void addBitmapToMemoryCache(String key, Bitmapbitmap) { 

    if (getBitmapFromMemCache(key) == null){ 

        mMemoryCache.put(key,bitmap); 

    } 

    

public Bitmap getBitmapFromMemCache(String key){ 

    return mMemoryCache.get(key); 

}

ThreadLocal 是 Java 中的一个类,它提供了一种线程局部变量的机制。线程局部变量是指每个线程都有自己的变量副本,每个线程对该变量的访问都是独立的,互不影响。 ThreadLocal 主要用于解决多线程并发访问共享变量时的线程安全问题。在多线程环境下,如果多个线程共同访问同一个变量,可能会出现竞争条件,导致数据不一致或者出现线程安全问题。通过使用 ThreadLocal,可以为每个线程提供独立的副本,从而避免了线程安全问题。 ThreadLocal 的工作原理是,每个 Thread 对象内部都维护了一个 ThreadLocalMap 对象,ThreadLocalMap 是一个 key-value 结构,其中 key 是 ThreadLocal 对象,value 是该线程对应的变量副本。当访问 ThreadLocal 的 get() 方法时,会根据当前线程获取到对应的 ThreadLocalMap 对象,并从中查找到与 ThreadLocal 对象对应的值。如果当前线程尚未设置该 ThreadLocal 对象的值,则会通过 initialValue() 方法初始化一个值,并将其存入 ThreadLocalMap 中。当访问 ThreadLocal 的 set() 方法时,会将指定的值存入当前线程对应的 ThreadLocalMap 中。 需要注意的是,ThreadLocal 并不能解决共享资源的并发访问问题,它只是提供了一种线程内部的隔离机制。在使用 ThreadLocal 时,需要注意合理地使用,避免出现内存泄漏或者数据不一致的情况。另外,由于 ThreadLocal 使用了线程的 ThreadLocalMap,因此在使用完 ThreadLocal 后,需要手动调用 remove() 方法清理对应的变量副本,以防止内存泄漏。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值