此适配器/视图可用作 FragmentStatePagerAdapter 的替代品。
如果您寻求的是在从 Backstack 重新进入时保留 Fragments,而使用此适配器很难实现。
为了防止这种情况,团队设置了许多休息时间,只有上帝知道为什么......
他们本可以使用自分离 lifeCycle 观察者,该功能已在其代码中预见到,但在 android 架构中没有任何地方使用该功能....
他们应该使用这个未完成的组件来监听全局 Fragments 生命周期而不是它的 viewLifeCycle,从这里开始,可以将监听从 Fragment 扩展到 viewLifeCycle。 (附加/分离 viewLifeCycle 观察者 ON_START/ON_STOP)
其次...即使这样做了,viewPager 本身是建立在 recyclerView 之上的事实使得处理您对 Fragment 行为的期望变得非常困难,这是一种保存状态,一个时间实例化和明确定义的生命周期(可控/预期破坏)。
这个适配器在功能上是矛盾的,它检查 viewPager 是否已经被提供了 Fragment,同时在重入时仍然需要一个“新”的适配器。
它在退出到 backStack 时保留 Fragments,同时期望在重新进入时重新创建所有片段。
假设 所有 其他变量已经考虑到正确的 viewLifeCycle 处理(注册/注销和设置和重置参数),防止字段实例化适配器的地方是:
@Override
public final void restoreState(@NonNull Parcelable savedState) {
if (!mSavedStates.isEmpty() || !mFragments.isEmpty()) {
throw new IllegalStateException(
"Expected the adapter to be 'fresh' while restoring state.");
}
.....
}
第二次休息:
@CallSuper
@Override
public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
checkArgument(mFragmentMaxLifecycleEnforcer == null);
mFragmentMaxLifecycleEnforcer = new FragmentMaxLifecycleEnforcer();
mFragmentMaxLifecycleEnforcer.register(recyclerView);
}
mFragmentMaxLifecycleEnforcer 在重入时必须为 == null,否则会在 checkArgument() 中引发异常。
第三:
Fragment 垃圾收集器在重入时放置(到视图,从后台堆栈),它在 10 秒后延迟,试图销毁屏幕外的 Fragment,导致内存泄漏所有屏幕外页面,因为它会杀死控制其生命周期的各自 FragmentManager。
private void scheduleGracePeriodEnd() {
final Handler handler = new Handler(Looper.getMainLooper());
final Runnable runnable = new Runnable() {
@Override
public void run() {
mIsInGracePeriod = false;
gcFragments(); // good opportunity to GC
}
};
mLifecycle.addObserver(new LifecycleEventObserver() {
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
if (event == Lifecycle.Event.ON_DESTROY) {
handler.removeCallbacks(runnable);
source.getLifecycle().removeObserver(this);
}
}
});
handler.postDelayed(runnable, GRACE_WINDOW_TIME_MS);
}
所有这些都是因为它的罪魁祸首:构造函数:
public FragmentStateAdapter(@NonNull FragmentManager fragmentManager,
@NonNull Lifecycle lifecycle) {
mFragmentManager = fragmentManager;
mLifecycle = lifecycle;
super.setHasStableIds(true);
}