java - WeakReference to a RecyclerView's View never breaks? -
i have weakreference recyclerview's view in asynctask (the task loads image show in view). (if use listview) view collected gc when disappears task won't use it, in case (with recyclerview) view never collected gc task yet has weakreference pointing view, has new role (another image show). how solve it? right understanding of situation?
thanks!
i hope u understand though english not native...
edit: code asynctask:
class loadpicturetask extends asynctask<string, void, bitmap> { private final weakreference<imageview> mimageviewreference; private final int mimagesize; loadpicturetask(imageview imageview, int imagesize) { // use weakreference ensure imageview can garbage collected mimageviewreference = new weakreference<>(imageview); mimagesize = imagesize; } @override protected bitmap doinbackground(string... params) { string path = params[0]; return decodesampledbitmapfromfile(path, mimagesize, mimagesize); } @override protected void onpostexecute(bitmap bitmap) { if (mimageviewreference.get() != null && bitmap != null) { final imageview imageview = mimageviewreference.get(); if (imageview != null) { imageview.setimagebitmap(bitmap); } } } ... }
my fear in onpostexecute set imageview resulting bitmap (a recycled one)
so tested above case , indeed views' references totally abused. asynctask put images wrong views , messed up. solved saving pointer asynctask viewholder, , in onbindviewholder cancelled executed asynctask , disabled visibilty of view until set visible again new asynctask.
the code clarify intentions:
package com.teamagam.dailyselfie; import android.content.context; import android.support.v7.widget.recyclerview; import android.view.layoutinflater; import android.view.view; import android.view.viewgroup; import android.widget.imageview; import android.widget.textview; import java.util.list; class pictureadapter extends recyclerview.adapter<pictureadapter.pictureviewholder> { private layoutinflater minflater; private list<pictureinfo> mpictureinfolist; pictureadapter(context context, list<pictureinfo> pictureinfolist) { minflater = layoutinflater.from(context); mpictureinfolist = pictureinfolist; } @override public pictureviewholder oncreateviewholder(viewgroup parent, int viewtype) { view view = minflater.inflate(r.layout.layout_picture, parent, false); return new pictureviewholder(view); } @override public void onbindviewholder(pictureviewholder pictureviewholder, int position) { pictureinfo pictureinfo = mpictureinfolist.get(position); pictureviewholder.mtextview.settext(pictureinfo.filename); int imagesize = pictureviewholder.mimageview .getcontext() .getapplicationcontext() .getresources() .getinteger(r.integer.activity_main_thumbnail_size); if (null != pictureviewholder.mloadpicturetask) { pictureviewholder.mloadpicturetask.cancel(true); } pictureviewholder.mimageview.setvisibility(view.invisible); pictureviewholder.mloadpicturetask = new loadpicturetask(pictureviewholder.mimageview, imagesize); pictureviewholder.mloadpicturetask.execute(pictureinfo.path); } @override public int getitemcount() { return mpictureinfolist.size(); } class pictureviewholder extends recyclerview.viewholder { imageview mimageview; textview mtextview; loadpicturetask mloadpicturetask; pictureviewholder(view itemview) { super(itemview); mimageview = (imageview) itemview.findviewbyid(r.id.ivitemlistimage); mtextview = (textview) itemview.findviewbyid(r.id.tvitemlistimage); } } }
and of course code asynctask:
package com.teamagam.dailyselfie; import android.graphics.bitmap; import android.graphics.bitmapfactory; import android.graphics.bitmapfactory.options; import android.os.asynctask; import android.view.view; import android.widget.imageview; import java.lang.ref.weakreference; class loadpicturetask extends asynctask<string, void, bitmap> { private final weakreference<imageview> mimageviewreference; private final int mimagesize; loadpicturetask(imageview imageview, int imagesize) { // use weakreference ensure imageview can garbage collected mimageviewreference = new weakreference<>(imageview); mimagesize = imagesize; } @override protected bitmap doinbackground(string... params) { string path = params[0]; return decodesampledbitmapfromfile(path, mimagesize, mimagesize); } @override protected void onpostexecute(bitmap bitmap) { if (mimageviewreference.get() != null && bitmap != null) { final imageview imageview = mimageviewreference.get(); if (imageview != null) { imageview.setimagebitmap(bitmap); imageview.setvisibility(view.visible); } } } private static bitmap decodesampledbitmapfromfile(string path, int requiredwidth, int requiredheight) { // first decode injustdecodebounds=true check dimensions final options options = new options(); options.injustdecodebounds = true; bitmapfactory.decodefile(path, options); // calculate insamplesize options.insamplesize = calculatesamplesize(options, requiredwidth, requiredheight); // decode bitmap insamplesize set options.injustdecodebounds = false; return bitmapfactory.decodefile(path, options); } private static int calculatesamplesize(options options, int requiredwidth, int requiredheight) { // raw height , width of image final int height = options.outheight; final int width = options.outwidth; int samplesize = 1; if (height > requiredheight || width > requiredwidth) { final int halfheight = height / 2; final int halfwidth = width / 2; // calculate largest samplesize value power of 2 , keeps both // height , width larger requested height , width. while ((halfheight / samplesize) >= requiredheight && (halfwidth / samplesize) >= requiredwidth) { samplesize *= 2; } } return samplesize; } }
Comments
Post a Comment