我正在开发我的第一个 Android 应用程序。它有一个模型,当用户进行更新时,该模型会持久保存到数据库中。
当 onSaveInsanceState 被调用时,我想保存一个 id,该 id 可用于从数据库加载用户正在处理的文档。但这只有在文档完全进入数据库后才会发生。在某些情况下,保留一个复杂的文档可能需要几秒钟(我希望一旦我完成所有冗长的注销后这会加快速度,并且在实际使用中用户将分阶段构建一个复杂的文档,每个将被持久化到数据库中,因此不太可能将一个复杂的文档一次全部保存。
现在,Android 线程的第一条规则是“不要阻塞 UI 线程”,因此数据库交互当然发生在单独的线程上。但是我对Android生命周期的理解是,在很多情况下调用onSaveInstanceState是因为Android系统要kill进程。这表明我不能允许此方法返回,直到数据库线程完成保存文档(事实上,在我当前的设计中,在将文档保存到数据库之前,我实际上并不知道文档的 ID 号是多少,所以我什至不能把它放在保存状态的包中)。
在这种情况下,阻塞等待持久化任务完成的 UI 线程是否合适?当 onSaveInstanceState 因为进程被终止而被调用时,应用程序不再在前台可见,因此没有界面变得无响应。
但是 onSaveInstanceState 也会在 Activity 实例被配置更新破坏时调用,这发生在屏幕方向改变时。非常不幸的是,当向侧面旋转屏幕几秒钟后无法执行任何操作时。在这种情况下,进程(因此内存空间)仍然存在,所以我不需要严格确保文档访问数据库,只要我可以在 Bundle 中存储对它的引用而不是它的 id。但我不知道有什么方法可以区分这两种情况。
对于这些情况是否有公认的做法?为了安全起见,我应该只阻塞线程吗?我可以只使用普通的 Java 线程原语来阻塞和等待吗?有什么我可以做的,不会阻塞线程,但确保持久任务将在 Android 关闭进程之前完成?
所有这些也适用于 onPause,因为不一定会调用 onSaveInstanceState。
最佳答案
您不必在onSaveInstanceState 中进行持久化保存,您几乎可以只将实例状态保存在Bundle 中,这样实例就可以快速在 onRestoreInstanceState 中恢复。
文档指出您应该将关键的持久数据(例如用户编辑)写入存储在 onPause 中,但它也指出它应该很快,以便下一个 Activity 可以开始做任何它它想做什么。
我认为我的建议是将文档文本和 Bundle 中的任何内容保存在 onSaveInstanceState 中,然后在 onRestoreInstanceState 中恢复它。使用 onPause 快速保存“备份副本”(也许是临时文件?),如果尚未保存到数据库,则可以在 onResume 中恢复。并使用 onStop(当 Activity 已经在后台时调用)将数据实际保存到数据库。
请注意, Activity 可能会在 onPause 被调用后被终止(以前不会,除非系统剩余的资源非常少......),这就是为什么我会在尝试之前保存一个快速备份将其提交到数据库中。
编辑 - 基于评论的额外内容
为了确保正在执行保存过程的后台线程在应用程序被系统杀死之前完成保存,我认为最好阻塞并等待保存线程完成后再返回来自 onPause,但我建议使用 android:configChanges="orientation" 来防止在方向改变时 Activity 重启(和 onPause 调用)。
关于android - onSaveInstanceState/onPause - 等到状态完全保存后再允许进程被终止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7466740/
我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0
我打算为ruby脚本创建一个安装程序,但我希望能够确保机器安装了RVM。有没有一种方法可以完全离线安装RVM并且不引人注目(通过不引人注目,就像创建一个可以做所有事情的脚本而不是要求用户向他们的bash_profile或bashrc添加一些东西)我不是要脚本本身,只是一个关于如何走这条路的快速指针(如果可能的话)。我们还研究了这个很有帮助的问题:RVM-isthereawayforsimpleofflineinstall?但有点误导,因为答案只向我们展示了如何离线在RVM中安装ruby。我们需要能够离线安装RVM本身,并查看脚本https://raw.github.com/wayn
当我的预订模型通过rake任务在状态机上转换时,我试图找出如何跳过对ActiveRecord对象的特定实例的验证。我想在reservation.close时跳过所有验证!叫做。希望调用reservation.close!(:validate=>false)之类的东西。仅供引用,我们正在使用https://github.com/pluginaweek/state_machine用于状态机。这是我的预订模型的示例。classReservation["requested","negotiating","approved"])}state_machine:initial=>'requested
我需要检查DateTime是否采用有效的ISO8601格式。喜欢:#iso8601?我检查了ruby是否有特定方法,但没有找到。目前我正在使用date.iso8601==date来检查这个。有什么好的方法吗?编辑解释我的环境,并改变问题的范围。因此,我的项目将使用jsapiFullCalendar,这就是我需要iso8601字符串格式的原因。我想知道更好或正确的方法是什么,以正确的格式将日期保存在数据库中,或者让ActiveRecord完成它们的工作并在我需要时间信息时对其进行操作。 最佳答案 我不太明白你的问题。我假设您想检查
我正在处理旧代码的一部分。beforedoallow_any_instance_of(SportRateManager).toreceive(:create).and_return(true)endRubocop错误如下:Avoidstubbingusing'allow_any_instance_of'我读到了RuboCop::RSpec:AnyInstance我试着像下面那样改变它。由此beforedoallow_any_instance_of(SportRateManager).toreceive(:create).and_return(true)end对此:let(:sport_
对于作为String#tr参数的单引号字符串文字中反斜杠的转义状态,我觉得有些神秘。你能解释一下下面三个例子之间的对比吗?我特别不明白第二个。为了避免复杂化,我在这里使用了'd',在双引号中转义时不会改变含义("\d"="d")。'\\'.tr('\\','x')#=>"x"'\\'.tr('\\d','x')#=>"\\"'\\'.tr('\\\d','x')#=>"x" 最佳答案 在tr中转义tr的第一个参数非常类似于正则表达式中的括号字符分组。您可以在表达式的开头使用^来否定匹配(替换任何不匹配的内容)并使用例如a-f来匹配一
我目前正在使用以下方法获取页面的源代码:Net::HTTP.get(URI.parse(page.url))我还想获取HTTP状态,而无需发出第二个请求。有没有办法用另一种方法做到这一点?我一直在查看文档,但似乎找不到我要找的东西。 最佳答案 在我看来,除非您需要一些真正的低级访问或控制,否则最好使用Ruby的内置Open::URI模块:require'open-uri'io=open('http://www.example.org/')#=>#body=io.read[0,50]#=>"["200","OK"]io.base_ur
最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路
我想为我的Task模型创建一个status属性,该属性将按以下顺序指示它在三部分进度中的位置:打开=>进行中=>完成。它的工作方式类似于亚马逊包裹的交付方式:已订购=>已发货=>已交付。我想知道设置此属性的最佳方法是什么。我可能是错的,但创建三个独立的bool属性似乎有点多余。实现此目标的最佳方法是什么? 最佳答案 Rails4有一个内置的enummacro.它使用单个整数列并映射到键列表。classOrderenumstatus:[:ordered,:shipped,:delivered]end状态映射如下:{ordered:0,
s=Socket.new(Socket::AF_INET,Socket::SOCK_STREAM,0)s.connect(Socket.pack_sockaddr_in('port','hostname'))ssl=OpenSSL::SSL::SSLSocket.new(s,sslcert)ssl.connect从这里开始,如果ssl连接和底层套接字仍然是ESTABLISHED,或者它是否在默认值7200之后进入CLOSE_WAIT,我想检查一个线程几秒钟甚至更糟的是在实际上不需要.write()或.read()的情况下关闭。是用select()、IO.select()还是其他方法完成