public class ImageDownloader extends AsyncTask<String, Void, Drawable> {
Context context;
ImageView image;
public ImageDownloader(ImageView image) {
this.image = image;
}
protected void onPreExecute() {
}
protected Drawable doInBackground(String... urls) {
InputStream is;
Drawable d = null ;
try {
is = (InputStream)new URL(urls[0]).getContent();
d = Drawable.createFromStream(is, "Image");
return d;
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return d;
}
protected void onPostExecute(Drawable d) {
if(d != null){
d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
image.setBackgroundDrawable(d);
}else{
image.setBackgroundDrawable(context.getResources().getDrawable(R.drawable.noimage));
Toast.makeText(context, "No image", Toast.LENGTH_LONG).show();
}
}
}
because it's working in the beginning but when i download a lot of images it crash. I looked in my LogCat and this is because there is no more allocation for it.
I want to do do an application like Pulse News, which display images but doesn't crash everytime. And i'm in ice cream sandwich, just in case.
You need to know about SoftReference class in java.
Go ahead and search for it.You will get your answer
I found this class and it works fine, very fine !
public class LoaderImageView extends LinearLayout{
private static final int COMPLETE = 0;
private static final int FAILED = 1;
private Context mContext;
private Drawable mDrawable;
private ProgressBar mSpinner;
private ImageView mImage;
/**
* This is used when creating the view in XML
* To have an image load in XML use the tag 'image="http://developer.android.com/images/dialog_buttons.png"'
* Replacing the url with your desired image
* Once you have instantiated the XML view you can call
* setImageDrawable(url) to change the image
* @param context
* @param attrSet
*/
public LoaderImageView(final Context context, final AttributeSet attrSet) {
super(context, attrSet);
final String url = attrSet.getAttributeValue(null, "image");
if(url != null){
instantiate(context, url);
} else {
instantiate(context, null);
}
}
/**
* This is used when creating the view programatically
* Once you have instantiated the view you can call
* setImageDrawable(url) to change the image
* @param context the Activity context
* @param imageUrl the Image URL you wish to load
*/
public LoaderImageView(final Context context, final String imageUrl) {
super(context);
instantiate(context, imageUrl);
}
/**
* First time loading of the LoaderImageView
* Sets up the LayoutParams of the view, you can change these to
* get the required effects you want
*/
private void instantiate(final Context context, final String imageUrl) {
mContext = context;
mImage = new ImageView(mContext);
mImage.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
mSpinner = new ProgressBar(mContext);
mSpinner.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
mSpinner.setIndeterminate(true);
addView(mSpinner);
addView(mImage);
if(imageUrl != null){
setImageDrawable(imageUrl);
}
}
/**
* Set's the view's drawable, this uses the internet to retrieve the image
* don't forget to add the correct permissions to your manifest
* @param imageUrl the url of the image you wish to load
*/
public void setImageDrawable(final String imageUrl) {
mDrawable = null;
mSpinner.setVisibility(View.VISIBLE);
mImage.setVisibility(View.GONE);
new Thread(){
public void run() {
try {
mDrawable = getDrawableFromUrl(imageUrl);
imageLoadedHandler.sendEmptyMessage(COMPLETE);
} catch (MalformedURLException e) {
imageLoadedHandler.sendEmptyMessage(FAILED);
} catch (IOException e) {
imageLoadedHandler.sendEmptyMessage(FAILED);
}
};
}.start();
}
/**
* Callback that is received once the image has been downloaded
*/
Handler.Callback call = new Handler.Callback() {
public boolean handleMessage(Message msg) {
switch (msg.what) {
case COMPLETE:
mImage.setImageDrawable(mDrawable);
mImage.setVisibility(View.VISIBLE);
mSpinner.setVisibility(View.GONE);
break;
case FAILED:
default:
// Could change image here to a 'failed' image
// otherwise will just keep on spinning
break;
}
return true;
}
};
private final Handler imageLoadedHandler =new Handler(call);
/**
* Pass in an image url to get a drawable object
* @return a drawable object
* @throws IOException
* @throws MalformedURLException
*/
private static Drawable getDrawableFromUrl(final String url) throws IOException, MalformedURLException {
return Drawable.createFromStream(((java.io.InputStream)new java.net.URL(url).getContent()), "name");
}
}
To use it, it's simple :
LoderImageView image = (LoaderImageView) findViewById(R.id.myid);
image.setImageDrawable(url);