본문 바로가기

안드로이드

Error ) NavigationExtensions - does not have a NavController set

반응형

에러 내용

java.lang.RuntimeException: Unable to destroy activity .... does not have a NavController set

Caused by: java.lang.IllegalStateException: View androidx.fragment.app.FragmentContainerView{d4cc327 V.E...... ......ID 0,143-1080,1868 #7f0900e0 app:id/main_nav_container} does not have a NavController set

재현 상황

 

android/architecture-components-samples

Samples for Android Architecture Components. . Contribute to android/architecture-components-samples development by creating an account on GitHub.

github.com

1. 안드로이드 샘플의 NavigationExtensions를 사용

2. 시작점이 되는 Fragment 에서 액티비티 finish 호출 or 액티비티 onDestroyView 호출 될때 or NavController를 가져오려고 할 때

3. 펑

알아 둘 것

@Override
public void onDestroyView() {
    super.onDestroyView();
    if (mViewParent != null && Navigation.findNavController(mViewParent) == mNavController) {
        Navigation.setViewNavController(mViewParent, null);
    }
    mViewParent = null;
}

우선, NavHostFragment는

onViewCreated 에서 navController 를 설정하고

onDestroyView 에서 navController 를 null로 변경함

 

액티비티에 있는 FragmentContainerView

navController 값이 들어가거나 null 이 들어가는 거임

원인

2021-02-03 22:43:57.661 3340-3340/com.~~~~ D/TestLog: attachNavHostFragment
2021-02-03 22:43:57.743 3340-3340/com.~~~~ D/TestLog: detachNavHostFragment
2021-02-03 22:43:57.781 3340-3340/com.~~~~ D/TestLog: detachNavHostFragment

안드로이드 샘플의 NavigationExtensions은 초기 로딩 시

모든 시작점인 NavHostFragment를 순서대로 생성한 후

첫 번째 프래그먼트를 attach 하고

나머지 프래그먼트는 detach 시킴

 

근데, 마지막에 실행된 게 detach 임

-> 모든 과정의 마지막으로 onDestroyView 가 불린 거임

-> 두둥 null 이 세팅됨

 

이 상황에서 액티비티가 NavController를 가져오려고 하면?

당연히 없으니 펑

해결법

detach 가 뒤에 호출되는 게 문제임

 

NavigationExtensions 코드에서

NavHostFragment 생성하는 부분을 거꾸로 실행하도록 바꿔 주면 됨

( + index 도 같이 뒤집어 주어야한다. )

navGraphIds.forEachIndexed { index, navGraphId ->
    val fragmentTag = getFragmentTag(index)

    // Find or create the Navigation host fragment
    val navHostFragment = obtainNavHostFragment(
        fragmentManager,
        fragmentTag,
        navGraphId,
        containerId
    )
   
밑에 처럼 뒤집어 주면 됨.

navGraphIds.reversed().forEachIndexed { index, navGraphId ->
    val index = navGraphIds.lastIndex - index
    val fragmentTag = getFragmentTag(index)
    
    
    
2021-02-03 23:07:21.881 3574-3574/~~~~~ D/TestLog: detachNavHostFragment
2021-02-03 23:07:21.997 3574-3574/~~~~~ D/TestLog: detachNavHostFragment
2021-02-03 23:07:22.082 3574-3574/~~~~~ D/TestLog: attachNavHostFragment

 

반응형