diff --git a/bottom-nav-watson/src/main/kotlin/bottom_nav_watson/BottomNavWatson.kt b/bottom-nav-watson/src/main/kotlin/bottom_nav_watson/BottomNavWatson.kt index c82c2b6..78526a1 100644 --- a/bottom-nav-watson/src/main/kotlin/bottom_nav_watson/BottomNavWatson.kt +++ b/bottom-nav-watson/src/main/kotlin/bottom_nav_watson/BottomNavWatson.kt @@ -263,7 +263,7 @@ private fun AppCompatActivity.obtainNavHostFragment( // but it starts to corrupt the back stack when Don't keep activities is enabled, which is avoided by // calling NavHostFragment.create(graphResId) and setting as the start destination of the graph -in the xml // declaration- an empty fragment. - val navHostFragment = NavHostFragment.create(graphResId) + val navHostFragment = LenientNavHostFragment.create(graphResId) fragmentManager.beginTransaction() .add(containerId, navHostFragment, fragmentTag) .commitNow() diff --git a/bottom-nav-watson/src/main/kotlin/bottom_nav_watson/LenientNavHostFragment.kt b/bottom-nav-watson/src/main/kotlin/bottom_nav_watson/LenientNavHostFragment.kt new file mode 100644 index 0000000..613ad63 --- /dev/null +++ b/bottom-nav-watson/src/main/kotlin/bottom_nav_watson/LenientNavHostFragment.kt @@ -0,0 +1,36 @@ +package bottom_nav_watson + +import android.os.Bundle +import androidx.navigation.fragment.NavHostFragment + +/** + * We need to subclass NavHostFragment to try/catch the call to super::onDestroyView + * as it throws an IllegalStateException when a deep link is launched starting from version + * 2.3.0 of the navigation component. Specifically, it crashes when the NavHostFragment + * tries to dispose itself by finding its associated NavController and there is none. + */ +class LenientNavHostFragment : NavHostFragment() { + + override fun onDestroyView() { + try { + super.onDestroyView() + } catch (e: IllegalStateException) { + // We only sallow the exception when it contains the message related with the issue that we know. + // Otherwise we rethrow, this is brittle as it ties the implementation to a private reporting message error, + // but we prefer this way to avoid hiding unrelated exceptions. + if (e.message?.contains("does not have a NavController set") == false) { + throw e + } + } + } + + companion object { + // We need to duplicate here the key as it's a private field in the library, which is brittle but it is what it is. + private const val KEY_GRAPH_ID = "android-support-nav:fragment:graphId" + + fun create(graphResId: Int): NavHostFragment = LenientNavHostFragment().apply { + arguments = Bundle().apply { putInt(KEY_GRAPH_ID, graphResId) } + } + } + +}