У меня есть курсор, возвращенный при обратном вызове onLoadFinished
(из LoaderManager.LoaderCallbacks
), и я хочу выполнить некоторую (возможно, дорогостоящую) постобработку этого курсора. Итак, я запускаю AsyncTask
, который использует этот курсор. Однако я получаю периодические сбои с этим исключением:
android.database.StaleDataException: Attempted to access a cursor after it has been closed.
Я подозреваю, что это происходит потому, что курсор (управляемый загрузчиком в потоке пользовательского интерфейса) закрывается до того, как фоновый поток завершит работу с ним, поскольку это управляемый курсор. Вот некоторый перефразированный код:
private class LoaderListener implements LoaderManager.LoaderCallbacks<Cursor> {
@Override
public void onCreateLoader(int d, Bundle args) {
return new CursorLoader(context, uri, projection, selection, selectionArgs, sortOrder);
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
processCursor(cursor)
}
}
private void processCursor(final Cursor cursor) {
new AsyncTask<Void, Void, Result> {
@Override
Result doInBackground(Void... params) {
while(cursor.isAfterLast() == false) {
// doing some costly things with cursor
}
}
}.execute();
}
Возможно ли,
Как-нибудь пометьте курсор, чтобы предотвратить его закрытие из потока пользовательского интерфейса.
Сообщите менеджеру, что курсор все еще используется.
Клонируйте его, чтобы клонированный экземпляр не был закрыт менеджером.
Другое, еще лучшее решение?
Однако выполнение этой постобработки в потоке пользовательского интерфейса абсолютно не вариант, поскольку это может быть очень дорогостоящим.
CursorLoader
и сделать начальный запрос + дорогостоящую обработку вAsyncTask
. - person user   schedule 09.06.2012