onRestart() вызывается при нажатии кнопки «Назад», как это предотвратить?

Мое приложение вызывает несколько веб-служб, когда оно только что запущено. Я также хотел бы вызывать эти веб-службы, если пользователь запускает приложение (которое работало в фоновом режиме) и возобновляет работу. Я изучил все методы, запускаемые при запуске приложений и когда активные действия находятся в фокусе. onStart(), onResume(), onRestart() и т.д....

Я думал, что onRestart будет хорошей ставкой, чтобы сделать вызовы моей веб-службы и обновить мое представление, проблема в том, что если я перейду от действия A (тот, который делает звонки) к действию B и нажму кнопку «Назад», действие A сработает onRestart() и вызвать веб-службы. Я не хочу, чтобы это происходило каждый раз, когда я возвращаюсь на главный экран из какой-либо активности в своем приложении. Я хочу, чтобы службы вызывались только в том случае, если моя активность приложения A находится в центре внимания извне. Есть ли какие-либо другие события, о которых я должен знать, которые могут мне помочь? Если я нажму кнопку «Домой», а затем нажму значок своего приложения, оно должно обновиться, но не в том случае, если я нажму что-то на своем главном экране, открою новое действие, а затем нажму кнопку «Назад».

Надеюсь, вопрос имеет смысл.

Спасибо.


person PaulG    schedule 05.12.2011    source источник
comment
Когда вы говорите, что если пользователь запускает приложение (которое работало в фоновом режиме), как приложение перешло в фоновый режим, нажав кнопку «Назад» или кнопку «Домой»?   -  person havexz    schedule 05.12.2011
comment
Кнопка HOME должна была упомянуть об этом.   -  person PaulG    schedule 05.12.2011


Ответы (3)


В соответствии с жизненным циклом действия, onRestart будет вызываться перед onResume. Поэтому, если вы поместите свои веб-вызовы в onResume, они будут вызываться при первом запуске активности и в любое время, когда она возобновляется. onRestart вызывается только тогда, когда пользователь возвращается к этому действию. Таким образом, вы можете иметь логическое значение в своей деятельности (например, логическое значение isActivityRestarting), для которого установлено значение false, а затем установлено значение true в onRestart. Если это правда, когда onResume попадает, тогда не делайте свои веб-звонки.

Пример кода:

public void onRestart() {
    isActivityRestarting = true;
}

public void onResume() {
    if (!isActivityRestarting) {
        executeWebCalls();
    }

    isActivityRestarting = false;
}
person Jason Robinson    schedule 05.12.2011
comment
Спасибо за ответ. Это не сработает. В настоящее время я печатаю каждый вызов onResume() onStart() onRestart() onStop() onPause() и т. д. из всех моих действий в журнал. Это моя первоначальная проблема: если я щелкну что-то на своем главном экране (экране вызова веб-службы) и открою действие B, а затем нажму НАЗАД, будут запущены следующие методы: onRestart() onStart() onResume() в этом порядке. Таким образом, с логикой вашего ответа он в любом случае вызовет веб-службы. - person PaulG; 05.12.2011
comment
Я думаю, вы неправильно понимаете. К тому времени, когда вы доберетесь до onResume(), вы уже будете знать, перезапускается активность или нет. Я отредактировал свой ответ, чтобы показать код. - person Jason Robinson; 05.12.2011
comment
Что если пользователь выйдет из моего приложения с помощью кнопки HOME? Когда он снова запустится, он вызовет onRestart() onStart() onResume() в этом порядке, поэтому я ДЕЙСТВИТЕЛЬНО хочу, чтобы он вызывал веб-службы, когда происходит onRestart, а не когда он исходит от нажатия кнопки НАЗАД. - person PaulG; 05.12.2011
comment
Из-за моей проблемы в моем последнем комментарии я решил попробовать установить для флага shouldUpdate значение false в событии onBackPressed моей активности B, это не работает, потому что в какой-то момент мне нужно установить этот флаг в значение true для вызова веб-служб. но пока не придумал где это сделать. - person PaulG; 05.12.2011
comment
в любом методе жизненного цикла, который вы используете для своих веб-вызовов, в конце установите для флага shouldUpdate значение true. Это сбросит это логическое значение. Инициализируйте логическое значение значением true, чтобы оно было ложным только при срабатывании onBackPressed. - person Jason Robinson; 05.12.2011
comment
Прямо сейчас мои веб-сервисы вызываются в OnCreate() моей MainActivity. Итак, я установил для логического значения значение true в OnCreate(), но когда я перехожу к ActivityB и нажимаю в ответ, для него устанавливается значение false, чего я и хочу, НО когда оно когда-нибудь снова станет равным true ?? Это моя дилемма, зная, когда установить его на истину. - person PaulG; 05.12.2011
comment
Ну, во-первых, вам нужно переместить свои веб-вызовы из onCreate. Я бы рекомендовал переместить его в onResume. В самой последней строке вашего метода onResume установите для shouldUpdate значение true. - person Jason Robinson; 05.12.2011
comment
Когда я верну для shouldUpdate значение true после того, как для него было установлено значение false с помощью кнопки BACK? Я тоже думал сделать это таким образом, но, как я уже сказал, я не знаю, когда установить флаг обратно в значение true, чтобы он действительно мог получать новые данные. Если бы я мог обнаружить нажатие кнопки HOME (что не является законным на Android), я мог бы установить там значение true и заставить его вызывать мои веб-службы, когда я открываю приложение, но не могу. Я пробовал много вещей - person PaulG; 05.12.2011
comment
Прочитайте последнее предложение моего предыдущего комментария. - person Jason Robinson; 06.12.2011

Что ж, onCreate — ваш лучший выбор, но с некоторыми оговорками. (основной экран здесь - это экран, который вызывает веб-сервис)

  • Если пользователь нажмет кнопку НАЗАД на главном экране, будет вызван onCreate.
  • Если пользователь нажимает кнопку НАЗАД на другом экране и возвращается к основному экрану, onCreate вызываться не будет.
  • Если пользователь выходит из главного экрана с помощью кнопки HOME и возвращается долгим нажатием кнопки HOME и выбором вашего приложения, onCreate не вызывается.

Пока все хорошо, вот загвоздка.

  • Если пользователь нажимает кнопку HOME для выхода, а затем переходит к значку запуска, onCreate не вызывается. Теоретически это последовательное поведение, но может выглядеть странно, поскольку пользователь может подумать, что он запускает приложение с самого начала, забыв, как он изначально вышел.

На ваш ответ, onCreate — это путь с небольшими проверками.

Решение при использовании onStart или onRestart:

Одна проверка, которую вы можете сделать, это сохранить отметку времени в ваших общих настройках, которая соответствует времени, когда вы вызывали веб-службы. Теперь, когда пользователь вышел (будь то клавишей HOME или BACK) и вернулся, вы можете проверить время и сравнить его с сохраненным временем. Если разница велика, просто вызовите веб-сервис. Чтобы сделать эту работу, вы должны использовать onStart или onRestart.

person havexz    schedule 05.12.2011
comment
Точно моя проблема. Я делаю вызовы веб-службы в OnCreate() прямо сейчас, но, как вы сказали, OnCreate не будет вызываться, когда я возобновлю свое приложение. Я изучал эти небольшие проверки около 2 часов, но ничего не придумал. Мы не можем поймать нажатие кнопки HOME по понятным причинам, я близок к концу своей веревки. - person PaulG; 05.12.2011
comment
Разница во времени может быть высокой, если пользователь не выходит из приложения. И onStart(), и onRestart() все равно будут вызываться, если я нажму BACK на главный экран. - person PaulG; 05.12.2011
comment
Скажи мне одну вещь, это как-то вредит, если пользователь находится на каком-то экране и возвращается через долгое время, и мы делаем вызов веб-службы, так как локальные данные могут быть устаревшими к этому времени? Таким образом, идея вместо вызовов на основе жизненного цикла у нас есть вызовы на основе истекшего времени. - person havexz; 05.12.2011
comment
Вы правы, это, вероятно, не повредит пользователю, поскольку он все равно должен получать новые данные. - person PaulG; 05.12.2011

Поскольку это нормальное поведение (см. http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle) Я бы рекомендовал не пытаться работать против него, а работать с методами жизненного цикла.

Ваше приложение привлекает внимание извне, будь то это другое действие или что-то еще.

Возможно, вам следует вызвать службы в onCreate?

person skynet    schedule 05.12.2011
comment
OnCreate не вызывается при возобновлении работы приложения. В любом случае спасибо - person PaulG; 05.12.2011
comment
Ну, вы не всегда хотите вызывать его, если ваше приложение возобновляется, иначе вы бы использовали onResume или onStart, верно? - person skynet; 05.12.2011
comment
В идеале да, но onResume() и onStart() ОБА вызываются всякий раз, когда я нажимаю кнопку «Назад» от действия B обратно к действию A (mainScreen). Я не хочу вызывать веб-службы каждый раз, когда возвращаюсь на главный экран. - person PaulG; 05.12.2011
comment
Когда вы хотите, чтобы веб-сервисы вызывались? Не могли бы вы отредактировать свой вопрос, определяющий эти случаи? Если вы хотите сделать это только один раз за жизнь активности, используйте onCreate - person skynet; 05.12.2011
comment
В основном я хочу, чтобы веб-службы вызывались всякий раз, когда пользователь нажимает значок приложения. Здесь могут произойти две вещи. 1) Приложение запускается и вызывается onCreate, таким образом вызывая веб-службы 2) Приложение запускается, но, поскольку оно уже работает в фоновом режиме (пользователь, вероятно, нажал кнопку «Домой» в предыдущем сеансе), onCreate не вызывается и нет сети службы называются. - person PaulG; 05.12.2011
comment
Спасибо, Крейги, звучит здорово, но я рассмотрю это в крайнем случае, я уверен, что есть более простой способ добиться этого. - person PaulG; 05.12.2011