4

I am starting handler in a fragment like below :

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

I am removing all callbacks in onDetach and onDestroyView functions, but it is not working.

When I load a different fragment in the same activity this handler doesn't stop itself, handler stops only when I load some other activity in my application.

I want this handler to run only when the fragment in which I am using it is loaded in the activity, if some other fragment is being loaded in the same activity it should be stopped.

Also, this fragment is inside viewpager, so when I switch the tab and other fragment gets loaded the handler doesn't stop. Please check the below code in activity :

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

When I select any other tab at that time I'm calling the method removeHandler in FeedFragment.

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

But still handler is getting called.

Please help me if anyone have idea about this.

Thanks a lot in advance

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Prithniraj Nicyone
  • 5,021
  • 13
  • 52
  • 78
  • Did you put break points and check? – Raghunandan Dec 16 '16 at 07:43
  • I have added print statements in functions onDetach, onDestroy and onStop, but when the new fragment is being replaced in the same activity, neither of these functions are getting called. Please help me if you have any idea. – Prithniraj Nicyone Dec 16 '16 at 07:56
  • How do you replace fragment? Post the code – Raghunandan Dec 16 '16 at 07:58
  • You can just call removeCallBack when you replace another fragment. Note you can communicate to the hosting activity with interface as a callback – Raghunandan Dec 16 '16 at 08:04
  • I use this code in activity to replace the fragments. `if (fragment != null) { FragmentManager fragmentManager = getSupportFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); fragmentTransaction.replace(R.id.main_content, fragment).commit(); }` Which method of fragment lifecycle gets called when fragment is not being displayed any more with replace function. – Prithniraj Nicyone Dec 16 '16 at 08:06

1 Answers1

3

I don't think it has to do with your fragment lifecycle. You need to replace

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

with

handler.removeCallbacks(runnableCode);

Just an alternative create a method in FeedsFragment

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

In activity when you want to replace fragment

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

Edit:

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

Then

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

Have a interface

 public interface FragmentLifeCycle {

 void onPauseFragment();
 void onResumeFragment();

 }

Implement the interface in all fragments. Assuming the handler is used in Fragment at position 0.

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

In other fragment just implement the interface and do nothing.

Raghunandan
  • 132,755
  • 26
  • 225
  • 256
  • I have used this code and it is working fine, Thanks a lot. But I am having one more issue with this, that my fragment is in viewpager and the handler is not getting stopped when the other fragments of viewpager gets loaded. Please help me how can I do that ? I have added `**addOnPageChangeListener**` on view pager and removing that fragments call back handler but it is not working, still that handler is being called. Please help me if you have any idea about this one as well. Thanks a lot for your help. :) – Prithniraj Nicyone Dec 16 '16 at 13:19
  • @PrithnirajNicyone how do you do it. post your code. not as a comment but an edit to the question – Raghunandan Dec 16 '16 at 13:23
  • you need to understand how view pager works. when in fragment 1 you have fragment 2 also created. The fragments are on each side of current fragment are in memory. – Raghunandan Dec 16 '16 at 13:43
  • @PrithnirajNicyone is the fragment on which you have the handler is in position 0? – Raghunandan Dec 16 '16 at 14:32
  • Yes, that fragment in which I am running the handler in on position 0 in viewpager. – Prithniraj Nicyone Dec 19 '16 at 04:24
  • Yes Raghunandan, I've tried it just now and it is working fine. Thanks a lot for all your efforts. :) – Prithniraj Nicyone Dec 19 '16 at 08:16
  • If the above answer does not solve you problem, here is another great upvoted answer. https://stackoverflow.com/a/22719065/10323334 – Ali Tamoor Oct 05 '21 at 05:06