构建Android缓存模块 Memory Cache & File Cache

  次阅读 作者:智能小宝 来源:互联网 2016-01-19 12:27 我要评论(0)

在我翻译的Google官方系列教程中,Bitmap系列由浅入深地介绍了如何正确的解码Bitmap,异步线程操作以及使用Fragments重用等技术,并且在最后给出了非常强大的独家秘笈:BitmapFun,让猿媛们得以一窥究竟Google的攻城师们是如何高屋建瓴地秒杀OOM的。

前言

在下载到BitmapFun.rar这个神圣的压缩包以后,我是双手颤抖,似乎是打开上古秘藏一般,心情激动导致久久不能自已。我还记得那天上海下着小雨,我当时霍然起身,伫立在23楼的窗台,仰着头向江水对岸的东方明珠望去,似乎这样我郁积已久的眼泪就不能掉下来。说到这里,Ryan又暗自抹了一把眼泪。短暂地忘记了过去的黑暗时光,那一个漫长的被OOM的淫威所折磨的盛夏。。。

最后在Boss诧异的目光中,我回到办公桌,按捺着内心汹涌的情绪波动,然后小心翼翼的打开BitmapFun.rar。当那些在洪荒时代就活跃在Android平台的大师们书写的篇章呈现在我眼前时,我的表情与阿宝从师父手里得到Dragon Scroll时一般,永久的定格在了极度天真的期待与眼角一抽一抽的状态。

那些泛黄的代码在我看去,通篇只有一句话:老子看不懂!

自力更生,构建自己的缓存模块

Google的这个demo堪称详尽,考虑极其周详,自然是极好的。但是当原理被层层的 特殊情况 包装起来,原本简单的例子变得异常复杂,几个类之间的关系错综复杂,堪比吸血鬼日记几个帅哥美女之间的关系。要理解清楚每一句代码的含义,你一定要有理解Matt那人老珠黄的老娘和他和失落的好朋友Taylor搞在一起的觉悟。

好了,吐槽一下就收,千万不要怀疑Google,人家已经仁至义尽了。BitmapFun中在下载后将Bitmap缓存起来,缓存做了两份:LruCache和DiskLruCache,分别是内存缓存和硬盘缓存。此外两个至关重要的类是:

1

BitmapWorkerTask(ImageView imageView)

2

3

AsyncDrawable extends BitmapDrawable

4

AsyncDrawable(Resources res, Bitmap bitmap,BitmapWorkerTask bitmapWorkerTask)

BitmapWorkerTask持有一个WeakReference<ImageView> imageViewReference,弱引用ImageView,用作异步处理加载图片的任务。

AsyncDrawable巧妙的引用持有弱引用WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference,是BitmapDrawable的子类,这样就可以setImageBitmap(AsyncDrawable)

关系:AsyncDrawable中弱引用BitmapWorkerTask。其实是图片引用ImageView的关系,而ImageView.getDrawable又可以获得图片。这种高妙的思想不是正值得我们学习么?

当然,这节课并不是讲解官方Demo的,在讲解它之前,我们先来学习一个更加简单的缓存实现方案,使用最简单的方式快速构建自己应用的缓存模块,有效避免OOM异常。它的难度非常小也很方便理解,可以在这个缓存实现的基础上,我们再去理解更加高妙的BitmapFun的缓存实现方案。

后面将要介绍的缓存方案已经应用在一个项目中(该项目将于13年1月20开源,使用Github托管,纪念我22岁的生日),效果相当不错,下载并显示上百张Bitmap也异常流畅,甚至没有半点的停顿,全程使用Emulator测试也没有出现过OOM异常,内存处于可控状态。

如何解决OOM

Bitmap之所以容易引起OOM异常,原因已经在Bitmap系列教程中说的明明白白。但是我们至少清楚一点:一个手机屏幕再大,合理尺寸的Bitmap也不至于耗空所有内存,那要怎么做才能避免OOM呢?

加载合理尺寸的Bitmap

避免反复解码、重复加载Bitmap

控制Bitmap的生命周期,合理回收

此外网上也有不少歪门邪道,我个人认为是不可取的,使用这些简单粗暴的方法,后期会为你带来更大的麻烦:

减损图片质量(使用过高的inSampleSize值)

使用decodeStream(绕过Java层,直接调用JNI)

强制增加heap size

其他

控制Bitmap的生命周期才是正解,BitmapFun使用的LruCache是将它将最近被引用到的对象存储在一个强引用的 LinkedHashMap中,并且在缓存超过了指定大小之后将最近不常使用的对象释放掉。

Memory Cache的Size是受限的,因此加入DiskLruCache,虽然在访问速度上逊于Memory Cache,但是速度也是相当可观的。

本站文章信息来源于网络以及网友投稿,本站只负责对文章进行整理、排版、编辑,是出于传递更多信息之目的,并不意味着赞同其观点或证实其内容的真实性。如果您有什么意见或建议,请联系QQ28-1688-302!

人工智能实验室
相关文章相关文章
  • 韩春雨称已能重复实验结果 近期将有消息公布

    韩春雨称已能重复实验结果 近期将有消息公布

  • 英国研发“杀生”机器人 通过生命体获取能量

    英国研发“杀生”机器人 通过生命体获取能量

  • 无人驾驶汽车如何改变城市生活?听听他们怎么说

    无人驾驶汽车如何改变城市生活?听听他们怎么说

  • 未来两年人工智能要怎么走?看这篇就够了

    未来两年人工智能要怎么走?看这篇就够了

网友点评网友点评
阅读推荐阅读推荐

据国外媒体报道,在过去两年内,聊天机器人(chatbot)、人工智能以及机器学习的研发和采用取得了巨大进展。许多初创公司正利用人工智能和...

霍金 视觉中国 图 英国著名物理学家霍金(Stephen Hawking)再次就人工智能(AI)发声,他认为:对于人类来说,强大AI的出现可能是最美妙的...

文|郑娟娟 今年,人工智能(AI) 60岁了。在AI60岁的时候,笔者想要介绍一下AI100,一个刚刚2岁的研究项目,但它的预设寿命是100年,甚至更长...

AlphaGo与李世石的人机大战,为大众迅速普及了人工智能的概念。 但对谷歌而言,除了下围棋,现在的人工智能进展到哪一步了?未来,人工智能...