Подтвердить что ты не робот

Android SQLiteException: не удалось изменить локаль для db в 'en_US'

Недавно я обновил одно из моих приложений с открытым исходным кодом, и мои пользователи получают исключение, которое я не могу воспроизвести. Ключевыми частями являются:

android.database.sqlite.SQLiteDatabaseLockedException: database is locked (code 5)

а затем

Caused by: android.database.sqlite.SQLiteException: Failed to change locale for db '/data/data/com.airlocksoftware.hackernews/databases/hacker_news_cache.db' to 'en_US'.

Это происходит на устройствах с Android 2.3 - 4.2.1 и в нескольких местах в приложении, где я пытаюсь подключиться к базе данных. Я закрываю базу данных после ее использования.

Я не могу найти много информации об исключении "не удалось изменить locale for db". Когда я смотрю на источник для SQLiteConnection (строка 386), это кажется проблемой с таблицей "android_metadata" или "обновлением индексов с использованием новой локали".

Вот код, вызывающий исключение (в Github).

java.lang.RuntimeException: An error occured while executing doInBackground()
at android.support.v4.content.ModernAsyncTask$3.done(ModernAsyncTask.java:137)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
at java.util.concurrent.FutureTask.run(FutureTask.java:239)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
at java.lang.Thread.run(Thread.java:856) Caused by: android.database.sqlite.SQLiteException: Failed to change locale for db '/data/data/com.airlocksoftware.hackernews/databases/hacker_news_cache.db' to 'en_US'.
at android.database.sqlite.SQLiteConnection.setLocaleFromConfiguration(SQLiteConnection.java:386)
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:218)
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:193)
at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:463)
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:185)
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:177)
at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:804)
at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:789)
at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:694)
at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:854)
at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:229)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:224)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:164)
at com.airlocksoftware.database.DbInterface.(DbInterface.java:28)
at com.airlocksoftware.hackernews.loader.StoryLoader.loadStories(StoryLoader.java:62)
at com.airlocksoftware.hackernews.loader.StoryLoader.loadInBackground(StoryLoader.java:54)
at com.airlocksoftware.hackernews.loader.StoryLoader.loadInBackground(StoryLoader.java:1)
at android.support.v4.content.AsyncTaskLoader.onLoadInBackground(AsyncTaskLoader.java:240)
at android.support.v4.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:51)
at android.support.v4.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:40)
at android.support.v4.content.ModernAsyncTask$2.call(ModernAsyncTask.java:123)
at java.util.concurrent.FutureTask.run(FutureTask.java:234)
... 3 more Caused by: android.database.sqlite.SQLiteDatabaseLockedException: database is locked (code 5)
at android.database.sqlite.SQLiteConnection.nativeExecute(Native Method)
at android.database.sqlite.SQLiteConnection.execute(SQLiteConnection.java:548)
at android.database.sqlite.SQLiteConnection.setLocaleFromConfiguration(SQLiteConnection.java:364)
... 24 more
4b9b3361

Ответ 1

проверьте содержимое своей базы данных, особенно 'android_metadata'. это таблица с этим DDL:

CREATE TABLE android_metadata ( 
    locale TEXT 
);

который должен содержать по крайней мере одну запись с этим контентом:

en_US

это решило мою собственную проблему.

для более подробной информации:
откройте файл базы данных с помощью редактора sqlite, такого как SQLiteStudio, затем откройте таблицу android_metadata​​strong > (если она не существует создайте его (вы можете создать его с помощью редактора запросов (инструменты > открыть редактор запросов) и скопировать/вставить код DDL выше)

для вставки записи вы можете скопировать/вставить эту строку в редакторе запросов:

insert into android_metadata values ('en_us');
Подсказка

: чтобы запустить запрос в SQLiteStudio, вы должны нажать кнопку с иконкой lightening на панели инструментов.

Ответ 2

Это не полностью отвечает на вопрос, но вы также можете проверить эту статью и посмотреть, можете ли вы поработать над этим в своем DbHelperSingleton, так как это похоже на ту же ошибку, с которой вы сталкиваетесь:

Не удалось изменить локаль для db '/data/data/my.easymedi.controller/databases/EasyMediInfo.db' в 'en_US'

Ответ 3

Ключ android.database.sqlite.SQLiteDatabaseLockedException.

У меня была такая же проблема, и она продолжала расти с увеличением блокировки базы данных.

Что делать? - ликвидировать блокировку базы данных.

Как?. Убедитесь, что не происходит одновременных вызовов записи, и

Вы можете больше узнать об избежании блокировки базы данных здесь и в этом очень хорошо объясненном SO-ответе.

Я бы предложил переместить все ваши вызовы на запись в одном потоке, таким образом избегая блокировки. Вы можете использовать AsyncQueryHandler для этого.

Ответ 4

Если вы меняете свой язык в приложении, убедитесь, что вы его изменили, прежде чем открывать свою базу данных.

У меня была эта же проблема в моем приложении, когда я переключал язык после открытия моей базы данных и пытался переключиться на другую базу данных на основе локали, которой не было.