Search code examples
androidandroid-fragmentsfragmenttransaction

classcastexception after commit when try to invoke method in fragment


I try to describe the situation, I have activity with listview1 and container where I keep fragment. it looks like this enter image description here

Yellow is the container with fragment. At the beginning when app starts, in the yellow container I keep fragment with another for example listView2. When I click on the listView1, on the yellow part should appear another fragment which shows picture. And when I want to close this picture, the listview2 should appear back on the yellow side and everything works great until this code.

here I make the replace action in the yellow container and after that I try to recreate the listview2 in the new replaced fragment

public void backToList()
    {
        FragmentTransaction fragmentTransaction = fragManager.beginTransaction();

        Fragment fragment =null;

        fragment = new Presence_Fragment();


        fragmentTransaction.replace(R.id.main_screen_fragment_container, fragment);
        fragmentTransaction.commit();
        createProperlyListViewInPresenceOrAktywnosciFragment();
    }

and here is method which invokes CreateListViewMethod() from fragment

public void createProperlyListViewInPresenceOrAktywnosciFragment()
    {

            Presence_Fragment presence_Fragment = (Presence_Fragment) fragManager.findFragmentById(R.id.main_screen_fragment_container);
            presence_Fragment.CreateListView();


    }

The logcat:

09-13 00:52:35.653: E/AndroidRuntime(2980): FATAL EXCEPTION: main
09-13 00:52:35.653: E/AndroidRuntime(2980): Process: com.example.kinder, PID: 2980
09-13 00:52:35.653: E/AndroidRuntime(2980): java.lang.ClassCastException: com.example.kinder.ChildBioFragment cannot be cast to com.example.kinder.Presence_Fragment
09-13 00:52:35.653: E/AndroidRuntime(2980):     at com.example.kinder.MainScreen.createProperlyListViewInPresenceOrAktywnosciFragment(MainScreen.java:175)
09-13 00:52:35.653: E/AndroidRuntime(2980):     at com.example.kinder.MainScreen.backToList(MainScreen.java:216)
09-13 00:52:35.653: E/AndroidRuntime(2980):     at com.example.kinder.ChildBioFragment$1.onClick(ChildBioFragment.java:47)
09-13 00:52:35.653: E/AndroidRuntime(2980):     at android.view.View.performClick(View.java:4445)
09-13 00:52:35.653: E/AndroidRuntime(2980):     at android.view.View$PerformClick.run(View.java:18446)
09-13 00:52:35.653: E/AndroidRuntime(2980):     at android.os.Handler.handleCallback(Handler.java:733)
09-13 00:52:35.653: E/AndroidRuntime(2980):     at android.os.Handler.dispatchMessage(Handler.java:95)
09-13 00:52:35.653: E/AndroidRuntime(2980):     at android.os.Looper.loop(Looper.java:136)
09-13 00:52:35.653: E/AndroidRuntime(2980):     at android.app.ActivityThread.main(ActivityThread.java:5139)
09-13 00:52:35.653: E/AndroidRuntime(2980):     at java.lang.reflect.Method.invokeNative(Native Method)
09-13 00:52:35.653: E/AndroidRuntime(2980):     at java.lang.reflect.Method.invoke(Method.java:515)
09-13 00:52:35.653: E/AndroidRuntime(2980):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:796)
09-13 00:52:35.653: E/AndroidRuntime(2980):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:612)
09-13 00:52:35.653: E/AndroidRuntime(2980):     at dalvik.system.NativeStart.main(Native Method)

The logcat looks for me like in container I still keep old fragment, but it's impossible I already replace ChildBioFragment with Presence_Fragment and make commit. And I want to invoke method from Presence_fragment so what is wrong with this code


Solution

  • You're making an assumption here: that commit() immediately executes. However, that is not the case. It executes asynchronously (on the UI thread), as per the documentation:

    The commit does not happen immediately; it will be scheduled as work on the main thread to be done the next time that thread is ready.

    One way to execute the commit synchronously is to call the following right after it:

    fragmentManager.executePendingTransactions();
    

    Refer to the docs for details:

    If you want to immediately executing any such pending operations [fragment transactions], you can call this function (only from the main thread) to do so.

    Alternatively, just keep a reference to the Presence fragment you instantiate (in stead of retrieving it from the manager). Just remember that commit() runs asynchronously, so don't try to touch any of its views etc right after the commit.