首先,我调查了 SO 上的其他 StaleDataExceptions,但没有一个真正回答,或者引导我找到解决当前应用程序设计问题的方法。
我正在创建一个音乐播放器应用程序,我最初设计它是为了从内容提供程序中检索信息来查询它MediaStore.Audio
-CursorLoader
这工作正常,但显然如果你有一个大的音乐库,那么可能需要一个非常理想的等待时间来获取所有内容每次加载应用程序时返回的信息。我的第二种方法是在应用程序首次启动时启动远程Service
,它查询MediaStore.Audio
使用 aCursorLoader
并注册任何更新。当Cusror
返回时,我然后运行AsyncTask
将信息处理到自定义 POJO 类的 ArrayList 中,该类实现Parcelable Interface
然后通过Intent
返回音乐应用程序中的处理程序。此解决方案运行良好,因为如果应用程序已关闭并重新打开,它只需查询Service
最新ArrayList
的 custom Objects
,而不必查询MediaStore.Audio
-Service
实现LoaderCallback<Cursor>
并始终更新ArrayList
customObjects
并在打开时通知应用程序,如果没有它有当应用程序重新打开时,它们已准备好。
正确 - 解决问题(好吧,花了一些时间,但有必要的背景信息)。问题是:如果我在另一个媒体应用程序中并开始快速连续删除音乐文件,则Listener
在我的服务中注册的服务将被回调并提供新的光标,但是AsyncTask
我用来迭代现有光标的Race Condition
位置是被另一个Thread
/CursorLoader
随着更新而关闭Cursor
- 抛出异常:android.database.StaleDataException: Attempted to access a cursor after it has been closed.
我正在使用的当前解决方法是setUpdateThrottle
在注册侦听器时使用 20 秒,这有效,但是意味着将更新的信息返回给服务会有延迟。
有没有可行的解决方案或方法可以避免这个问题?
提前致谢。
更新
一个可行的解决方案实际上很容易实现 - 但它最初的问题确实说明了我缺乏使用装载机的经验,但是我已经获得了一些关于寻找解决方案的知识。
解决方案:
我还在用遥控器Service
。但是,当我仍在回调中处理它时,我没有使用CursorLoader
- 来关闭它,而是使用. 与a 耦合仍然可以监视来自 a 的底层数据更改,但不像 a 那样直接与对象耦合。我能够监视数据更改并告知它需要重新加载数据(新任务。cursor
onLoadComplete()
AsyncTaskLoader
AsyncTaskLoader
ContentObserver
Uri
Cursor
CursorLoader
AsyncTaskLoader
forceLoad()