2023. 7. 18. 14:27ㆍAndroid/개발 CASE
[이슈] navigation 시 app crash
[원인] netsted graph는 startDestination만을 통해 접근 가능
Nested Graph Fragment -> Root Graph Fragment : O
Root Graph Fragment -> Nested Graph Fragment : X
명시적으로 navigate한 경우 발생하는데, 내 프로젝트의 경우 state에 따른 타이밍 이슈 때문에 발생함
[재현 조건]
초기 Navigation BackQueue : Root Graph - Nested Graph - AFragment
중간 Navigation BackQueue : Root Graph - Nested Graph - AFragment - CFragment
종결 Navigation BackQueue : Root Graph - Nested Graph - AFragment - CFragment - BFragment
Single Activity를 가지고 그 안에서 Fragment로 이동하는 Navigation의 기본 구조대로 진행
1. 초기 상태에서 Activity의 특정 state collect가 수행되어 CFragment로 navigate
2. 초기 상태에서 AFragment의 특정 state collect가 수행되어 BFragment로 navigate(여기서는 A, B Fragment가 동일 Nested Graph에 있다고 가정(이동가능하다는 가정하에))
1이 먼저 수행되면서 2가 이후 수행 시, Root Graph Fragment -> Nested Graph Fragment : X 를 수행하는 것이므로 에러 발생
[해결]
2를 방지하기 위해서 collect함수를 repeatOnLifeCycle로 감쌌지만 동일 문제 발생
viewLifecycleOwner.lifecycleScope.launch {
viewLifecycleOwner.lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
collectState(this)
}
}
repeatOnLifecycle(Lifecycle.State.STARTED)는 onStart()~onPause() 직전까지 수행
하지만, 1번과 같이 navigate가 불리는 순간 onPause의 수행되지 않고 collect가 진행됨(이후, onStop()이 바로 호출됨)
-> 왜그런지는 WIP
이를 방지하기 위해, Lifecycle.State.RESUMED로 변경하면 정상 동작함
[STARTED]
2023-07-18 14:09:06.090 9946-9946 AFragment E AFragment onCreateView()
2023-07-18 14:09:06.105 9946-9946 AFragment E AFragment onStart()
2023-07-18 14:09:06.112 9946-9946 AFrag...collectState E AFragment collectState : null
2023-07-18 14:09:06.212 9946-9946 MainActivi...collectState E MainActivity go to CFragment
2023-07-18 14:09:06.234 9946-9946 AFrag...collectState E AFragment collectState : CHANGED
2023-07-18 14:09:06.235 9946-9946 AFrag...collectState E AFragment collectState go to AFragment
2023-07-18 14:09:10.647 9946-9946 AndroidRuntime E FATAL EXCEPTION: main
Process: , PID: 9946
java.lang.IllegalArgumentException: Navigation action/destination BFragment cannot be found from the current destination Destination(CFragment) label=CFragment class=package.CFragment
at androidx.navigation.NavController.navigate(NavController.kt:1540)
at androidx.navigation.NavController.navigate(NavController.kt:1472)
at package.AFragment$collectState$1$1.emit(AFragment.kt:96)
at package.AFragment$collectState$1$1.emit(AFragment.kt:89)
at kotlinx.coroutines.flow.StateFlowImpl.collect(StateFlow.kt:398)
at kotlinx.coroutines.flow.StateFlowImpl$collect$1.invokeSuspend(Unknown Source:15)
Navigation BackQueue
2023-07-18 14:09:06.231 9946-9946 MainActivity$onCreate D navBackStackEntry ===============================
2023-07-18 14:09:06.232 9946-9946 MainActivity$onCreate D navBackStackEntry = root_graph
2023-07-18 14:09:06.232 9946-9946 MainActivity$onCreate D navBackStackEntry = nested_graph
2023-07-18 14:09:06.232 9946-9946 MainActivity$onCreate D navBackStackEntry = AFragment
2023-07-18 14:09:06.233 9946-9946 MainActivity$onCreate D navBackStackEntry = CFragment
[RESUMED]
2023-07-18 14:07:46.807 9328-9328 AFragment E AFragment onCreateView()
2023-07-18 14:07:46.821 9328-9328 AFragment E AFragment onStart()
2023-07-18 14:07:46.909 9328-9328 MainActivi...collectState E MainActivity go to CFragment
2023-07-18 14:07:46.944 9328-9328 AFragment E AFragment onStop()
Navigation BackQueue
2023-07-18 14:09:06.231 9946-9946 MainActivity$onCreate D navBackStackEntry ===============================
2023-07-18 14:09:06.232 9946-9946 MainActivity$onCreate D navBackStackEntry = root_graph
2023-07-18 14:09:06.232 9946-9946 MainActivity$onCreate D navBackStackEntry = nested_graph
2023-07-18 14:09:06.232 9946-9946 MainActivity$onCreate D navBackStackEntry = AFragment
2023-07-18 14:09:06.233 9946-9946 MainActivity$onCreate D navBackStackEntry = CFragment