`
samwong
  • 浏览: 290576 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Android的ListView异步下载图片官方提供的源码

 
阅读更多


源文:

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

    这里的“android listView 异步加载图片”指的是在不阻塞UI线程的情况下,从网络、本地存储或其他来源加载图片到ListView中的技术。 这篇名为“ImageLoader”的Java文件很可能就是一个实现图片异步加载的工具类。在...

    Android应用源码 ListView下拉刷新 Demo

    这个"Android应用源码 ListView下拉刷新 Demo"提供了一个实际的例子,帮助开发者了解如何在ListView中实现这一功能。 1. **SwipeRefreshLayout**:Android SDK 提供了一个名为SwipeRefreshLayout的布局容器,它是...

    android ListView异步加载图片源码

    在项目里面使用ListView,并要求ListView的条目中有图片显示,而且这个图片是通过网络动态获取的。 这时候,会发现ListView加载很慢,半天才显示出来,影响了用户的体验。...应该另外开辟线程异步下载图片。

    android listview 异步加载图片并防止错位

    在提供的AsyncImageLoader-master项目中,可能包含了具体的实现方式,可以参考其源码学习如何自定义一个异步图片加载器。通过实践和理解这些原理,开发者可以更好地优化自己的应用,提供流畅的图片加载体验。

    Android ListView中异步获取图片 源码

    因此,Android开发者需要掌握如何在ListView中异步获取并加载网络图片。本文将深入探讨这一主题,提供相关的源码分析。 首先,异步加载图片的目标是将耗时的操作(如网络请求和图片解码)移到后台线程,以避免阻塞...

    Android ListView实现各种版面设计功能 源码

    在Android开发中,ListView是一种非常常见的控件,用于展示大量数据列表。本资源"Android ListView实现各种版面设计...这个源码资源提供了一个很好的学习平台,帮助开发者深入理解并掌握Android ListView的高级用法。

    listview异步加载源码

    综上所述,"listview异步加载源码"涉及到的主要知识点包括Android线程模型、异步加载策略、AsyncTask、CursorLoader和LoaderManager的使用、RecyclerView优化以及图片加载库的使用。理解并掌握这些知识点,能够帮助...

    ListView异步加载网络图片

    总之,ListView异步加载网络图片是一项关键技术,它涉及到Android多线程、内存管理和图片缓存策略。合理地运用这些技术,可以构建出性能优良、用户体验良好的应用。同时,使用SoftReference可以平衡内存使用和图片...

    Android Listview下拉刷新上拉加载源码

    在深入研究"Android Listview下拉刷新上拉加载源码"提供的代码之前,开发者应了解这些基本概念和流程。此外,对于性能优化,还需考虑异步加载数据、避免内存泄漏和防止过度绘制等问题。总之,这个资源对于想要在...

    Android ListView 固定列头源码

    标题"Android ListView 固定列头源码"提示我们将讨论如何在ListView中实现这样的功能。 在Android中,实现ListView固定列头的一种常见方法是使用自定义适配器和布局管理器。一种常见的实现方式是创建两个ListView:...

    Android应用源码动态ListView,支持异步更新列表,异步更新图片.zip

    本示例中的“Android应用源码动态ListView,支持异步更新列表,异步更新图片.zip”提供了一个实现动态加载和异步更新功能的ListView的实例。下面将详细讲解这个主题中的关键知识点。 1. **动态ListView**: - 动态...

    Android ListView分页功能源码

    Android SDK提供了一个AbsListView.OnScrollListener接口,我们可以为ListView设置该监听器,通过实现`onScrollStateChanged()`和`onScroll()`方法来判断是否已经滚动到底部。例如,当滚动状态改变且最后一条数据...

    安卓Android源码——listview实现图片的异步加载.zip

    本资料“安卓Android源码——listview实现图片的异步加载.zip”应该包含一个示例项目,演示了如何在ListView中高效地加载网络图片。 1. **异步加载原理**:异步加载是为了避免主线程(UI线程)被阻塞,将耗时的图片...

    Android实现ListView的增删改查Demo

    在Android开发中,ListView是一种常用的UI组件,用于展示大量数据列表。这个"Android实现ListView的增删改查Demo"是一个实战教程,旨在教你如何在Android应用中实现对ListView中的数据进行添加、删除、修改和查询...

    安卓Android源码——动态ListView,支持异步更新列表,异步更新图片.zip

    本项目“安卓Android源码——动态ListView,支持异步更新列表,异步更新图片”提供了一种解决方案,通过异步加载机制优化用户体验。 1. **ListView的工作原理**: - ListView通过复用convertView来提高性能,减少...

    Android ListView分页功能源码.zip源码资源下载

    本资源提供了一个关于Android ListView分页功能的源码示例,帮助开发者深入理解并实现这一功能。下面将详细阐述相关知识点。 1. **ListView基础**: - ListView是Android SDK中的一个ViewGroup,它能滚动显示多个...

    android Listview分批加载+自动加载改进版 源码下载

    提供的源码`Listview_auto_load_onScroll`可能包含了以下关键部分: 1. **ListView的适配器(Adapter)**:适配器需要处理新数据的添加,通常会有一个专门的方法用于加载更多数据,如`loadMoreData()`。 2. **滚动...

    Android listview获取网络图片缓存优化源码.zip

    综上所述,优化Android ListView中网络图片的加载涉及到多个层次的技术,包括异步加载、缓存策略、图片库选择、Bitmap配置、ViewHolder模式以及适配器和滚动事件的处理。通过综合运用这些技术,我们可以显著提高...

    Android源码——ListView分页功能源码.zip

    - Android的Loader框架可以很好地处理异步数据加载,配合LoaderManager监听数据变化,实现ListView的分页加载。 5. **使用RecyclerView和Pagination Library**: - RecyclerView是ListView的现代替代品,配合官方...

Global site tag (gtag.js) - Google Analytics