有exception:片段已经激活

我有一个片段 ;

MyFragment myFrag = new MyFragment(); 

我把bundle数据放到这个片段中:

 Bundle bundle = new Bundle(); bundle.putString("TEST", "test"); myFrag.setArguments(bundle); 

然后,我用这个replace旧的碎片,并放在后台

 //replace old fragment fragmentTransaction.replace(R.id.fragment_placeholder, myFrag, "MyTag"); //put on backstack fragmentTransaction.addToBackStack(null); //commit & get transaction ID int transId = fragmentTransaction.commit(); 

后来,我用上面的事务ID( transIdpopupbackstack

 //pop the transaction from backstack fragmentManager.popBackStack(transId,FragmentManager.POP_BACK_STACK_INCLUSIVE); 

后来,我再次将bundle数据设置为我的片段( myFrag )的参数:

 //Got Java.lang.IllegalStateException: fragment already active myFrag.setArguments(bundle); 

正如你所看到的,我的上面的代码有exceptionJava.lang.IllegalStateException: fragment already active我不明白为什么 myFrag 仍然是活跃的,虽然我已经从后台popup了它的交易。 无论如何,因为我得到的例外,我以为我别无select,只是去除了片段,所以,我做了:

 Fragment activeFragment = fragMgr.findFragmentByTag("MyTag"); fragmentTransaction.remove(activeFragment); 

我不知道是否我的上面的代码真的可以去掉这个片段,因为我没有find如何去掉一个片段。 🙁

之后,当我尝试再次将捆绑数据设置到我的片段myFrag时,我仍然得到相同的错误:

 Java.lang.IllegalStateException: fragment already active 

似乎即使我删除的片段,它仍然活跃… 为什么? 如何去激活一个片段?

阅读setArguments(Bundle args)源将帮助你理解:

 /** * Supply the construction arguments for this fragment. This can only * be called before the fragment has been attached to its activity; that * is, you should call it immediately after constructing the fragment. The * arguments supplied here will be retained across fragment destroy and * creation. */ public void setArguments(Bundle args) { if (mIndex >= 0) { throw new IllegalStateException("Fragment already active"); } mArguments = args; } 

你不能在同一个Fragment的代码中再次使用setArguments(Bundle args) 。 你想做什么,我猜是要创build一个新的 片段,并再次设置参数。 或者,您可以使用getArguments() ,然后使用该包的put方法来更改其值。

尝试删除以前的片段,然后添加新的: https : //stackoverflow.com/a/6266144/969325

删除()改变片段状态去激活。 在你的情况下,你只是在删除(..)后没有调用commit()。

 fragmentTransaction.remove(activeFragment); 

你也可以在remove()之后执行commit()。

 fragmentTransaction.remove(activeFragment).commit(); 

有同样的问题。 我正在将这个片段添加到后台。 而这个错误是因为我没有调用popbackstack()。 使用popbackstack帮助了我

我在Xamarin.android上遇到同样的问题。 这里是文件说的。

这只能在片段附加到其活动之前调用

只需从片段调用公共方法

 if(userFragment==null){ userFragment = new UserFragment(); Bundle bundle = new Bundle(); bundle.putString(Constants.EXTRA_CUSTOMER, result); userFragment.setArguments(bundle); }else{ try { Customer customer = new Customer(); customer.parseCustomer(new JSONObject(result)); userFragment.updateVeiw(customer); } catch (JSONException e) { e.printStackTrace(); } } 

首先,我从描述为什么发生这种情况开始,然后我会想出解决scheme,我发现工作…。

当Android从堆栈中删除片段但是还没有完成删除时,会发生这个问题。 为了检查这个,你可以使用片段的isRemoving()方法。 如果为false ,即片段不活动,则可以继续使用setArguments(bundle)设置参数。 否则,不能将参数设置为已经激活的片段,只能通过使用getArguments().putAll(bundle)寻址相同的参数来覆盖它。

总而言之,

  if (myFrag.isRemoving()) { myFrag.getArguments().putAll(bundle); } else { myFrag.setArguments(bundle); } 

如果你想避免这种情况,即一次删除片段,所以没有活动片段,你可能想使用onBackPressed()中的onBackStackChangedListener() ,这将设置isRemoving()false