使用多个Activity后,如何在Activity到达前台后处理保留的数据?

时间:2012-01-03 10:11:09

标签: android activity-lifecycle android-lifecycle

目前我对Android的生命周期管理感到有些困惑。在Activity返回前台后,至少有4种可能性可以恢复保留的数据:

  • Android处理:如果有足够的内存,Android会在Activity重启后存储并恢复重要数据(已检查的单选按钮,EditText文本,-...等)当Activity进入后台时,用户具有与之前相同的状态。

  • onPause,onResume:覆盖onPause并将重要数据保存到数据库或文本文件中,并在下次执行onResume时恢复它。

  • onSavedInstance(Bundle),onRestoreInstance(Bundle):我可以将数据作为键值对保存到包中,并在执行onRestoreInstance后恢复它们。

  • onRetainNonConfigurationInstance(),getLastNonConfigurationInstance():我在一个大对象中处理所有存储问题,并在执行onCreate时读取getLastNonConfigurationInstance()。

尽管令人困惑的是哪种方法最好,但我认为它依赖于开发经验来知道何时使用哪种可能性。如果你有一些很好的例子我会很高兴,但这不是我的问题。我想知道当我有不同的活动时如何处理所有这些,当一个Activity在后台暂停时会被一个Activity杀死:

在我的情况下,我有一个MainActivity和一个MessageActivity。 MessageActivity由一个ViewSwitcher组成,它由两个状态组成。状态1是单选按钮选择列表。状态二是带有两个按钮的EditText(发送和中止)。当我测试每个状态时,点击Android主页按钮,然后重启应用程序,当我将处理留给Android时,具有正确状态的正确活动和旧数据进入前台。这样才有用。
但是当Android在后台销毁MessageActivity时会发生什么: 如果我使用Android方式,数据会丢失,我想MainActivity(而不是MessageActivity-> state(1或2))将在我重新启动应用程序后下次启动(这是正确的吗?)。因此,当我想保留MessageActivity的数据时,我必须使用其他三种可能性之一 当应用程序入口点(因此MainActivity)与上一个活动的Activity不同时,如何巧妙地做到这一点。问题是我必须使用特殊状态的ViewSwitcher恢复一个特殊的Activity。我可以使用onStart()或onResume()方法中的startActivity(Intent)从MainActivity启动MessageActivity(因为MainActivity可能是入口点)但是我在生命周期管理中遇到了很多逻辑问题。由于这个事实,我不认为这是正确的方法。

但是,这样做的最佳方式是什么?

4 个答案:

答案 0 :(得分:2)

这不是我想要获得最佳答案的尝试,但是在评论部分进入的时间太长了。

首先,我建议不要依赖“Android方式” - 这将导致应用程序行为不一致,具体取决于设备的可用内存 - 不良做法。

我的建议是,每次进入onPause()中的MessageActivity时,都会将您的状态相关数据保存在SharedPreferences中的键值对中。在SharedPreferences中存储一个标志,指示哪个是上次打开的活动(如果您只有两个活动,则可以轻松转到0/1或真/假标志)。 当您重新启动应用程序时,将AndroidManifest.xml中标记的Activity作为“入口点”启动是正常的。很自然地,您将检查onResume()MainActivity的旗帜,并根据需要启动其他活动。在MessageActivity's onResume()中检查SharedPreferences中的值并填写必要的内容...... 如果您的应用程序“恢复”到ActivityStack中最后一个活动,则会在ActivityStack 中的最后一个活动中调用onResume()

答案 1 :(得分:2)

  

我想MainActivity(而不是MessageActivity-> state(1或2))将在我重新启动应用程序后下次启动(这是正确的吗?)

不,我不相信这是正确的,这取决于你的代码在onCreate()中的作用。如果你以正确的方式去做事,那肯定不会需要是正确的。测试此操作的一种简单方法是旋转屏幕,重新创建正在运行的活动,除非您已覆盖默认配置更改行为。

我建议您仔细阅读Android文档中的这一部分:

http://developer.android.com/guide/topics/fundamentals/activities.html#SavingActivityState

特别是:

  

即使你什么都不做而且没有实现onSaveInstanceState(),Activity类的默认实现onSaveInstanceState()也会恢复一些活动状态。具体来说,默认实现为布局中的每个View调用onSaveInstanceState(),这允许每个视图提供有关应保存的自身的信息。几乎Android框架中的每个窗口小部件都会适当地实现此方法,以便在重新创建活动时自动保存和恢复对UI的任何可见更改。例如,EditText小部件保存用户输入的任何文本,CheckBox小部件保存是否已选中。您需要的唯一工作是为要保存其状态的每个小部件提供唯一的ID(带有android:id属性)。如果窗口小部件没有ID,则无法保存其状态。

这意味着,只要您不在任何onCreate()调用中强制执行任何UI状态,您的活动堆栈和UI状态就会恢复。

就个人而言,我首选的方法是在我的活动的成员变量中保持尽可能少的状态,使用onSave/RestoreInstanceState()保存和恢复它,并依靠默认实现来保存其余的UI状态(文本盒子内容等)。应该在会话之间保留的数据我会在更改后立即提交到我的数据库或首选项(例如,在点击处理程序中)。这意味着我不需要担心活动的生命周期。我的UI只是尽可能地呈现了我的数据库中的数据视图(使用CursorAdapter等)。

修改

关于恢复整个活动堆栈:

  

当用户通过按HOME键离开任务时,...系统保留任务中每个活动的状态。如果用户稍后通过选择开始任务的启动器图标来恢复任务,则任务将到达前台并在堆栈顶部恢复活动。

(见http://developer.android.com/guide/topics/fundamentals/tasks-and-back-stack.html

答案 2 :(得分:1)

我过去处理这样一个问题的方法是在后台运行一个服务,它通过Intents和listener处理来自不同活动的信息流(最好,因为它们最容易解耦)解决方案),或者如果您非常小心,并且由于某种原因唯一可行的解​​决方案是通过直接属性访问或方法调用来存储数据,您也可以在服务类上使用静态属性/方法。但是,我强烈建议使用Intent / listener方法,因为它通常更灵活,线程安全和解耦。此外,明智的做法是确保在任何时间点都没有发生太多事情(换句话说,使用此服务进行Intent处理),否则服务将倾向于CPU时间和RAM,当它不是真正需要时。

在这种方法中需要考虑的一些资源是IntentService及其相关的类,包括超类,服务。但是,IntentService值得注意处理一些关于异步Intent处理的事情,服务不会自动附带。

希望这对你有所帮助!

答案 3 :(得分:1)

login.setOnClickListener(new View.OnClickListener()      {
    public void onClick(View view)         {
        String name=username.getText().toString();
        SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
        SharedPreferences.Editor editor = settings.edit();
        editor.putString("username", name);
        if(name.equals("xxx"))                 {
            Intent intent=new Intent(currentactivity.this,nextactivity.class);
            intent.putExtras(bundle);
            startActivityForResult(intent,0);
        }
    }
});