Запускать задачу каждые 30 секунд, только пока MainActivity имеет фокус

#java #android #handler #periodic-task

#java #Android #обработчик #периодическая задача

Вопрос:

Я хочу обновлять некоторые элементы в MainActivity моего приложения каждые 30 секунд. Мне нужно, чтобы это происходило только тогда, когда MainActivity имеет фокус, поэтому, как только я меняю действия или закрываю приложение, эта периодическая задача должна прекратиться.

Я пытался использовать обработчик с возможностью выполнения и рекурсивный postDelayed , но у меня продолжают возникать проблемы с тем, что выполняемые файлы не останавливаются, несколько одновременно запущенных и т. Д.

Я даже не уверен, что это тот способ, который я должен использовать для этой желаемой функциональности, поэтому здесь я спрашиваю, делал ли кто-нибудь что-то подобное и может поделиться своим способом достижения этого.

PS. Я пишу свое приложение Java .

Ответ №1:

Я не знаю, идеален ли мой путь. В любом случае, мне нравится это:

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

[исправлено] альтернатива с обработчиком:

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

Комментарии:

1. Спасибо вам за это. Он работает именно так, как я хочу, хотя из того, что я прочитал TimerTask , не рекомендуется использовать в приложениях для Android. например. medium.com/@f2016826/timers-vs-handlers-aeae5d3cb5a

2. @SpyrosG Я обновляю свой пост с Handler версией.

3. Это супер круто, спасибо! Работает исключительно!

Ответ №2:

 Handler handler = new Handler(Looper.getMainLooper());
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                
                //do something here
                
                handler.postDelayed(this, 30000);
            }
        };
 

Комментарии:

1. Я полагаю, вы забыли упомянуть handler.post(runnable); в конце. Я пробовал, но не соответствует запрошенным потребностям, поскольку задача все еще выполняется, даже когда я меняю действия или закрываю приложение…

Ответ №3:

Во-первых: пожалуйста, опубликуйте свой код и журнал!

Если вы хотите выполнять бесконечную операцию ТОЛЬКО в макете, используйте обработчик, вызывайте его в нужном действии.

Не забудьте вызвать postDealyed внутри объявления runnable и Runnable#start() снаружи от самих себя

Комментарии:

1. Я попросил предложение, поскольку мой код вообще не делает то, что мне нужно. Какой смысл добавлять его сюда, поскольку он не работает? Просто используя обработчик, задача продолжает выполняться периодически даже после изменения действий или закрытия приложения. По крайней мере, это то, что я испытываю, что является нежелательным поведением…

2. О, я только что снова прочитал свой ответ. Мне не удалось объяснить. Извините! Я не имел в виду макет, это поток.

3. Всегда лучше опубликовать ту часть вашего кода, о которой вы говорите. Это может помочь тому, кто ответит, дать вам хорошее решение. 😉

4. Я согласен, я обычно это делаю. Хотя не имело особого смысла делать это здесь, поскольку, вероятно, это был неправильный подход к проблеме в целом. Вот почему я только что объяснил, чего я хотел достичь. В любом случае, спасибо, что нашли время, чтобы помочь мне! 🙂