“持久状态”与“当前状态”
Posted
技术标签:
【中文标题】“持久状态”与“当前状态”【英文标题】:"persistent state" vs. "current state" 【发布时间】:2012-08-06 03:50:06 【问题描述】:试图决定(对于我的应用程序)在onPause() 中保存什么以及在onSaveInstanceState() 中保存什么,我梳理了整个 SO 以获得提示和明确的指导。
如果我理解正确,onSaveInstanceState() 最适合保存“运行时更改”或“当前状态”(无论是什么意思),而 onPause() 最适合保存“持久状态”(无论是什么意思)。
我仍然难以确定我的应用程序中的的构成。例如,虽然用户偏好显然是持久的,但当用户更改它们时,android UI 框架总是自动保存它们,我是否需要将它们保存在onPause()
中?
类数据成员需要保存在onSaveInstanceState()吗?我需要为我的应用程序中的每个类都这样做吗?
我很困惑。
你能举出真实世界的例子,说明哪些内容必须保存在onPause()
中,哪些内容必须保存在onSaveInstanceState()
中? Except 用于设备配置更改,即。
--
一些新的见解,我的问题得到了回答:
onSaveInstanceState 的Bundle
是 not written to anything,而且无论如何都不是持久的。
onSaveInstanceState 的Bundle
数据在应用程序关闭之前将仅为held in memory。
【问题讨论】:
“设备配置更改除外”...这是什么意思? 这与方向类型的变化有关。 @AlexLockwood “除外”一词是其含义的链接。几乎无聊的例子是方向类型的变化,但它可能是别的什么? (例如,已连接 USB 键盘、已建立 Internet 连接等) 【参考方案1】:我的案例是一个游戏,我想将持久性数据保存到游戏服务器。
由于这可能需要一段时间,我发现尝试保存在 onPause
中并不是一件好事,而是保存在 onStop
中。
根据我所做的测试,onStop
似乎能够在后台运行,而onPause
阻塞,至少在我按下 home 时是这种情况(使用简单的 1
到 @987654327 进行测试@循环在onPause
和onStop
)。
谁能证实这个阻塞理论?
onStop
需要 Honeycomb
向上 (api11+
),因为在该版本之前,您可以在调用 onClose
之前被杀死。
查看here 并在表中查找killable
- 如果实际情况与文档相符则是另一个问题:)。
【讨论】:
【参考方案2】:这是答案。您可以通过三种不同的方式保存状态。
1) 子类化应用程序(不是一个好主意)。 2)SharedPreferences(适用于简单数据,快速可靠) 3) SQLite 数据库(更复杂,也更可靠)。
现在回答你的问题。 android真的没有保证。在任何时候,它都可以并且可能在不调用任何特定函数的情况下破坏您的应用程序。因此,如果有重要的数据需要保存,答案是一拿到就保存。如果您知道需要立即保存某些东西,那么稍后保存通常没有太大的优势。
onSaveInstanceState() 仅用于保存与布局或方向更改相关的临时变量。
总结持久状态/数据(应该在崩溃中幸存),应该尽快保存,不要等待onPause()
,因为没有保证.这就是现实。
【讨论】:
很好的说明。谢谢! (我将强调我认为的关键提示) 很好的澄清,但 onPause 保证在应用程序被杀死之前被调用......有一些逻辑语句我们可以从 1 中得出这个推论。永远不会被恢复的应用程序被 android 2 杀死. 只有在调用应用程序 onPause 时,应用程序才会进入非恢复(暂停状态),如果我在这里遗漏了什么,请告诉我【参考方案3】:您不需要在 onPause 中存储用户偏好,因为正如您所说,框架会为您完成。
要区分持久数据和状态信息,请考虑一个文本编辑器应用程序。
持久数据
假设用户输入了几个单词,然后退出了应用。用户没有明确告诉我们将这些数据保存到文件中,但是当他们回来时将这些数据存储起来肯定会很好。这是持久性数据,您希望将其存储在 onPause() 中。
状态数据
同样,假设您有 2 个选项卡和一个用于跟踪当前选择的选项卡的变量。这是您将存储在 onSaveInstanceState() 中的状态数据。
灰质
最后想象一下,您在编辑器中有一个类,用于跟踪编辑器中的字符数和行数。这是状态数据,您可以将其存储在 onSaveInstanceState() 中,也可以将其丢弃并在重新启动时重新计算。是否丢弃它可能取决于计算需要多长时间,例如,如果您可以通过存储数据来阻止网络请求,那么就这样做。
进一步的想法
通过使用您的应用程序,您应该可以清楚地看出是否存在您未能存储正确数据的区域。请务必执行诸如点击主页按钮然后从设备管理器中关闭您的应用程序之类的操作。这将使您能够解决应用关闭而不是暂停的极端情况。
如果您的 UI 状态在整个生命周期事件中保持一致并且您的用户数据仍然存在,那么做得很好。
根据评论编辑
我认为这里有 2 条标准来确定何时/保存什么。
第一个是相当主观的 - 你想保存数据吗?确实没有什么可以强迫您保存状态或数据。保存这些信息会带来更好的用户体验吗?如果您正在写一封电子邮件并尝试从另一个应用程序复制/粘贴文本,那么每次应用程序关闭时丢失您输入一半的电子邮件将是令人沮丧的。
第二部分,确定要保存的内容取决于您是否可以根据您拥有的数据重建您的 UI 状态。例如,如果您保存了文本数据,那么这一定意味着用户正在编辑文本。所以现在我们知道切换到编辑文本选项卡并填写保存的文本。
一般来说,如果您希望将用户返回到他们离开的地方,那么您需要考虑返回该点所需的状态数据。想象一下您的应用程序的原始加载版本
需要更改哪些数据才能将其变为用户的最后状态 看到了吗? 您需要存储哪些数据才能返回此处?这确实是 android 的工作方式,您的 Activity 被销毁并重新创建,您的工作是再次启动各个部分(如果您选择这样做)。
【讨论】:
这正是我需要的答案类型,所以接受。尽管如此,为了让事情更清楚一点:为什么选择的选项卡分类与用户键入的单词不同?这是因为键入的单词是关键数据,而选择的选项卡是“很高兴拥有”?这是决定什么是持久性和什么是状态的标准吗? (顺便说一句,我见过编辑器会持续保存选定的选项卡,即使在重新启动之间也是如此)。 我认为这里有两条标准。第一个是相当主观的——保存这些信息会带来更好的用户体验吗?如果您正在编写电子邮件并尝试从另一个应用程序复制/粘贴文本,那么每次切换应用程序时丢失一半键入的电子邮件会令人沮丧。第二部分是您是否可以根据您拥有的数据重建您的 UI 状态 - 如果您保存了一定意味着用户正在编辑文本的文本数据,请切换到该选项卡并填写保存的文本。 P.S.在onPause()
中保存日期只是故事的一半。取消或停止某些操作似乎是另一半,如CookieSyncManager documentation 所示。或者这也可以算是存储?
Cookie 同步特定于您在应用程序中使用 web 视图并希望将 cookie 同步到磁盘,这样它们就不会意外地从缓存中清除。但一般来说,您应该注意停止任何可能启动的辅助线程。
我倾向于在 onPause 中停止,这又取决于你在做什么。为 UI 上显示的模拟计算物理方程的线程?在 onPause() 中停止它。提供 GPS 路由的线程...返回按钮关闭您的应用程序而不是暂停它。 onPause 始终是您可能永远不会返回后台的信号,我相信这一点,onStop() 在所有情况下都不会被调用,例如当 OOM 杀手提名您时。我很少使用 onStop。以上是关于“持久状态”与“当前状态”的主要内容,如果未能解决你的问题,请参考以下文章