一个开源项目,关于图像异步缓存下载的简单apps,网上有相应的代码,但是没有任何说明和讲解(英文blog中有,讲了一下框架),那就自己研究吧。
主要对ImageDownloader分析:
Bitmap downloadBitmap(String url);//从网站下载一幅图片,比较简单
HttpClient:
AndroidHttpClient:Apache DefaultHttpClient的子类,已经配置好默认的合理设置和Android注册过的方案。不能直接创建对象。
AndroidHttpClient newInstance(String userAgent,Context context)创建一个新HttpClient对象。
HttpResponse:一个HTTP应答。
HttpEntity getEntity(),获得应答的消息实例
HttpEntity:一个可以发送接收HTTP消息的实例。
在一些情况下,javaDoc根据它们的内容来源把entity分三种:streamed,即内容来源是数据流,一般不可重复的;self-contained,内容来自内
存也意味着和连接以及其他entities没有关系,一般可重复;wrapping,内容从另一个entity获得。
InputStream getContent():创建实例的一个新的InputStream对象
consumeContent():这个方法被调用意味着这个实例的内容不再被请求了,而该实例分配的所有资源都会被释放。
但是在 BitmapFactory.decodeStream
之前版本的bug可能会阻止代码进行慢连接,而newFlushedInputStream(inputStream)方法可以解决这个问题。
static class FlushedInputStream extends FilterInputStream;其中里面的skip函数是为了使在以后的读输入流时准确的跳过n个字节。
public FlushedInputStream(InputStream inputStream) {
super(inputStream);
}
@Override
publiclong skip(long n) throws IOException {
long totalBytesSkipped =0L;
while (totalBytesSkipped < n) {
long bytesSkipped = in.skip(n - totalBytesSkipped);
if (bytesSkipped ==0L) {
intbyte= read();//read()只读一个字节,但返回0~255的随机数
if (byte<0) {
break; //到文件结尾
} else {
bytesSkipped =1; // 读一个字节,这里当跳过0个字节时为什么要读一个字节不是太懂……
}
}
totalBytesSkipped += bytesSkipped;
}
return totalBytesSkipped;
}
}
如果在ListAdapter的getView方法中直接下载图片,效果会很卡,因为每一个新图像的显示都要等图像下载下来。
非常遗憾的是,AndroidHttpClient竟然不能在主线程里运行,否则会显示"This thread forbids HTTP requests" 错误信息。对于AsyncTask类,它提供其中一个最简单的方法来使新任务脱离UI线程运行。
我们创建了一个ImageDownloader类来负责生成这些新的下载任务(task),它提供download方法来分配一张从URL下载的图片到对应的ImageView中。
publicvoid download(String url, ImageView imageView) {
BitmapDownloaderTask task =new BitmapDownloaderTask(imageView);
task.execute(url);
}
}
BitmapDownloaderTask是AsyncTask的子类,用来实际下载图片的。调用execute(url)来运行它,能够立即返回结果,这也是UI线程调用它的主要原因。
其中doInBackground方法中调用了downloadBitmap来下载图片,onPostExecute是当下载结束时UI线程调用的,将存储在BitmapDownloaderTask中的imageView和下载的Bitmap相关联,而这个ImageView是一个弱引用,可以被系统回收,所以要在onpostExecute中检查弱引用和这个imageView不为空。
private String url;
privatefinal WeakReference<ImageView> imageViewReference;
public BitmapDownloaderTask(ImageView imageView) {
imageViewReference =new WeakReference<ImageView>(imageView);
}
@Override
// Actual download method, run in the task thread
protected Bitmap doInBackground(String... params) {
// params comes from the execute() call: params[0] is the url.
return downloadBitmap(params[0]);
}
@Override
// Once the image is downloaded, associates it to the imageView
protectedvoid onPostExecute(Bitmap bitmap) {
if (isCancelled()) {
bitmap =null;
}
if (imageViewReference !=null) {
ImageView imageView = imageViewReference.get();
if (imageView !=null) {
BitmapDownloaderTask bitmapDownloaderTask = getBitmapDownloaderTask(imageView);
// Change bitmap only if this process is still associated with this ImageView
if(this== bitmapDownloaderTask){
imageView.setImageBitmap(bitmap);
}
}
}
}
对于ListView上的图像浏览,当用户快速滑动ListView时,某一个ImageView对象会被用到很多次,每一次显示都会触发一个下载,然后改变对应的图片。和大多数并行应用一样,有顺序相关的问题。在这个程序中,不能保证下载会按开始的顺序结束,有可能先开始的后下载完,“ The result is that the image finally displayed in the list may come from a previous item, which simply happened to have taken longer to download. ” 结果就是,由于与该item对应的网络图片下载慢,导致该item位置还暂时显示着之前的item显示的图片(还没被刷新,有可能长时间不被刷新)
为了解决这个问题,我们应该记住下载的顺序,使得最后的下载会被有效地显示,要让每一个ImageView记住它们的上一次下载任务。因此我们给出了DownloadedDrawable类,向ImageView中加入对对应下载任务的弱引用来暂时绑定正在下载图片的ImageView。
static class DownloadedDrawable extends ColorDrawable ;//该类包含了一个对下载的弱引用
public DownloadedDrawable(BitmapDownloaderTask bitmapDownloaderTask) {
super(Color.BLACK);
bitmapDownloaderTaskReference =
new WeakReference<BitmapDownloaderTask>(bitmapDownloaderTask);
}
public BitmapDownloaderTask getBitmapDownloaderTask() {
return bitmapDownloaderTaskReference.get();
上面ImageDownload中的download修改为:
if (cancelPotentialDownload(url, imageView)) {
BitmapDownloaderTask task =new BitmapDownloaderTask(imageView);
DownloadedDrawable downloadedDrawable =new DownloadedDrawable(task);
imageView.setImageDrawable(downloadedDrawable);
task.execute(url);
}
}
private static BitmapDownloaderTask getBitmapDownloaderTask(ImageView imageview);
//通过ImageView得到对应的下载
if (imageView !=null) {
Drawable drawable = imageView.getDrawable();
if (drawable instanceof DownloadedDrawable) {
DownloadedDrawable downloadedDrawable = (DownloadedDrawable)drawable;
return downloadedDrawable.getBitmapDownloaderTask();
}
}
returnnull;
}
下面总结下载过程:
download(url , imageview)——>
@创建一个和该imageview相对应的下载任务,这个任务对imageview进行弱引用
@创建与这个任务相对应的DownloadedDrawable,对这个任务弱引用
@imageview加载DownloadedDrawable
@执行下载任务,下载对应url的图像 ——execute(url)进入下载任务类
在下载任务类中:
——>doInBackground ===>downloadBitmap(url) 下载图片,结果Bitmap作为下面的参数
——>onPostExcute(Bitmap)
@获得任务引用的imageview
@通过DownloadedDrawable获得该imageview所对应的任务
@如果当前任务是这个imageview所对应的任务,则设置这个imageview的图片为下载下
来的Bitmap
imageview和任务相互弱引用,形成绑定关系
相关推荐
[开源项目]Android_炫酷的3D音乐播放器_各种特效OpenGL[开源项目]Android_炫酷的3D音乐播放器_各种特效OpenGL[开源项目]Android_炫酷的3D音乐播放器_各种特效OpenGL[开源项目]Android_炫酷的3D音乐播放器_各种特效...
[开源]HTTP协议相关Android开源_android-async-http-master
【开源项目jamendo-android】是一个基于Android平台的音乐播放应用,其源代码是公开的,允许开发者进行查看、学习和修改。这个项目的核心是提供一个平台,让用户能够免费收听和分享独立音乐人的作品,同时也为开发者...
"android-flip"是一个开源项目,专门针对Android平台设计,提供了左右和上下翻页的功能,为开发者提供了一种实现翻页动画的解决方案。这个项目对于那些希望在应用中加入翻页效果的开发者来说,无疑是一个宝贵的资源...
- Android-x86 是一个开源项目,旨在为x86架构的设备(如个人电脑、笔记本电脑和平板电脑)提供Android操作系统支持。 - 该项目通过移植Android源代码到x86平台,使得用户能够在非ARM架构的硬件上运行原生的...
作为开源项目,`android-backup-extractor`具有以下优势: - 可定制性:用户可以根据自己的需求修改代码,实现特定功能。 - 透明度:源代码公开,用户可以验证工具的安全性和隐私保护。 - 社区支持:开发者社区...
Omni-Notes:开源笔记Android应用程序,有许多功能比如分享,搜索,附加图片,视频,音频,在笔记中涂鸦,添加提醒等。
github上的开源项目android-pdfview,集成后需要添加libvudroid.so依赖.亲测可以打开本地pdf文件在应用中进行浏览翻页,效果不错。
`android-async-http`是一个非常流行的开源框架,用于简化Android应用程序中的HTTP网络请求。本文将深入探讨这个框架的核心特性、使用方法以及其在处理JSON数据方面的优势。 一、框架简介 `android-async-http`,...
顶部图片循环播放开源库Android-ConvenientBanner的使用参考源码,文章地址:http://blog.csdn.net/xroocky/article/details/50837866
HotApp云笔记 - 精品开源demo-基于免费API(源代码+截图)HotApp云笔记 - 精品开源demo-基于免费API(源代码+截图)HotApp云笔记 - 精品开源demo-基于免费API(源代码+截图)HotApp云笔记 - 精品开源demo-基于免费API(源...
国外开源项目OpenHAB - 智能家居Android客户端 源代码 运行环境 Android 4.0 开放式家庭自动化的总线(openHAB)项目旨在提供一个通用的集成平台,为家庭自动化周围的一切事物。这是一个纯Java解决方案,完全基于...
【开源项目-gen2brain-go-sdl2-android-example.zip】是一个开源项目,主要目的是展示如何在Android平台上使用Go语言和SDL2库开发应用。这个项目由gen2brain创建,旨在为Go程序员提供一个实用的起点,让他们能够利用...
在Android应用开发中,图片加载优化是一个至关重要的环节,特别是在处理大量图片或者网络图片时,如果处理不当,可能会导致应用卡顿甚至崩溃。...这个开源组件是Android开发者的强大工具,值得在实际项目中广泛应用。
【Cocos2d-android-1学习笔记】 Cocos2d是一个开源的游戏开发框架,它为开发者提供了构建2D游戏、动态应用以及各种图形交互式体验的工具。在Android平台上,Cocos2d-x是一个非常流行的分支,它用C++编写,并且支持...
Facebook SDK for Android是一个开源库,允许开发者将Facebook集成到所开发的Android应用中。