2011-07-25 124 views
1

在我的应用程序中,我有一个Activity,它由一个叠加的侧面板(导航菜单)和一个LinearLayout组成,这是我的主布局。我在我的布局上进行交易并更换里面的碎片。我只允许用户向前导航,所以我根本不使用后台堆栈。相反,当用户在菜单中向前导航时,我使用Hashmap(伪缓存)将片段实例保留在内存中。这种方法唯一的问题是,当我尝试用缓存中的片段替换当前在主布局中的片段时(我通过调试器运行并且它说FragmentTransaction.replace()方法检查后台(??))。我不太确定问题在哪。Android:片段和背堆栈

07-25 22:03:47.690: ERROR/AndroidRuntime(3141): FATAL EXCEPTION: main 
07-25 22:03:47.690: ERROR/AndroidRuntime(3141): java.lang.IllegalStateException: Fragment already added: GuideFragment{409f2fd8 id=0x7f06008c} 
07-25 22:03:47.690: ERROR/AndroidRuntime(3141):  at android.app.BackStackRecord.doAddOp(BackStackRecord.java:322) 
07-25 22:03:47.690: ERROR/AndroidRuntime(3141):  at android.app.BackStackRecord.replace(BackStackRecord.java:360) 
07-25 22:03:47.690: ERROR/AndroidRuntime(3141):  at android.app.BackStackRecord.replace(BackStackRecord.java:352) 
07-25 22:03:47.690: ERROR/AndroidRuntime(3141):  at StartActivity.changeContent(StartActivity.java:194) 
07-25 22:03:47.690: ERROR/AndroidRuntime(3141):  at StartActivity$5.onClick(StartActivity.java:165) 
07-25 22:03:47.690: ERROR/AndroidRuntime(3141):  at android.view.View.performClick(View.java:3117) 
07-25 22:03:47.690: ERROR/AndroidRuntime(3141):  at android.view.View$PerformClick.run(View.java:11935) 
07-25 22:03:47.690: ERROR/AndroidRuntime(3141):  at android.os.Handler.handleCallback(Handler.java:587) 
07-25 22:03:47.690: ERROR/AndroidRuntime(3141):  at android.os.Handler.dispatchMessage(Handler.java:92) 
07-25 22:03:47.690: ERROR/AndroidRuntime(3141):  at android.os.Looper.loop(Looper.java:132) 
07-25 22:03:47.690: ERROR/AndroidRuntime(3141):  at android.app.ActivityThread.main(ActivityThread.java:4025) 
07-25 22:03:47.690: ERROR/AndroidRuntime(3141):  at java.lang.reflect.Method.invokeNative(Native Method) 
07-25 22:03:47.690: ERROR/AndroidRuntime(3141):  at java.lang.reflect.Method.invoke(Method.java:491) 
07-25 22:03:47.690: ERROR/AndroidRuntime(3141):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841) 
07-25 22:03:47.690: ERROR/AndroidRuntime(3141):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599) 
07-25 22:03:47.690: ERROR/AndroidRuntime(3141):  at dalvik.system.NativeStart.main(Native Method) 
+0

后从更新的logcat – antlersoft

+0

堆栈跟踪。我想我的问题是,是否有可能将碎片保存在HashMap而不是Backstack中?根据文档,如果碎片没有被添加到Backstack中,它将被破坏。然而,当我将它添加到HashMap并稍后检索它时,它不是null。另外,为什么LogCat告诉我,碎片已经被添加了,因为它从来没有放在Backstack上? –

+0

您是在模拟器上还是在物理设备上测试?我在我的应用程序中以类似的方式处理碎片,并且它在物理设备上运行良好,但在模拟器上出现同样的错误。 – theisenp

回答

1

我一直有类似的问题。正如我在评论中提到的,我的应用在物理设备上运行良好,但在模拟器上崩溃。我不是很积极,为什么它会抛出这个Fragment already added错误,但我找到了一个解决方法。

在尝试替换一个片段之前,我首先使用try-catch块删除它(这似乎违反直觉,但似乎适用于我)。

FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); 
fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); 
try 
{ 
    fragmentTransaction.remove(guideFragment); 
} 
catch(IllegalStateException e) 
{ 
    e.printStackTrace(); 
} 
fragmentTransaction.replace(R.id.container, guideFragment, GUIDE_FRAGMENT_TAG); 
fragmentTransaction.commit(); 

看来,replace()方法有一些奇怪的行为,并不总是像你期望的那样工作。 Others也必须使用解决方法。

0

检查在替换之前是否添加了碎片。

1

看来你的片段无法在视图中替换。膨胀时,你可能会缺少LayoutInflater.inflate()的第三个参数。

检查,应该像

 @Override 
     public View onCreateView(LayoutInflater inflater, ViewGroup container, 
       Bundle savedInstanceState) { 
      View view = inflater.inflate(R.layout.session_frag, container, false); 
      return view; 
     }