Android学习笔记 - BitmapFun解析
如果图片资源是静态的,当我们要在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();
}
源码下载地址: http://commondatastorage.googleapis.com/androiddevelopers/shareables/training/BitmapFun.zip
Android学习笔记 - BitmapFun解析的更多相关文章
- Android 学习笔记之Volley(七)实现Json数据加载和解析...
学习内容: 1.使用Volley实现异步加载Json数据... Volley的第二大请求就是通过发送请求异步实现Json数据信息的加载,加载Json数据有两种方式,一种是通过获取Json对象,然后 ...
- Android学习笔记之JSON数据解析
转载:Android学习笔记44:JSON数据解析 JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,为Web应用开发提供了一种 ...
- android学习笔记36——使用原始XML文件
XML文件 android中使用XML文件,需要开发者手动创建res/xml文件夹. 实例如下: book.xml==> <?xml version="1.0" enc ...
- 【转】 Pro Android学习笔记(七十):HTTP服务(4):SOAP/JSON/XML、异常
目录(?)[-] SOAP JSON和XMLPullParser Exception处理 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件,转载须注明出处:http://blog. ...
- 【转】 Pro Android学习笔记(六七):HTTP服务(1):HTTP GET
目录(?)[-] HTTP GET小例子 简单小例子 出现异常NetworkOnMainThreadException 通过StrictMode进行处理 URL带键值对 Andriod应用可利用ser ...
- 【转】Pro Android学习笔记(十三):用户界面和控制(1):UI开发
目录(?)[-] UI开发 方式一通过XML文件 方式二通过代码 方式三XML代码 UI开发 先理清一些UI概念: view.widget.control:这三个名词其实没有什么区别,都是一个UI元素 ...
- 【转】Pro Android学习笔记(十二):了解Intent(下)
解析Intent,寻找匹配Activity 如果给出component名字(包名.类名)是explicit intent,否则是implicit intent.对于explicit intent,关键 ...
- 【转】Pro Android学习笔记(四):了解Android资源(下)
处理任意的XML文件 自定义的xml文件放置在res/xml/下,可以通过R.xml.file_name来获取一个XMLResourceParser对象.下面是xml文件的例子: <rootna ...
- 【转】Pro Android学习笔记(三):了解Android资源(上)
在Android开发中,资源包括文件或者值,它们和执行应用捆绑,无需在源代码中写死,因此我们可以改变或替换他们,而无需对应用重新编译. 了解资源构成 参考阅读Android学习笔记(三八):资源res ...
随机推荐
- Python In Action:二、 最小的GUI程序:麻雀虽小,五脏俱全
Python in Action第二个例子,倒是很简单,却是最基本的GUI程序框架,里面有最基本的实现GUI流程 import wx class MyApp(wx.App): def OnInit(s ...
- C# 内嵌其他程序到自己程序
写一xxx聊天机器人啊什么的可能会用到这种技术.比如把QQ窗体嵌入自己的winform中其实很简单,调用两个API函数即可. [DllImport("User32.dll ", E ...
- java并发编程(一)可重入内置锁
每个Java对象都可以用做一个实现同步的锁,这些锁被称为内置锁或监视器锁.线程在进入同步代码块之前会自动获取锁,并且在退出同步代码块时会自动释放锁.获得内置锁的唯一途径就是进入由这个锁保护的同步代码块 ...
- ehcache memcache redis 三大缓存
最近项目组有用到这三个缓存,去各自的官方看了下,觉得还真的各有千秋!今天特意归纳下各个缓存的优缺点,仅供参考! Ehcache 在Java项目广泛的使用.它是一个开源的.设计于提高在数据从RDBMS ...
- 前端开发与SEO
前端开发中通过一些小习惯,可以有利于SEO,本着蚊子再小也是肉的原则,能抓住自然不能忽略. 1.控制首页链接数量,不能过多,也不要太少.更不要为了凑数而添加 2.扁平化层次,力争跳转三次可以到任何页面 ...
- centos部署gitlab服务器
gitlab的安装和配置非常简单,关于git,这里摘抄一下百度百科: Git是一款免费.开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目.Git是一个开源的分布式版本控制系统,可以有效. ...
- Html中Table的简单使用
虽然Table布局已经过时,偶尔还是会用到,简要实用代码,如下: <table border="1" cellpadding="0" cellspacin ...
- jiajianhao
#include<stdio.h> int map[4][4]={ 0,1,0,0, 0,0,0,0, 0,0,0,0, 0,1,0,0}; int flag=0; int minci=9 ...
- iOS App Store上架新APP与更新APP版本
iOS App Store上架新APP与更新APP版本 http://www.jianshu.com/p/9e8d1edca148
- js,css小知识点记录
JS手册中提到:可以使用任意表达式作比较表达式.任何值为0.null.未定义或空字符串的表达式被解释为 false.其他任意值的表达式解释为 true.也就是说,这里会隐式的转换为布尔值. ...