Search code examples
androidandroid-jetpackandroid-architecture-components

Why I have StackOverflowError when implementing Include in Navigation Controller?


my project file: https://drive.google.com/file/d/11llz7ylWe7ACyLMBbqp6YzugUL8hhImt/view?usp=sharing

so I have 2 navigation graph. called main navigation graph and also auth graph.

I include main graph into auth graph and vice versa, auth graph in main graph.

I want to implement login system, so when the user successfully logged in then the user will go to main activity (that has bottom navigation view and toolbar), auth activity does not have bottom navigation view or fragment. here is the graphs

  1. main navigation graph:

enter image description here

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:app="http://schemas.android.com/apk/res-auto"
            xmlns:tools="http://schemas.android.com/tools"
            android:id="@+id/navigation_graph"
            app:startDestination="@id/destination_home">

    <include app:graph="@navigation/auth_graph" />

    <fragment android:id="@+id/destination_home" android:name="com.muchammadagunglaksana.navcontroller.HomeFragment"
              android:label="Home Judul" tools:layout="@layout/fragment_home">
        <action android:id="@+id/action_toAuthActivity" app:destination="@id/auth_graph"/>
    </fragment>


    <fragment android:id="@+id/destination_camera" android:name="com.muchammadagunglaksana.navcontroller.CameraFragment"
              android:label="Camera Judul" tools:layout="@layout/fragment_camera">
        <action android:id="@+id/toPhotosDestination" app:destination="@id/destination_photos"/>
    </fragment>


    <fragment android:id="@+id/destination_photos" android:name="com.muchammadagunglaksana.navcontroller.PhotosFragment"
              android:label="Foto Judul" tools:layout="@layout/fragment_photos">
        <action android:id="@+id/toHomeDestination" app:destination="@id/destination_home"/>
        <argument android:name="numberOfPhotos" app:argType="integer" android:defaultValue="0"/>
    </fragment>


    <fragment android:id="@+id/destination_settings"
              android:name="com.muchammadagunglaksana.navcontroller.SettingsFragment"
              android:label="Setting Judul" tools:layout="@layout/fragment_settings"/>
</navigation>
  1. Auth graph: enter image description here

    <include app:graph="@navigation/navigation_graph" />
    
    <fragment android:id="@+id/loginFragment" android:name="com.muchammadagunglaksana.navcontroller.LoginFragment"
              android:label="fragment_login" tools:layout="@layout/fragment_login">
        <action android:id="@+id/action_toMainActivity" app:destination="@id/navigation_graph"/>
    </fragment>
    

when login button clicked in the LoginFragment then I use the code below:

       login_button.setOnClickListener {
            Navigation.findNavController(it).navigate(R.id.action_toMainActivity)
        }

and also in the HomeFragment, when the logout button did clicked I use:

logout_button.setOnClickListener {
            Navigation.findNavController(it).navigate(R.id.action_toAuthActivity)
        }

but I got stackoverflowerror:

E/AndroidRuntime: FATAL EXCEPTION: main Process: com.muchammadagunglaksana.navcontroller, PID: 14322 java.lang.StackOverflowError: stack size 8MB at android.support.v4.util.SparseArrayCompat.(SparseArrayCompat.java:77) at android.support.v4.util.SparseArrayCompat.(SparseArrayCompat.java:62) at androidx.navigation.NavGraph.(NavGraph.java:44) at androidx.navigation.NavGraphNavigator.createDestination(NavGraphNavigator.java:54) at androidx.navigation.NavGraphNavigator.createDestination(NavGraphNavigator.java:29) at androidx.navigation.NavInflater.inflate(NavInflater.java:100) at androidx.navigation.NavInflater.inflate(NavInflater.java:80) at androidx.navigation.NavInflater.inflate(NavInflater.java:128) at androidx.navigation.NavInflater.inflate(NavInflater.java:80) at androidx.navigation.NavInflater.inflate(NavInflater.java:128) at androidx.navigation.NavInflater.inflate(NavInflater.java:80) at androidx.navigation.NavInflater.inflate(NavInflater.java:128) at androidx.navigation.NavInflater.inflate(NavInflater.java:80) at androidx.navigation.NavInflater.inflate(NavInflater.java:128) at androidx.navigation.NavInflater.inflate(NavInflater.java:80) at androidx.navigation.NavInflater.inflate(NavInflater.java:128)

na.navcontroller E/JavaBinder: !!! FAILED BINDER TRANSACTION !!!

what went wrong ?


Solution

  • An <include> tag is the exact equivalent of copy/pasting the exact content of the including graph in place of the <include>. By having your auth_graph include the navigation_graph, you've built a loop: navigation_graph contains auth_graph which contains navigation_graph on and on forever.

    What you need to do is remove the <include app:graph="@navigation/navigation_graph" /> from your auth_graph. Because your auth_graph is already within the navigation_graph, you don't need to add it a second time, but you can reference any of those destinations directly.