我不知道这种行为是否正常,因为我认为调用finish()会阻止重新创建活动。
以下是活动类的摘录:
public class MyActivity extends FragmentActivity {
private RetainFragment retainFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
......
retainFragment = getSupportFragmentManager().findFragmentByTag("RetainFragment");
if(retainFragment == null) {
retainFragment = new RetainFragment();
getSupportFragmentManager().beginTransaction().add(retainFragment, "RetainFragment").commitAllowingStateLoss();
}
if(retainFragment.isFinish) {
Log.v("MyActivity", "isFinish == true");
this.finish();
}
}
// a on-click event handler for a finish button
public void onFinishClicked(View view) {
retainFragment.isFinish = true;
this.finish();
}
private class RetainFragment extends Fragment {
private boolean isFinish = false;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setRetainInstance(true);
}
}
}
活动是持久的(我也将其他持久变量存储在RetainFragment中,但我没有显示它们)并且仅在用户单击完成按钮后关闭,此时将调用onFinishClicked(View),并且活动应该由系统完成。在重合屏幕旋转后,我预计系统不会重新创建它。这很少发生,我通过在onCreate()方法中再次调用finish()来处理它。但是,它看起来很丑陋,因为完成的活动应该永远消失,现在我必须明确处理它。 :( 我是否对活动生命周期或保留片段有任何误解?
答案 0 :(得分:2)
如果你在Android上工作,每当你听到自己说“此活动将仅在X
之后关闭”。别。您永远不应该依赖具有高度受控生命周期的Activity。你的Activity应该以这样的方式设计,无论它何时被销毁和重新创建,它都能正常工作。
要保留旋转等信息,请将代码添加到onSaveInstanceBundle
,然后在onCreate
上检查并提取已保存的值。
答案 1 :(得分:0)
这是标准的Android行为。看一下Android documentation的这一段。
除非您另行指定,否则配置更改(例如屏幕方向,语言,输入设备等的更改)将导致您的当前活动被破坏,通过onPause(),onStop的正常活动生命周期过程( )和onDestroy()视情况而定。如果活动位于前台或对用户可见,则在该实例中调用onDestroy()后,将创建活动的新实例,其中包含先前实例生成的任何savedInstanceState的onSaveInstanceState(束)。
为避免这种情况,您可以在其清单中设置android:configChanges属性。对于任何类型的配置更改,您说您在那里处理,您将收到对当前活动的onConfigurationChanged(配置)方法的调用,而不是重新启动。但是,如果配置更改涉及您未处理的任何内容,则仍将重新启动活动,并且不会调用onConfigurationChanged(Configuration)。
答案 2 :(得分:0)
我遇到了同样的问题。也就是说,我有一个活动A,它将使用startActivityForResult启动活动B. B的方向被清单锁定。 A的方向未锁定。
当我旋转设备以使方向不同时,将不会重新创建活动B.这是预期和正常的。但是,一旦我执行完成()活动B的UI动作,而不是看到活动A被重建并显示在屏幕上,我再次显示了活动B.此外,正在调用Activity的B onActivityResult,而不是A的onActivityResult。
我弄清楚发生了什么。我使用了用于启动A的相同Intent对象来启动B.在方向更改之后和B完成之后,Android系统检测到需要重建活动A,因为A是在方向不同时最后构建的。系统将使用最初用于构建A的相同Intent对象重建A.但是,Intent对象被修改为启动B,因此系统将重建活动B而不是活动A.
我的代码遵循类似于下面的逻辑:
public class A extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//...omitted code for clarity...
Intent i = getIntent();
i.setClass(this, B.class);
startActivityForResult(i, 0);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
//...omitted code for clarity...
}
}
我的活动B看起来像:
public class B extends Activity {
//...omitted code for clarity....
public void myFinishingClickHandler(View clickedView) {
//...omitted code for clarity...
finish();
}
}
方案的快速演练:
解决方案:不要分享用于启动活动的意图。使用Intent复制构造函数。
另外,锁定您的活动'方向更少担心方向变化(其他配置变化将导致您的活动被重建,例如更改语言)。