The OutOfMemoryException is most likely caused by the images.
Lets say you want to show a list of hotels with pictures. You get the hotel info in XML format and save them in a List (or similar structure). Your hotel class could have a member like URL pictureURL
and a member like WeakReference<Drawable> picture
that will be null until needed.
You can make your list adapter to start a AsyncTask
to download a image in the getView() method (if picture point to null) and set it to both the ImageView in your list and Hotel.picture
.
Because Hotel.picture is a weak reference, the memory will be freed when the image goes off screen as the ImageViews
get recycled
Your getView method might contain something like this:
private class MyCustomAdapter extends BaseAdapter {
...
List<Hotel> hotelList;
...
@Override
public View getView(int position, View convertView, ViewGroup parent) {
...
Hotel hotel = hotelList.get(position);
ImageView ivHotelPic = //your image view from the list (child of 'view')
...
if (hotel.picture == null || hotel.picture.get() == null){
new DownloadImageTask(hotel,ivHotelPic).execute(hotel.pictureURL)
}
else{
ivHotelPic.setImageDrawable( hotel.picture.get() );
}
return view;
}
}
private class DownloadImageTask extends AsyncTask<URL, Integer, Drawable> {
Hotel hotel;
ImageView imageView;
DownloadImageTask(Hotel hotel,ImageView imageView){
this.hotel = hotel;
this.imageView = imageView;
}
protected Drawable doInBackground(URL... urls) {
assert urls.length == 1;
Drawable image = //download image from urls[0] (or hotel.pictureURL);
return image;
}
protected void onPostExecute(Drawable result) {
imageView.setImageDrawable(result);
hotel.picture = new WeakReference<Drawable>(result);
}
}
You could also use a regular reference for your images if you want to keep them until the activity closes, but this might cause OutOfMemory when too many images were downloaded.