两种缓存Bitmap的方式,手慢无

  • 下面是一个为bitmap建立[LruCache]( ) 的示例:
  1. private LruCache mMemoryCache;

  2. @Override

  3. protected void onCreate(Bundle savedInstanceState) {

  4. // Get memory class of this device, exceeding this amount will throw an

  5. // OutOfMemory exception.

  6. final int memClass = ((ActivityManager) context.getSystemService(

  7. Context.ACTIVITY_SERVICE)).getMemoryClass();

  8. // Use 1/8th of the available memory for this memory cache.

  9. final int cacheSize = 1024 * 1024 * memClass / 8;

  10. mMemoryCache = new LruCache(cacheSize) {

  11. @Override

  12. protected int sizeOf(String key, Bitmap bitmap) {

  13. // The cache size will be measured in bytes rather than number of items.

  14. return bitmap.getByteCount();

  15. }

  16. };

  17. }

  18. public void addBitmapToMemoryCache(String key, Bitmap bitmap) {

  19. if (getBitmapFromMemCache(key) == null) {

  20. mMemoryCache.put(key, bitmap);

  21. }

  22. }

  23. public Bitmap getBitmapFromMemCache(String key) {

  24. return mMemoryCache.get(key);

  25. }

    • Note:  在上面的例子中, 有1/8的程序内存被作为Cache. 在一个常见的设备上(hdpi),最小大概有4MB (32/8). 一个全屏的 [GridView]( ) 组件,如果被800x480像素的图片填满大概会花费1.5MB (800*480*4 bytes), 因此这大概最少可以缓存2.5张图片到内存中.
  • 当加载位图到 [ImageView]( ) 时,[LruCache]( ) 会先被检查是否存在这张图片。如果找到有,它会被用来立即更新 [ImageView]( ) 组件,否则一个后台线程则被触发去处理这张图片。

  1. public void loadBitmap(int resId, ImageView imageView) {

  2. final String imageKey = String.valueOf(resId);

  3. final Bitmap bitmap = getBitmapFromMemCache(imageKey);

  4. if (bitmap != null) {

  5. mImageView.setImageBitmap(bitmap);

  6. } else {

  7. mImageView.setImageResource(R.drawable.image_placeholder);

  8. BitmapWorkerTask task = new BitmapWorkerTask(mImageView);

  9. task.execute(resId);

  10. }

  11. }

  • 上面的程序中 [BitmapWorkerTask]( ) 也需要做添加到内存Cache中的动作:
  1. class BitmapWorkerTask extends AsyncTask {

  2. // Decode image in background.

  3. @Override

  4. protected Bitmap doInBackground(Integer… params) {

  5. final Bitmap bitmap = decodeSampledBitmapFromResource(

  6. getResources(), params[0], 100, 100));

  7. addBitmapToMemoryCache(String.valueOf(params[0]), bitmap);

  8. return bitmap;

  9. }

  10. }

Use a Disk Cache [使用磁盘缓存]


  • 内存缓存能够提高访问最近查看过的位图,但是你不能保证这个图片会在Cache中。像类似 [GridView]( ) 等带有大量数据的组件很容易就填满内存Cache。你的程序可能会被类似Phone call等任务而中断,这样后台程序可能会被杀死,那么内存缓存就会被销毁。一旦用户恢复前面的状态,你的程序就又需要为每个图片重新处理。

  • 磁盘缓存磁盘缓存可以用来保存那些已经处理好的位图,并且在那些图片在内存缓存中不可用时减少加载的次数。当然从磁盘读取图片会比从内存要慢,而且读取操作需要在后台线程中处理,因为磁盘读取操作是不可预期的。

  • Note:  如果图片被更频繁的访问到,也许使用 [ContentProvider]( ) 会更加的合适,比如在Gallery程序中。

  • 在下面的sample code中实现了一个基本的 DiskLruCache 。然而,Android 4.0 的源代码提供了一个更加robust并且推荐使用的DiskLruCache 方案。(libcore/luni/src/main/java/libcore/io/DiskLruCache.java). 因为向后兼容,所以在前面发布的Android版本中也可以直接使用。 (quick search 提供了一个实现这个解决方案的示例)。

  1. private DiskLruCache mDiskCache;

  2. private static final int DISK_CACHE_SIZE = 1024 * 1024 * 10; // 10MB

  3. private static final String DISK_CACHE_SUBDIR = “thumbnails”;

  4. @Override

  5. protected void onCreate(Bundle savedInstanceState) {

  6. // Initialize memory cache

  7. File cacheDir = getCacheDir(this, DISK_CACHE_SUBDIR);

  8. mDiskCache = DiskLruCache.openCache(this, cacheDir, DISK_CACHE_SIZE);

  9. }

  10. class BitmapWorkerTask extends AsyncTask {

  11. // Decode image in background.

  12. @Override

  13. protected Bitmap doInBackground(Integer… params) {

  14. final String imageKey = String.valueOf(params[0]);

  15. // Check disk cache in background thread

  16. Bitmap bitmap = getBitmapFromDiskCache(imageKey);

  17. if (bitmap == null) { // Not found in disk cache

  18. // Process as normal

  19. final Bitmap bitmap = decodeSampledBitmapFromResource(

  20. getResources(), params[0], 100, 100));

  21. }

  22. // Add final bitmap to caches

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

img
img

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V:vip204888 备注Android获取(资料价值较高,非无偿)
img

设计模式学习笔记

设计模式系列学习视频

,并且后续会持续更新**
如果你觉得这些内容对你有帮助,可以添加V:vip204888 备注Android获取(资料价值较高,非无偿)
[外链图片转存中…(img-VskzxbNv-1711598894826)]

设计模式学习笔记

[外链图片转存中…(img-jg7VL3sm-1711598894826)]

设计模式系列学习视频

[外链图片转存中…(img-eHM2lRms-1711598894827)]

本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值