我有Fragment
设置ListView
并创建Handler
以定期更新Listview
。但是,在Handler
被销毁之后,Fragment
仍然可以运行。
以下是代码。
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//boilerplate code
final Handler handler = new Handler();
handler.post(new Runnable() {
@Override
public void run() {
assignAdapter();
handler.postDelayed(this, 15000);
}
});
return v;
}
在销毁ListView
后更新Fragment
会导致应用崩溃。当Handler
被破坏时,如何使Fragment
停止?我还想知道如果暂停应用程序在Handler
上有什么影响。
答案 0 :(得分:20)
您需要实现像这样的处理程序
private Handler myHandler;
private Runnable myRunnable = new Runnable() {
@Override
public void run() {
//Do Something
}
};
@Override
public void onDestroy () {
mHandler.removeCallbacks(myRunnable);
super.onDestroy ();
}
答案 1 :(得分:6)
您需要存储对处理程序的引用并在片段中运行,然后当片段被销毁时,您需要从传递runnable的处理程序中删除回调。
private Handler mHandler;
private Runnable mRunnable;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//boilerplate code
mRunnable = new Runnable() {
@Override
public void run() {
assignAdapter();
handler.postDelayed(this, 15000);
}
};
mHandler = new Handler(mRunnable);
mHandler.post();
return v;
}
@Override
public void onDestroy() {
mHandler.removeCallbacks(mRunnable);
super.onDestroy();
}
答案 2 :(得分:2)
使用WeakReference
对片段停止处理程序的另一种方法:
static final class UpdateUIRunnable implements Runnable {
final WeakReference<RouteGuideFragment> weakRefToParent;
final Handler handler;
public UpdateUIRunnable(RouteGuideFragment fragment, Handler handler) {
weakRefToParent = new WeakReference<RouteGuideFragment>(fragment);
this.handler = handler;
}
public void scheduleNextRun() {
handler.postDelayed(this, INTERVAL_TO_REDRAW_UI);
}
@Override
public void run() {
RouteGuideFragment fragment = 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 again
this.scheduleNextRun();
}
}
}
}
其中fragment.hasBeenDestroyed()
只是片段的mDestroyed
属性的getter:
@Override
public void onDestroy() {
super.onDestroy();
mDestroyed = true;
}
答案 3 :(得分:0)
有人发布了另一个类似的问题,问题是由ChildFragmentManager
中的错误引起的。基本上,当ChildFragmentManager
从Activity
分离时,{{1}}最终会出现内部状态损坏。看看original answer here
答案 4 :(得分:0)
使用Rxjava,它更好
subscription = Observable.timer(1000, TimeUnit.MILLISECONDS)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(aLong -> whatToDo());
private void whatToDo() {
System.out.println("Called after 1 second");
}
然后在ondestroy()方法中调用
RxUtils.unsubscribe(subscription);