为什么Android O失败并且“不属于这个FragmentManager!”

我已将我的应用程序迁移到Android Studio 3中的Android O.

在Android O模拟器上运行我的所有dialogFragments现在都失败了: –

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) 

我没有做任何代码更改。

以前工作的DialogFragments现在失败的Android O有什么变化?

 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 sro 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' } 

Solutions Collecting From Web of "为什么Android O失败并且“不属于这个FragmentManager!”"

我有同样的问题,绝对是一个机器人的bug。 当您使用它作为目标显示来自另一个片段的片段时,就会发生这种情况。 作为解决方法,您可以使用:

 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) getActivity().getFragmentManager().beginTransaction().add(dialogFrag, "dialog").commit(); else getChildFragmentManager().beginTransaction().add(dialogFrag,"dialog").commit(); 

对我来说,这不仅是Android O上的问题,也是旧版本的问题。 我测试的最旧版本是API Level 16。

我使用以下代码实例化我的片段:

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

其中ParentFragment.this是一个扩展android.support.v4.app.Fragment的自定义类, MyFragment也扩展了这个类,它是ParentFragment片段的子片段(因此它的名字)。

我认为我必须使用SupportFragmentManager( getSupportFragmentManager()方法),因为我使用了支持包的片段,因此我尝试调用getActivity().getSupportFragmentManager()来获取支持此方法的活动引用。

这似乎不是正确的方法。 我将这些电话改为:

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

所以片段决定它自己使用哪个FragmentManager,错误现在消失了。

希望这有助于某人。

当我们迁移到Android Studio 3并将支持库升级到版本26时,我刚刚遇到了我目前正在处理的项目中的相同问题。突然间,在不更改代码的情况下,我们得到了大量的此exception。 最后我发现了以下内容:

今年1月,谷歌在v4片段管理器的源代码中添加了一个新的“健全性检查”(不确定是什么版本)拒绝使用片段管理器添加片段,如果它有一个目标片段集和目标片段片段无法在相同片段管理器的活动片段中find。 这里将详细介绍该补丁

Ealier版本似乎并不关心这一点。 我花了几天时间来更新代码中的所有区域,其中使用支持片段管理器添加的片段使用子片段管理器将子片段作为目标使用子片段。 好吧,写错码的后期处罚。

我有与Markus Ressel相同的案例,但我使用的是getChildFragmentManager()。 我用getFragmentManager()替换了它,它解决了这个问题。

更新:我现在一直在使用childFragmentManager并得到一些反馈。

处理由片段托管的内部片段(因此片段中的片段)时,请使用childFragmentManager。 此片段管理器与活动getSupportFragmentManager不同。 两者不一样。 这是一个关注点的分离。

所以我制定了一个规则,托管子片段的片段将始终使用childFragmentManager,而不在宿主片段内的东西可以使用getSupportfragmentManager。

我的应用程序运行良好,直到将目标版本升级到27然后我在调用setTargetFragment(Fragment fragment,int requestCode)时遇到同样的问题

示例: chooseRegionFragment.setTargetFragment(ParentFragment.this, REQUEST_CODE_CHOOSE_REGION);

只需更改为: chooseRegionFragment.setTargetFragment(getRootParentFragment(this), REQUEST_CODE_CHOOSE_REGION);

getRootParentFragment(this)此方法将为您find片段的根父级

/** * find root parent of fragment */ public static Fragment getRootParentFragment(Fragment fragment) { Fragment parent = fragment.getParentFragment(); if(parent == null) return fragment; else return getRootParentFragment(parent); }