我遇到了使用目标SDK 4.3编译并运行的Android应用程序的问题。该应用程序有两个活动,一个MainActivity,也是Launcher活动和SecondActivity。两者都在使用Fragments。为了支持旧设备,还使用了支持库。
在下面的场景中,它出现了“IllegalStateException:Fragment already added”错误。
1)启动应用程序 - > MainActivity显示为
2)用Intent切换到SecondActivity
3)按主页按钮
4)等待更长时间(24小时测试)
5)再次按下应用程序图标 - >例外。如果时间较短,则SecondActivity会像预期的那样显示。
我在Fragment处理过程中读过很多IllegalStateExceptions,但是所有这些都指向了replace()方法的问题。在Stacktrace中,我自己的代码永远不会被调用。
Fragement添加在Activies onCreate()方法:
中protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(..);
ListFragment listFragment = this.getCaptureListFragment();
FragmentTransaction tx = this.getSupportFragmentManager().beginTransaction();
tx.add(R.id.MainFragmentContainer, listFragment, "list_fragment_tag");
tx.commit();
}
private ListFragment getListFragment() {
ListFragment listFragment = (ListFragment) this.getSupportFragmentManager().findFragmentByTag("list_fragment_tag");
if (listFragment == null) {
listFragment = new ListFragment();
}
return listFragment;
}
java.lang.RuntimeException: Unable to start activity ComponentInfo{de.myexample.demo/de.myexample.demo.ui.SecondActivity}: java.lang.IllegalStateException: Fragment already added: ListFragment{42283f58 #0 id=0x7f060094 de.myexample.demo.ui.ListFragment}
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2211)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
at android.app.ActivityThread.access$600(ActivityThread.java:141)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5103)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.IllegalStateException: Fragment already added: ListFragment{42283f58 #0 id=0x7f060094 de.myexample.demo.ui.ListFragment}
at android.support.v4.app.FragmentManagerImpl.addFragment(SourceFile:1175)
at android.support.v4.app.BackStackRecord.run(SourceFile:616)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(SourceFile:1460)
at android.support.v4.app.FragmentActivity.onStart(SourceFile:556)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1171)
at android.app.Activity.performStart(Activity.java:5143)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2184)
... 11 more
java.lang.IllegalStateException: Fragment already added: ListFragment{42283f58 #0 id=0x7f060094 de.myexample.demo.ui.ListFragment}
at android.support.v4.app.FragmentManagerImpl.addFragment(SourceFile:1175)
at android.support.v4.app.BackStackRecord.run(SourceFile:616)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(SourceFile:1460)
at android.support.v4.app.FragmentActivity.onStart(SourceFile:556)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1171)
at android.app.Activity.performStart(Activity.java:5143)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2184)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
at android.app.ActivityThread.access$600(ActivityThread.java:141)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5103)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
答案 0 :(得分:14)
好的,我自己解决了。
我将所有片段放在onPause()中并将状态存储在一些布尔值中。根据布尔值,片段放在onResume()中。无论活动在后台运行多长时间,启动都是稳定的。
boolean addList = false;
@Override
protected void onResume() {
FragmentTransaction tx = this.getSupportFragmentManager().beginTransaction();
if (this.addList) {
ListFragment list = this.getListFragment();
tx.add(R.id.MainFragmentContainer, list, "list_fragment_tag");
}
tx.commit();
super.onResume();
this.addList = false;
}
@Override
protected void onPause() {
this.addList = this.getListFragment().isAdded();
...
if (this.addList) {
FragmentTransaction tx = this.getSupportFragmentManager().beginTransaction();
tx.remove(this.getListFragment());
tx.commit();
}
this.getSupportFragmentManager().executePendingTransactions();
super.onPause();
}
也许这可以帮助有同样问题的人
答案 1 :(得分:9)
为了重现这一点,人们可以激活“不要保持活动”。在设置 - >开发者选项。然后暂停并恢复活动。
这样你就不必等待24小时了。)
答案 2 :(得分:0)
片段管理器在退出时保存其状态。因此,您不必再次添加片段。
这样做:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(..);
if (savedInstanceState == null) {
ListFragment listFragment = this.getCaptureListFragment();
FragmentTransaction tx = this.getSupportFragmentManager().beginTransaction();
tx.add(R.id.MainFragmentContainer, listFragment, "list_fragment_tag");
tx.commit();
}
}
答案 3 :(得分:-3)
没有必要创建新的布尔字段来检查片段的添加状态。片段中还有一种方法。
只需使用它:
myFragment.isAdded()
强>