출처 : http://theeye.pe.kr/entry/downloading-remote-image-file-by-asynchronous-on-android
안드로이드에서 원격지에 이미지를 읽어오는 방식은 다양한 방식이 있습니다. 하지만 안드로이드 자체의 문제인지 3G환경 이하에서 이미지를 제대로 못 읽어오거나 현재의 동작에 영향을 주지 않는 별도의 쓰레드에서 동작하게 하는것은 쉽지 않습니다.

사용자 삽입 이미지
간단하게 사용할 수 있는 비동기 이미지 다운로더를 공개합니다. 구글 안드로이드 블로그에서 봤었던 다운로더에 제가 단순하게 만든 캐싱 기능을 추가하였습니다.


ImageDownloader.java
public class ImageDownloader 
{ 
  public static final int IMGAE_CACHE_LIMIT_SIZE = 50; 
  public static HashMap<String, Bitmap> mImageCache = new HashMap<String, Bitmap>(); 
   
  public static void download(String url, ImageView imageView) 
  { 
    Bitmap cachedImage = mImageCache.get(url); 
    if(cachedImage != null) 
    { 
      imageView.setImageBitmap(cachedImage); 
    } 
    else if(cancelPotentialDownload(url, imageView)) 
    { 
      if(mImageCache.size() > IMGAE_CACHE_LIMIT_SIZE) 
      { 
        mImageCache.clear(); 
      } 
       
      ImageDownloaderTask task = new ImageDownloaderTask(url, imageView); 
      DownloadedDrawable downloadedDrawable = new DownloadedDrawable(task); 
      imageView.setImageDrawable(downloadedDrawable); 
      task.execute(url); 
    } 
  } 
 
  private static boolean cancelPotentialDownload(String url, ImageView imageView) 
  { 
    ImageDownloaderTask bitmapDownloaderTask = getBitmapDownloaderTask(imageView); 
 
    if(bitmapDownloaderTask != null) 
    { 
      String bitmapUrl = bitmapDownloaderTask.url; 
      if((bitmapUrl == null) || (!bitmapUrl.equals(url))) 
      { 
        bitmapDownloaderTask.cancel(true); 
      } 
      else 
      { 
        return false; 
      } 
    } 
    return true; 
  } 
 
  private static ImageDownloaderTask getBitmapDownloaderTask(ImageView imageView) 
  { 
    if(imageView != null) 
    { 
      Drawable drawable = imageView.getDrawable(); 
      if(drawable instanceof DownloadedDrawable) 
      { 
        DownloadedDrawable downloadedDrawable = (DownloadedDrawable) drawable; 
        return downloadedDrawable.getBitmapDownloaderTask(); 
      } 
    } 
    return null; 
  } 
 
  static class DownloadedDrawable extends ColorDrawable 
  { 
    private final WeakReference<ImageDownloaderTask> bitmapDownloaderTaskReference; 
 
    public DownloadedDrawable(ImageDownloaderTask bitmapDownloaderTask) 
    { 
      super(Color.TRANSPARENT); 
      bitmapDownloaderTaskReference = new WeakReference<ImageDownloaderTask>(bitmapDownloaderTask); 
    } 
 
    public ImageDownloaderTask getBitmapDownloaderTask() 
    { 
      return bitmapDownloaderTaskReference.get(); 
    } 
  }

ImageDownloaderTask.java

public class ImageDownloaderTask extends AsyncTask<String, Void, Bitmap> 
{ 
  public String url; 
  public String targetUrl; 
  private WeakReference<ImageView> imageViewReference; 
 
  public ImageDownloaderTask(String url, ImageView imageView) 
  { 
    this.targetUrl = url; 
    this.imageViewReference = new WeakReference<ImageView>(imageView); 
  } 
 
  @Override 
  protected Bitmap doInBackground(String... params) 
  { 
    return downloadBitmap(params[0]); 
  } 
 
  @Override 
  protected void onPostExecute(Bitmap bitmap) 
  { 
    if(isCancelled()) 
    { 
      bitmap = null; 
    } 
 
    if(imageViewReference != null) 
    { 
      ImageView imageView = imageViewReference.get(); 
      ImageDownloaderTask bitmapDownloaderTask = getBitmapDownloaderTask(imageView); 
       
      if(this == bitmapDownloaderTask) 
      { 
        ImageDownloader.mImageCache.put(targetUrl, bitmap); 
        imageView.setImageBitmap(bitmap); 
      } 
    } 
  } 
   
  private ImageDownloaderTask getBitmapDownloaderTask(ImageView imageView) 
  { 
    if(imageView != null) 
    { 
      Drawable drawable = imageView.getDrawable(); 
      if(drawable instanceof DownloadedDrawable) 
      { 
        DownloadedDrawable downloadedDrawable = (DownloadedDrawable) drawable; 
        return downloadedDrawable.getBitmapDownloaderTask(); 
      } 
    } 
    return null; 
  } 
 
  static Bitmap downloadBitmap(String url) 
  { 
    final HttpClient client = new DefaultHttpClient(); 
    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; 
        //BitmapFactory.Options options = new BitmapFactory.Options(); 
        //options.inSampleSize = 2; 
         
        try 
        { 
          inputStream = entity.getContent(); 
          final Bitmap bitmap = BitmapFactory.decodeStream(new FlushedInputStream(inputStream)); 
          //final Bitmap bitmap = BitmapFactory.decodeStream(new FlushedInputStream(inputStream), null, options); 
          return bitmap; 
        } 
        finally 
        { 
          if(inputStream != null) 
          { 
            inputStream.close(); 
          } 
          entity.consumeContent(); 
        } 
      } 
    } 
    catch(Exception e) 
    { 
      getRequest.abort(); 
    } 
    return null; 
  } 
 
  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 bytes = read(); 
          if(bytes < 0) 
          { 
            break; // we reached EOF 
          } 
          else 
          { 
            bytesSkipped = 1; // we read one byte 
          } 
        } 
        totalBytesSkipped += bytesSkipped; 
      } 
      return totalBytesSkipped; 
    } 
  } 
}


+ Recent posts