我想了解Android中活动生命周期和片段生命周期之间的交互,因此我决定启动一个新项目并从this page复制代码。
然后我认为为了提高我的理解力,在平板电脑上测试它,切换它的方向并看看它发生了什么是有用的(虽然它可能不适合这个)。
通过logcat,我跟踪了活动和国家片段上发生的主要事件,例如我写的Activity Oncreate:
Log.d("TAG", "Activity: 1.onCreate");
这是我从纵向视图开始然后旋转时得到的结果:
TAG:活动:1.onCreate
标签:活动:2.onStart
标签:## ContryFrag:1.onAttach
标签:## ContryFrag:2.onCreateView
标签:## ContryFrag:3.onStart
标签:活动:3.onResume
标签:## ContryFrag:4.onResume
标签:活动:-3。因为
标签:## ContryFrag:-4.onPause
标签:活动:-2.onStop
标签:## ContryFrag:-3.onStop
标签:活动:-1.onDestroy
标签:## ContryFrag:-2.onDestroyView
标签:## ContryFrag:-1.onDetach
标签:活动:1.onCreate
标签:## ContryFrag:1.onAttach
标签:## ContryFrag:1.onAttach
标签:## ContryFrag:2.onCreateView
标签:活动:2.onStart
标签:## ContryFrag:2.onCreateView
标签:## ContryFrag:3.onStart
标签:## ContryFrag:3.onStart
标签:活动:3.onResume
标签:## ContryFrag:4.onResume
标签:## ContryFrag:4.onResume
似乎在纵向视图中通过FragmentManager添加的片段仍然在旋转后重新创建,尽管它之前已被分离。即使不显示,也会再次跟踪恢复它的事件链 你能帮我理解这里发生的事吗?
修改
当我检查片段是否为InLayout()
时Log.d("TAG", "## ContryFrag: 1.onAttach /" + isInLayout() );
我意识到旋转后有两个片段:一个用旋转创建,另一个似乎是前一个活动的剩余部分(不应该是)。
TAG:活动:1.onCreate
标签:## ContryFrag:1.onAttach / false
标签:## ContryFrag:1.onAttach / true
标签:## ContryFrag:2.onCreateView / true
标签:活动:2.onStart
标签:## ContryFrag:2.onCreateView / false
标签:## ContryFrag:3.onStart / false
标签:## ContryFrag:3.onStart / true
标签:活动:3.onResume
标签:## ContryFrag:4.onResume / false
标签:## 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);
}
编辑3
这是my code。抱歉延迟,这是我第一次使用github。
答案 0 :(得分:4)
向Fragment
添加FragmentManager
后,它会一直保留在那里,直到您手动删除它或直到Activity
永久结束。 (重新启动Activity
,例如设备旋转时发生的情况不会导致它完成)
旋转设备不会清除碎片。如果您创建新的Fragment
并在FragmentManager
生命周期中随时将其添加到Activity
,而无需先检查Fragment
中是否已存在FragmentManager
,每次执行导致Fragment
重新启动的任何操作时,您只需添加一个新的Activity
。
例如,此代码应仅允许添加一个片段副本。
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.");
}
虽然每次旋转设备时都会添加一个新的。
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.");
}
链接处的代码似乎使用savedInstanceState
的存在来确定是否添加片段或是否从方法返回。这不可靠,因为您可能无法保存状态中的任何内容,因此它可能始终为null。最好特别检查一下你是否已经添加了片段。
即
if (savedInstanceState != null)
return;
答案 1 :(得分:0)
看起来您不使用片段的上一个实例。 当由于配置更改而重新启动Activity时,Android会保留Fragment布局和关联的后台堆栈。 看起来当重新创建Activity时会创建一个新片段。 尝试将以下代码添加到Activity的onCreate:
@Override
public void onCreate(Bundle savedInstanceState) {
...
ContryFrag fragment = (ContryFrag) mFragmentManager.findFragmentById(R.id.fragment_container);
if (fragment == null) {
FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
fragmentTransaction.add(R.id.fragment_container, new ContryFrag());
fragmentTransaction.commit();
}
}
删除片段创建代码。
答案 2 :(得分:0)
链接文章包含在布局xml中定义的片段。您在github中的代码是按代码创建和添加片段。你在一起使用这两个吗?