Stop Handler After The Fragment Has Been Destroyed
I have a Fragment which sets up a ListView and creates a Handler to update the Listview periodically. However, it looks like the Handler still runs after the Fragment has been dest
Solution 1:
You need to implement handler like this
private Handler myHandler;
privateRunnablemyRunnable=newRunnable() {
@Overridepublicvoidrun() {
//Do Something
}
};
@OverridepublicvoidonDestroy() {
mHandler.removeCallbacks(myRunnable);
super.onDestroy ();
}
Solution 2:
You need to store a reference to your handler and runnable in the fragment, and then when the fragment is destroyed you need to remove callbacks from the handler passing in the runnable.
privateHandler mHandler;
privateRunnable mRunnable;
@OverridepublicViewonCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//boilerplate code
mRunnable = newRunnable() {
@Overridepublicvoidrun() {
assignAdapter();
handler.postDelayed(this, 15000);
}
};
mHandler = newHandler(mRunnable);
mHandler.post();
return v;
}
@OverridepublicvoidonDestroy() {
mHandler.removeCallbacks(mRunnable);
super.onDestroy();
}
Solution 3:
Another way of stopping the handler with the use of WeakReference
to the fragment:
staticfinalclassUpdateUIRunnableimplementsRunnable {
final WeakReference<RouteGuideFragment> weakRefToParent;
final Handler handler;
publicUpdateUIRunnable(RouteGuideFragment fragment, Handler handler) {
weakRefToParent = newWeakReference<RouteGuideFragment>(fragment);
this.handler = handler;
}
publicvoidscheduleNextRun() {
handler.postDelayed(this, INTERVAL_TO_REDRAW_UI);
}
@Overridepublicvoidrun() {
RouteGuideFragmentfragment= weakRefToParent.get();
if (fragment == null || fragment.hasBeenDestroyed()) {
Log.d("UIUpdateRunnable", "Killing updater -> fragment has been destroyed.");
return;
}
if (fragment.adapter != null) {
try {
fragment.adapter.forceUpdate();
} finally {
// schedule againthis.scheduleNextRun();
}
}
}
}
where fragment.hasBeenDestroyed()
is simply a getter for mDestroyed
property of a fragment:
@OverridepublicvoidonDestroy() {
super.onDestroy();
mDestroyed = true;
}
Solution 4:
Someone posted another question similar and the problem is due to a bug in the ChildFragmentManager
. Basically, the ChildFragmentManager
ends up with a broken internal state when it is detached from the Activity
. Have a look at the original answer here
Solution 5:
Use Rxjava, its better
subscription = Observable.timer(1000, TimeUnit.MILLISECONDS)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(aLong -> whatToDo());
privatevoidwhatToDo() {
System.out.println("Called after 1 second");
}
Then in ondestroy() method call
RxUtils.unsubscribe(subscription);
Post a Comment for "Stop Handler After The Fragment Has Been Destroyed"