源文:
http://android-developers.blogspot.com/2010/07/multithreading-for-performance.html
一个图片的下载体
static Bitmap downloadBitmap(String url) {
final AndroidHttpClient client = AndroidHttpClient.newInstance("Android");
final HttpGet getRequest = new HttpGet(url);
try {
HttpResponse response = client.execute(getRequest);
final int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
Log.w("ImageDownloader", "Error " + statusCode + " while retrieving bitmap from " + url);
return null;
}
final HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream inputStream = null;
try {
inputStream = entity.getContent();
final Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
return bitmap;
} finally {
if (inputStream != null) {
inputStream.close();
}
entity.consumeContent();
}
}
} catch (Exception e) {
// Could provide a more explicit error message for IOException or IllegalStateException
getRequest.abort();
Log.w("ImageDownloader", "Error while retrieving bitmap from " + url, e.toString());
} finally {
if (client != null) {
client.close();
}
}
return null;
}
作者说BitmapFactory.decodeStream
是有bug的,怎样fixed呢??
static class FlushedInputStream extends FilterInputStream {
public FlushedInputStream(InputStream inputStream) {
super(inputStream);
}
@Override
public long skip(long n) throws IOException {
long totalBytesSkipped = 0L;
while (totalBytesSkipped < n) {
long bytesSkipped = in.skip(n - totalBytesSkipped);
if (bytesSkipped == 0L) {
int byte = read();
if (byte < 0) {
break; // we reached EOF
} else {
bytesSkipped = 1; // we read one byte
}
}
totalBytesSkipped += bytesSkipped;
}
return totalBytesSkipped;
}
}
异步下载
public class ImageDownloader {
public void download(String url, ImageView imageView) {
BitmapDownloaderTask task = new BitmapDownloaderTask(imageView);
task.execute(url);
}
}
/* class BitmapDownloaderTask, see below */
}
class BitmapDownloaderTask extends AsyncTask<String, Void, Bitmap> {
private String url;
private final 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
protected void onPostExecute(Bitmap bitmap) {
if (isCancelled()) {
bitmap = null;
}
if (imageViewReference != null) {
ImageView imageView = imageViewReference.get();
if (imageView != null) {
imageView.setImageBitmap(bitmap);
}
}
}
}
处理并发(Handling concurrency)
static class DownloadedDrawable extends ColorDrawable {
private final WeakReference<BitmapDownloaderTask> bitmapDownloaderTaskReference;
public DownloadedDrawable(BitmapDownloaderTask bitmapDownloaderTask) {
super(Color.BLACK);
bitmapDownloaderTaskReference =
new WeakReference<BitmapDownloaderTask>(bitmapDownloaderTask);
}
public BitmapDownloaderTask getBitmapDownloaderTask() {
return bitmapDownloaderTaskReference.get();
}
}
public void download(String url, ImageView imageView) {
if (cancelPotentialDownload(url, imageView)) {
BitmapDownloaderTask task = new BitmapDownloaderTask(imageView);
DownloadedDrawable downloadedDrawable = new DownloadedDrawable(task);
imageView.setImageDrawable(downloadedDrawable);
task.execute(url, cookie);
}
}
private static boolean cancelPotentialDownload(String url, ImageView imageView) {
BitmapDownloaderTask bitmapDownloaderTask = getBitmapDownloaderTask(imageView);
if (bitmapDownloaderTask != null) {
String bitmapUrl = bitmapDownloaderTask.url;
if ((bitmapUrl == null) || (!bitmapUrl.equals(url))) {
bitmapDownloaderTask.cancel(true);
} else {
// The same URL is already being downloaded.
return false;
}
}
return true;
}
private static BitmapDownloaderTask getBitmapDownloaderTask(ImageView imageView) {
if (imageView != null) {
Drawable drawable = imageView.getDrawable();
if (drawable instanceof DownloadedDrawable) {
DownloadedDrawable downloadedDrawable = (DownloadedDrawable)drawable;
return downloadedDrawable.getBitmapDownloaderTask();
}
}
return null;
}
private static BitmapDownloaderTask getBitmapDownloaderTask(ImageView imageView) {
if (imageView != null) {
Drawable drawable = imageView.getDrawable();
if (drawable instanceof DownloadedDrawable) {
DownloadedDrawable downloadedDrawable = (DownloadedDrawable)drawable;
return downloadedDrawable.getBitmapDownloaderTask();
}
}
return null;
}
if (imageViewReference != null) {
ImageView imageView = imageViewReference.get();
BitmapDownloaderTask bitmapDownloaderTask = getBitmapDownloaderTask(imageView);
// Change bitmap only if this process is still associated with it
if (this == bitmapDownloaderTask) {
imageView.setImageBitmap(bitmap);
}
}
分享到:
相关推荐
这里的“android listView 异步加载图片”指的是在不阻塞UI线程的情况下,从网络、本地存储或其他来源加载图片到ListView中的技术。 这篇名为“ImageLoader”的Java文件很可能就是一个实现图片异步加载的工具类。在...
这个"Android应用源码 ListView下拉刷新 Demo"提供了一个实际的例子,帮助开发者了解如何在ListView中实现这一功能。 1. **SwipeRefreshLayout**:Android SDK 提供了一个名为SwipeRefreshLayout的布局容器,它是...
在项目里面使用ListView,并要求ListView的条目中有图片显示,而且这个图片是通过网络动态获取的。 这时候,会发现ListView加载很慢,半天才显示出来,影响了用户的体验。...应该另外开辟线程异步下载图片。
在提供的AsyncImageLoader-master项目中,可能包含了具体的实现方式,可以参考其源码学习如何自定义一个异步图片加载器。通过实践和理解这些原理,开发者可以更好地优化自己的应用,提供流畅的图片加载体验。
因此,Android开发者需要掌握如何在ListView中异步获取并加载网络图片。本文将深入探讨这一主题,提供相关的源码分析。 首先,异步加载图片的目标是将耗时的操作(如网络请求和图片解码)移到后台线程,以避免阻塞...
在Android开发中,ListView是一种非常常见的控件,用于展示大量数据列表。本资源"Android ListView实现各种版面设计...这个源码资源提供了一个很好的学习平台,帮助开发者深入理解并掌握Android ListView的高级用法。
综上所述,"listview异步加载源码"涉及到的主要知识点包括Android线程模型、异步加载策略、AsyncTask、CursorLoader和LoaderManager的使用、RecyclerView优化以及图片加载库的使用。理解并掌握这些知识点,能够帮助...
总之,ListView异步加载网络图片是一项关键技术,它涉及到Android多线程、内存管理和图片缓存策略。合理地运用这些技术,可以构建出性能优良、用户体验良好的应用。同时,使用SoftReference可以平衡内存使用和图片...
在深入研究"Android Listview下拉刷新上拉加载源码"提供的代码之前,开发者应了解这些基本概念和流程。此外,对于性能优化,还需考虑异步加载数据、避免内存泄漏和防止过度绘制等问题。总之,这个资源对于想要在...
标题"Android ListView 固定列头源码"提示我们将讨论如何在ListView中实现这样的功能。 在Android中,实现ListView固定列头的一种常见方法是使用自定义适配器和布局管理器。一种常见的实现方式是创建两个ListView:...
本示例中的“Android应用源码动态ListView,支持异步更新列表,异步更新图片.zip”提供了一个实现动态加载和异步更新功能的ListView的实例。下面将详细讲解这个主题中的关键知识点。 1. **动态ListView**: - 动态...
Android SDK提供了一个AbsListView.OnScrollListener接口,我们可以为ListView设置该监听器,通过实现`onScrollStateChanged()`和`onScroll()`方法来判断是否已经滚动到底部。例如,当滚动状态改变且最后一条数据...
本资料“安卓Android源码——listview实现图片的异步加载.zip”应该包含一个示例项目,演示了如何在ListView中高效地加载网络图片。 1. **异步加载原理**:异步加载是为了避免主线程(UI线程)被阻塞,将耗时的图片...
在Android开发中,ListView是一种常用的UI组件,用于展示大量数据列表。这个"Android实现ListView的增删改查Demo"是一个实战教程,旨在教你如何在Android应用中实现对ListView中的数据进行添加、删除、修改和查询...
本项目“安卓Android源码——动态ListView,支持异步更新列表,异步更新图片”提供了一种解决方案,通过异步加载机制优化用户体验。 1. **ListView的工作原理**: - ListView通过复用convertView来提高性能,减少...
本资源提供了一个关于Android ListView分页功能的源码示例,帮助开发者深入理解并实现这一功能。下面将详细阐述相关知识点。 1. **ListView基础**: - ListView是Android SDK中的一个ViewGroup,它能滚动显示多个...
提供的源码`Listview_auto_load_onScroll`可能包含了以下关键部分: 1. **ListView的适配器(Adapter)**:适配器需要处理新数据的添加,通常会有一个专门的方法用于加载更多数据,如`loadMoreData()`。 2. **滚动...
综上所述,优化Android ListView中网络图片的加载涉及到多个层次的技术,包括异步加载、缓存策略、图片库选择、Bitmap配置、ViewHolder模式以及适配器和滚动事件的处理。通过综合运用这些技术,我们可以显著提高...
- Android的Loader框架可以很好地处理异步数据加载,配合LoaderManager监听数据变化,实现ListView的分页加载。 5. **使用RecyclerView和Pagination Library**: - RecyclerView是ListView的现代替代品,配合官方...