Reputation: 1991
I'm making an android app that is very picture-oriented, thus I'm using a lot of Bitmaps. I know that it is good practice to use Bitmap.recycle();
to help with garbage collection, but the rest of my app is not allowing me to do so.
I made a class called URLImageView
that extends ImageView
which allows you to set the image from a URL. I have another class that I found online called SlidingUpPanelLayout
which extends ViewGroup
, and if I call Bitmap.recycle();
, I get an error saying that it can't draw recycled bitmaps.
Can anyone think of a good work-around so that I free up resources, but still have them available for the SlidingUpPanelLayout
?
Below is the URLImageView
class that I created.
public class URLImageView extends ImageView
{
private ImageLoadTask task = null;
public URLImageView(Context context)
{
this(context, null, 0);
}
public URLImageView(Context context, AttributeSet attrs)
{
this(context, attrs, 0);
}
public URLImageView(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
}
public void setImageFromURL(String url)
{
//System.gc();
Bitmap bitmap = ImageCache.getBitmapFromCache(url);
if(bitmap == null)//the bitmap was not found in the cache, so let's actually build it
{
if(task != null)
task.cancel(true);
task = new ImageLoadTask();
if(Build.VERSION.SDK_INT >= 11)//load the images in parallel instead of waiting
{
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, url);
}
else //too bad. we have to load them in series :(
{
task.execute(url);
}
}
else//the bitmap was in the cache, so just set it
{
this.setImageBitmap(bitmap);
}
//if(bitmap != null)
// bitmap.recycle();
bitmap = null;
}
private class ImageLoadTask extends AsyncTask<String, String, Bitmap>
{
private String url;
@Override
protected void onPreExecute()
{
setImageResource(R.drawable.blank);
}
@Override
protected Bitmap doInBackground(String... args)
{
try
{
//System.gc();
url = args[0];
Bitmap bitmap = BitmapFactory.decodeStream((InputStream)new URL(url).getContent());
return bitmap;
}
catch (Exception e)
{
return null;
}
}
@Override
protected void onPostExecute(Bitmap bitmap)
{
//System.out.println("onPostExecute...");
if(bitmap != null)
{
ImageCache.addBitmapToCache(url, bitmap);
URLImageView.this.setImageBitmap(bitmap);
//bitmap.recycle();
bitmap = null;
}
else
{
setImageResource(R.drawable.blank);
}
task = null;
}
}
}
Upvotes: 1
Views: 158
Reputation: 1933
This is because of large bitmap which occupies everything in RAM . :D
You can load a scaled image, which will decrease a lot the memory usage, but you have to know your images to not lose too much quality of it.
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;
Bitmap bitmap = BitmapFactory.decodeStream(stream, null, options);
Reference: http://developer.android.com/reference/android/graphics/BitmapFactory.Options.html
Upvotes: 2
Reputation: 1325
use this function http://developer.android.com/reference/android/graphics/Bitmap.html#createBitmap(android.graphics.Bitmap, int, int, int, int) then u dont need to recycle. if u cant downsize use lrucache
Upvotes: 1