android-fragments 在销毁片段后停止处理程序

eit6fx6z  于 2022-11-14  发布在  Android
关注(0)|答案(4)|浏览(175)

我有一个Fragment,它设置了一个ListView,并创建了一个Handler来定期更新Listview。但是,看起来HandlerFragment被销毁后仍然运行。
下面是代码。

@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会导致应用崩溃。我如何才能在Fragment被破坏时使Handler停止?我还想知道暂停应用对Handler有什么影响。

ebdffaop

ebdffaop1#

您需要实现如下处理程序

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

@Override
public void onDestroy () {

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

}
4jb9z9bj

4jb9z9bj2#

您需要在片段中存储一个对处理程序和runnable的引用,然后当片段被销毁时,您需要从传入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();
}
wsewodh2

wsewodh23#

另一种停止处理程序的方法是使用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;
}
xuo3flqw

xuo3flqw4#

有人发布了另一个类似的问题,这个问题是由于ChildFragmentManager中的一个bug引起的。基本上,当ChildFragmentManagerActivity分离时,ChildFragmentManager以一个破坏的内部状态结束。请看一下original answer here

相关问题