首先,我在SO上调查了其他StaleDataExceptions,但没有人真正回答,或者引导我解决当前的App设计问题。
我正在创建一个音乐播放器应用,我最初设计用MediaStore.Audio
查询CursorLoader
以从内容提供商处检索信息 - 这很好用,但是很明显,如果你有一个大的音乐库可能有一个超过理想的等待时间,每当应用程序加载时获取所有信息。我的第二种方法是在应用程序首次启动时启动远程Service
,使用MediaStore.Audio
查询CursorLoader
并注册任何更新。当返回Cusror
时,我运行AsyncTask
将信息处理到Custom POJO类的ArrayList中,该类实现Parcelable Interface
,然后通过Intent
进行编组/解组。回到音乐应用程序中的处理程序。此解决方案效果很好,因为如果应用已关闭,并且重新打开,则只需查询Service
以查找最新的ArrayList
自定义Objects
,而无需在MediaStore.Audio
处查询Service
全部 - LoaderCallback<Cursor>
实施ArrayList
并始终更新自定义Objects
Listener
并通知应用程序是否已打开,如果没有,则会在应用重新打开时为其准备好。< / p>
正确 - 问题(确定花了一点时间,但必要的背景信息)。问题是:如果我在另一个媒体应用程序中并开始快速连续删除音乐文件,我的服务中已注册的AsyncTask
将被回调,并且会传递新的游标,但Race Condition
我是用于迭代现有游标的Thread
随着CursorLoader
的更新而被另一个Cursor
/ android.database.StaleDataException: Attempted to access a cursor after it has been closed.
关闭 - 抛出异常:setUpdateThrottle
< / p>
我正在使用的当前解决方法是在注册监听器时使用Service
到20秒,这是有效的,但这意味着将更新信息返回给服务会有延迟。
有没有可行的解决方案或方法可以避免这个问题?
提前致谢。
更新
一个可行的解决方案实际上很容易实现 - 但最初的问题确实说明了我缺乏装载机的经验,但是我已经获得了一些寻找解决方案的知识。
解决方案:
我仍在使用远程CursorLoader
。但是,我在cursor
回调中处理它时,而不是使用onLoadComplete()
- 正在关闭AsyncTaskLoader
,我正在使用AsyncTaskLoader
。与ContentObserver
结合的Uri
仍然可以监控来自Cursor
的基础数据更改,但不会像CursorLoader
那样直接与AsyncTaskLoader
对象相关联。我能够监视数据更改并让forceLoad()
知道它需要重新加载数据(x1 <- (africanaDamRate$BB6-africanaDamRate$BB0)/29
x2 <- (africanaDamRate$BB6-africanaDamRate$BB0)/22
x3 <- (africanaDamRate$BB6-africanaDamRate$BB0)/34
x4 <- (africanaDamRate$BB6-africanaDamRate$BB0)/30
F1 <- function(y){
if(africanaDamRate$Site0==1){africanaDamRate$BBDR<-x1}
if(africanaDamRate$Site0==2){africanaDamRate$BBDR<-x2}
if(africanaDamRate$Site0==3){africanaDamRate$BBDR<-x3}
if(africanaDamRate$Site0==4){africanaDamRate$BBDR<-x4}
}
africanaDamRate$BBDR<-F1(y)
),但这是排队的,并且不会影响loadInBackground()方法的处理 - 一旦返回,它只是取消任务并启动新任务。