【问题标题】:Save multiple instances states of the same Activity in Android在Android中保存同一个Activity的多个实例状态
【发布时间】:2013-02-08 14:42:24
【问题描述】:

我正在开发一个 Android 应用程序,并且我希望避免在使用相同的额外内容来自同一个 Activity 时重新加载类似的数据。

具体来说,当我使用 extra 启动我的 Activity 'A' 时,我会使用这个 extra 从服务器加载远程数据。 通过这个 Activity,我可以使用不同的额外功能重新启动“A”等等。

例子:

A:id1 --> A:id2 --> A:id3

但是,它也可以是我已经加载的额外内容:

A:id1 --> A:id2 --> A:id3 --> A:id1

在这种情况下,我不会再次请求服务器或丢失活动堆栈。

据我了解,“onSaveInstanceState”允许保存一个 Activity 的一个实例,但就我而言,它是同一 Activity 的多个实例(具有不同的附加功能)。

那么,管理同一 Activity 的已保存实例状态(捆绑)列表是否是解决方案?还是别的什么?

提前致谢

【问题讨论】:

    标签: android android-activity


    【解决方案1】:

    onSaveInstanceState 方法没有按照您描述的方式使用。 Check this out, 这是活动类的文档,特别是活动生命周期部分。 onSaveInstanceState 是一种在操作系统出于某种原因必须终止 Activity 时调用的方法。它允许您填充一个 Bundle,这将有助于重新创建用户离开的 Activity 的特定实例。这通常是因为用户切换到不同的应用程序并且操作系统正在终止 Activity 以回收内存,但也会发生在屏幕旋转时,因此至少要注意平台的细微差别。

    至于您的问题,我要做的是使用数据库来存储从服务器检索到的信息。当你启动一个 Activity 时,你可以先检查数据库中是否存在需要填充该 Activity 的数据。如果是,则从那里加载并显示它,否则进行服务器调用。

    这很好,因为数据将在应用程序的多次使用中保持不变。更进一步,如果来自服务器的数据有可能是陈旧的,您可以轻松扩展它以最初显示来自数据库的数据,并触发对数据的异步请求,该数据将在返回时更新 UI 和数据库.您的用户几乎永远不会处于等待加载的状态,这总是一件好事!

    Here's a good tutorial on the basics of implementing an sqlite database. 这还将为您提供额外的好处,即在应用程序的单独运行中保存数据。

    作为替代方案,如果您真的不需要数据库的持久性或其他特性,并且认为开销不值得,您可以创建一个 Singleton 类来跟踪返回的数据,也许使用Application class 来实现它。重要的是要注意(并带我们完整循环)任何存储此数据的内存方法都应使用onSaveInstanceState 进行管理,以确保如果 Activity 在意外时间被终止,您不会丢失任何数据。

    【讨论】:

    • 首先,感谢您的回答。现在我了解了 onSaveInstanceState 的好处。我曾想过保存数据(例如在数据库中),但是有一件事我之前没有指定。我得到的一些数据是 API 提供的图片,根据使用条款,我无权存储它们。这就是为什么,我试图恢复视图而不是数据。
    • 我明白了。图像很棘手,无法将它们保存到磁盘会限制您的选择。需要注意的一些事情是图像(尤其是位图,如果您使用的是位图)会占用大量内存并导致 OutOfMemoryExceptions,这很糟糕。最好将所有可以存储的数据存储在数据库中,然后在每次需要图像时调用新的 API。您可以尝试某种类型的缓存,正如我作为替代解决方案提出的那样,但它的工作量更大,并且更有可能引入不稳定。
    • 是的,我会尽量存储所有数据,并依靠Android Universal Image Loader 来管理缓存的图片。
    【解决方案2】:

    +1 表示 MattDavis 的回答,但我也建议您使用所谓的“单例模式”。

    本质上,这是一种在内存中缓存内容的方法。您创建了一个类,其目的是保存您不想继续重新加载的所有数据库数据。此对象有一个全局实例,最初为空。您调用一个返回该实例的静态方法。如果静态方法发现实例为空,它会创建实例,从数据库中填充它,缓存它,然后将它返回给调用者。从那时起,对实例的所有请求都只返回缓存的副本。如果您的应用因缺乏资源而被系统杀死,并在稍后重新启动,它会根据需要透明地重新创建实例。

    这是一个非常常见的实现,并且在多线程环境中工作:

    public class Singleton {
        private static volatile Singleton instance = null;
        private Singleton() {
            // This is the place where you initialize the instance
            // from the database.
        }
        public static Singleton getInstance() {
            if (instance == null) {
                synchronized(Singleton.class) {
                    if (instance == null) {
                        instance = new Singleton();
                    }
                }
            }
            return instance;
        }
    }
    

    我在很多地方都使用这种模式;非常方便。

    要真正做到正确,您还应该在活动中实现onLowMemory() 或onTrimMemory(),以便在资源紧张时释放单例实例。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多