mar*_*mor 34 java android illegalstateexception android-fragments android-viewpager
我知道这听起来像是FragmentStatePagerAdapter IllegalStateException的副本:<MyFragment>当前不在FragmentManager中, 但他的解决方案与我的情况无关.
我很少遇到以下崩溃:
java.lang.RuntimeException:无法暂停活动{MyActivity}:
...
引起:java.lang.IllegalStateException:片段MyFragment {40648258 id = 0x7f070051}当前不在android.support.v4.app.FragmentStatePagerAdapter的android.support.v4.app.FragmentManagerImpl.putFragment(MT:516)的FragmentManager中.saveState(MT:185)在android.support.v4.view.ViewPager.onSaveInstanceState(MT:881)
...
在Android.app.Activity.onSaveInstanceState(Activity.java:1138)的com.android.internal.policy.impl.PhoneWindow.saveHierarchyState(PhoneWindow.java:1522)的android.view.View.saveHierarchyState(View.java:6238) )在MyActivity.onSaveInstanceState(MT:336)的android.support.v4.app.FragmentActivity.onSaveInstanceState(MT:480)处
看起来这是我无法理解的奇怪代码FragmentStatePagerAdapter:
for (int i=0; i<mFragments.size(); i++) {
Fragment f = mFragments.get(i);
if (f != null) {
if (state == null) {
state = new Bundle();
}
String key = "f" + i;
mFragmentManager.putFragment(state, key, f);
}
}
Run Code Online (Sandbox Code Playgroud)
它看起来像适配器获取我Fragment的mFragments但不能添加其状态FragmentManager.
我找不到任何方法在我的测试设备上重新创建它,只是从一些用户那里收到了这个.
我正在使用支持包v4.
有帮助吗?谢谢.
Gre*_*nis 16
这FragmentStatePagerAdapter是一段可怕的代码,充斥着谷歌承认与否的错误,因此我使用此代码来修复此特定崩溃:
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
// Yet another bug in FragmentStatePagerAdapter that destroyItem is called on fragment that hasnt been added. Need to catch
try {
super.destroyItem(container, position, object);
} catch (IllegalStateException ex) {
ex.printStackTrace();
}
}
Run Code Online (Sandbox Code Playgroud)
piu*_*lte 10
当在ViewPager上设置FragmentStatePagerAdapter时会发生这种情况,其中Fragments正在填充,但由于在ViewPager发生布局之前Activity暂停,因此尚未添加到FragmentManager.通过从onCreate启动另一个Activity可以实现这一点,同时适配器也设置在onCreate中.在这种情况下,最好不要设置适配器,而是将其设置为onActivityResult.请参阅此问题:https://code.google.com/p/android/issues/detail?id = 77285
我还提交了一个补丁来检查在尝试保存状态之前是否添加了Fragment.
小智 7
我遇到了确切的异常.
在我的例子中,我有几个片段由FragmentPagerStateAdapter管理,但有时片段将被切换到位.
我重写getItemPosition()并返回新位置并调用notifyDataSetChanged()来刷新ViewPager.一切正常,但有时当我离开ViewPager时会发生崩溃.
经过几个小时的挖掘,我发现FragmentPagerStateAdapter中存在一个错误.
适配器不仅缓存状态,还缓存它认为"活动"的片段
private ArrayList<Fragment.SavedState> mSavedState = new ArrayList<Fragment.SavedState>();
private ArrayList<Fragment> mFragments = new ArrayList<Fragment>();
Run Code Online (Sandbox Code Playgroud)
但它不会检查碎片的位置是否已失效或移动.
这就是它如何得到这个例外:
1.我在ViewPager和Adapter中有A,B,C三个片段.
2.我将位置切换到适配器中的B,A,C并调用notifyDataSetChanged().
3.ViewPager按新顺序重新布局片段.但是mFragments缓存仍然是{A,B,C}
4.Swipe几页,ViewPager将要求适配器销毁第一个片段.然后在缓存中将片段B而不是A设置为null.现在mFragments是{null,A,C}.
5.离开ViewPager,并触发onSaveInstanceState.mFragments中的所有片段都被认为是活动的,并且调用putFragment()直到FragmentManagerImpl发现A不在其中并抛出异常.
所以这是我不太温和的解决方案:
1.复制整个FragmentPagerStateAdapter源代码.
2.Override notifyDataSetChanged()方法重新排列缓存,如下所示.
@Override
public void notifyDataSetChanged() {
List<Fragment> oldFragments = new ArrayList<>(mFragments);
List<Fragment.SavedState> oldStates = new ArrayList<>(mSavedState);
for (int i = 0; i < getCount(); i++) {
if (i < mFragments.size()) {
Fragment f = mFragments.get(i);
if (f != null) {
int newPosition = getItemPosition(f);
if (newPosition == POSITION_UNCHANGED || newPosition == i) {
} else if (newPosition == POSITION_NONE) {
if (i < mSavedState.size()) {
mSavedState.set(i, null);
}
mFragments.set(i, null);
} else {
while (i >= mFragments.size()) {
mFragments.add(null);
}
if (oldStates.size() > i) {
mSavedState.set(newPosition, oldStates.get(i));
}
mFragments.set(newPosition, oldFragments.get(i));
}
} else {
/*
* No Fragment but that's possible there's savedState and position has
* changed.
*/
}
}
}
super.notifyDataSetChanged();
}
Run Code Online (Sandbox Code Playgroud)
希望对你们有些人有用!
| 归档时间: |
|
| 查看次数: |
21683 次 |
| 最近记录: |