本文基于implementation "androidx.fragment:fragment-ktx:1.3.1"源码,分析了为什么fragment以show/hide方式,在Activity内存不足重新打开时会出现重叠问题的原因,及解决思路。
首先查看Activity的super.onSaveInstanceState(outState)方法
最后会在Activity中的onSaveInstanceState方法中看到
Parcelable p = mFragments.saveAllState();
if (p != null) {
outState.putParcelable(FRAGMENTS_TAG, p);
}
如上代码,看看mFragments是什么
final FragmentController mFragments = FragmentController.createController(new HostCallbacks());
发现mFragments是FragmentController对象的引用,查看FragmentController是如何创建的
private final FragmentHostCallback<?> mHost;
/**
* Returns a {@link FragmentController}.
*/
public static final FragmentController createController(FragmentHostCallback<?> callbacks) {
return new FragmentController(callbacks);
}
private FragmentController(FragmentHostCallback<?> callbacks) {
mHost = callbacks;
}
发现其通过静态createController方法,直接创建了FragmentController对象并返回,并将
FragmentHostCallback对象赋值给mHost在FragmentController保存了起来。
而HostCallback通过new的方式直接创建,查看HostCallback类发现
class HostCallbacks extends FragmentHostCallback<Activity> {
public HostCallbacks() {
super(Activity.this /*activity*/);
}
}
HostCallback类继承了FragmentHostCallback类,并在构造方法中传入了Activity实例,此时
FragmentHostCallback持有了Activity对象的引用
继续查看saveAllStete方法
/**
* Saves the state for all Fragments.
*/
public Parcelable saveAllState() {
return mHost.mFragmentManager.saveAllState();
}
其调用了mHost.mFragmentManager,FragmentManager的saveAllState方法
查看FragmentHostCallback类可知
final FragmentManager mFragmentManager = new FragmentManagerImpl();
mFragmentManager对象是直接new出来的。现在查看FragmentManagerImpl类
class FragmentManagerImpl extends FragmentManager {
}
发现只是继承了FragmentManager
找到FragmentManager的saveAllSate方法
Parcelable saveAllState() {
// Make sure all pending operations have now been executed to get
// our state update-to-date.
forcePostponedTransactions();
endAnimatingAwayFragments();
execPendingActions(true);
mStateSaved = true;
mNonConfig.setIsStateSaved(true);
// First collect all active fragments.首先收集全部活动的fragments
ArrayList<FragmentState> active = mFragmentStore.saveActiveFragments();
if (active.isEmpty()) {
if (isLoggingEnabled(Log.VERBOSE)) Log.v(TAG, "saveAllState: no fragments!");
return null

本文深入剖析了在Android中使用Fragment时,由于Activity内存不足导致的Fragment重叠问题。通过跟踪源码,揭示了问题产生的根本原因,并提出了解决方案。
最低0.47元/天 解锁文章
6182

被折叠的 条评论
为什么被折叠?



