Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Android学习笔记 - BitmapFun解析

Android学习笔记 - BitmapFun解析

作者头像
我思故我在
发布于 2022-05-07 08:16:26
发布于 2022-05-07 08:16:26
34600
代码可运行
举报
文章被收录于专栏:我思故我在我思故我在
运行总次数:0
代码可运行

如果图片资源是静态的,当我们要在View上显示图片时,只需要简单的将图片赋值给ImageView就可以了,但如果需要浏览网络上的图片时该如何做呢?有可能图片很大,有可能网速很慢并且不稳定,这种情况下该如何增加用户体验。Android官方的BitmapFun示例程序已经给了我们很好的解决方法 - 其实万变不离其中,还是采用了提升性能的两种常用方法:异步和缓存

不多说我们先来看BitmapFun的主要类图:

ImageWorker:这个是加载图片的核心类,建议大家看源代码从这个类看起。它的主要功能是从内存/磁盘缓存中加载图片,或者是从网络上下载。这里第一要使用缓存,第二从网络上下载,必然要使用异步线程,所以这里从类图中大家也可以看到它有两个关联类BitmapWorkerTask(继承自AsynTask)和ImageCache, 分别用来处理异步和缓存。

ImageWorker提供给外部的主要接口是loadImage方法 - 加载图片,如果内存中有,直接加载。否则使用异步线程(BitmapWorkerTask)后台加载 - 从磁盘或者是网络上下载

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 public void loadImage(Object data, ImageView imageView) {}

BitmapWorkerTask: 异步处理图片 - 下载并绑定图片

ImageCache: 图片的缓存处理,这里使用了二级缓存: 内存和磁盘。这里从类图也可以看到它有一个关联类DiskLruCache。

DiskLruCache: 关于这个类网上有一些详尽的解释文章。在看这个类时切忌一开始就看代码,一定要先看类的说明,主要是journal file的格式,否则你就很难明白它的一些代码为什么那么写。这里把几个重点提一下,相信大家再看代码会容易的多

  1 前5行是固定(最开始是固定的5行,值是可变)

  2 一条记录用类Entry来描述,一条记录就是一个Entry实例, 比如 CLEAN 3400330d1dfc7f3f7f4b8d4d803dfcf6 832 21054 在程序中就是一个Entry实例

  3 Editor是Entry的操作器,用来读写数据

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
     *     libcore.io.DiskLruCache
     *     1
     *     100
     *     2
     *
     *     CLEAN 3400330d1dfc7f3f7f4b8d4d803dfcf6 832 21054
     *     DIRTY 335c4c6028171cfddfbaae1a9c313c52
     *     CLEAN 335c4c6028171cfddfbaae1a9c313c52 3934 2342
     *     REMOVE 335c4c6028171cfddfbaae1a9c313c52
     *     DIRTY 1ab96a171faeeee38496d8b330771a7a
     *     CLEAN 1ab96a171faeeee38496d8b330771a7a 1600 234
     *     READ 335c4c6028171cfddfbaae1a9c313c52
     *     READ 3400330d1dfc7f3f7f4b8d4d803dfcf6
     *

写到这里先停一下,我们再次说明ImageWorker的功能,从内存直接加载或异步加载(从磁盘缓存或网络下载)图片。缓存的实现-ImageCache, 异步加载的实现 - BitmapWorkerTask。是不是比较清晰了。

接下来继续往下看:

ImageResizer:继承自ImageWorker,可能有的童鞋会问ImageWorker不是已经实现异步和缓存了吗,这个类是干嘛的呢?这个主要是根据给定的大小对Image做调整。比如当图片太大时,不能简单的加载到内存,需要做大小调整处理。

这里对它的几个主要接口说明一下:

  setImageSize:设置图片要调整的大小

  calculateInSampleSize: 计算缩放比例 - 根据原图大小和要调整后的大小计算

  decodeSampledBitmapFrom***:得到调整大小后的图片,,这里好几个方法,数据源不一样而已,没啥大区别。

ImageFetcher:继承自ImageResizer。从网络下载图片。这里要澄清一点,processBitmap在ImageWorker中是一个抽象方法,并没有实现体,在本示例中,是在ImageFetcher中实现的。之所以这样设计,是因为图片的来源是不确定和可变的,有可能从网络下载,有可能从本地数据库获取。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    protected abstract Bitmap processBitmap(Object data);

 最后就是在View这一层如何来使用了,从类图中可以看出,View这一层基本上操作ImageFetcher就可以了。以IamgeGridFragment为例:

1 在onCreate中实例化ImageFetcher,并且添加缓存处理实例

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // The ImageFetcher takes care of loading images into our ImageView children asynchronously
        mImageFetcher = new ImageFetcher(getActivity(), mImageThumbSize);
        mImageFetcher.setLoadingImage(R.drawable.empty_photo);
        mImageFetcher.addImageCache(getActivity().getSupportFragmentManager(), cacheParams);
    }

2 onCreateView中异步加载图片

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 @Override
    public View onCreateView(
           
        mGridView.setAdapter(mAdapter);
   }      

ImageAdapter.getView - 调用ImageFetcher.loadImage加载图片

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Override
        public View getView(int position, View convertView, ViewGroup container) {
            mImageFetcher.loadImage(Images.imageThumbUrls[position - mNumColumns], imageView);
            return imageView;
        }

3 在destroty时候关闭缓存

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Override
    public void onDestroy() {
        super.onDestroy();
        mImageFetcher.closeCache();
    }

 源码下载地址: http://commondatastorage.googleapis.com/androiddevelopers/shareables/training/BitmapFun.zip

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2013-12-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
[翻译]Bitmap的异步加载和缓存
本文主要介绍了如何在Android开发中实现高效的图片加载和显示。首先介绍了如何通过自定义ImageView和Bitmap类来优化图片加载和显示,然后介绍了如何使用AsyncDrawable和BitmapWorkerTask类来实现异步加载和显示图片,最后给出了一组示例代码和注意事项。
用户1172465
2018/01/08
1.9K0
Android实现图片异步加载操作
Android实现图片异步加载操作 在Android开发过程中,为了防止阻塞UI,图片加载时经常采用异步的方法来加载,异步加载图片的主要流程是进行判断缓存中是否存在图片,如果存在则直接返回,如果不存在则进行下载并进行缓存。 以下是建立一个异步下载类: /** * User: Tom * Date: 13-5-13 * Time: 下午8:07 */ public class AsnycImageLoader { //定义一个HashMap进行存放缓存的Image key为String Val
用户1289394
2018/02/26
1.3K0
Android照片墙完整版,完美结合LruCache和DiskLruCache
用户1158055
2018/01/05
1.6K0
Android照片墙完整版,完美结合LruCache和DiskLruCache
listview异步加载图片并防止错位
android listview 异步加载图片并防止错位 网上找了一张图, listview 异步加载图片之所以错位的根本原因是重用了 convertView 且有异步操作. 如果不重用 conv
xiangzhihong
2018/02/01
9380
listview异步加载图片并防止错位
Android开发笔记(七十七)图片缓存算法
由于手机流量有限,又要加快app的运行效率,因此好的app都有做图片缓存。图片缓存说起来简单,做起来就用到很多知识点,可算是集Android技术之大全了。只要理解图片缓存的算法,并加以实践把它做好,我觉得差不多可以懂半个Android的开发。
aqi00
2019/01/18
1.1K0
Android ListView异步加载图片乱序问题,原因分析及解决方案
用户1158055
2018/01/08
1.8K0
Android ListView异步加载图片乱序问题,原因分析及解决方案
Bitmap的加载和Cache
“Bitmap,表示位图,由像素点构成。Bitmap的承载容器是jpg、png等格式的文件,是对bitmap的压缩。当jpg、png等文件需要展示在手机上的控件时,就会解析成Bitmap并绘制到view上。通常处理图片时要避免过多的内存使用,毕竟移动设备的内存有限。”
胡飞洋
2020/07/23
6430
实例演示Android异步加载图片
本文给大家演示异步加载图片的分析过程。让大家了解异步加载图片的好处,以及如何更新UI。 首先给出main.xml布局文件: 简单来说就是 LinearLayout 布局,其下放了2个TextView和
欢醉
2018/01/22
1.5K0
DiskLruCache解析
https://github.com/JakeWharton/DiskLruCache
用户1205080
2018/10/18
9890
大量图片优化
最近在练习中用GridView加入相册中图片发现加入大量的相片之后,GirdView会变得很卡,想到或许可以用异步加载的方式来解决,但是能力有限,想得到却无法实现。在读了一些大牛的博客和代码之后,终于实现了。 1  在异步加载之前的代码的和普通加载代码一样,只需要在GirdView的Adapter的public View getView(int position, View convertView, ViewGroupparent)方法使用异步加载的方式返回ImageView。 2  如果能把加载过的
xiangzhihong
2018/01/30
9500
listview优化(中)
1,对Imageview使用setTag()方法来解决图片错位问题,这个Tag中设置的是图片的url,然后在加载的时候取得这个url和要加载那position中的url对比,如果不相同就加载,相同就是复用以前的就不加载了 2,对于要加载的图片资源,先在内存缓存中找(原始的方法是使用SoftRefrence,最新的方法是使用android提供的Lrucache),如果找不到,则在本地缓存(可以使用DiskLrucache类)中找(也就是读取原先下载过的本地图片),还找不到,就开启异步线程去下载图片,下载以
xiangzhihong
2018/01/30
1.2K0
Art of Android Development Reading Notes 12
《Android开发艺术探索》读书笔记 (12) 第12章 Bitmap的加载和Cache
宅男潇涧
2018/08/01
4120
高频面试点:Android性能优化之内存优化(下篇)
链接:https://juejin.im/post/5e72b2d151882549236f9cb8
陈宇明
2020/12/16
6420
【Android应用开发】 Universal Image Loader ( 使用简介 | 示例代码解析 )
转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/50824912
韩曙亮
2023/03/27
1.2K0
【Android应用开发】 Universal Image Loader ( 使用简介 | 示例代码解析 )
Android照片墙应用实现,再多的图片也不怕崩溃
根据文章内容为用户返回摘要总结。
用户1158055
2018/01/05
1.7K0
Android照片墙应用实现,再多的图片也不怕崩溃
OKHttp源码解析(七)--中阶之缓存机制
Entry内部类是实际用于存储的缓存数据的实体类,每一个url对应一个Entry实体
隔壁老李头
2018/08/30
1.1K0
Android 开发艺术探索笔记三
常用的缓存策略:LruCache与DiskLruCache,其中LruCache用作内存缓存,而DiskLruCache用作磁盘缓存。
Yif
2019/12/26
5840
android使用LruCache对listview加载图片时候优化处理
注意:LruCache是有版本限制的,低版本的sdk需要在libs文件夹添加相应的support-4v文件。 本文改造的大部分是参考http://www.iteye.com/topic/1118828,感谢。 不废话直接上工程代码,内有关键注释,项目就不上传了,自己对照着上面网址改呗。 首先是Application文件,负责创建图片存储文件夹: public class MyApp extends Application{ @Override public void onCrea
xiangzhihong
2018/01/29
8510
Android车轮之图片加载框架Android-Universal-Image-Loader
前言:从学习Android已经有十周时间了,之前都在学习PHP脚本语言,曾经还用纯php写了一个小型论坛,虽然不难,即使你用的东西自己同样封装了,但是最终总是感觉不太舒服,后来就用了国内的ThinkPHP框架作为框架学习,然而就慢慢体验到了使用框架的好处,比如优化的程序较好,更容易学习到框架里面不错的知识模块...... 其实Android也是一样的,倘若你开发一个项目的话,一切都从零开始,嘿嘿,那你就可悲╮(╯▽╰)╭,对于开源的东西,学会选择轮子以及会用轮子对于开发项目是非常重要的,接下来介绍的轮子就
AlicFeng
2018/06/08
6650
Android 三重缓存
在 Android 应用中不可避免地要显示很多图片,如果不做处理,不管图片是否显示过,每次启动时都需要从网络拉取,这就极大影响了图片加载速度和浪费用户流量,并且整个应用中的图片内存无法控制在一个总的范围内。因此,图片缓存在一个图片加载模块中很重要并且不可缺少。
全栈程序员站长
2022/08/31
4740
Android 三重缓存
相关推荐
[翻译]Bitmap的异步加载和缓存
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验