片段被销毁后停止处理程序
Stop handler after the fragment has been destroyed
我有一个 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 ();
}
有人发布了另一个类似的问题,问题是由于 ChildFragmentManager
中的一个错误。基本上,当 ChildFragmentManager
与 Activity
分离时,它会以内部状态中断而告终。看看 original answer here
您需要在片段中存储对您的处理程序和可运行对象的引用,然后当片段被销毁时,您需要从传入可运行对象的处理程序中删除回调。
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
属性 的 getter:
@Override
public void onDestroy() {
super.onDestroy();
mDestroyed = true;
}
我有一个 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 ();
}
有人发布了另一个类似的问题,问题是由于 ChildFragmentManager
中的一个错误。基本上,当 ChildFragmentManager
与 Activity
分离时,它会以内部状态中断而告终。看看 original answer here
您需要在片段中存储对您的处理程序和可运行对象的引用,然后当片段被销毁时,您需要从传入可运行对象的处理程序中删除回调。
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
属性 的 getter:
@Override
public void onDestroy() {
super.onDestroy();
mDestroyed = true;
}