2011-09-19 56 views
8

我正在处理我的第一个Android应用程序。它有一个随着用户更新而持久保存到数据库的模型。onSaveInstanceState/onPause - 等到状态完全保存后才允许进程被终止

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

现在,线程在Android上的#1规则是“不要屏蔽UI线程”,所以当然数据库交互发生在一个单独的线程上。但是我对Android生命周期的理解是,在很多情况下onSaveInstanceState被调用,因为Android系统想要终止进程。这表明我不能让这个方法返回,直到数据库线程完成保存文档为止(事实上,使用我目前的设计,实际上我并不知道文档的ID号是什么,直到它被保存到数据库中,所以我甚至不能把它放在保存好的状态中)。

在这些情况下阻止UI线程等待持久任务是否合适?当调用onSaveInstanceState是因为进程被终止时,该应用程序在前台不再可见,所以没有界面变得无法响应。

但是,当Activity实例被配置更新抛弃时,也会调用onSaveInstanceState,这会在屏幕方向更改时发生。这是非常不幸的,当侧向旋转屏幕无法做任何事情几秒钟。在这种情况下,进程(因此内存空间)仍然存在,所以如果我可以只在Bundle中存储引用而不是其ID,那么我并不严格需要确保文档到达数据库。但我不知道有什么方法可以说明这两种情况之间的区别。

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

所有这些也适用于,因为onSaveInstanceState不一定会被调用。

回答

0

你应该试试AsyncTask,它会阻止你的用户界面,但不会显示空白屏幕,将加载必要的XML元素,然后将异步任务调用异步任务保存您的文档在数据库中。

请点击此链接:AyncTask Exmaple

+0

我认为'AsyncTask'的重点是它*不会阻塞UI线程?难道不是使用它来做长期作业的重点吗? – Ben

+0

如果您在配置更改时遇到问题,请不要担心,只需在此活动标记中的mainfest文件中记下configChanges,以便在方向更改时从不调用onSaveInstanceState()。它不会强制重新启动 –

+0

这很方便(但有其自身的问题),但与问题完全无关,这是如何确保在应用程序被终止时实际保存的持久数据(如果保存是由背景完成的)线。 – Ben

2

你不必做永久保存在onSaveInstanceState,就可以非常简单,只是保存实例状态在Bundle,以便实例可以迅速恢复onRestoreInstanceState

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

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

请注意,在调用之后(以前从未这么做,除非系统只剩下非常少的资源...),否则活动可能会中断,这就是为什么在尝试将其提交到数据库之前保存快速备份的原因。

编辑 - 额外的基于评论

要确保在做保存过程完成之前保存应用程序可以被系统杀死后台线程,我认为它的罚款,以阻止和等待为了在从返回之前完成保存线程,但我建议使用android:configChanges="orientation"来防止在方向更改时重新启动活动(和调用)。

+0

我实际上一旦写入数据库就将所有数据提交给数据库。我不会在'onSaveInstanceState'中执行。麻烦的是,当调用'onSaveInstanceState'时,最后触发的保存操作*可能仍在进行中。我需要知道如何等待告诉Android系统“现在可以杀了我”,直到持久数据实际上是安全的。如果系统的资源如此之低以至于无论如何都会随意杀死我的进程,那么可以丢失未经过编辑的编辑,但我不希望在正常操作条件下通过数据库操作中途中止进程。 – Ben

+0

在这种情况下,您可以按照mak_just4anything的建议,通过在清单文件中使用android:configChanges =“orientation”来跳过'onSaveInstanceState'。只要确保保存在'onPause' /'onStop'中完成。更多信息在这里:http://developer.android.com/guide/topics/resources/runtime-changes.html#HandlingTheChange – Zharf

+0

我显然没有让我的问题理解。可以说我的'onPause'调用了'tellBackgroundThreadToSaveStateToDb'。好。完成。现在,当Android想要杀死我的进程时,如何确保后台线程不处理该请求? – Ben