onSaveInstanceState / onPause - 等待状态完全保存,然后才允许进程被终止

时间:2011-09-19 05:21:10

标签: android multithreading lifecycle

我正在处理我的第一个Android应用。它有一个模型,当用户进行更新时,它会持久保存到数据库中。

当调用onSaveInsanceState时,我想保存一个可用于从数据库加载用户正在处理的文档的id。但这只能在文档完全访问数据库后才会发生。在某些情况下,持久化复杂文档可能需要几秒钟(我希望一旦我完成所有详细的注销,这将加速,并且在实际使用中,用户将分阶段构建复杂文档,每个文档其中的数据将被保存到数据库中,因此复杂的文档不太可能一次性保存。)

现在,Android上线程的第一条规则是“不要阻止UI线程”,因此数据库交互当然发生在一个单独的线程上。但我对Android生命周期的理解是,在许多情况下,调用onSaveInstanceState是因为Android系统想要终止进程。这表明我不能允许这种方法返回,直到数据库线程完成保存文档(事实上,根据我目前的设计,我实际上并不知道文档的ID号是什么,直到#39 ; s已被保存到数据库中,因此我甚至无法将其保存在已保存的状态包中。)

在这些情况下是否适合阻止等待执行持久性任务的UI线程?当因为进程被杀死而调用onSaveInstanceState时,应用程序在前台不再可见,因此没有任何界面无法响应。

但是,当Activity实例被配置更新破坏时,也会调用onSaveInstanceState,这会在屏幕方向更改时发生。当侧面旋转屏幕几秒钟没能做任何事情时,这是非常不幸的。在这种情况下,进程(以及因此内存空间)仍然存在,因此我不需要确保文档访问数据库,如果我可以在Bundle中存储对它的引用而不是它的id。但我不知道如何区分这两种情况。

这些情况是否有公认的做法?我应该阻止线程安全吗?我可以使用普通的Java线程原语来阻止和等待吗?我能做些什么没有阻止线程,但确保在Android关闭进程之前完成持久性任务?

这一切也适用于onPause,因为onSaveInstanceState不一定会被调用。

2 个答案:

答案 0 :(得分:2)

您不必对onSaveInstanceState中的持久保存执行操作,您只需在Bundle中保存实例状态,以便可以在onRestoreInstanceState中快速恢复实例}。

文档声明您应该将重要的持久性数据(例如用户编辑)写入onPause中的存储,但它也声明它应该很快,以便下一个活动可以开始做它想要的任何内容要做。

我认为我的建议是在onSaveInstanceState中保存文档文本以及Bundle中的任何内容,并在onRestoreInstanceState中恢复它。使用onPause快速保存“备份副本”(临时文件可能?),如果尚未保存到数据库,则可以在onResume中恢复。并使用onStop(当活动已在后台时调用)实际将数据保存到数据库。

请注意,在onPause被调用之后,活动可能会被杀死(除非系统资源非常少,除非......),这就是为什么我会在尝试提交之前保存快速备份的原因在数据库中。

修改 - 额外基于评论

为了确保在系统终止应用程序之前保存正在执行保存过程的后台线程,我认为可以阻止并等待保存线程完成后再返回来自onPause,但我建议在方向更改时使用android:configChanges="orientation"来阻止活动重启(和onPause调用)。

答案 1 :(得分:0)

您应该尝试AsyncTask,它将阻止您的ui但不会显示空白屏幕,将加载必要的xml元素,然后将从Async任务调用,在异步任务中将您的doc保存在数据库中。

请点击此链接:AyncTask Exmaple