android - Memory leak when loading bitmaps from path in viewholder -
i'm trying find out ages why got memory leak in viewholder of listview.
the strange part when setting imageview (coveriv) ((bitmapdrawable)_activity.resources.getdrawable(resource.drawable.splash)).bitmap, there's no problem @ all.
when use await imageloader.decodesampledbitmapfromresourceasync (localimagelocation, imgwidth, imgheight) ,there's huge memory leak each time scroll bit in listview
i tried finding references memory analyzer tool there none... although mat says problem bitmaps
public void imageloaded(string localimagelocation) { int screenwidth = _activity.resources.displaymetrics.widthpixels; int imgwidth = screenwidth - (int)convertdptopix (32f); int imgheight = (int)(convertdptopix(206f)); bundleprogress.visibility = viewstates.gone; if (coveriv.drawable != null) { ((bitmapdrawable)coveriv.drawable).bitmap.recycle (); ((bitmapdrawable)coveriv.drawable).bitmap.dispose (); coveriv.setimagedrawable (null); } coveriv.setimagebitmap ( //memoryleak: await imageloader.decodesampledbitmapfromresourceasync (localimagelocation, imgwidth, imgheight) ((bitmapdrawable)_activity.resources.getdrawable(resource.drawable.splash)).bitmap );
the methods in imageloader class:
public static async task<bitmap> decodesampledbitmapfromresourceasync (string path,int reqwidth, int reqheight) { // first decode injustdecodebounds=true check dimensions of image bitmapfactory.options options = new bitmapfactory.options(); options.injustdecodebounds = true; bitmap bitmap = await bitmapfactory.decodefileasync(path, options); // calculate insamplesize options.insamplesize = calculateinsamplesize(options, reqwidth, reqheight); // decode bitmap insamplesize set options.injustdecodebounds = false; options.inpreferredconfig = bitmap.config.argb8888; //options.indither = true; return await bitmapfactory.decodefileasync(path, options); } public static int calculateinsamplesize(bitmapfactory.options options, int reqwidth, int reqheight) { // raw height , width of image float height = options.outheight; float width = options.outwidth; double insamplesize = 1d; if (height > reqheight || width > reqwidth) { int halfheight = (int)(height / 2); int halfwidth = (int)(width / 2); // calculate insamplesize power of 2 - decoder use value power of 2 anyway. while ((halfheight / insamplesize) > reqheight && (halfwidth / insamplesize) > reqwidth) { insamplesize *= 2; } } return (int)insamplesize; }
the adapter:
public override view getview (int position, view convertview, viewgroup parent) { basebundelvo bundle = _bundles [position]; dsbundlelistitem bundleholder = null; dsbundlearchiveitem archiveholder = null; int type = getitemviewtype(position); if (convertview == null) { bundleholder = new dsbundlelistitem (_activity.applicationcontext); archiveholder = new dsbundlearchiveitem (_activity.applicationcontext); switch (type) { case 0: convertview = _activity.layoutinflater.inflate (resource.layout.dsbundlelistitem, null); bundleholder.iconiv = convertview.findviewbyid<imageview> (resource.id.iconiv); bundleholder.coveriv = convertview.findviewbyid<imageview> (resource.id.coveriv); bundleholder.covertitletv = convertview.findviewbyid<textview> (resource.id.covertitletv); bundleholder.coversubtitletv = convertview.findviewbyid<textview> (resource.id.coversubtitletv); bundleholder.bundleprogress = convertview.findviewbyid<progressbar> (resource.id.bundleprogress); convertview.tag = bundleholder; break; case 1: convertview = _activity.layoutinflater.inflate (resource.layout.dsbundlearchiveitem, null); archiveholder.archivetitletv = convertview.findviewbyid<textview> (resource.id.archivetitletv); archiveholder.archivesubtitletv = convertview.findviewbyid<textview> (resource.id.archivesubtitletv); convertview.tag = archiveholder; break; } } else { switch (type) { case 0: bundleholder = (dsbundlelistitem)convertview.tag; break; case 1: archiveholder = (dsbundlearchiveitem)convertview.tag; break; } } switch (type) { case 0: bundleholder.covertitletv.text = bundle.title; bundleholder.coversubtitletv.text = bundle.subtitle; bundleholder.coveriv.setimagedrawable (null); bundleholder.iconiv.setimagedrawable (null); bundleholder.loadimage(bundle.coverimagelocation,bundle.icon); break; case 1: archiveholder.archivetitletv.text = "archief"; archiveholder.archivesubtitletv.text = "bekijk onze eerder verschenen publicaties"; break; } return convertview; } public void setdata(list<basebundelvo> bundles) { _bundles.clear (); _bundles.addrange(bundles); }
use the picasso library when using images, works wonders!
Comments
Post a Comment