Al *_*ath 2 android android-fragments
下面是我要了解片段处理的一段测试代码.第一个输出是记录片段列表.有2个:GameMenuFragment和Game1Fragment0.然后记录后栈.它包含Game1Fragment0.然后弹出后栈.那么后面的堆栈日志显示它什么都没有.布埃诺.但现在,再次循环遍历片段列表,而size()仍然返回为2,它在NPE上崩溃,因为(显然)Game1Fragment0不在那里.
所以,显然,弹出后面的堆栈已经从片段列表中删除了该片段,但是大小仍然是2.有人能解释一下吗?
输出:
Game1Fragment(1617):fragmentList size:2
Game1Fragment(1617):fragmentList:2131492865:GameMenuFragment
Game1Fragment(1617):fragmentList:2131492865:Game1Fragment0
Game1Fragment(1617):getBackStackEntryCount:1(0-based)
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
}
Run Code Online (Sandbox Code Playgroud)
当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();
}
Run Code Online (Sandbox Code Playgroud)
保持跟踪已发布的索引,ArrayList<Integer> mAvailIndices
将在将索引分配给Fragments
将来新创建时使用.
这是getFraments
返回的方法代码mActive
:
@Override
public List<Fragment> getFragments() {
return mActive;
}
Run Code Online (Sandbox Code Playgroud)
第二次调用时fragmentManager.getFragments()
,列表包含该已发布索引的null.因此,Fragment
在使用它之前,我们应该始终对实例进行空检查.
从后台堆栈弹出将反转该事务.如果它已在事务中添加,那么它将被删除并进一步销毁.这是我编写的示例应用程序的调用堆栈:
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
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1825 次 |
最近记录: |