Нажать на "закрытом" экране в Android

Jul 30, 2014   #android 

Как вы думаете, возможно ли пользователем (то есть не программным вызовом метода, а именно собственным пальчиком) нажать на экране приложения, когда оно не считается активным, не ожидает ввода да и вообще потенциально считается закрытым?

Занимаясь обработкой нажатий в 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. Это легко повторяется с нажатием на элементы списка, но не работает с нажатием на обычные кнопки.

comments powered by Disqus