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

Android onSaveInstanceState/onPause—等待状态完全保存后,才允许终止进程,android,multithreading,lifecycle,Android,Multithreading,Lifecycle,我正在开发我的第一个Android应用程序。它有一个模型,当用户进行更新时,该模型将被持久化到数据库中 调用onsaveInAsseState时,我想保存一个id,该id可用于从数据库加载用户正在处理的文档。但这只能在文档完全进入数据库后发生。在某些情况下,持久化一个复杂的文档可能需要几秒钟的时间(我希望在我完成所有详细的注销后,这将加快速度,并且在实际使用中,用户将分阶段创建一个复杂的文档,每个文档都将持久化到数据库中,因此复杂的文档不太可能一次性全部保存) 现在,Android上线程的#1规

我正在开发我的第一个Android应用程序。它有一个模型,当用户进行更新时,该模型将被持久化到数据库中

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

现在,Android上线程的#1规则是“不要阻塞UI线程”,因此DB交互当然发生在单独的线程上。但我对Android生命周期的理解是,在许多情况下,之所以调用onSaveInstanceState是因为Android系统想要终止该进程。这意味着,在DB线程完成保存文档之前,我不能允许此方法返回(事实上,在我当前的设计中,在将文档保存到DB之前,我实际上不知道文档的id号,所以我甚至不能将其放在保存状态包中)

在这些情况下,阻止等待持久化任务完成的UI线程是否合适?当由于进程被终止而调用
onSaveInstanceState
时,应用程序在前台不再可见,因此没有界面变得无响应

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

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


所有这一切也适用于
onPause
,因为不一定要调用
onSaveInstanceState

您应该尝试AsyncTask,它将阻止您的ui,但不会显示空白屏幕,将加载必要的xml元素,然后从Async task获得调用,在Async task中将您的文档保存到数据库中


遵循此链接:

您不必在
onSaveInstanceState
中进行持久保存,您几乎可以将实例状态保存在
捆绑包中
,以便在
onRestoreInstanceState
中快速恢复实例

文档中指出,您应该将关键的持久性数据(如用户编辑)写入到
onPause
中的存储器中,但也指出它应该是快速的,以便下一个活动可以开始做它想做的任何事情

我认为我的建议是只将文档文本和捆绑包中的任何内容保存在
onSaveInstanceState
中,然后在
onRestoreInstanceState
中还原它。使用
onPause
将“备份副本”快速保存到某个位置(可能是临时文件?),如果尚未保存到数据库,则可以在
onResume
中还原该副本。并使用
onStop
(当活动已在后台时调用)将数据实际保存到数据库中

请注意,在调用了
onPause
之后,该活动可能会被终止(以前从未发生过,除非系统剩下的资源非常少……),这就是为什么我会在尝试将其提交到数据库之前保存一个快速备份的原因

编辑-基于评论的额外内容


为了确保执行保存过程的后台线程在系统杀死应用程序之前完成了保存,我认为在从
onPause
返回之前阻塞并等待保存线程完成是可以的,但我建议使用
android:configChanges=“orientation”
来防止活动重新启动(和
onPause
call)当方向改变时。

我认为
AsyncTask
的要点是它不会阻塞UI线程?这不是使用它进行长期操作的全部意义吗?如果您在更改配置方面遇到问题,那么不要担心,只需将配置更改写在这个活动标记的mainfest文件中,这样就永远不会发生方向更改时调用onSaveInstanceState()。它不会强制活动重新启动。这很方便(但有它自己的问题),但这与问题完全无关,即如果保存是由后台线程完成的,我如何确保应用程序被终止时实际保存的持久数据。实际上,我会在写入数据库后立即将所有内容提交到数据库。我不会在
onSaveInstanceState
中执行此操作。问题在于上次触发的保存操作调用
onSaveInstanceState
时可能仍在进行中。我需要知道如何等待告诉Android系统“现在可以杀了我”直到永久性数据真正安全。如果系统资源太少,以至于任意终止了我的进程,丢失未持久化的编辑是可以的,但我不希望进程在正常操作条件下在DB操作的中途终止。在这种情况下,您可以使用安卓:conf跳过
onSaveInstanceState
按照mak_just4anythi的建议,在清单文件中igChanges=“orientation”