隐藏片段的生命周期

Giu*_*ini 4 android android-lifecycle android-fragments

我想了解 Android 中 Activity 生命周期和片段生命周期之间的交互,所以我决定开始一个新项目并从这个页面复制代码。
然后我想,为了提高我的理解力,在平板电脑上测试它,切换它的方向并看看它会发生什么(尽管它可能不是为此而设计的)会很有用。通过 logcat,我跟踪了在活动和国家/地区片段上触发的主要事件,例如在 Activity Oncreate 中我写道:

Log.d("TAG", "Activity: 1.onCreate");
Run Code Online (Sandbox Code Playgroud)

这是我从纵向视图开始然后旋转时得到的结果:

标签:活动:1.onCreate
标签:活动:2.onStart
标签:## ContryFrag:1.onAttach
标签:## ContryFrag:2.onCreateView
标签:## ContryFrag:3.onStart
标签:活动:3.onResume
标签: ## ContryFrag: 4.onResume
TAG: Activity: -3.onPause
TAG: ## ContryFrag: -4.onPause
TAG: Activity: -2.onStop
TAG: ## ContryFrag: -3.onStop
TAG: Activity: -1。 onDestroy
TAG:## ContryFrag:-2.onDestroyView
TAG:## ContryFrag:-1.onDetach
TAG:Activity:1.onCreate
TAG:## ContryFrag:1.onAttach
TAG:## ContryFrag:1.onAttach
TAG:## ContryFrag:2.onCreateView
标签:活动:2.onStart
标签:## ContryFrag:2.onCreateView
标签:## ContryFrag:3.onStart
标签:## ContryFrag:3.onStart
标签:活动:3.onResume
标签:## ContryFrag:4.onResume
标签:## ContryFrag:4 .onResume

似乎通过纵向视图中的 FragmentManager 添加的片段在旋转后仍然重新创建,尽管它之前被分离了。恢复它的事件链会再次被跟踪,即使它不会被显示。
你能帮我理解这里发生了什么吗?

编辑

当我检查片段是否为 isInLayout()

Log.d("TAG", "## ContryFrag: 1.onAttach /" + isInLayout() );
Run Code Online (Sandbox Code Playgroud)

我意识到旋转后有两个片段:一个是通过旋转创建的,另一个似乎是前一个活动的剩余部分(不应该是)。

标签:活动:1.onCreate
标签:## ContryFrag:1.onAttach /false
标签:## ContryFrag:1.onAttach /true
标签:## ContryFrag:2.onCreateView /true
标签:活动:2.onStart
标签:# # ContryFrag: 2.onCreateView /false
TAG: ## ContryFrag: 3.onStart /false
TAG: ## ContryFrag: 3.onStart /true
TAG: Activity: 3.onResume
TAG: ## ContryFrag: 4.onResume /false
TAG: ## ContryFrag: 4.onResume /true

编辑 2

这是我用来获取 onSelectedCountry(String country) 的虚拟代码,未提供:

public void onSelectedCountry(String country)
{
    String[] x = {country, "city0", "city1", "city2", "city3", "city4", "city5"};
    adapter.clear();
    adapter.addAll(x);
}
Run Code Online (Sandbox Code Playgroud)

编辑 3

这是我的代码。抱歉耽搁了,这是我第一次使用github。

Kuf*_*ffs 5

将 a 添加Fragment到 后FragmentManager,它将一直保留在那里,直到您手动将其删除或直到Activity永久完成。(重新启动Activity诸如设备旋转时发生的情况不会使其完成)

旋转设备不会清除碎片。如果您在Lifecycle中的任何时间创建了一个新的Fragment并将其添加到FragmentManager中,Activity而没有先检查 中是否Fragment已经存在,则每次执行导致重新启动的任何操作时FragmentManager,您只需添加一个新的。FragmentActivity

例如,此代码应仅允许添加片段的一个副本。

protected void onResume() {

    String TAG = "COUNTRYFRAG";

    CountryFrag f = (CountryFrag) getSupportFragmentManager().findFragmentByTag(TAG);

    if (f == null) {
        f = new CountryFrag();
        getSupportFragmentManager().beginTransaction()
                .add(f, TAG)
                .commit();
    }

    int count = getSupportFragmentManager().getFragments().size();
    Log.v("FRAGS", "There are " + count + "fragments in the fragment manager.");

}
Run Code Online (Sandbox Code Playgroud)

而每次旋转设备时,这个都会添加一个新的。

protected void onResume() {

    String TAG = "COUNTRYFRAG";

        CountryFrag f = new CountryFrag();
        getSupportFragmentManager().beginTransaction()
                .add(f, TAG)
                .commit();

    int count = getSupportFragmentManager().getFragments().size();
    Log.v("FRAGS", "There are " + count + "fragments in the fragment manager.");

}
Run Code Online (Sandbox Code Playgroud)

链接处的代码似乎是使用的存在savedInstanceState来确定是否添加 Fragment 或是否从方法返回。这是不可靠的,因为您可能不会在状态中保存任何内容,因此它可能始终为空。最好专门检查您是否已经添加了 Fragment。

IE

if (savedInstanceState != null) 
            return;
Run Code Online (Sandbox Code Playgroud)