Android学习笔记 - BitmapFun解析

浏览:
字体:
发布时间:2013-12-13 14:31:35
来源:
如果图片资源是静态的,当我们要在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();
>更多相关文章
24小时热门资讯
24小时回复排行
资讯 | QQ | 安全 | 编程 | 数据库 | 系统 | 网络 | 考试 | 站长 | 关于东联 | 安全雇佣 | 搞笑视频大全 | 微信学院 | 视频课程 |
关于我们 | 联系我们 | 广告服务 | 免责申明 | 作品发布 | 网站地图 | 官方微博 | 技术培训
Copyright © 2007 - 2024 Vm888.Com. All Rights Reserved
粤公网安备 44060402001498号 粤ICP备19097316号 请遵循相关法律法规
');})();