我的应用程序在onPause()
期间将当前图像数据保存到文件,以便在会话期间保持它。
但是,我注意到如果我在应用程序位于前台时关闭设备,应用程序会暂停并重新连续多次重启,最后在onPause()
写入文件的过程中被终止。
在onPause()
中,我通过使用GLSurfaceView
调用gLSurfaceView.queueEvent()
然后调用FutureTask
来询问并等待futureTask.get()
的呈现器线程中的图像数据}。然后,在我获得数据后,我调用gLSurfaceView.onPause()
然后将数据写入外部存储器上的文件。之后我拨打super.onPause()
。
但是,在写入外部存储时看起来onPause()
被中断,因此当下次重新启动应用时,它会在尝试读取已保存的数据时报告java.io.EOFException
。
我记录了关闭设备时发生的情况。这是跟踪:
05-17 16:03:47.405: V/App(4633): onPause called
05-17 16:03:47.405: V/App(4633): Get data from render thread.
05-17 16:03:47.670: V/App(4633): Got data from render thread.
05-17 16:03:47.855: V/App(4633): Save image start
05-17 16:03:48.265: V/App(4633): Image saved!
05-17 16:03:48.265: V/App(4633): super.onPause()
05-17 16:03:48.270: V/App(4633): onPause finished
05-17 16:03:48.270: V/App(4633): onSaveInstanceState()
05-17 16:03:48.315: V/App(4633): onCreate()
05-17 16:03:48.345: V/App(4633): restoreState() with bundle
05-17 16:03:48.345: V/App(4633): Start read image.
05-17 16:03:49.055: V/App(4633): Image read
05-17 16:03:49.715: V/App(4633): onResume()
05-17 16:03:51.595: V/App(4633): onPause called
05-17 16:03:51.595: V/App(4633): Get data from render thread.
05-17 16:03:51.770: V/App(4633): Got data from render thread.
05-17 16:03:51.910: V/App(4633): Save image start
05-17 16:03:52.580: V/App(4633): Image saved!
05-17 16:03:52.580: V/App(4633): super.onPause()
05-17 16:03:52.580: V/App(4633): onPause finished
05-17 16:03:52.585: V/App(4633): onSaveInstanceState()
05-17 16:03:53.795: V/App(4633): onResume()
05-17 16:03:53.805: V/App(4633): onPause called
05-17 16:03:53.805: V/App(4633): Get data from render thread.
05-17 16:03:54.205: V/App(4633): Got data from render thread.
05-17 16:03:54.520: V/App(4633): Save image start
之后,设备关闭,或者至少停止记录。
据推测,数据在前两次正确保存,但是由于应用程序没有完成对文件的写入,它会在第3次被删除。
我正在考虑实现一个双缓冲解决方案,在这里我会交替写入数据的缓冲区,并在成功写入后保存对哪个缓冲区包含最新数据的引用。但我认为必须有一种更简单的方法。
有关如何避免/解决此问题的建议吗?
注意:由于整个onPause()接近1秒,我也尝试在后台线程中执行序列[从GLSurfaceView读取,暂停GLSurfaceView并保存到文件],但是我也进入了onCreate的情况( )当后台线程仍在写入时尝试读取图像数据,这显然也会导致错误。
答案 0 :(得分:0)
在onPause()调用期间,您是否正好在UI线程中保存图像?如果是,您应该将图像保存部分移动到AsyncTask
并提供某种布尔标记或互斥锁,以防止在上一个图像仍然被保存或已经保存时启动类似的AsyncTasks。
小心使用上下文和内部类数据,以防AsyncTask
比其他类更长,并确保它不会触及任何不属于它的任何类。