出现异常:片段已激活
Posted
技术标签:
【中文标题】出现异常:片段已激活【英文标题】:Got exception: fragment already active 【发布时间】:2012-05-09 00:27:26 【问题描述】:我有一个片段;
MyFragment myFrag = new MyFragment();
我把捆绑数据放到这个片段中:
Bundle bundle = new Bundle();
bundle.putString("TEST", "test");
myFrag.setArguments(bundle);
然后,我用这个替换旧片段并放入backstack:
//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
)pop backstack:
//pop the transaction from backstack
fragmentManager.popBackStack(transId,FragmentManager.POP_BACK_STACK_INCLUSIVE);
稍后,我将 捆绑数据 再次设置为我的片段(myFrag
)的参数:
//Got Java.lang.IllegalStateException: fragment already active
myFrag.setArguments(bundle);
如您所见,我上面的代码出现异常 Java.lang.IllegalStateException: fragment already active
。 我不明白为什么 myFrag
仍然处于活动状态,尽管我已经从后台弹出了它的事务。,无论如何,因为我得到了异常,所以我认为我没有选择但停用片段,所以,我做到了:
Fragment activeFragment = fragMgr.findFragmentByTag("MyTag");
fragmentTransaction.remove(activeFragment);
我不确定我上面的代码是否真的可以停用片段,因为我没有找到如何停用片段。 :(
之后,当我再次尝试将捆绑数据设置到我的片段myFrag
时,我仍然遇到同样的错误:
Java.lang.IllegalStateException: fragment already active
似乎即使我删除了片段,它仍然处于活动状态......为什么?如何停用片段?
【问题讨论】:
你的片段是单例吗?如果有的话,给我看看你的 newInstance() 方法。 我希望这对某人有所帮助。 ***.com/a/15263921/541620 ***.com/a/15263921/541620 我希望这可以帮助别人。 我希望这对某人有所帮助。 [这里][1] [1]:***.com/a/15263921/541620 【参考方案1】:阅读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)。我猜你想要做的是创建一个 new Fragment 并再次设置参数。或者你可以使用getArguments(),然后使用bundle的put
方法来改变它的值。
【讨论】:
+1 表示“你可以使用 getArguments() 然后使用 bundle 的 put 方法来改变它的值。” 这是一个很好的例子,也有详细的解释。 emuneee.com/blog/2013/01/07/saving-fragment-statesgetArguments().putAll(bundle);
将覆盖整个包
getArguments().putAll(bundle);
不会覆盖整个捆绑包。调用此键后,我仍然拥有以前的键和值。就我而言,我使用了 getArguments().clear();
并清理了参数。
如果之前没有设置 setArguments(),则不能使用 getArguments().putAll(),因为 getArguments() 返回 null。【参考方案2】:
在添加新片段之前尝试删除之前的片段:https://***.com/a/6266144/969325
【讨论】:
我首先尝试了 "fragmentTransaction.remove(myFrag)" 然后 "replace(...)" ,它没有帮助。我有同样的例外 nono 以前的。所以堆栈上的任何东西都用 remove 删除,然后用 myfrag 替换。fragmentTransaction.remove(myFrag)
从其addedFragment
堆栈中删除片段,但将其实例保留在其activeFragment
堆栈中。【参考方案3】:
remove() 将片段状态更改为停用。在您的情况下,您只是没有在 remove(..) 之后调用 commit()。
fragmentTransaction.remove(activeFragment);
你也可以在 remove() 之后执行 commit()。
fragmentTransaction.remove(activeFragment).commit();
【讨论】:
【参考方案4】:有同样的问题。我正在将片段添加到后台堆栈。错误是因为我没有调用 popbackstack()。使用 popbackstack 帮助了我
【讨论】:
【参考方案5】:我在 Xamarin.android 上遇到了同样的问题。 the documentation 是这么说的。
这只能在片段附加到其活动之前调用
【讨论】:
【参考方案6】:只需从片段中调用公共方法
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();
【讨论】:
【参考方案7】:首先我会描述为什么会发生这种情况,然后我会想出我发现可行的解决方案......
当 Android 从堆栈中移除片段但尚未完成移除时,会发生此问题。为了检查这一点,您可以使用片段的isRemoving()
方法。如果false
,即片段未激活,您可以继续使用setArguments(bundle)
设置参数。否则,您无法为已经处于活动状态的片段设置参数,只能通过使用getArguments().putAll(bundle)
寻址相同的参数来覆盖它。
总结一下,
if (myFrag.isRemoving())
myFrag.getArguments().putAll(bundle);
else
myFrag.setArguments(bundle);
如果您想避免这种情况,即立即删除片段以便没有活动片段,您可能希望在onBackStackChangedListener()
中使用onBackPressed()
,这会将isRemoving()
设置为false
。
【讨论】:
【参考方案8】:例如检查您的布局是当前的还是旧的
setContentView(R.layout.activity_main);
删除项目文件中的旧 .gradle 文件并为项目重建 gradle 文件。
【讨论】:
以上是关于出现异常:片段已激活的主要内容,如果未能解决你的问题,请参考以下文章
活动到片段通信:当我尝试从活动更新片段中的文本视图时,出现空指针异常
以编程方式创建 MapView 并添加标记导致片段中出现空指针异常
mvn命令异常:An error has occurred in Javadoc report generation: Unable to find javadoc command异常已解决(代码片段
mvn命令异常:An error has occurred in Javadoc report generation: Unable to find javadoc command异常已解决(代码片段