IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> 两种缓存Bitmap的方式,android界面设计实验报告 -> 正文阅读

[移动开发]两种缓存Bitmap的方式,android界面设计实验报告

  • 设备的屏幕大小与密度是多少? 一个具有特别高密度屏幕(xhdpi)的设备,像?Galaxy Nexus?会比?Nexus S?(hdpi)需要一个更大的Cache来hold住同样数量的图片.

  • 位图的尺寸与配置是多少,会花费多少内存?

  • 图片被访问的频率如何?是其中一些比另外的访问更加频繁吗?如果是,也许你想要保存那些最常访问的到内存中,或者为不同组别的位图(按访问频率分组)设置多个[LruCache]( )?对象。

  • 你可以平衡质量与数量吗? 某些时候保存大量低质量的位图会非常有用,在另外一个后台任务中加载更高质量的图片。

  • 没有指定的大小与公式能够适用与所有的程序,那取决于分析你的使用情况后提出一个合适的解决方案。一个太小的Cache会导致额外的花销却没有明显的好处,一个太大的Cache同样会导致java.lang.OutOfMemory的异常[Cache占用太多内存,其他活动则会因为内存不够而异常],并且使得你的程序只留下小部分的内存用来工作。

  • 下面是一个为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

  23. addBitmapToCache(String.valueOf(imageKey,?bitmap);

  24. return?bitmap;

  25. }

  26. }

  27. public?void?addBitmapToCache(String?key,?Bitmap?bitmap)?{

  28. //?Add?to?memory?cache?as?before

  29. if?(getBitmapFromMemCache(key)?==?null)?{

  30. mMemoryCache.put(key,?bitmap);

  31. }

  32. //?Also?add?to?disk?cache

  33. if?(!mDiskCache.containsKey(key))?{

//?Add?to?memory?cache?as?before

  1. if?(getBitmapFromMemCache(key)?==?null)?{

  2. mMemoryCache.put(key,?bitmap);

  3. }

  4. //?Also?add?to?disk?cache

  5. if?(!mDiskCache.containsKey(key))?{

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-01-29 23:11:58  更:2022-01-29 23:13:18 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 12:58:40-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码