У меня есть курсор, возвращаемый обратным вызовом 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();
}
Возможно ли,
Как-то пометить курсор, чтобы предотвратить его закрытие из потока пользовательского интерфейса.
Уведомить менеджера о том, что курсор все еще используется.
Клонируйте его, чтобы клонированный экземпляр не был закрыт менеджером.
Другое, еще лучшее решение?
Однако выполнение этой постобработки в потоке пользовательского интерфейса абсолютно не вариант, так как это может быть очень дорогостоящим.