android - fragment reference null on resume -
im having issue appears after several hours of inactivity, researched ive tried various ways of fixing no avail. issue after app has been dormant several hours references fragments null, however; still exist in frag manager. use references pull tag, or id findfragmentby...() can call specific methods within them updating , not. fragments dynamic , have ui. have several activities , service called on main activity. can close app , resume, call activities, pull info service, close, use button, without issue. give idea of how app structured...
public class appclass extends application { public fragment fragmenta; public fragment fragmentb; public fragment fragmentc; @override public void oncreate() { super.oncreate(); new fragmenttemplate(); fragemnta = fragmenttemplate.newinstance(getdbname(), usefuldata, "a list"); new fragmenttemplate(); fragemntb = fragmenttemplate.newinstance(getdbname(), usefuldata, "b list"); new fragmenttemplate(); fragemntc = fragmenttemplate.newinstance(getdbname(), usefuldata, "c list"); } }
moving on activity fragments used in viewager...
public class mainactivity extends appcompatactivity implements ...listeners{ appclass myappclass; fragmentmanager fragmgr; viewpager viewpager; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); myappclass = (appclass) getapplication(); settheme(myappclass.getapptheme()); setcontentview(r.layout.activity_my_layout); //toolbar actionbar stuff fragmgr = getsupportfragmentmanager(); viewpager = (viewpager) findviewbyid(r.id.viewpager); viewpager.setadapter(new viewpageradapter(fragmgr)); //tab setup } //inner class pager adapter here }
this pager adapter
class viewpageradapter extends fragmentpageradapter implements viewpager.onpagechangelistener{ fragment fragment; public viewpageradapter(fragmentmanager fm) { super(fm); } @override public fragment getitem(int position) { switch (position) { case 0: if (myappclass.fragmenta != null) { fragment = myappclass.fragemnta ; } break; case 1: if (myappclass.fragmentb != null) { fragment = myappclass.fragmentb ; } break; case 2: if (myappclass.fragmentc != null) { fragment = myappclass.fragmentc ; } break; } return fragment; } @override public int getcount() { return 3; } }
i have fab , listener looks this
@override public void onclick(view v) { fraggment fragment; int = viewpager.getcurrentitem(); if (v.getid() == floatingactionbutton.getid()) { switch (i) { case 0: fragment= (fragment) fragmgr.findfragmentbytag(myappclass.fragmenta.gettag()); fragment.additem(fragment.getsomestring()); break; case 1: fragment= (fragment) fragmgr.findfragmentbytag(myappclass.fragmentb.gettag()); fragment.additem(fragment.getsomestring()); break; case 2: fragment= (fragment) fragmgr.findfragmentbytag(myappclass.fragmentc.gettag()); fragment.additem(fragment.getsomestring()); break; } } }
code fragment
public class fragmenttemplate extends fragment implements recycleradapter.alistener { private appclass myappclassreference; private recyclerview recyclerview; private view view; private fragmenttitle; public static fragmenttemplate newinstance(string a, string b, string c) { bundle args = new bundle(); args.putstring(key_a, a); args.putstring(key_b, b); args.putstring(key_c, c); fragmenttemplate fragment = new fragmenttemplate(); fragment.setarguments(args); return fragment; } public string getfragmenttitle() { return fragmenttitle; } @override public view oncreateview(layoutinflater inflater, viewgroup container, final bundle savedinstancestate) { view = inflater.inflate(r.layout.list, container, false); myappclassreference= ((appclass) getactivity().getapplication()); recyclerview = (recyclerview) view.findviewbyid(r.id.listview); //get list local function loads list db source recycleradapter recycler = new recycleradapter(getactivity(), getlist()); recycler.setlistener(this); recyclerview.setadapter(recycler); recyclerview.setlayoutmanager(newlearlayoutmanager(getactivity())); recyclerview.addonitemtouchlistener(new recyclertouchlistener(getactivity(), recyclerview, new clicklistener() {}}; return view; } }
when things go wonky app not crash right away, tabs still scroll, viewpager still scrolls, empty, not until hit fab nullpointerexception, trying invoke method on nullpointer reference within onclick listener crash.
this happening because messing way android framework handles fragments you. when viewpageradapter gets fragments in getitem(int)
, it's using fragmentmanager gave attach fragments. once activity killed because of low memory, fragmentmanager automatically create new instances of fragments. @ point there 2 copies of fragments, ones fragmentmanager created , ones recreated in appclass.
you should never keep references fragments. fragmentmanager free destroy them , create new ones. if need communicate between activity , fragments in viewpager, can either make fragment ask activity commands, use event bus, or explore sketchy solutions here.
Comments
Post a Comment