Run task every 30 seconds only while MainActivity has focus

Viewed 271

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.

3 Answers

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);
}
Handler handler = new Handler(Looper.getMainLooper());
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                
                //do something here
                
                handler.postDelayed(this, 30000);
            }
        };

First: please post your code and a log!

When you wanna an infinite operation in ONLY a layout, use the Handler, call it in the Activity wanted.

Remember to call the postDealyed inside the declaration of the runnable and the Runnable#start() outside from itselves

Related