Проблема разработки приложения: android.database.StaleDataException
Во-первых, я исследовал другие исключения StaleDataException для SO, но ни один из них не дал ответа или не привел меня к решению моей текущей проблемы с дизайном приложения.
Я создаю приложение Music Player, которое я изначально разработал для запроса MediaStore.Audio
с CursorLoader
извлекать информацию из контент-провайдера - это прекрасно работает, однако, очевидно, если у вас большая музыкальная библиотека, может быть более желательное время ожидания для получения всей информации, когда приложение загружается каждый раз. Мой второй подход состоял в том, чтобы запустить удаленный Service
при первом запуске приложения, которое запрашивает MediaStore.Audio
используя CursorLoader
и регистрируется для любых обновлений. Когда Cusror
возвращается я тогда запустить AsyncTask
обработать информацию в ArrayList пользовательского класса POJO, который реализует Parcelable Interface
который затем получает / демаршаллируется через Intent
вернуться к обработчику в приложении Music. Это решение хорошо работает, потому что, если приложение закрыто и вновь открыто, оно просто запрашивает Service
для последних ArrayList
обычая Objects
вместо того, чтобы запрашивать MediaStore.Audio
вообще - то Service
инвентарь LoaderCallback<Cursor>
и всегда обновления ArrayList
обычая Objects
и уведомляет приложение, если оно открыто, если нет, оно готово к моменту его открытия.
Правильно - к проблеме (хорошо, потребовалось немного времени, но необходима справочная информация). Проблема: если я нахожусь в другом мультимедийном приложении и начинаю быстро удалять музыкальные файлы, зарегистрированные Listener
в моем сервисе вызывается обратный вызов и доставляется новый курсор, однако AsyncTask
Я использую, чтобы перебрать существующий курсор имеет Race Condition
где он закрыт другим Thread
/ CursorLoader
как Cursor
обновлено - исключение выдано: android.database.StaleDataException: Attempted to access a cursor after it has been closed.
Текущий обходной путь, который я использую, это использование setUpdateThrottle
до 20 секунд при регистрации прослушивателя, это работает, однако означает, что имеется задержка в получении обновленной информации обратно в Сервис.
Есть ли какое-либо жизнеспособное решение или подход, где я могу избежать этой проблемы?
Заранее спасибо.
ОБНОВИТЬ
Работающее жизнеспособное решение, на самом деле, было довольно легко достичь - эта первоначальная проблема, тем не менее, иллюстрирует мой недостаток опыта работы с Loaders, однако я получил некоторые знания о том, как найти решение.
Решение:
Я все еще пользуюсь пультом Service
, Однако вместо использования CursorLoader
- который закрывал cursor
пока я все еще обрабатывал его в onLoadComplete()
обратный звонок, я использую AsyncTaskLoader
, AsyncTaskLoader
в сочетании с ContentObserver
все еще может отслеживать изменения базовых данных из Uri
но не напрямую связан с Cursor
объект как CursorLoader
, Я могу отслеживать изменения данных и позволить AsyncTaskLoader
знаю, что нужно перезагрузить данные (forceLoad()
), однако это ставится в очередь и не влияет на обработку метода loadInBackground() - как только он возвращается, он просто отменяет задачу и запускает новую задачу.