【问题标题】:Android - Turning on "Don't keep activities" in Android Developer options duplicates my FragmentActivityAndroid - 在 Android 开发人员选项中打开“不保留活动”会重复我的 FragmentActivity
【发布时间】:2025-12-25 13:30:16
【问题描述】:

我从我的应用程序的一些用户那里收到一个错误,当从我的 MainActivity 中单击 listItem 时,他们会将他们带到 DetailActivity(这是所需的结果),但如果他们按下返回或向上,他们会看到 MainActivity一切都重复了(listView,menuItems)。有人建议可能因为内存而导致活动被终止,所以我在手机上进入开发人员选项并打开“不保留活动”。这使我能够复制问题。现在我必须弄清楚为什么一切都重复了,但我有点不知道该往哪个方向走。这不像我在 onResume() 中创建菜单和布局。我在 onCreate() 中做所有事情。有人对从未保留的活动中优雅地恢复有任何建议吗?

编辑 1:

回应@Tomer Mor 的评论

我一共有三项活动。 A -> B-> C

在这种情况下,MainActivity 是 B,DetailActivity 是 C。我的活动 A 是一个“LoginActivity”,在我成功“登录”后完成()。

编辑 2:

如果有帮助,我的 MainActivity 是 FragmentActivity。

编辑 3:

回应@Doctoror Drive。我的 MainActivity 扩展了 FragmentActivity。 MainActivity 添加 MyFragment.java

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setUpActionBar();
    Toast.makeText(this, this.getClass().getSimpleName(), 1).show();
    setContentView(R.layout.my_placement);

    myFragment = new MyFragment();

    FragmentManager fragmentManager = getSupportFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    fragmentTransaction.add(R.id.fragment_container, myFragment);

    fragmentTransaction.commit();

}

我在 MainActivity extends FragmentActivity 的 onCreate 中放了一个日志,它被称为 ONCE。 我在 onCreateOptionsMenu()MyFragment.java 中放了一个 Log.d(),它显示 TWICE! 所以它被调用了两次,但我不确定它是否只被创建一次。

编辑 4:

03-24 14:17:37.038: E/MainActivity(26486): onCreate hit!
03-24 14:17:37.048: D/SherlockFragmentActivity(26486): [supportInvalidateOptionsMenu]
03-24 14:17:37.048: D/SherlockFragmentActivity(26486): [invalidateOptionsMenu]
03-24 14:17:37.048: D/ActionBarSherlock(26486): [dispatchInvalidateOptionsMenu]
03-24 14:17:37.048: E/MyFragment(26486): onActivityCreated!
03-24 14:17:37.048: D/SherlockFragmentActivity(26486): [supportInvalidateOptionsMenu]
03-24 14:17:37.048: D/SherlockFragmentActivity(26486): [invalidateOptionsMenu]
03-24 14:17:37.048: D/ActionBarSherlock(26486): [dispatchInvalidateOptionsMenu]
03-24 14:17:37.048: E/MyFragment(26486): onActivityCreated!

编辑 5:

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    savedInstanceState=null;
    super.onActivityCreated(savedInstanceState);

    setHasOptionsMenu(true);

    adapter = AnimalList.getAnimalAdapter();
    setListAdapter(adapter);



}

【问题讨论】:

  • 签入manifast MainActivity launchMode 参数
  • 这是你的片段被复制了,不是吗?发布您的 Activity 的 onCreate()。
  • Don't start a new question onActivityCreated()是Fragment的一个方法。你有两个片段,所以它被调用了两次。看我的回答。

标签: java android android-layout android-listview android-activity


【解决方案1】:

在 Activity 恢复其状态时添加 Fragment 是一个常见错误。 仅当 Activity 的 savedInstanceState 为 null 时才应添加 Fragment,否则 FragmentManager 会自动为您添加它,最终会附加两个 Fragment 实例。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    ...

    if (savedInstanceState == null) {
        final FragmentManager fragmentManager = getSupportFragmentManager();
        final FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.add(R.id.fragment_container, myFragment);
        fragmentTransaction.commit();
    }
}

另一个不好的做法是使用成员访问片段。 Fragment 的生命周期可能与活动稍有不同,因此 myFragment 成员可以在某个时候指向过时的 Fragment 实例。 正确的方法是当你需要 MyFragment 时,在 FragmentManager 中找到它

//if you need to do something with MyFragment
public void doSomething() {
    final MyFragment myFragment = getMyFragment();
    // can be null if re-creating or not yet attached.
    if (myFragment != null) {
        myFragment.doSomething();
    }
}

private MyFragment getMyFragment() {
    return (MyFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_container);
}

【讨论】:

  • 在我实施你的答案之前......我仍然对我显然如何拥有“两个”片段感到困惑。 Android 说 For example, when the activity is paused, so are all fragments in it, and when the activity is destroyed, so are all fragments. developer.android.com/guide/components/fragments.html 我的 MainActivity extends FragmentActivity 肯定被破坏了,因为我在 onDestroy() 中有一个 Toast。这会导致我的片段也发生 onDestroy() 吗?
  • @user2676468 当Activity在内存不足时被系统销毁或者设置了“不保留Activity”时,FragmentManager保存fragment信息,当你恢复它时,Activity恢复Views的状态FragmentManager 会在销毁时恢复所有 Fragment。因此,如果 savedInstanceState 不为 null,则永远不要在 onCreate 上手动添加 Fragments。
  • 知道了。我实现了非空检查,现在我有一个菜单实例(是的!),但我的 listView 现在根本不显示。它之前播放过两次 =/ 有什么想法吗?
  • ListView 位于何处?你如何填充它?
  • 我在onActivityCreated() 的 MyFragment.java 中设置了ListAdapter()。我通过适配器填充它。