Странное поведение с жизненным циклом активности Android при подключении к клиенту API Google

В документах говорится о onRestart< /strong> (выделено мной):

Вызывается после onStop(), когда текущее действие повторно отображается пользователю (пользователь вернулся к нему). За ним следует onStart(), а затем onResume().

Теперь в моем приложении, как и рекомендуется, я (пытаюсь) подключиться к «Клиенту Google API» в onStart и отключиться в onStop следующим образом: (упрощенно)...

@Override
public void onStart(){
    super.onStart();
    mGoogleAPIClient.connect();
}

@Override
public void onStop(){
    super.onStop();
    mGoogleAPIClient.disconnect();
}

Я случайно запустил свое приложение и сразу же нажал кнопку «домой», чтобы избавиться от него, оно перешло в фоновый режим, а затем через несколько секунд снова ожило и начало пытаться подключить googleAPIClient. Это происходило только в том случае, если домашняя клавиша (или клавиша обзора, если на то пошло) была нажата быстро, т. е. до того, как появился диалог подключения (или, другими словами, до того, как был вызван mGoogleApiClient.connect()).

При дальнейшем тестировании стало очевидно, что если я удалю mGoogleAPIClient.connect() из onStart, он останется в фоновом режиме, как и ожидалось/требовалось. Я также подтвердил, что когда это происходит, вызывается onRestart, и действительно, он вызывается до вызова onStart. Однако это не имеет для меня никакого смысла.

Если проблема вызвана тем, что mGoogleAPIClient пытается подключиться (и при этом возвращает активность на передний план), а mGoogleAPIClient.connect() вызывается в onStart, который называется после onRestart, как onRestart может быть вызвано, если событие не произошло в этот момент?

Я также подтверждаю, что пробовал как минимум 2 других приложения из Play Store, которые также демонстрируют такое поведение.

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


comment
супер.onStop() ?   -  person iGio90    schedule 29.04.2017
comment
before the connecting dialogue had a chance to appear что за диалог подключения?   -  person natario    schedule 29.04.2017
comment
@ iGio90, опечатка - исправлено :-)   -  person Zippy    schedule 29.04.2017
comment
@natario, извините, когда вы подключаетесь к клиенту Google API, вы получаете диалоговое окно, которое появляется на экране (в моем случае я подключаюсь к Play Games Services) - это диалог, о котором я говорю. Появляется логотип Play Games, затем экран выбора учетной записи.   -  person Zippy    schedule 29.04.2017
comment
Я думаю, вы смотрите на это неправильно, IMO, это первый вызов onStart, который запускает диалог. Когда диалог готов, onRestart и onStart вызываются снова, но connect() в этот момент бесполезен.   -  person natario    schedule 29.04.2017
comment
@natario, да, конечно, ты прав, я не знаю, почему я этого не видел. По какой-то причине я предполагал, что если домашняя клавиша будет нажата во время onStart, то сразу же включится onPause/onStop. Спасибо, что прояснили это. У вас есть какие-либо предложения относительно того, как этого можно избежать (я имею в виду, что если пользователь запускает приложение в фоновом режиме, последнее, чего он хочет, это чтобы оно снова ожило само по себе через 3 секунды), ура.   -  person Zippy    schedule 29.04.2017
comment
Я думаю, что вы ничего не можете сделать, кроме как подать отчет об ошибке / запрос функции   -  person natario    schedule 29.04.2017
comment
@natario, без проблем. У меня есть обходной путь, так что на данный момент этого должно быть достаточно. Если вы хотите опубликовать свое объяснение в качестве ответа, я отмечу его как принятое, спасибо.   -  person Zippy    schedule 29.04.2017


Ответы (2)


Диалоговое окно Play Games, о котором вы говорите, требует некоторого времени для создания (предположим, игровые сервисы должны подключаться к их API), поэтому есть вероятность, что:

  • вы открываете приложение и onStart() вызывается
  • клиент начинает подключение
  • вы закрываете приложение
  • фоновая работа клиента завершается успешно, и приложение выводится на передний план
  • onRestart() и onStart() вызываются именно в таком порядке, как говорится в документации. В этот момент вызов connect() бесполезен.

Поскольку это внутреннее поведение, на мой взгляд, мы мало что можем сделать, кроме как отключить клиент onStop(). Если вы считаете, что это важно, вы можете попытаться отправить запрос об ошибке / функции.

person natario    schedule 29.04.2017

Я думаю, это потому, что connect() происходит в фоновом режиме, ваше быстрое нажатие клавиши обходит разъединение() (состояние не устанавливается с помощью connect()), поэтому для того же соединения предполагается, что безопасно показывать диалог даже он должен снова вызвать приложение.

Вы можете попробовать следующее:

// Check if it is not already connected in onStart()
if(!mGoogleAPIClient.isConnected() || !mGoogleAPIClient.isConnecting()){
    mGoogleAPIClient.connect();
}

Во-вторых, вызовите блокировку disconnect() в onStop():

while(true){
    if(mGoogleAPIClient.isConnected()){
    mGoogleAPIClient.disconnect();
    break;
    }
}
person Manish Kumar Sharma    schedule 29.04.2017
comment
Спасибо @pulp_fiction, к сожалению, это не сработало - также цикл while не компилируется, я получаю оператор '!' нельзя применить к 'void' - я полагаю, потому что метод разъединения не возвращает логическое значение (на самом деле он ничего не возвращает) :-( Спасибо - person Zippy; 29.04.2017
comment
@Zippy: Мне плохо, что я забыл об этом. Смотрите сейчас. - person Manish Kumar Sharma; 29.04.2017
comment
@Zippy: Еще одна вещь, вы используете автоматическое управление API? - person Manish Kumar Sharma; 29.04.2017