我有一个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;
}
销毁Fragment
后更新ListView
会导致应用崩溃。如何使Handler
在Fragment
被破坏时停止?我还想知道如果暂停应用程序也会对Handler
产生什么影响。
你需要像这样实现处理程序
private Handler myHandler;
private Runnable myRunnable = new Runnable() {
@Override
public void run() {
//Do Something
}
};
@Override
public void onDestroy () {
mHandler.removeCallbacks(myRunnable);
super.onDestroy ();
}
您需要在片段中存储对处理程序和可运行的引用,然后在片段被销毁时,您需要从传入可运行的处理程序中删除回调。
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();
}
使用片段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
获取器:
@Override
public void onDestroy() {
super.onDestroy();
mDestroyed = true;
}
有人发布了另一个类似的问题,问题是由于ChildFragmentManager
中的错误。基本上,当ChildFragmentManager
与Activity
分离时,它最终会得到一个破碎的内部状态。看看这里的原始答案