Как обработать завершение процедуры опроса всего приложения?

У меня какая-то сложная ситуация в моем приложении. Я реализовал механизм, который связывается с удаленным сервером каждые 60 секунд, чтобы проверить, доступны ли новые данные. Если это так, новые данные отображаются в приложении. Все идет нормально.

Я реализовал механизм следующим образом:

  • Он запускается в методе onCreate() моей MainActivity.
  • Процедура опроса останавливается в методе onDestroy() моей MainActivity.

Это гарантирует, что опрос всегда активен, пока приложение работает. Кроме того, если я запускаю другое действие из основного действия, я также хочу, чтобы опрос выполнялся.

Моя проблема:

Когда я выхожу из своего приложения с помощью кнопки «Назад», все работает нормально, и опрос прекращается. Но когда я выхожу из своего приложения с помощью кнопки «Домой», процедура опроса остается активной, поскольку onDestroy() моей основной активности не вызывается, но я хочу, чтобы она остановилась.

Если я изменю свой код и остановлю процедуру опроса в методе onPause() моей MainActivity, у меня возникнет проблема, заключающаяся в том, что опрос также останавливается, когда я запускаю новую активность.

Что я хочу:

Я хочу, чтобы опрос выполнялся до тех пор, пока мое приложение (не моя MainActivity) находится на переднем плане/видимо для пользователя. Как только пользователь выходит из приложения, нажав кнопку «Домой» из любого места в приложении или нажав кнопку «Назад» из MainActivity, я хочу, чтобы опрос прекратился.

ДОПОЛНИТЕЛЬНО:

Я также не хочу перезапускать и останавливать службу каждый раз, когда я переключаю действия. Поскольку пользователь моего приложения будет переключать действия очень часто, это будет просто много накладных расходов. Кроме того, я хочу, чтобы цикл «обновления» составлял ровно 60 секунд. Я не могу гарантировать это, когда я всегда перезапускаю службу и снова останавливаю ее. Его нужно запустить один раз, когда приложение запускается, и остановить, когда приложение больше не находится на переднем плане.

Как этого добиться?

Есть какой-нибудь простой способ проверить, когда приложение находится на переднем плане, а когда оно скрыто/закрыто?

Это мой механизм опроса синглтона:

private Timer t;
private static Updater instance;

protected Updater() {
      // Exists only to defeat instantiation.
}

public static Updater getInstance() {

    if(instance == null) {
        instance = new Updater();
    }

    return instance;
}

public void startPollingRoutine(int interval, int delay) {      

    t = new Timer();

    // Set the schedule function and rate
    t.scheduleAtFixedRate(new TimerTask() {

        @Override
        public void run() {

            update(); // some asynctask that does the updating
        }

    }, delay, interval);
}

public static void stopPollingRoutine() {
    t.cancel();
}

В коде:

Updater.getInstance().startPollingRoutine(60000, 0);
Updater.getInstance().stopPollingRoutine();

person Philipp Jahoda    schedule 26.09.2013    source источник


Ответы (4)


Я думаю, что лучший способ справиться с этим — создать некую BaseActivity, на которую будут распространяться все действия. И выполнять эти действия в onResume/onPause. Или можно попробовать воспользоваться сервисами.

person user2729200    schedule 26.09.2013
comment
Да, это было бы возможно, но это не соответствует моим требованиям. (См. ДОПОЛНИТЕЛЬНО в моем вопросе) - person Philipp Jahoda; 26.09.2013
comment
Вы можете сохранить в настройках отметку времени последнего сканирования и запустить таймер, когда вам это нужно. - person user2729200; 26.09.2013

вам нужно создать службу и запустить ее в своем основном классе, эта служба будет запущена, если вы явно не остановите ее при уничтожении, означает onBackpressed()/onDetroy() и позволите ей работать в методе onPause()

person Usman Kurd    schedule 26.09.2013
comment
Да, но когда остановить службу? Недостаточно остановить службу в onDestroy(), поскольку она не будет вызываться при нажатии кнопки «Домой». onPause() также не подходит, так как опрос не должен останавливаться при запуске нового действия. - person Philipp Jahoda; 26.09.2013
comment
кроме того, вы также можете использовать широковещательный приемник vogella.com/articles/AndroidBroadcastReceiver/article. html - person Usman Kurd; 26.09.2013

Используйте синглтон и пусть у него есть переменная-счетчик. Увеличьте его, когда вы отправляете намерение начать новую активность, и уменьшите его в onPause. Чем вы можете сказать, должен ли опрос остановиться; когда счетчик в синглтоне равен нулю.

person hakanostrom    schedule 26.09.2013
comment
это не сработает, потому что вы можете нажать кнопку «Домой» из любого действия, поэтому, если вы выполняете 3 действия, и пользователь попадает в дом, опрос не остановится, как он хочет. - person tyczj; 26.09.2013
comment
Я уже использую синглтон, вопрос только в том, как его остановить, чтобы он соответствовал моим требованиям. - person Philipp Jahoda; 26.09.2013
comment
Я имел в виду, уменьшите его с onPause каждой активности. - person hakanostrom; 26.09.2013
comment
@hakanostrom, так что же происходит, когда пользователь нажимает кнопку «Домой», когда на счету 3 ?? - person tyczj; 27.09.2013

Спасибо всем за вашу помощь и время. Наконец-то я сам нашел решение, отвечающее всем моим требованиям.

Я следовал этому руководству, чтобы заставить его работать: http://www.mjbshaw.com/2012/12/determining-if-your-android-application.html

Основная идея состоит в том, чтобы расширить класс Application и сохранить ссылку на то, сколько действий "активно" в определенное время.

person Philipp Jahoda    schedule 26.09.2013