Den*_*989 4 android listview list filter android-cursorloader
在我们的项目中,我们经常处理列表,并在过去使用它并使用以下“模式”:
ListView 位于 Fragment 中,在 onActivityCreated 中初始化,我们首先启动 CursorLoaders,然后在 onFinish 中将 Cusor 交换到 ListAdapter。然后,我们使用 filterQueryProvider 实现了搜索功能,该功能仅通过 contentResolver.query(...) 返回游标。如果我在选择列表中的某些内容时进行了一些方向更改,则在许多情况下(不定期)会出现以下错误:
android.database.StaleDataException: Attempted to access a cursor after it has been closed.
12-05 10:36:59.531: E/ACRA(12079): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1967)
12-05 10:36:59.531: E/ACRA(12079): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1992)
12-05 10:36:59.531: E/ACRA(12079): at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3378)
12-05 10:36:59.531: E/ACRA(12079): at android.app.ActivityThread.access$700(ActivityThread.java:127)
12-05 10:36:59.531: E/ACRA(12079): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1162)
12-05 10:36:59.531: E/ACRA(12079): at android.os.Handler.dispatchMessage(Handler.java:99)
12-05 10:36:59.531: E/ACRA(12079): at android.os.Looper.loop(Looper.java:137)
12-05 10:36:59.531: E/ACRA(12079): at android.app.ActivityThread.main(ActivityThread.java:4448)
12-05 10:36:59.531: E/ACRA(12079): at java.lang.reflect.Method.invokeNative(Native Method)
12-05 10:36:59.531: E/ACRA(12079): at java.lang.reflect.Method.invoke(Method.java:511)
12-05 10:36:59.531: E/ACRA(12079): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:823)
12-05 10:36:59.531: E/ACRA(12079): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:590)
12-05 10:36:59.531: E/ACRA(12079): at dalvik.system.NativeStart.main(Native Method)
12-05 10:36:59.531: E/ACRA(12079): Caused by: android.database.StaleDataException: Attempted to access a cursor after it has been closed.
12-05 10:36:59.531: E/ACRA(12079): at android.database.BulkCursorToCursorAdaptor.throwIfCursorIsClosed(BulkCursorToCursorAdaptor.java:75)
12-05 10:36:59.531: E/ACRA(12079): at android.database.BulkCursorToCursorAdaptor.getColumnNames(BulkCursorToCursorAdaptor.java:170)
12-05 10:36:59.531: E/ACRA(12079): at android.database.AbstractCursor.getColumnIndex(AbstractCursor.java:248)
12-05 10:36:59.531: E/ACRA(12079): at android.database.AbstractCursor.getColumnIndexOrThrow(AbstractCursor.java:266)
12-05 10:36:59.531: E/ACRA(12079): at android.database.CursorWrapper.getColumnIndexOrThrow(CursorWrapper.java:78)
12-05 10:36:59.531: E/ACRA(12079): at android.support.v4.widget.CursorAdapter.swapCursor(CursorAdapter.java:344)
12-05 10:36:59.531: E/ACRA(12079): at
Run Code Online (Sandbox Code Playgroud)
这是在方向更改后在 onLoadFinished 中使用 swapCursor 时的情况。
我现在使用带有参数的 restartLoader 和使用带有附加路径(即约束)的 Contacts.CONTENT_FILTER_URI 重新实现了过滤器功能,然后在 onLoadFinished 中交换此游标,因此我删除了 filterQueryProvider,它看起来工作正常。
问题是:是否有可能(或好的实践)最初使用 CursorLoader 和 filterQueryProvider?或者我必须决定?因为当我仅使用 filterQueryProvider 并使用约束 null 进行过滤时,我会得到相同的结果,它只会加载我所需的联系人列表,然后进行过滤。
有什么建议吗?我没有通过谷歌找到这方面的 mathinc 信息;)
顺便说一句,这是我当前的 LoaderCallbacks 实现:
private LoaderManager.LoaderCallbacks<Cursor> phoneBookContactsLoaderCallback = new LoaderManager.LoaderCallbacks<Cursor>() {
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
// if(constraint != null && constraint.length() > 0) {
// selection = Contacts.DISPLAY_NAME + " LIKE ?";
// selectionArgs = new String [] {"%" + constraint + "%"};
// }
numLoaderManagersRunning++;
String constraint = null;
if(args != null){
constraint = args.getString(CONSTRAINT);
}
Uri uri = null;
if(constraint!= null && !constraint.isEmpty()){
uri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, constraint);
} else {
uri = Contacts.CONTENT_URI;
}
return new CursorLoader(getActivity(), uri , PROJECTION_PHONEBOOK_CONTACTS,
null, null, Contacts.DISPLAY_NAME + " COLLATE NOCASE ASC");
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
Logger.e(TAG, "Load finished ");
// phoneBookContactsCursorAdapter.swapCursor(new MatrixCursor(new String [] { Contacts._ID,
// Contacts.DISPLAY_NAME, Contacts.PHOTO_ID }));
phoneBookContactsCursorAdapter.swapCursor(data);
if (actualMultiFilterListener != null){
actualMultiFilterListener.onFilterComplete(data.getCount());
}
//filterList("");
numLoaderManagersRunning--;
if (numLoaderManagersRunning <= 0) {
// The list should now be shown.
if (isResumed()) {
setListShown(true);
} else {
setListShownNoAnimation(true);
}
}
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
// phoneBookContactsCursorAdapter.swapCursor(null);
Logger.e(TAG, "Load resetted ");
}
};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3468 次 |
| 最近记录: |