Home > Back-end >  [SOLVED]NavHostFragment.findNavController throw: Method addObserver must be called on the main threa
[SOLVED]NavHostFragment.findNavController throw: Method addObserver must be called on the main threa

Time:04-06

I have another Fragment where this function work. But when i receive a response by the server the program crash and return this exeception. I'm new in android, so i don't really catch the meaning and the funtion of the Navigation tools. I don't know if other file are needed for a solution, by the way you can ask to post other details.

EDIT: i found out that the problem is that i tried to change fragment by another thread. I usually get this error while working with javaFX. is there any function similiar to the "Platform.runlater()"???

SOLVED:

  getActivity().runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            NavHostFragment.findNavController(LoginFragment.this).navigate(R.id.action_LoginFragment_to_FirstFragment);
                        }
                    });

on the Fragment:

 @Override
        public void onResponse(Call call, Response response) throws IOException {
            String sessione = "";
            String email = "";
            try {
                String msg = response.body().string();
                JSONObject obj = new JSONObject(msg);
                sessione = obj.getString("message");
                if (sessione.equals("sessione esistente")) {
                    email = obj.getString("email");
                    NavHostFragment.findNavController(LoginFragment.this).navigate(R.id.action_LoginFragment_to_FirstFragment);
                    //intent.putExtra("user", email);
                    //startActivity(intent);
                }
                Looper.prepare();
                Toast.makeText(getContext(), sessione, Toast.LENGTH_SHORT).show();
                Looper.loop();
            } catch (JSONException e) {
                System.out.println("Errore onResponse ----> "   e.getMessage());
                Toast.makeText(getContext(), sessione, Toast.LENGTH_SHORT).show();
                e.printStackTrace();
            }
        }});

nav_graph.xml:

<?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/nav_graph"
            app:startDestination="@id/FirstFragment">

    <fragment
            android:id="@ id/FirstFragment"
            android:name="com.example.progetto.FirstFragment"
            android:label="@string/first_fragment_label"
            tools:layout="@layout/fragment_first">

        <action
                android:id="@ id/action_FirstFragment_to_SecondFragment"
                app:destination="@id/SecondFragment"/>
    </fragment>

    <fragment
            android:id="@ id/SecondFragment"
            android:name="com.example.progetto.SecondFragment"
            android:label="@string/second_fragment_label"
            tools:layout="@layout/fragment_second">

        <action
                android:id="@ id/action_SecondFragment_to_FirstFragment"
                app:destination="@id/FirstFragment"/>
    </fragment>

    <fragment
            android:id="@ id/nav_home"
            android:name="com.example.progetto.FirstFragment"
            android:label="@string/menu_home"
            tools:layout="@layout/fragment_first">
    </fragment>
    <fragment
               android:id="@ id/nav_login"
               android:name="com.example.progetto.LoginFragment"
               android:label="@string/login"
               tools:layout="@layout/activity_login_page">
        <action
                android:id="@ id/action_LoginFragment_to_FirstFragment"
                app:destination="@id/FirstFragment"/>
    </fragment>


    <fragment
        android:id="@ id/nav_myLesson"
        android:name="com.example.progetto.myLesson.myLessonFragment"
        android:label="@string/menu_myLesson"
        tools:layout="@layout/fragment_my_lesson">
    </fragment>
</navigation>

CodePudding user response:

In android if you want a piece of code to run on the main thread, you can use a coroutine scope with dispatcher context as MAIN. eg -

CoroutineScope(Dispatchers.Main).launch {
    stuffYouWantOnTheMainThread()
}

This would run the code on the main thread regardless of whether this code is located within another thread

  • Related