-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
SQLiteDatabaseLockedException при выходе из экрана "Добавить рекомендованные" в процессе добавления #36
Comments
Еще один эксепшен, возможно, по этой же теме. Начал добавлять на эмуляторе плейлист первого канала, закрыл экран дозавершения, через некоторое время вылетел на главном экране (через довольно продолжительно время, поэтому, возможно, дело не в фоновом добавлении, а в чем-то другом).
updt: тут же явно видно, что это WatchVideoActivity, в текущей версии это вот эта строка: private void playVideoItem(final VideoItem videoItem, final boolean resetCurrPos) {
[...]
// теперь то, что в фоне
videoLoadingExecutor.execute(new Runnable() {
@Override
public void run() {
// посчитать просмотр (для ролика, загруженного из базы)
if (videoItem.getId() != -1) {
videodb.videoItemDao().countView(videoItem.getId());
}
loadVideoItem(videoItem);
}
});
[...]
}
это пойдет в отдельный тикет: #38 |
Пока добавлю сюда, а там видно будет. Cейчас при добавлении панели обновления всех плейлистов на эмуляторе могу поймать ошибку "SQLite busy" (не с вылетом приложения, а на самом экране) - это если в процессе добавления нажму вырубить инет, а потом, дождавшись экран ошибки по таймату, нажму "Продолжить". Ошибка приходит из СontentLoader.addPlaylistNewItems и ловится внутри. Возможно, сдесь дело тоже в том, как создается и как освобождается объект подключения к б/д. В рамках этого тикета можно попробовать замутить глобальный рефактор на эту тему во всех местах, где идут фоновые обращения к б/д. |
еще раз поймал в эмуляторе (поставил добавляться рекомендованные, вышел из экрана, ждал до эксепшена довольно долго):
|
или, к пример, завершать длинный цикл добавления сразу после onDestroy (нужно проверить, что вызывается раньше - onDestroy или завершается фоновый поток) |
еще похожий тикет, но ситуация другая: #33 |
История такая:
вот, например:
здесь причина эксепшена - вызов WatchVideoActivity videodb.videoItemDao().countView(videoItem.getId()); который, как видно, ведет в сгенерированный румовский файл: __db.beginTransaction(); Предварительный выход - прибивать фоновый поток как можно раньше после выхода из активного экрана. Например, проверять, открыт ли текущий экран перед добавлением каждого нового плейлиста. Однако, это минимизирует ошибку, но не даст гарантии того, что она не произойдет вообще - например, если выйти из экрана добавления в момент добавление большого плейлиста - в таком случае будет достаточно времени переключиться на экран с плеером. Еще большая минимизация проблемы - прирывать транзакцию внутри ContentLoader при сигнале закрытия экрана. Как минимум, можно перестать выкачивать новые страницы. |
гарантированный способ получить эксепшен - дождаться начала добавление большого плейлиста (например, Гостелерадио), выйти из экрана добавления рекомендованных и пойти в плеер. |
Аналогичные проблемы будут на экранах:
|
А при выходе из добавления ноывых элементов для всех плейлистов вот такой эксепшен:
на: int addedCount = ContentLoader.getInstance().addPlaylistNewItems(
ConfigurePlaylistsNewItemsFragment.this.getContext(),
plInfo.getId(), plInfo.getUrl(), taskController); final VideoDatabase videodb = VideoDatabase.getDb(context); похоже, что здесь как раз битый контекст из фрагмента после onDestroy |
Прерывание фоновой задачи проверкой флага происходит в нескольких местах - в начале каждого цикла (там, где есть последовательность плейлистов) до и после длительных сетевых операций по выкачиванию контента внутри транзакции добавления/обновления плейлиста. Патч не устраняет возможность эксепшена полностью: есть вероятность успеть закрыть экран добавления в момент этой самой операции (между двумя проверками taskControlller.isCanceled*() и обратиться к базе (например, с главного экрана). Но довольно хорошо минимизирует вероятность возникновения такой ситаци. Полностью исключить такую возможность довольно проблематично. С учетом того, что фоновая операция остается жить уже после того, как пользователь закрыл активити, на которой она была вызвана, и перешел на другую активити, если операция - относительно длительная транзакция, получается что вообще любая операция обращения к б/д в любой активи потенциально может закончиться ошибкой "db is locked". Чтобы решать проблему строго, нужно или обертывать дополнительно вообще любые обращения к бд в try/catch (и быть готовым к тому, что она может закончиться неудачно) или как-то дожидаться завершения фоновых потоков из другой активити (при этом блокировать интерфейс и не обращаться вообще к базе?) стейт-машина, учитывающая состояния из другой закрытой активити - пипец). Или выстраивать какую-то межэкранную очередь запросов к б/д (тоже пипец, плюс непредсказуемое время выполнения некоторых запросов). В общем, пока ничего такого делать не хочется, с этим патчем основных вылетов больше нет, поймать другие довольно сложно - будут пойманы, будет реопен или новый тикет. |
Начал добавлять рекомендованные, не дожидаясь окончания, нажал назад. Поймал пару раз..
The text was updated successfully, but these errors were encountered: