17

我最近更新了我的一个(开源)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
4

4 回答 4

4

检查您的数据库内容,特别是“android_metadata”。这是一个带有这个 DDL 的表:

CREATE TABLE android_metadata ( 
    locale TEXT 
);

其中应包含至少一条具有以下内容的记录:

en_US

这解决了我自己的问题。

有关更多详细信息:使用SQLiteStudio
等 SQLite 编辑器打开您的数据库文件,然后打开android_metadata表(如果它不存在,请创建它。(您可以使用查询编辑器创建它(工具>打开查询编辑器)并复制/粘贴 DDL上面的代码)

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

insert into android_metadata values ('en_us');

提示:要在 SQLiteStudio 中运行查询,您应该按下工具栏中带有闪电图标的按钮。

于 2014-09-27T08:09:37.477 回答
2

关键是android.database.sqlite.SQLiteDatabaseLockedException

我遇到了同样的问题,并且随着数据库锁定的增加而不断增加。

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

如何?- 确保没有并发的写调用发生,并且

您可以阅读更多关于避免数据库锁定的信息,以及在这个很好解释的SO 答案中。

我建议将所有写调用转移到一个线程上,这样可以避免锁定。您可以为此使用AsyncQueryHandler

于 2017-03-09T05:59:31.497 回答
1

这并不能完全回答这个问题,但您可能还想查看这篇文章,看看是否可以将它用于您的DbHelperSingleton,因为它似乎与您面临的错误相同:

无法将 db '/data/data/my.easymedi.controller/databases/EasyMediInfo.db' 的区域设置更改为 'en_US'

于 2013-11-28T03:08:41.323 回答
1

如果您要更改应用程序中的区域设置,请确保在打开数据库之前更改它。

当我在打开数据库后切换区域设置时,我的应用程序中遇到了同样的问题,并且它试图根据不存在的区域设置切换到不同的数据库。

于 2017-03-09T06:03:41.210 回答