安卓SQLiteException:无法为DB改变区域设置为“EN_US”(Android SQLi

2019-07-19 02:22发布

我最近更新了我的(开源的)Android应用程序之一,我的用户获得的是我不能复制的例外。 关键的部分是:

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,并且在应用程序内的多个地方,我尝试连接到一个数据库。 我关闭数据库后,我使用它。

我找不到太多的信息有关“未能改变语言环境数据库”异常。 当我看着源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

Answer 1:

检查数据库的内容,特别是“android_metadata”。 它与该DDL的表:

CREATE TABLE android_metadata ( 
    locale TEXT 
);

它应该包含这个内容的至少一个记录:

en_US

这个解决我自己的问题。

更多细节:
打开数据库文件与源码编辑器如SQLiteStudio然后打开android_metadata表(如果它不存在,创建它。(你可以用查询编辑器(工具>打开查询编辑器)和复制创建/粘贴上面的DDL代码)

插入您可以复制的记录/粘贴在查询编辑这一行:

insert into android_metadata values ('en_us');

提示:运行在SQLiteStudio你应该按下按钮查询 工具栏图标。



Answer 2:

这并不完全回答这个问题,但你也可能想看看这篇文章,看看你也许可以工作到这一点你DbHelperSingleton ,因为它似乎是你都面临着同样的错误:

无法更改语言环境数据库“/data/data/my.easymedi.controller/databases/EasyMediInfo.db”到“EN_US”



Answer 3:

关键是android.database.sqlite.SQLiteDatabaseLockedException

我有同样的问题,它一直在数据库锁定的增加而增加。

该怎么办? - 消除数据库锁定。

怎么样? - 确保没有并发写入调用发生,并且

你可以阅读更多关于避免数据库锁定在这里 ,并在这个非常好解释的SO回答 。

我建议移在单个线程上所有的写调用,这样避免了锁定。 您可以使用AsyncQueryHandler这一点。



Answer 4:

如果你的应用改变你的语言环境,确保你改变它,你打开你的数据库之前。

我有同样的问题在我的应用程序,当我打开我的数据库之后切换语言环境,并试图切换到基于语言环境,并不存在不同的数据库。



文章来源: Android SQLiteException: Failed to change locale for db to 'en_US'