2013-01-09 53 views
3

我正在使用LoaderManager从我的手机加载联系人列表光标。与LoaderManager竞争条件?

我从字面上只使用示例代码在这里给出:

http://developer.android.com/reference/android/app/LoaderManager.html

我唯一的变化是,而不是以此作为主屏幕列表视图适配器,我用它作为适用于AutoCompleteTextView的适配器。我的问题是,当我迅速更改文本,通过输入愤怒,或按住删除按钮连续删除一切,它会导致这个错误:

01-09 02:36:47.248: E/AndroidRuntime(24231): FATAL EXCEPTION: main 
01-09 02:36:47.248: E/AndroidRuntime(24231): android.database.StaleDataException: Attempted to access a cursor after it has been closed. 
01-09 02:36:47.248: E/AndroidRuntime(24231): at android.database.BulkCursorToCursorAdaptor.throwIfCursorIsClosed(BulkCursorToCursorAdaptor.java:64) 
01-09 02:36:47.248: E/AndroidRuntime(24231): at android.database.BulkCursorToCursorAdaptor.getColumnNames(BulkCursorToCursorAdaptor.java:159) 
01-09 02:36:47.248: E/AndroidRuntime(24231): at android.database.AbstractCursor.getColumnIndex(AbstractCursor.java:283) 
01-09 02:36:47.248: E/AndroidRuntime(24231): at android.database.AbstractCursor.getColumnIndexOrThrow(AbstractCursor.java:308) 
01-09 02:36:47.248: E/AndroidRuntime(24231): at android.database.CursorWrapper.getColumnIndexOrThrow(CursorWrapper.java:78) 
01-09 02:36:47.248: E/AndroidRuntime(24231): at android.widget.CursorAdapter.swapCursor(CursorAdapter.java:338) 
01-09 02:36:47.248: E/AndroidRuntime(24231): at android.widget.CursorAdapter.changeCursor(CursorAdapter.java:309) 
01-09 02:36:47.248: E/AndroidRuntime(24231): at android.widget.CursorFilter.publishResults(CursorFilter.java:67) 
01-09 02:36:47.248: E/AndroidRuntime(24231): at android.widget.Filter$ResultsHandler.handleMessage(Filter.java:282) 
01-09 02:36:47.248: E/AndroidRuntime(24231): at android.os.Handler.dispatchMessage(Handler.java:99) 
01-09 02:36:47.248: E/AndroidRuntime(24231): at android.os.Looper.loop(Looper.java:137) 
01-09 02:36:47.248: E/AndroidRuntime(24231): at android.app.ActivityThread.main(ActivityThread.java:5070) 
01-09 02:36:47.248: E/AndroidRuntime(24231): at java.lang.reflect.Method.invokeNative(Native Method) 
01-09 02:36:47.248: E/AndroidRuntime(24231): at java.lang.reflect.Method.invoke(Method.java:511) 
01-09 02:36:47.248: E/AndroidRuntime(24231): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795) 
01-09 02:36:47.248: E/AndroidRuntime(24231): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:558) 
01-09 02:36:47.248: E/AndroidRuntime(24231): at dalvik.system.NativeStart.main(Native Method) 

回答

2

看来,一个CursorAdapter具有基实现getFilter(),它在通过runQueryOnBackgroundThread()之后返回当前游标。这对LoaderManager的原始Android开发者例子来说工作正常,因为ListViews根本不使用过滤器。但是,AutoCompleteTextViews确实使用了过滤器,所以我基本上正在运行两个尝试加载游标的异步线程,而且这些线程不是线程安全的。

由于Filter已经提供了与LoaderManager相同的异步加载功能,我只是抛弃了LoaderManager,并通过重载CursorAdapter.runQueryOnBackgroundThread()来通过Filter加载。