Как вы думаете, возможно ли пользователем (то есть не программным вызовом метода, а именно собственным пальчиком) нажать на экране приложения, когда оно не считается активным, не ожидает ввода да и вообще потенциально считается закрытым?
Занимаясь обработкой нажатий в Android, столкнулся с интересной проблемой.
Как известно, любая Activity проходит следующий жизненный цикл: created → started → resumed → paused(=started) → stopped(=created) → destroyed.
Иногда у программистов возникает непонимание, чем отличаются состояния paused и resumed (да и я не всегда могу сразу решить, какой из методов: onStart или onResume — лучше выбрать для написания какой-то части логики) и что может произойти во временном промежутке между этими состояниями (рассматривается именно случай перехода активности между состояниями, а не перекрытие её другими активностями, когда состояния становятся легко различимы). На самом деле на глаз эти состояния отличить легко. Например, при нажатии Home активити сворачивается и в процессе анимации сворачивания она уже paused, но ещё не stopped.
Именно об этом процессе (не анимации, а переходе) сейчас и будет идти речь.
Возможно (и скорее всего), описываемое ниже поведение является багом Android, но оно существует, поэтому с ним нужно мириться.
Создадим проект с одной активностью, добавим в него ListView, создадим следующий обработчик нажатий на элемент:
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Log.d(TAG, "onItemClick");
}
});
Добавим обработчики колбеков активности onPause и onStop:
@Override
protected void onPause() {
super.onPause();
Log.d(TAG, "onPause");
}
@Override
protected void onStop() {
super.onStop();
Log.d(TAG, "onStop");
}
А теперь произведём следующие манипуляции: нажмём пальцем на любой элемент списка и не отпуская его свернём приложение кнопкой Home. В процессе анимации сворачивания отпустим палец. В логе появятся следующие строчки:
onPause
onItemClick
onStop
Получилось, что пункт списка был нажат на экране, который не считается активным и не ожидает пользовательского ввода.
Поэтому необходимо быть осторожным и не стоит полагаться на то, что активность ещё открыта, когда производится нажатие.
На этом всё.
P.S. Это легко повторяется с нажатием на элементы списка, но не работает с нажатием на обычные кнопки.