我有一个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
有什么影响。
你需要像这样实现处理程序
private Handler myHandler;
private Runnable myRunnable = new Runnable() {
@Override
public void run() {
//Do Something
}
};
@Override
public void onDestroy () {
mHandler.removeCallbacks(myRunnable);
super.onDestroy ();
}
您需要存储对处理程序的引用并在片段中运行,然后当片段被销毁时,您需要从传递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();
}
使用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
分离时最终会破坏内部状态。看看original answer here
使用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);