在Android中防止碎片恢复

yquaqz18  于 2022-12-25  发布在  Android
关注(0)|答案(9)|浏览(208)

我们正在使用Fragments,并且不需要在Activity重新创建时自动恢复这些Fragments。但Android每次调用Activity::onCreate(Bundle savedInstanceState)-〉super.onCreate(savedInstanceState)时都会恢复Fragments,即使我们对这些Fragments使用setRetainInstance(false)。
此外,在这些Fragments中,Fragment.performCreateView()是直接调用的,而没有经过Fragment::onAttach()等等。另外,在恢复的Fragment中,一些字段为空...
有人知道如何防止Android恢复碎片吗?
另外,我们知道,在重新创建配置更改活动的情况下,可以通过添加ndroid:configChanges="orientation|screenSize|screenLayout到清单来完成。但是,在自动内存清理的情况下,重新创建活动怎么办?

azpvetkf

azpvetkf1#

最后,我们向活动中添加了:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(null);
}

它抑制“活动”的创建/重新创建周期中任何已保存的数据,并避免自动重新创建片段。

ui7jx7zq

ui7jx7zq2#

@goRGon的回答对我来说非常有用,但是当有一些更多的信息需要在重新创建后转发到您的活动时,这样的使用会导致严重的问题。
这里是改进的版本,只删除“碎片”,但保留每一个其他参数。
从bundle中移除的ID是android.support.v4.app.FragmentActivity类的一部分,作为FRAGMENTS_TAG字段。当然,它可能会随时间而更改,但这不是预期的。

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(createBundleNoFragmentRestore(savedInstanceState));
}

/**
 * Improve bundle to prevent restoring of fragments.
 * @param bundle bundle container
 * @return improved bundle with removed "fragments parcelable"
 */
private static Bundle createBundleNoFragmentRestore(Bundle bundle) {
    if (bundle != null) {
        bundle.remove("android:support:fragments");
    }
    return bundle;
}
cl25kdpy

cl25kdpy3#

我在使用TransactionTooLargeException时遇到了一个问题。所以谢天谢地,在使用tolargetool后,我发现碎片(android:support:fragments)一直在内存中,事务变得太大了。所以最后我这样做了,效果很好。

@Override
public void onSaveInstanceState(final Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putSerializable("android:support:fragments", null);
}

编辑:我把它添加到活动中。在我的情况下,我有一个单一的活动应用程序和多个片段。

vwkv1x7d

vwkv1x7d4#

使用已接受答案中描述的方法时获得带ViewPager的NPE的用户,请覆盖
第一个月
方法和调用
super.onRestoreInstanceState(null);
而不是。

ubbxdtey

ubbxdtey5#

我删除了Activity的onCreate中的片段。

bjp0bcyl

bjp0bcyl6#

对于使用ViewPager的应用程序,我在创建onCreate()中的片段之前删除了它们。
基于此线索:Remove all fragments from container,我们有:

FragmentManager fm = getSupportFragmentManager();
for (Fragment fragment: fm.getFragments()) {
  fm.beginTransaction().remove(fragment).commitNow();
}
wsxa1bj1

wsxa1bj17#

使用这个为androidx

override fun onCreate(savedInstanceState: Bundle?) {
   preventFragmentRecreation()
   super.onCreate(savedInstanceState) 
}

private fun preventFragmentRecreation() {
   supportFragmentManager.addFragmentOnAttachListener { _, _ ->
            savedStateRegistry.unregisterSavedStateProvider("android:support:fragments")
        }
}
yv5phkfx

yv5phkfx8#

这对我很有效

@Override
public void onSaveInstanceState(final Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.remove("androidx.lifecycle.BundlableSavedStateRegistry.key");
}
eanckbw9

eanckbw99#

视图层次结构不会自动恢复。因此,在Fragment.onCreateView()Activity.onCreate()中,必须恢复所有视图(从xml或以编程方式)。每个包含片段的ViewGroup都必须具有与第一次创建时相同的ID。创建视图层次结构后,Android会恢复所有片段并将其视图放入正确的ViewGroup中,这要归功于ID。假设Android记住了片段所在的ViewGroup的ID。这发生在onCreateView()onStart()之间的某个地方。

相关问题