У меня немного тупица. У меня есть игровое приложение с 3 фрагментами. Фрагмент A, фрагмент B, фрагмент C с использованием оперативных данных и компонента навигации из Google. Когда пользователь завершает работу с фрагментом C, я использую компонент навигации, чтобы вернуть задний стек обратно к фрагменту A.
первая проблема: когда я вставляю задний стек, вызывается onDestroy () этого фрагмента. У меня сложилось впечатление, что этого поста не должно происходить: Ссылка .
вторая проблема: как только пользователь возвращается к фрагменту A, появляется возможность перейти к фрагменту B. После вызова строки для навигации, каким-то образом фрагмент C добавляется в задний стек и создается представление, вызывая сбой моего приложения, так как у меня есть слушатель, прослушивающий переменную в моей viewModel, которая используется для фрагментов, заданных во фрагменте B.
Я понятия не имею, почему фрагмент уничтожается, когда я вытаскиваю задний стек, и я не знаю, почему он создается, когда я пытаюсь перейти к фрагменту B.
Я зарегистрировал обратные вызовы жизненного цикла, чтобы убедиться, что фрагмент C уничтожается и воссоздается. И я следил за обратным стеком навигационного компонента, проходя через приложение. Видеть, что фрагмент C добавляется, казалось бы, случайно.
Учитывая, что это код внутри наблюдателя, который разбил мое приложение, я также попытался только добавить наблюдателя в onResume () и отсоединить его в onDestroy (), однако, когда фрагмент воссоздается, он проходит через onResume () и просто прикрепил наблюдателя сразу
Переход от фрагмента A к фрагменту B
viewModel.addPlayer(asPlayer).addOnCompleteListener {
Log.d("Game", "current destination before joining: "+resources.getResourceEntryName(navController.currentDestination!!.id))
navController.navigate(R.id.action_joinGameFragment_to_waitingFragment)
}
Наблюдатель вызван, что приводит к падению.
//so this observer is not getting detached, maybe manually detach it and reattach it in on resume
viewModel.gameExists.observe(this, androidx.lifecycle.Observer { exists ->
//someone ended the game
var debug = navController
if(!exists && navController.currentDestination?.id == R.id.gameFragment){ endGame() }
})
функция, которая вылетела
fun endGame(){
viewModel.endGame()
Log.d("Game", "current destination before crash: "+resources.getResourceEntryName(navController.currentDestination!!.id))
timer.cancel()
Log.d("Game", "current destination before poping: "+resources.getResourceEntryName(navController.currentDestination!!.id))
navController.popBackStack(R.id.startFragment, false)
Log.d("Game", "current destination after poping: "+resources.getResourceEntryName(navController.currentDestination!!.id))
}
результаты из журнала cat
2019-06-16 20:13:40.278 13021-13021/com.dangerfield.spyfall D/Game: current destination before poping: (FRAGMENT C)
2019-06-16 20:13:40.279 13021-13021/com.dangerfield.spyfall D/Game: current destination after poping: (FRAGMENT A)
2019-06-16 20:13:40.279 13021-13021/com.dangerfield.spyfall D/View Model: game = null
2019-06-16 20:13:40.299 13021-13021/com.dangerfield.spyfall D/GAME: ON DESTROY
2019-06-16 20:13:40.315 13021-13021/com.dangerfield.spyfall D/View Model: game = null
2019-06-16 20:14:05.289 13021-13021/com.dangerfield.spyfall D/Game: current destination before joining: (FRAGMENT A)
2019-06-16 20:14:05.316 13021-13021/com.dangerfield.spyfall D/Game: on Create
2019-06-16 20:14:05.317 13021-13021/com.dangerfield.spyfall D/Game: onCreateView
2019-06-16 20:14:05.353 13021-13021/com.dangerfield.spyfall D/GAME: ON RESUME
2019-06-16 20:14:05.353 13021-13021/com.dangerfield.spyfall D/Game: current destination before crash: (FRAGMENT C)
019-06-16 20:14:05.359 13021-13021/com.dangerfield.spyfall E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.dangerfield.spyfall, PID: 13021
kotlin.UninitializedPropertyAccessException: lateinit property timer has not been initialized
at com.dangerfield.spyfall.game.GameFragment.endGame(GameFragment.kt:158)
(фрагмент игры - фрагмент C)
Любая помощь / направление будет принята с благодарностью, большое спасибо.