有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( transId
) popupbackstack :
//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
。