Notice
Recent Posts
Recent Comments
반응형
오늘도 공부
[펌][Java/Android] 원격지 이미지 다운로드 (Remote Image Downloader) 본문
Android/Tip&Tech
[펌][Java/Android] 원격지 이미지 다운로드 (Remote Image Downloader)
행복한 수지아빠 2011. 8. 11. 15:56반응형
출처 : http://theeye.pe.kr/entry/downloading-remote-image-file-by-asynchronous-on-android
안드로이드에서 원격지에 이미지를 읽어오는 방식은 다양한 방식이 있습니다. 하지만 안드로이드 자체의 문제인지 3G환경 이하에서 이미지를 제대로 못 읽어오거나 현재의 동작에 영향을 주지 않는 별도의 쓰레드에서 동작하게 하는것은 쉽지 않습니다.
간단하게 사용할 수 있는 비동기 이미지 다운로더를 공개합니다. 구글 안드로이드 블로그에서 봤었던 다운로더에 제가 단순하게 만든 캐싱 기능을 추가하였습니다.
ImageDownloader.java
ImageDownloaderTask.java
안드로이드에서 원격지에 이미지를 읽어오는 방식은 다양한 방식이 있습니다. 하지만 안드로이드 자체의 문제인지 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; } } }
반응형
'Android > Tip&Tech' 카테고리의 다른 글
[펌]죽지않는 서비스 만들기 (2) | 2011.08.21 |
---|---|
안드로이드 AsyncTask 와 Thread 차이 (0) | 2011.08.20 |
[Android] 물에 반사된 듯한 이미지 효과 만들기. (0) | 2011.08.10 |
[안드로이드]이미지 합성하는 방법 (0) | 2011.08.10 |
[안드로이드]모바일 웹에서 이미지 업로드 가능(2.2부터) (0) | 2011.08.08 |