Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is Android O failing with "does not belong to this FragmentManager!"

I have migrated my application to Android O in Android Studio 3

Running on an Android O emulator all my dialogFragments now fail with :-

java.lang.IllegalStateException: Fragment MyDialogFragment{43ccf50 #2 MyDialogFragment} declared target fragment SettingsFragment{ceed549 #0 id=0x7f0f0142 android:switcher:2131689794:0} that does not belong to this FragmentManager! at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1316) at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1624) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1689) at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:794) at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2470) at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2260) at android.support.v4.app.FragmentManagerImpl.optimizeAndExecuteOps(FragmentManager.java:2213) at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2122) at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:746) at android.os.Handler.handleCallback(Handler.java:769) at android.os.Handler.dispatchMessage(Handler.java:98) at android.os.Looper.loop(Looper.java:164) at android.app.ActivityThread.main(ActivityThread.java:6535) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767) 

I have made no code changes whatsoever.

What has changed in Android O that previously working DialogFragments now fail display?

Android Studio 3.0 Canary 1 Build #AI-171.4010489, built on May 15, 2017 JRE: 1.8.0_112-release-b736 x86_64 JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.o Mac OS X 10.11.6      compileSdkVersion 'android-O'     buildToolsVersion "26.0.0-rc2"     AndroidManifest.xml     defaultConfig {         minSdkVersion 16         targetSdkVersion 'O'         }  compile 'com.android.support:appcompat-v7:26.0.0-beta1' compile 'com.android.support:cardview-v7:26.0.0-beta1' compile 'com.android.support:design:26.0.0-beta1'     compile 'com.android.support:percent:26.0.0-beta1'    dependencies {         classpath 'com.android.tools.build:gradle:3.0.0-alpha1'      } 
like image 870
Hector Avatar asked May 26 '17 14:05

Hector


2 Answers

For me this was not only an issue on Android O but also on older versions. The oldest version I tested was API Level 16.

I was instantiating my fragments using this code:

MyFragment myFragment = MyFragment.newInstance(); myFragment.setTargetFragment(ParentFragment.this, 0); myFragment.show(getActivity().getSupportFragmentManager(), null); 

Where ParentFragment.this is a custom class extending android.support.v4.app.Fragment, MyFragment also extends this class and is a child fragment of the ParentFragment fragment (hence it's name).

I thought that I had to use a SupportFragmentManager (the getSupportFragmentManager() method) because I am using a fragment of the support package so I tried to call getActivity().getSupportFragmentManager() to get an activity reference that supported this method.

This does not seem to be the correct way though. I changed those calls to:

MyFragment myFragment = MyFragment.newInstance(); myFragment.setTargetFragment(ParentFragment.this, 0); myFragment.show(getFragmentManager(), null); 

so the fragment decides on it's own which FragmentManager to use and the error is gone now.

Hope this helps someone.

like image 192
Markus Ressel Avatar answered Sep 29 '22 10:09

Markus Ressel


I had the same problem, definitely an android bug. It happens when you are showing a fragment from another fragment using it as target. As workaround you can use:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)     getActivity().getFragmentManager().beginTransaction().add(dialogFrag, "dialog").commit(); else     getChildFragmentManager().beginTransaction().add(dialogFrag,"dialog").commit(); 
like image 30
greywolf82 Avatar answered Sep 29 '22 10:09

greywolf82