恢复活动后Android应用程序无法正常工作

时间:2013-01-14 03:23:28

标签: android android-fragments

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

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

在活动中添加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();

[编辑]

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

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

但是,我不知道你是如何强制应用程序记住片段的先前状态的?或者还有其他方法解决这个问题吗?

我仍然坚持这个问题。如果有人可以帮助我,真的很感激!

2 个答案:

答案 0 :(得分:4)

经过多次试验和错误以及许多阅读后,我终于找到了解决问题的方法。

根据我的理解,这个问题将由于Activity的生命周期而发生。 Tseng在这个论坛上的评论非常全面: http://forum.unity3d.com/threads/127794-Android-Apps-crashing-on-resume

似乎在某个活动为onPause/onStop时调用其他应用程序的时间内,如果没有足够的内存,Android可能会释放当前活动所持有的部分内存。在这种情况下,将暂停所有暂停活动所具有的当前对象或变量。因此,当活动重新开始焦点时,实际上会再次调用onCreate。因此,活动将不知道我目前需要哪个片段。

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

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以确保调用正确的片段。但是,我必须承认这种方式有点不正统,可能不太正确。

如果您有任何更好的想法,请随时分享!

答案 1 :(得分:0)

您可以尝试实施以下内容:

  1. 使用putFragment将当前位于FragmentManager中的所有片段保存到onSaveInstanceState中的包中;
  2. 然后您可以使用getFragment将所有以前存储的片段从onRestoreInstanceState中的包中取回。
  3. 另外......你可能需要一些HashMap来帮助确定片段的层次结构(如果你有容器和包含的片段)也要保存到bundle中。

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

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