3

我有一个应用程序,每当我通过主页硬件按钮退出应用程序时,它应该返回到应用程序所处的最后状态。但是,当我再次启动应用程序时,应用程序显示一个只有我的标题栏的白屏。当我单击标题栏的按钮时,应用程序崩溃,IllegalStateException应用程序无法找到单击按钮的方法。

我目前正在使用 Sherlocks Fragment 实现,其中标题栏是一个操作栏。我也在使用 HTC Rhyme,2.3 版(姜饼)。以下是在我的主应用程序中添加片段的代码。

在活动的 onCreate 方法中添加片段的代码:

FragmentTransaction trans = getSupportFragmentManager().beginTransaction();
Bundle bMain = getIntent().getExtras();
String statusCheck = "";
if (bMain != null) {
    statusCheck = bMain.getString("statusCheck");
}
if (statusCheck.equals("web")) {
    MyWebViewFragment webfrag = new MyWebViewFragment();
    trans.add(R.id.container,webfrag, "WebViewFragment");
} else if(statusCheck.equals("traveloguelist")) {
    MyTravelogueListFragment travelfrag = new MyTravelogueListFragment();
    trans.add(R.id.container,travelfrag, "TravelogueListFragment");
}
trans.commit();

这是我更改片段时的代码:

MyTravelogueListFragment travelfrag = new MyTravelogueListFragment();
getSupportFragmentManager().beginTransaction().replace(R.id.container, travelfrag).addToBackStack(null).commit();

[编辑]

经过大量阅读和运行后,我意识到主要问题是在恢复应用程序后,实际上又创建了活动。因此,我传入的一些参数没有注册,导致显示错误。我认为这是导致这种情况发生的错误:

Previously focused view reported id "myresID" during save, but can't be found during restore.

但是,不知道你是如何强制应用程序记住fragment之前的状态的?或者有没有其他方法可以解决这个问题?

我仍然很纠结这个问题。如果有人可以帮助我,我将不胜感激!

4

2 回答 2

4

经过多次反复试验和多次阅读,我终于找到了解决问题的方法。

据我了解,由于 Activity 的生命周期,会出现此问题。Tseng 在这个论坛的评论相当全面:http: //forum.unity3d.com/threads/127794-Android-Apps-crashing-on-resume

似乎在某个 Activity 调用其他应用程序时onPause/onStop,如果所需内存不足,Android 可能会释放该 Activity 当前持有的一些内存。在这种情况下,暂停的活动所拥有的所有当前对象或变量都将被销毁。因此,当活动重新聚焦时,onCreate实际上会再次调用 。因此,活动将不知道我当前需要哪个片段。

但是,我意识到它总是会调用本质上是一个捆绑对象的 saveInstanceState。所以我做了以下事情:

onSaveInstanceState 方法

  @Override
  public void onSaveInstanceState(Bundle bundle) {
      //activityFrag is a string object that tells me which fragment i am in currently
      bundle.putString("statusCheck", activityFrag);
  }

onCreate 方法

if (savedInstanceState != null) {
    getSupportFragmentManager().popBackStack(null, getSupportFragmentManager().POP_BACK_STACK_INCLUSIVE);
    //return;
    statusCheck = savedInstanceState.getString("statusCheck");
} else {
    statusCheck = b.getString("statusCheck");
}

我所做的是删除到目前为止我堆积的所有碎片,以消除任何缺少所需信息的问题。所以这就像重新开始。状态检查只是确定用户最后访问了哪个片段。

经过大量测试,它似乎确实解决了我的问题。虽然我不会说它是完美的。我遇到的主要缺点之一是,每当我更改我的片段时,我都必须更新和更改我的 statusCheck 以确保将调用正确的片段。但是,我不得不承认这种方式有点不正统,可能不是很正确。

如果大家有更好的想法,欢迎分享!

于 2013-01-25T10:24:24.937 回答
0

您可以尝试执行以下操作:

  1. 使用putFragment将当前位于 FragmentManager 中的所有 Fragment 保存到onSaveInstanceState中的 bundle 中;
  2. 然后您可以使用getFragment从onRestoreInstanceState中的捆绑包中获取所有先前存储的片段。

另外......您可能需要一些 HashMap 来帮助确定要保存到包中的片段的层次结构(如果您有容器和包含的片段)。

另外...从捆绑包中恢复时,您需要知道之前放置的所有片段的密钥。可能,最简单的方法是简单地组织一个键数组,并在将片段保存到实例中时将它们放入 bundle 中。

这样您的保存和恢复将是完整和集中的。

于 2013-06-19T09:17:51.207 回答