Android Task Back Stack и управление сеансом приложения после сбоя/убийства

Мне было интересно, каковы распространенные практики или шаблоны в современном мире разработки Android в отношении управления Back Stack, в частности обработки случаев, когда приложение убито или дает сбой, и система пытается воссоздать свои действия, потому что задача, созданная приложением, все еще существует.

Вот видео, демонстрирующее описанное выше поведение в примере приложения: https://www.dropbox.com/s/pkm88dvdpzsw9lm/IMG_2334-480.mov?dl=0

А вот исходный код — простое приложение, созданное с помощью мастера Android Studio: ssh://[email protected]:lukaszs-appdate/crashingtask.git

Допустим, приложение показывает активность входа в систему в начале. Затем, когда пользователь входит в систему, он загружает данные с сервера и позволяет пользователю работать с данными, запускать другие действия, управлять состоянием приложения и т. д. Важным предположением является то, что когда пользователь, например. переключается на другое приложение и возвращается к нашему приложению, они видят последнее действие и не возвращаются к входу в систему. Поэтому я не думаю, что комбинации флагов из документа https://developer.android.com/guide/components/activities/tasks-and-back-stack.html будет достаточно для решения проблемы.

И проблема в том, что когда: а) приложение вылетает и перезапускается, или б) приложение перемещается в фоновый режим с помощью кнопки переключения задач в Android, затем вручную убивается в Android Studio и возвращается, нажав значок задачи, затем Android пытается воссоздать действия из задачи. Я хочу, чтобы он просто запускал приложение с нуля в случае этих событий и показывал экран входа в систему.

Единственное решение, которое я вижу, это какой-то уродливый родительский класс для всех действий, кроме входа в систему, где мы проверяли бы, установлена ​​ли какая-то переменная псевдосеанса, и если это не так, предположим, что приложение было перезапущено, и замените весь стек задач на вход в систему, или сделать цепочку вызовов finish(), или другие вонючие вещи, подобные этому.

Любые другие идеи? Разве Android не может просто удалить задачу, созданную приложением, когда это приложение убито?

Чистым решением для этого было бы использовать какое-то управление сеансом, позволяющее любому действию восстанавливать бизнес-состояние приложения, эффективно позволяя пользователю правильно вернуть приложение из любого действия, даже если оно было убито. Но это для другого обсуждения.


person Łukasz Sromek    schedule 27.03.2017    source источник
comment
Вы решили это?   -  person Rafael Ruiz Muñoz    schedule 09.11.2018


Ответы (1)


Я написал этот код на Kotlin, который помогает мне определить, что это действие возвращается. Я понял, что возвращающаяся активность не вызывает onCreate(Bundle) (афаик). Так что, если у вас есть BaseActivity, вы можете сделать это таким образом.

class BaseActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        startedWithLauncher = startedWithLauncher || intent.action == Intent.ACTION_MAIN
        super.onCreate(savedInstanceState)
    }

    override fun onResume() {
        super.onResume()
        if (!didStartWithLauncher()) {
            // Do something
        }
    }

    fun didStartWithLauncher(): Boolean {
        return startedWithLauncher;
    }

    companion object {
        /**
         * Situation:
         * You have a Stack with Activity (A - Main Launcher, B, C). C crashes, when you click in "Open app again",
         * I don't know why but it opens the Activity B, recreating the stack, but this might not be
         * what you want.
         * We're setting this variable to ask if it started from the launcher.
         * We need to write this variable before super.onCreate(savedInstanceState).
         */
        private var startedWithLauncher = false
    }

}

ВНИМАНИЕ!

Если вы запускаете действие из Service (например, push-уведомления). Вы должны установить этот startedWithLauncher = true, иначе это будет выглядеть так, как будто приложение не запускалось с помощью Launcher Activity!

person Rafael Ruiz Muñoz    schedule 09.11.2018