`
samwong
  • 浏览: 282218 次
  • 性别: 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);
  }
}



分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics