android - RecyclerView leaks on recreate -


my recyclerview creating memory leak each time activity has been recreated. have google able find solution that. activity being destroyed button , being creating when button mainactivity. have post result of leak canary. thank you.

//commentlistadapater package com.support.android.designlibdemo.adapters;  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.textview;  import com.squareup.otto.subscribe; import com.support.android.designlibdemo.myapplication; import com.support.android.designlibdemo.r; import com.support.android.designlibdemo.events.commentsloadevent; import com.support.android.designlibdemo.events.eventfinished; import com.support.android.designlibdemo.events.networkerrorevent; import com.support.android.designlibdemo.models.redditcomment; import com.support.android.designlibdemo.models.redditobject; import com.support.android.designlibdemo.models.redditresponse; import com.support.android.designlibdemo.models.redditthread; import com.support.android.designlibdemo.services.redditservice;  import java.util.arraylist; import java.util.list;  import retrofit.callback; import retrofit.retrofiterror; import retrofit.client.response;  public class commentlistadapter extends recyclerview.adapter<commentlistadapter.viewholder> {     private list<redditcomment> mvalues = new arraylist();     private context mcontext;     private static final string subreddit_name = "subreddit_name";     private static final string thread_id = "thread_id";     private static final string thread_name = "thread_name";      public commentlistadapter(context context) {         mcontext = context;     }      public class viewholder extends recyclerview.viewholder {         public view mview;         public textview mbody;         public textview mauthor;          public viewholder(view itemview) {             super(itemview);             mview = itemview;             mbody = (textview) itemview.findviewbyid(r.id.body);             mauthor = (textview) itemview.findviewbyid(r.id.author_name);         }     }      @override     public void onbindviewholder(commentlistadapter.viewholder holder, int position) {         if (mvalues.get(position).selftext == null) {             holder.mbody.settext(mvalues.get(position).body);         } else {             holder.mbody.settext(mvalues.get(position).selftext);         }         holder.mauthor.settext(mvalues.get(position).author);     }      @override     public int getitemcount() {         if (mvalues == null) {             return 0;         }         return mvalues.size();     }      @override     public commentlistadapter.viewholder oncreateviewholder(viewgroup parent, int viewtype) {         // create new view         view v = layoutinflater.from(parent.getcontext())                 .inflate(r.layout.activity_comment_holder, parent, false);          viewholder vh = new viewholder(v);         return vh;     }      @subscribe     public void fetchdata(final commentsloadevent event) {         redditservice.implementation.get().getthreadcomments(event.subredditname, event.threadid,                 new callback<list<redditresponse<redditcomment>>>() {                     @override                     public void success(list<redditresponse<redditcomment>> redditresponses, response response) {                         mvalues.clear();                         (redditresponse rr : redditresponses) {                             redditcomment rc = (redditcomment) rr.getdata();                             (redditobject obj : rc.children) {                                 if (obj instanceof redditthread) {                                     redditthread t = (redditthread) obj;                                     redditcomment c = new redditcomment();                                     c.selftext = t.selftext;                                     c.author = t.author;                                     mvalues.add(c);                                 } else {                                     redditcomment c = (redditcomment) obj;                                     mvalues.add(c);                                 }                                 notifydatasetchanged();                                 myapplication.getbus().post(new eventfinished());                             }                         }                     }                      @override                     public void failure(retrofiterror error) {                         myapplication.getbus().post(new networkerrorevent(error, mcontext));                     }                 }         );      }      @override     public void onattachedtorecyclerview(recyclerview recyclerview) {         super.onattachedtorecyclerview(recyclerview);         myapplication.getbus().register(this);     }      @override     public void ondetachedfromrecyclerview(recyclerview recyclerview) {         super.ondetachedfromrecyclerview(recyclerview);         myapplication.getbus().unregister(this);     } }  //commentactivity package com.support.android.designlibdemo.activities;  import android.content.intent; import android.os.bundle; import android.support.v4.widget.swiperefreshlayout; import android.support.v7.widget.linearlayoutmanager; import android.support.v7.widget.recyclerview; import android.support.v7.widget.toolbar;  import com.squareup.otto.subscribe; import com.support.android.designlibdemo.myapplication; import com.support.android.designlibdemo.r; import com.support.android.designlibdemo.adapters.commentlistadapter; import com.support.android.designlibdemo.events.commentsloadevent; import com.support.android.designlibdemo.events.eventfinished;  public class commentactivity extends baseactivity {     public static final string subreddit_name = "subreddit_name";     public static final string thread_id = "thread_id";     public static final string thread_name = "thread_name";      private final string tag = getclass().getsimplename();     private recyclerview mrecyclerview;     private swiperefreshlayout mswiperefreshlayout;     private commentlistadapter madapter;     private recyclerview.layoutmanager mlayoutmanager;     private string msubredditname;     private string mthreadname;     private string mthreadid;      @override     protected void oncreate(bundle savedinstancestate) {         super.oncreate(savedinstancestate);          toolbar toolbar = (toolbar) findviewbyid(r.id.toolbar);         intent intent = getintent();         msubredditname = intent.getstringextra(subreddit_name);         mthreadname = intent.getstringextra(thread_name);         mthreadid = intent.getstringextra(thread_id);          toolbar.setsubtitle(mthreadname);         toolbar.settitle(msubredditname);         settoolbar();         setuprecyclerview();     }      @override     protected boolean hascustomicon() {         return false;     }      @override     protected int getlayout() {         return r.layout.activity_comment;     }      private void setuprecyclerview() {         if (mrecyclerview == null) {              mrecyclerview = (recyclerview) findviewbyid(r.id.comment_recycler);             mswiperefreshlayout = (swiperefreshlayout) findviewbyid(r.id.swipe_refresh);         }          if (mlayoutmanager == null) {             // use linear layout manager             mlayoutmanager = new linearlayoutmanager(this);             mrecyclerview.setlayoutmanager(mlayoutmanager);             mswiperefreshlayout.setcolorschemecolors(r.color.coloraccent,                                                      r.color.color_primary_dark,                                                      r.color.frame_background);             mswiperefreshlayout.setonrefreshlistener(new swiperefreshlayout.onrefreshlistener() {                 @override                 public void onrefresh() {                     myapplication.getbus().post(new commentsloadevent(                                     msubredditname, mthreadid)                     );                 }             });         }          if (madapter == null) {             madapter = new commentlistadapter(this);             mrecyclerview.setadapter(madapter);             mswiperefreshlayout.setrefreshing(true);             myapplication.getbus().post(new commentsloadevent(                             msubredditname, mthreadid)             );         }     }      @subscribe     public void stopswipe(final eventfinished event) {         mswiperefreshlayout.setrefreshing(false);     }      @override     public void onpause() {         super.onpause();         myapplication.getbus().unregister(this);     }      @override     public void onresume() {         super.onresume();         myapplication.getbus().register(this);     } }  //myapplication package com.support.android.designlibdemo;  import android.app.application;  import com.crashlytics.android.crashlytics; import com.squareup.leakcanary.leakcanary; import com.squareup.otto.bus;  import io.fabric.sdk.android.fabric;  public class myapplication extends application {     private static bus _bus;      @override public void oncreate() {         super.oncreate();         fabric.with(this, new crashlytics());         leakcanary.install(this);     }      public static bus getbus() {         if (_bus == null) {             _bus = new bus();         }         return _bus;     } } 

leak image 1

leak image 2

private static bus _bus; retaining instances deallocation. commentlistadapter accessing field, have instance in commentactivity. makes commentactivity not able deallocated (leaked).

i not familiar otto may not use properly.

if want communicate activity adapter, why don't make public method in adapter , call adapter.method() activity ?


Comments