【问题标题】:Stop Handler when Fragment is destroyed当 Fragment 被销毁时停止 Handler
【发布时间】:2017-05-01 22:32:30
【问题描述】:

我正在下面的片段中启动处理程序:

    public class FeedsFragment extends Fragment{
           private Handler handler;
           private Runnable runnableCode;

           @Override
           public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
// Create the Handler object (on the main thread by default)
        handler = new Handler();

        // Define the task to be run here
        runnableCode = new Runnable() {
            @Override
            public void run() {

                    // Get the No of New Feeds
                    getFeedCounts();

                    // Repeat this runnable code again every 30 seconds
                    handler.postDelayed(runnableCode, 30,000);
            }
        };

        handler.post(runnableCode);
}

@Override
    public void onDetach() {
        super.onDetach();
        handler.removeCallbacksAndMessages(runnableCode);

    }

@Override
    public void onDestroyView() {
        handler.removeCallbacksAndMessages(runnableCode);
        super.onDestroyView();
    }

@Override
    public void onPause() {
        super.onPause();
        handler.removeCallbacksAndMessages(runnableCode);
    }

 @Override
    public void onResume() {

        /**
         * Start the handler again if coming back from any profile page
         * or hashtag search
         */ 
            isHandlerStopped = false;
            handler.post(runnableCode);
        super.onResume();
    }

我正在删除 onDetach 和 onDestroyView 函数中的所有回调,但它不起作用。

当我在同一个活动中加载不同的片段时,这个处理程序 不会自行停止,只有当我加载其他一些时,处理程序才会停止 我的应用程序中的活动。

我希望这个处理程序仅在我使用它的片段加载到活动中时运行,如果其他片段正在加载到同一活动中,则应该停止它。

此外,这个片段在 viewpager 中,所以当我切换选项卡并加载其他片段时,处理程序不会停止。请在活动中检查以下代码:

ViewPager pager = (ViewPager) findViewById(R.id.viewpager);
FeedsFragment feedsFragment;
pager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                // when user do a swipe the selected tab change
                switch (position){
                    case 0:
                        break;
                    case 1:
                        feedsFragment.removeHandler();
                        break;
                    case 2:
                        feedsFragment.removeHandler();
                        break;
                    case 3:
                        feedsFragment.removeHandler();
                        break;

                }

            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });

FragmentAdapter adapter = new FragmentAdapter(getActivity().getSupportFragmentManager());

feedsFragment = FeedsFragment.newInstance(bundle);
                adapter.addFragmentWithIcon(FeedsFragment.newInstance(null))
                        , mContext.getResources().getString(R.string.feed_tab_name));
                adapter.addFragmentWithIcon(FeedFriendRequests.newInstance(null),
                        mContext.getResources().getString(R.string.requests_tab_name));
                adapter.addFragmentWithIcon(NewMessagesFragment.newInstance(null), mContext.getResources().getString(R.string.message_tab_name));
                adapter.addFragmentWithIcon(NotificationFragment.newInstance(null)
                        , mContext.getResources().getString(R.string.notification_tab_name));

pager.setAdapter(adapter);

当我当时选择任何其他选项卡时,我正在调用 FeedFragment 中的 removeHandler 方法。

public void removeHandler(){
        handler.removeCallbacks(runnableCode);
    }

但仍会调用处理程序。

如果有人对此有任何想法,请帮助我。

提前非常感谢

【问题讨论】:

  • 你放断点检查了吗?
  • 我在 onDetach、onDestroy 和 onStop 函数中添加了打印语句,但是当在同一个活动中替换新片段时,这些函数都不会被调用。如果您有任何想法,请帮助我。
  • 如何替换片段?贴出代码
  • 您可以在替换另一个片段时调用 removeCallBack。请注意,您可以使用接口作为回调与托管活动通信
  • 我在活动中使用此代码来替换片段。 if (fragment != null) { FragmentManager fragmentManager = getSupportFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); fragmentTransaction.replace(R.id.main_content, fragment).commit(); } 使用替换功能不再显示片段时,将调用片段生命周期的哪个方法。

标签: android fragment handler


【解决方案1】:

我认为这与您的片段生命周期无关。你需要更换

handler.removeCallbacksAndMessages(runnableCode);
// this does not seem to work

handler.removeCallbacks(runnableCode);

另一种方法是在 FeedsFragment 中创建一个方法

public void removeHandler()
{
    Log.i("Stop Handler ","Yes");
    handler.removeCallbacks(runnableCode);
}

在活动中当你想替换片段

if(feedsFragment.isAdded())
{
     feedsFragment.removeHandler();
}
...// rest of the code to replace the fragment with new one

编辑:

viewPager.addOnPageChangeListener(pageChangeListener);
    viewPager.post(new Runnable() {
        @Override
        public void run() {
            pageChangeListener.onPageSelected(0);
        }
    });

然后

    ViewPager.OnPageChangeListener pageChangeListener = new ViewPager.OnPageChangeListener() {

    int currentPosition = 0;

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {


    }

    @Override
    public void onPageSelected(int newPosition) {


        FragmentLifeCycle fragmentToShow = (FragmentLifeCycle) adapter.getItem(newPosition);
        fragmentToShow.onResumeFragment();

        if(newPosition==0)
        {
            currentPosition = newPosition;
        }else {
            FragmentLifeCycle fragmentToHide = (FragmentLifeCycle) adapter.getItem(currentPosition);
            fragmentToHide.onPauseFragment();

            currentPosition = newPosition;
        }
}

有接口

 public interface FragmentLifeCycle {

 void onPauseFragment();
 void onResumeFragment();

 }

在所有片段中实现接口。假设处理程序在位置 0 的 Fragment 中使用。

@Override
public void onPauseFragment() {

    if(handler!=null)
    handler.removeCallbacks(runnableCode);
}

@Override
public void onResumeFragment() {
    handler = new Handler();

    // Define the task to be run here
    runnableCode = new Runnable() {
        @Override
        public void run() {

            Log.i("Do ","Something");
            handler.postDelayed(runnableCode, 3000);
        }
    };

    handler.post(runnableCode);
}

在其他片段中,只实现接口,什么都不做。

【讨论】:

  • 我已经使用了这段代码,它运行良好,非常感谢。但是我还有一个问题,我的片段在 viewpager 中,并且当 viewpager 的其他片段被加载时处理程序没有停止。请帮助我,我该怎么做?我在视图寻呼机上添加了**addOnPageChangeListener** 并删除了该片段回调处理程序,但它不起作用,仍然调用该处理程序。如果您也对此有任何想法,请帮助我。非常感谢你的帮助。 :)
  • @PrithnirajNicyone 你是怎么做到的。发布您的代码。不是作为评论,而是对问题的编辑
  • 您需要了解视图寻呼机的工作原理。在片段 1 中,您还创建了片段 2。片段在当前片段的每一侧都在内存中。
  • @PrithnirajNicyone 是您让处理程序位于位置 0 的片段?
  • 是的,我在 viewpager 的位置 0 上运行处理程序的那个片段。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-10
  • 1970-01-01
相关资源
最近更新 更多