文档章节

BitmapFun解析

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

     

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

     

     

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

     

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

     

     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的操作器,用来读写数据

     

     

         *     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中实现的。之所以这样设计,是因为图片的来源是不确定和可变的,有可能从网络下载,有可能从本地数据库获取。

     

        protected abstract Bitmap processBitmap(Object data);

     

     

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

     

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

     

     

    @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中异步加载图片

     

     @Override

        public View onCreateView(

               

            mGridView.setAdapter(mAdapter);

       }      

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

     

    @Override

            public View getView(int position, View convertView, ViewGroup container) {

                mImageFetcher.loadImage(Images.imageThumbUrls[position - mNumColumns], imageView);

                return imageView;

            }

    3 在destroty时候关闭缓存

     

    @Override

        public void onDestroy() {

            super.onDestroy();

            mImageFetcher.closeCache();



© 著作权归作者所有

共有 人打赏支持
今日竹石
粉丝 41
博文 227
码字总数 181312
作品 0
朝阳
程序员
私信 提问
我使用fragment+viewpager组合,结合bitmapfun

我使用fragment+viewpager组合,结合bitmapfun用来做图片缓存的东西,fragment页面内容是一个gridview,里面会有图和一些文字排版内容,总共有三项,平常bitmapfun使用结合gridview时,速度很...

Corotata
2013/07/11
1K
11
关于异步加载大量图片的问题,请指教!

@RyanHoo 你好,想跟你请教个问题:我在项目中用例google官方提供的bitmapfun,但是感觉加载速度确实很慢,看了你提供的demo,这里面数据过多那么创建的线程也就会很多,想请教一下你们项目中...

furan
2013/08/15
111
0
listView加载完美几百张图片(加载思路bitmapfun)

既上回拿出来这个项目之后我有参照着bitmapfun的思想修改了一下我的代码,之前是如果你滑动的话他会傻乎乎的把你整个都加载完之后,然后显示最后一屏,之后有听人说起bitmapfun说是google自己...

找到组织
2014/01/17
832
0
bitmapfun如何改造成能直接读SD卡上的文件

最近看到google的bitmapfun,他对图片的网络加载以及缓存做得很好,如果是要加载网络图片的话,无疑做是很好用的,但现在有个需求是,部分图片已经是以压缩包的形式下载解压放在了本地,也就...

Corotata
2013/06/22
420
1
求解 bitmapfun 显示混乱 bug

使用google 官方提供的bitmapfun异步图片加载 ,测试的时候偶然发现一个BUG,指定2个或者多个imageview显示的URL 一样的话,会显示错乱。但是如果滚动以后,在回来,显示又正常了,我只修改了...

Otherguy
2013/09/03
163
1

没有更多内容

加载失败,请刷新页面

加载更多

《资治通鉴》读书笔记及阅读感悟2200字

《资治通鉴》读书笔记及阅读感悟2200字: 1.用夏桀,商纣暴虐昏君和商汤,周武王仁德明君做比较,因为人民归心,上天赐名要不然就永远要恪守臣节至死不渝。 又用商朝的微子取代纣王,商朝可以...

原创小博客
10分钟前
0
0
十万个为什么之为什么大家都说dubbo

Dubbo是什么? 使用背景 dubbo为什么这么流行, 为什么大家都这么喜欢用dubbo; 通过了解分布式开发了解到, 为适应访问量暴增,业务拆分后, 子应用部署在多台服务器上,而多台服务器通过可以通过d...

尾生
48分钟前
2
0
Docker搭建代码质量检测平台-SonarQube(中文版)

Sonar是一个用于代码质量管理的开源平台,用于管理源代码的质量,可以从七个维度检测代码质量。通过插件形式,可以支持包括java,C#,C/C++,PL/SQL,Cobol,JavaScrip,Groovy等等二十几种编程语言...

Jacktanger
55分钟前
2
0
Windows / Linux / MacOS 设置代理上网的方法汇总

本文汇总了 Windows / Linux / MacOS 设置代理上网的各种方法,总结如下: 1、设置系统代理(Windows、Linux、MacOS) 2、设置代理插件(Chrome、Chromium、Firefox、Opera、QQ等浏览器) 3、...

sunboy2050
昨天
4
0
自定义 Maven 的 repositories

有时,应用中需要一些比较新的依赖,而这些依赖并没有正式发布,还是处于milestone或者是snapshot阶段,并不能从中央仓库或者镜像站上下载到。此时,就需要 自定义Maven的<repositories>。 ...

waylau
昨天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部