I\'m a newbie programmer an I\'m making an android program that displays an image on ImageView from a given url. My problem is how do you use this on the AsyncTask?
Thes
well, I dont know why android SDK does not provide support for it (yet) I extended the ImageView class by UrlImageView class with asynchronous loading and caching support. I put the code of my class below, which is plug and play. The class body is at the end of my post, now I write two lines how to use it the convenient way.
Two more methods now are supported:
setImageUrl(URL url) // sets the bitmap by its URL
cancelLoading(); // tell this view to cancel pending load
How to use your java-code:
// [somewhere in your activity]
UrlImageView urlImg = new UrlImageView(this).setImageUrl("http://abc.png");
...
urlImg.setImageUrl("http://abc2.png"); // works like expected
How to bind in your layouts:
..and again in your activity java code:
((UrlImageView)findViewById(R.id.thumbnail)).setImageUrl("http://foo.bar.png");
I use it in lists with more than 100 entries - flinging very well. Here the class body, you can use it, modify it, extend it, whatever you like:
package com.gplushub.android.view;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.ImageView;
/**
* an {@link ImageView} supporting asynchronous loading from URL. Additional
* APIs: {@link #setImageURL(URL)}, {@link #cancelLoading()}.
*
* @author ep@gplushub.com / Eugen Plischke
*
*/
public class UrlImageView extends ImageView {
private static class UrlLoadingTask extends AsyncTask {
private final ImageView updateView;
private boolean isCancelled = false;
private InputStream urlInputStream;
private UrlLoadingTask(ImageView updateView) {
this.updateView = updateView;
}
@Override
protected Bitmap doInBackground(URL... params) {
try {
URLConnection con = params[0].openConnection();
// can use some more params, i.e. caching directory etc
con.setUseCaches(true);
this.urlInputStream = con.getInputStream();
return BitmapFactory.decodeStream(urlInputStream);
} catch (IOException e) {
Log.w(UrlImageView.class.getName(), "failed to load image from " + params[0], e);
return null;
} finally {
if (this.urlInputStream != null) {
try {
this.urlInputStream.close();
} catch (IOException e) {
; // swallow
} finally {
this.urlInputStream = null;
}
}
}
}
@Override
protected void onPostExecute(Bitmap result) {
if (!this.isCancelled) {
// hope that call is thread-safe
this.updateView.setImageBitmap(result);
}
}
/*
* just remember that we were cancelled, no synchronization necessary
*/
@Override
protected void onCancelled() {
this.isCancelled = true;
try {
if (this.urlInputStream != null) {
try {
this.urlInputStream.close();
} catch (IOException e) {
;// swallow
} finally {
this.urlInputStream = null;
}
}
} finally {
super.onCancelled();
}
}
}
/*
* track loading task to cancel it
*/
private AsyncTask currentLoadingTask;
/*
* just for sync
*/
private Object loadingMonitor = new Object();
public UrlImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public UrlImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public UrlImageView(Context context) {
super(context);
}
@Override
public void setImageBitmap(Bitmap bm) {
cancelLoading();
super.setImageBitmap(bm);
}
@Override
public void setImageDrawable(Drawable drawable) {
cancelLoading();
super.setImageDrawable(drawable);
}
@Override
public void setImageResource(int resId) {
cancelLoading();
super.setImageResource(resId);
}
@Override
public void setImageURI(Uri uri) {
cancelLoading();
super.setImageURI(uri);
}
/**
* loads image from given url
*
* @param url
*/
public void setImageURL(URL url) {
synchronized (loadingMonitor) {
cancelLoading();
this.currentLoadingTask = new UrlLoadingTask(this).execute(url);
}
}
/**
* cancels pending image loading
*/
public void cancelLoading() {
synchronized (loadingMonitor) {
if (this.currentLoadingTask != null) {
this.currentLoadingTask.cancel(true);
this.currentLoadingTask = null;
}
}
}
}