简体   繁体   English

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

[英]Android application not working after resuming activity

I have an application where whenever I exit the application via the home hardware button, it should return to the last state the application is in. However, when I launch the application again, the application shows a white screen with only my header bar. 我有一个应用程序,每当我通过家庭硬件按钮退出应用程序时,它应该返回到应用程序所在的最后状态。但是,当我再次启动应用程序时,应用程序显示一个只有我的标题栏的白色屏幕。 And when I click on the header bar's button, the application crashes with the IllegalStateException where the application cannot find the method for the button clicked. 当我单击标题栏的按钮时,应用程序崩溃并出现IllegalStateException ,其中应用程序找不到单击按钮的方法。

I am currently implementing with Sherlocks Fragment, where the header bar is an action bar. 我目前正在使用Sherlocks Fragment,标题栏是一个动作栏。 I'm also using HTC Rhyme, Version 2.3 (Gingerbread). 我也在使用HTC Rhyme,2.3版(Gingerbread)。 The following is the codes for the addition of fragments into my main app. 以下是将片段添加到我的主应用程序中的代码。

Codes to add the fragments within the onCreate method in the activity: 用于在活动中的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();

This is the codes when I change a fragment: 这是我更改片段时的代码:

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

[Edit] [编辑]

I realized after much reading and running that the main issuei have is that upon resuming the application, the activity is actually created again. 经过多次阅读和运行后,我意识到主要问题是在恢复应用程序时,实际上是再次创建活动。 Thus, some of the parameters i passed in does not get registered, resulting in the wrong display. 因此,我传入的一些参数没有被注册,导致显示错误。 I THINK this is the error that is causing that to happen: 认为这是导致这种情况发生的错误:

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

However, I don't know how you force the application to remember the previous state of the fragment? 但是,我不知道你是如何强制应用程序记住片段的先前状态的? Or is there any other way around this problem? 或者还有其他方法解决这个问题吗?

I'm still very stuck with this problem. 我仍然坚持这个问题。 Will really appreciate it if someone can help me! 如果有人可以帮助我,真的很感激!

After much trial and error and many readings, I finally found a way to sort of solve my problem. 经过多次试验和错误以及许多阅读后,我终于找到了解决问题的方法。

From what I understand, this problem will occur due to the Activity's life cycle. 根据我的理解,这个问题将由于Activity的生命周期而发生。 The comment by Tseng in this forum was quite comprehensive: http://forum.unity3d.com/threads/127794-Android-Apps-crashing-on-resume Tseng在这个论坛上的评论非常全面: http//forum.unity3d.com/threads/127794-Android-Apps-crashing-on-resume

It seems that during the time when other applications are invoked when a certain activity is onPause/onStop , Android might free up some of its memory the activity is currently holding on to if there is insufficient memory required. 似乎在某个活动是onPause/onStop时调用其他应用程序的时间,如果没有足够的内存,Android可能会释放当前活动所持有的部分内存。 In this case, all the current objects or variable the paused activity is having will be destroyed. 在这种情况下,将暂停所有暂停活动所具有的当前对象或变量。 Thus, when the activity is back on focus, the onCreate is actually invoked again. 因此,当活动重新开始焦点时,实际上会再次调用onCreate Thus, the activity will have no idea which fragment I am currently require. 因此,活动将不知道我目前需要哪个片段。

However, I realized that it will always call the saveInstanceState which is essentially a bundle object. 但是,我意识到它总是会调用saveInstanceState,它本质上是一个bundle对象。 So I did the following: 所以我做了以下事情:

onSaveInstanceState method 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 method onCreate方法

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

What I have done is to remove all the fragments I have stacked thus far to remove any issues where there is missing information needed. 我所做的就是删除目前已堆叠的所有片段,以消除所需缺少信息的任何问题。 So this is like starting anew again. 所以这就像重新开始一样。 The status check just determine which fragment the user has last visited. 状态检查仅确定用户上次访问的片段。

After much testing, it seems like it does solve my problem. 经过多次测试,它似乎确实解决了我的问题。 though I wouldn't say it is perfect. 虽然我不会说这是完美的。 One of the main downfall I have is that whenever I change my fragment, I have to update and change my statusCheck to make sure the correct fragment will be called. 我遇到的主要问题之一是每当我更改我的片段时,我必须更新并更改我的statusCheck以确保调用正确的片段。 However, I have to admit this way is a little unorthodox and might not be very correct. 但是,我必须承认这种方式有点不正统,可能不太正确。

If any of you have any better ideas, please feel free to share! 如果您有任何更好的想法,请随时分享!

You can try to implement following: 您可以尝试实现以下内容:

  1. Use putFragment to save all fragments, currently located in FragmentManager, into bundle in onSaveInstanceState ; 使用putFragment将当前位于FragmentManager中的所有片段保存到onSaveInstanceState中的 bundle中;
  2. And then you can use getFragment to get all previously stored fragments back from bundle in onRestoreInstanceState . 然后,您可以使用getFragmentonRestoreInstanceState中的 bundle中获取所有先前存储的片段。

Also... you'll probably need some HashMap that will help to determine the hierarchy of the fragments (in case you have containers and contained fragments) to be saved into bundle as well. 另外......你可能需要一些HashMap来帮助确定片段的层次结构(如果你有容器和包含的片段)也要保存到bundle中。

Also... when restoring from bundle you'll need to know keys for all fragment you've put there earlier. 另外......当从bundle恢复时,你需要知道你之前放在那里的所有片段的键。 Probably, the easiest way is simply to organize an array of keys and put them into bundle when saving the fragment into instance. 可能最简单的方法是组织一个键数组,并在将片段保存到实例时将它们放入包中。

This way your saving and restoring will be complete and centralized. 这样,您的保存和恢复将是完整和集中的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM