以下是我了解片段处理过程中的一段测试代码。第一个输出是记录片段列表。有2:GameMenuFragment和Game1Fragment0。然后,将记录后退堆栈。它包含Game1Fragment0。然后弹出后堆栈。因此,然后向后堆栈日志显示它什么也没有。布宜诺斯艾利斯。但是现在,再次循环遍历片段列表,而size()仍返回2,但由于(显然)Game1Fragment0不存在,它在NPE上崩溃了。
因此,很明显,弹出后退堆栈已从片段列表中删除了该片段,但大小仍为2。有人可以解释吗?
输出:
Game1Fragment(1617):fragmentList大小:2
Game1Fragment(1617):fragmentList:2131492865:GameMenuFragment
Game1Fragment(1617):fragmentList:2131492865:Game1Fragment0
Game1Fragment(1617):getBackStackEntryCount:1(从0开始)
Game1Fragment(1617):BackStackEntry :Game1Fragment0
Game1Fragment(1617):getBackStackEntryCount2:0(基于0)
Game1Fragment(1617):fragmentList2大小:2
Game1Fragment(1617):fragmentList2:2131492865:GameMenuFragment
AndroidRuntime(1617):FATAL EXCEPTION:main
AndroidRuntime(1617):java。 lang.NullPointerException
FragmentManager fragmentManager = fragmentActivity.getSupportFragmentManager();
List<Fragment> fragmentList = fragmentManager.getFragments();
Log.w("Game1Fragment", "fragmentList size: " + fragmentList.size());
for (Fragment fragment : fragmentList) {
Log.w("Game1Fragment", "fragmentList: " + fragment.getId() + " : "+ fragment.getTag());
}
Log.w("Game1Fragment", "getBackStackEntryCount: " + fragmentManager.getBackStackEntryCount() + " (0-based)");
for(int entry = 0; entry < fragmentManager.getBackStackEntryCount(); entry++){
Log.w("Game1Fragment", "BackStackEntry: " + fragmentManager.getBackStackEntryAt(entry).getName());
}
fragmentManager.popBackStackImmediate(); // pop Game1Fragment0
Log.w("Game1Fragment", "getBackStackEntryCount2: " + fragmentManager.getBackStackEntryCount() + " (0-based)");
for(int entry = 0; entry < fragmentManager.getBackStackEntryCount(); entry++){
Log.w("Game1Fragment", "BackStackEntry: " + fragmentManager.getBackStackEntryAt(entry).getName());
}
List<Fragment> fragmentList2 = fragmentManager.getFragments();
Log.w("Game1Fragment", "fragmentList2 size: " + fragmentList2.size());
for (Fragment fragment : fragmentList2) {
Log.w("Game1Fragment", "fragmentList2: " + fragment.getId() + " : "+ fragment.getTag()); // throws NPE on 2nd time through loop
}
当Fragment
被创建,参考被保持它的活性在Fragment
阵列的类型的ArrayList<Fragment>
。将索引分配给Fragment
实例,该索引是保留引用的数组元素的索引。
现在,Fragment
销毁销毁后,应该从中删除引用ArrayList<Fragment>
。如果Fragment
从中删除引用的ArrayList
元素,则其中的其他元素ArrayList
可能会重新定位(例如,如果删除第0个元素,则第1个元素现在将变为第0个元素)。这将使Fragments
实例内维护的索引无效。因此,不会从中破坏元素ArrayList
,而是将null分配给该索引。
这是处理它的代码。看线mActive.set(f.mIndex, null);
void makeInactive(Fragment f) {
if (f.mIndex < 0) {
return;
}
if (DEBUG) Log.v(TAG, "Freeing fragment index " + f);
mActive.set(f.mIndex, null);
if (mAvailIndices == null) {
mAvailIndices = new ArrayList<Integer>();
}
mAvailIndices.add(f.mIndex);
mActivity.invalidateFragment(f.mWho);
f.initState();
}
为了跟踪已发布的索引,ArrayList<Integer> mAvailIndices
将对其进行维护,以便Fragments
在将来将索引分配给新创建的索引时使用。
这是getFraments
返回的方法代码mActive
:
@Override
public List<Fragment> getFragments() {
return mActive;
}
第二次调用时fragmentManager.getFragments()
,列表包含该已发布索引的null。因此,Fragment
在使用实例之前,我们应该始终对实例进行null检查。
从后堆栈弹出会撤消事务。如果将其添加到事务中,则将其删除并进一步销毁。这是我编写的示例应用程序的调用堆栈:
MainActivity$Fragment2.onDestroy() line: 53
MainActivity$Fragment2(Fragment).performDestroy() line: 1912
FragmentManagerImpl.moveToState(Fragment, int, int, int, boolean) line: 1008
FragmentManagerImpl.removeFragment(Fragment, int, int) line: 1162
BackStackRecord.popFromBackStack(boolean) line: 714
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句