javaandroidhandlerperiodic-task

Run task every 30 seconds only while MainActivity has focus


I want to update some elements in my app's MainActivity every 30 seconds. I need that to happen only when MainActivity has focus, so once I change activities or close the app, this periodic task should stop.

I have tried using a Handler with Runnable and recursive postDelayed but I keep having issues with runnables not stopping, multiple ones running at the same time, etc.

I'm not even sure if this is the way I'm supposed to use for that wanted functionality, so here I am asking if anyone has done something similar and can share his way of achieving this.

PS. I'm writing my app in Java.


Solution

  • I don't know whether my way is ideal. Anyway, I do like this:

    private static final long TIMER_INTERVAL = 30000L;
    private Timer mTimer;
    
    @Override
    public void onResume() {
        super.onResume();
        resumeTimer();
    }
    
    @Override
    public void onPause() {
        pauseTimer();
        super.onPause();
    }
    
    private void resumeTimer() {
        pauseTimer(); // To avoid multiple occurrences,
                      // at first cancel existing timer if any
    
        mTimer = new Timer();
        mTimer.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
    
                // do your periodic task
    
            }
        }, 0, TIMER_INTERVAL);
    }
    
    private void pauseTimer() {
        if (mTimer != null) { // cancel existing timer if any
            mTimer.cancel();
            mTimer = null;
        }
    }
    

    [revised] an alternative with Handler:

    private static final long TIMER_INTERVAL = 30000L;
    private Handler mHandler;
    private Runnable mRunnable;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        mHandler = new Handler();
        mRunnable = new Runnable() {
            @Override
            public void run() {
    
                // do your periodic task
    
                mHandler.postDelayed(mRunnable, TIMER_INTERVAL);
            }
        };
    }
    
    @Override
    public void onResume() {
        super.onResume();
        resumeHandler();
    }
    
    @Override
    public void onPause() {
        pauseHandler();
        super.onPause();
    }
    
    private void resumeHandler() {
        pauseHandler(); // To avoid multiple occurrences,
                        // at first cancel existing task if any
    
        mHandler.post(mRunnable);
    }
    
    private void pauseHandler() {
        mHandler.removeCallbacks(mRunnable);
    }