当调用onSaveInsanceState时,我想保存一个id,该id可用于从数据库加载用户正在处理的文档.但这只能在文档完全访问数据库后才会发生.在某些情况下,持久化复杂的文档可能需要几秒钟(我希望一旦我采取所有详细的注销,这将加快,并且在实际使用中,用户将分阶段构建复杂的文档,每个文档都是将被保存到数据库中,因此复杂文档不太可能一次性保存.
现在,Android上线程的#1规则是“不要阻止UI线程”,所以当然数据库交互发生在一个单独的线程上.但我对Android生命周期的理解是,在很多情况下调用onSaveInstanceState是因为Android系统想要终止进程.这表明我不能允许这个方法返回,直到数据库线程完成保存文档(实际上我的当前设计,我实际上不知道文档的ID号是什么,直到它被保存到数据库,所以我甚至不能把它放在保存状态的束中).
在这些情况下是否适合阻止UI线程等待持久化任务完成?当因为进程被杀死而调用onSaveInstanceState时,应用程序在前台不再可见,因此没有界面变得无法响应.
但是当通过配置更新来修改Activity实例时也会调用onSaveInstanceState,这会在屏幕方向更改时发生.当侧面旋转屏幕几秒钟没有做任何事情时,这是非常不幸的.在这种情况下,进程(以及因此内存空间)仍然存在,因此我不需要确保文档命中数据库,如果我只能在Bundle中存储对它的引用而不是它的id.但我不知道如何区分这两种情况.
这些情况是否有公认的做法?我应该阻止线程安全吗?我可以使用普通的Java线程原语来阻止和等待吗?有什么我可以做的不会阻止线程,但确保在Android关闭进程之前完成持久性任务?
所有这些也适用于onPause,因为onSaveInstanceState不一定会被调用.
解决方法
文档声明您应该将重要的持久性数据(例如用户编辑)写入onPause中的存储,但它还指出它应该很快,以便下一个活动可以开始执行它想做的任何事情.
我认为我的建议是在onSaveInstanceState中保存文档文本和Bundle中的任何内容,并在onRestoreInstanceState中恢复它.使用onPause快速保存“备份副本”(临时文件可能?),如果尚未保存到数据库中,则可以在onResume中恢复.并使用onStop(当活动已在后台时调用)实际将数据保存到数据库.
请注意,在调用onPause之后,活动可能会被杀死(除非系统资源非常少,否则从未…),这就是为什么我会在尝试在数据库中提交之前保存快速备份的原因.
编辑 – 额外基于评论
为了确保在应用程序被系统杀死之前保存正在执行保存过程的后台线程,我认为在从onPause返回之前阻止并等待保存线程完成是可以的,但我建议使用android:configChanges = “方向”以防止在方向更改时重新启动活动(和onPause调用).