17

我有一个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

4

5 回答 5

28

您需要像这样实现处理程序

private Handler myHandler;
private Runnable myRunnable = new Runnable() {
    @Override
    public void run() {
        //Do Something
    }
};

@Override
public void onDestroy () {

    mHandler.removeCallbacks(myRunnable);
    super.onDestroy ();

}
于 2015-04-21T13:45:56.080 回答
5

您需要在片段中存储对处理程序和可运行的引用,然后当片段被销毁时,您需要从传递可运行的处理程序中删除回调。

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();
}
于 2015-04-21T13:53:38.303 回答
2

WeakReference使用to 片段停止处理程序的另一种方法:

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();
                }
            }
        }
    }

wherefragment.hasBeenDestroyed()只是mDestroyed片段属性的吸气剂:

@Override
public void onDestroy() {
    super.onDestroy();
    mDestroyed = true;
}
于 2015-04-21T22:40:49.187 回答
0

有人发布了另一个类似的问题,问题是由于ChildFragmentManager. 基本上,ChildFragmentManager当它与Activity. 在这里查看原始答案

于 2015-04-21T13:48:53.117 回答
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);
于 2017-02-24T03:57:14.523 回答