我最近更新了我的一个(开源)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的设备上,并且在我尝试连接数据库的应用程序中的多个位置.我使用它后关闭数据库.
我找不到有关"未能更改db语言环境"异常的更多信息.当我查看SQLiteConnection的源代码(第386行)时,它似乎是'android_metadata'表或'使用新的语言环境更新索引'的问题.
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 …Run Code Online (Sandbox Code Playgroud) 在我的Android应用程序中,我使用SQLiteOpenHelper来实现ContentProvider.查询,添加,删除操作都是通过ContentProvider完成的.
但是在我的一部Android手机(htc g13)中,我在目录/ data/data/[包名] /数据库中找到了*.db-wal文件.使用ContentProvider进行操作时,文件大小会非常快.它占用用户RAM空间太多.
建议关闭SQLiteOpenHelper来解决我的问题(这很有用)在这里输入链接描述.
但我希望找到一个"地方"来添加"close()"方法,因为我没有直接使用SQLiteOpenHelper(通过ContentProvider使用).ContentProvider中的query()方法必须返回一个Cursor,而SQLiteDatabse应保持打开状态.
我很困惑,我现在做什么让*.db-wal消失并正常使用ContentProvider?
我是Android开发的新手.我正在尝试创建一个从内部数据库(SQLite)读取的应用程序,并列出列表中的所有数据(我正在使用listView).
到目前为止,我得到了一个名为DatabaseHandlerextends 的类SQLiteOpenHelper,它正在执行所有数据库操作(选择数据,插入数据,删除数据......).
但是现在我想列出这些值,我正在阅读一些我必须使用的网站,Loader而不是Cursor一个ContentProvider.到目前为止,我理解ContentProvider提供对数据库的受控访问.
我的问题是:ContentProvider做同样的事SQLiteOpenHelper吗?
此外,我正在使用API级别8,并且ContentProvider只能在API级别11上使用.解决此问题的最佳方法是什么?
提前致谢.
我正在创建一个与数据库进行大量交互的应用程序(读写操作).
为了避免在每个请求中打开/关闭操作,我创建了SQLiteOpenHelper一个使用Singleton设计模式扩展的类.这样,我确信SQLiteOpenHelper在整个应用程序生命周期(而不仅仅是活动生命周期)中,只有一个与数据库建立连接的实例.
我还阅读了一些关于ContentProvider的文章,但我不确定这是一个更好的方法.
所以,这是我的Singleton类的主要逻辑(onCreate并onUpgrade删除):
public final class BaseSQLite extends SQLiteOpenHelper {
private static BaseSQLite mInstance = null;
private SQLiteDatabase db = null;
public static BaseSQLite getInstance(Context context) {
if (mInstance == null) {
mInstance = new BaseSQLite(context.getApplicationContext(),
DBNAME, DBVERSION);
}
return mInstance;
}
private BaseSQLite(final Context context, final String name,
final int version) {
super(context, name, null, version);
db = getWritableDatabase();
}
@Override
public synchronized void close() { …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用SQLite(OpenHelper)作为数据库,使用Robolectric 3.0 + Gradle运行多个测试.运行每个单独的测试工作正常,但启动整个测试套件总是在第二次测试中导致RuntimeException.
这是我的测试假人,不起作用.
@RunWith(RobolectricGradleTestRunner.class)
@Config(constants = BuildConfig.class, sdk = 21)
public class Dummy {
@Before
public void setUp() throws Exception {
// setup activity ...
}
@Test
public void testA() throws Exception {
Assert.assertTrue(true);
}
@Test
public void testB() {
Assert.assertTrue(true);
}
}
Run Code Online (Sandbox Code Playgroud)
例外
java.lang.RuntimeException: java.lang.IllegalStateException: Illegal connection pointer 1. Current pointers for thread Thread[pool-4-thread-1,5,main] []
at org.robolectric.shadows.ShadowSQLiteConnection$Connections.execute(ShadowSQLiteConnection.java:470)
at org.robolectric.shadows.ShadowSQLiteConnection.nativeResetStatementAndClearBindings(ShadowSQLiteConnection.java:286)
at android.database.sqlite.SQLiteConnection.nativeResetStatementAndClearBindings(SQLiteConnection.java)
at android.database.sqlite.SQLiteConnection.releasePreparedStatement(SQLiteConnection.java:915)
at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:519)
at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
at android.database.sqlite.SQLiteProgram.__constructor__(SQLiteProgram.java:58)
at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java)
at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java) …Run Code Online (Sandbox Code Playgroud) 我对android sqlite数据库和并发写入存在严重问题.为了更好的解释,我会给你一个真实的例子:
我有一个桌面小部件,我正在显示我的数据库中的项目列表(在后台我有DataService,它定期从我的远程服务器收集新数据,并用它们更新我的数据库).所以 - 当我点击列表中的某个项目时,我需要更新数据库中的点击项目(=写入操作).但是,当我完全点击项目时,当DataService正在更新我的数据库中的新数据时,它当然会记录如下错误:
android.database.sqlite.SQLiteException: error code 5: database is locked
Run Code Online (Sandbox Code Playgroud)
通常很难模拟,但如果你安排DataService每10秒运行一次(仅用于演示),你可以很容易地模拟这个错误.
我的问题是,如何处理这个?我在文档中读到,如果同时有两个写入事件,则只会执行第一个,第二个将被记录为错误.它听起来很奇怪,必须有另一个选项,例如第二次写入会等到第一次写完.或者其他解决方案?试图阅读文档,但似乎,这个项目在谷歌文档中不是很好...几乎我拥有的每一个信息,我在官方网页以外找到.
PS:这是我的DBHelper类的缩短版本:
public class DBHelper extends SQLiteOpenHelper {
private static final String TABLE_NEWS = "News";
private static final String COL_ID = "id";
private static final String COL_TITLE = "title";
private static final String COL_ALERT = "alert";
public DBHelper(Context context) {
super(context, "MY_DB_NAME", null, 1);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + TABLE_NEWS + "(" + COL_ID + " TEXT PRIMARY KEY," + COL_TITLE …Run Code Online (Sandbox Code Playgroud) 我有一个数据库的应用程序,使用标准的SQLiteOpenHelper创建和打开.
每当我升级数据库版本时,我也会升级应用程序的版本代码,因此数据库无法关闭(数据库版本号总是增加,永不减少).
我通过将android:allowBackup属性设置为false来禁用我的应用程序中的数据库备份.
但是当我在Play商店升级应用程序时,我遇到了很多崩溃
无法将数据库从版本降级
n到n-1
这些崩溃中有96%发生在运行的三星设备上.任何人都知道为什么会出现这个问题,更重要的是如何防止这种崩溃?
我知道我可以覆盖onDowngrade以防止崩溃但我实际上不明白为什么onDowngrade被调用,因为在总是使用数据库的最后版本的应用程序上调用了崩溃.
编辑:添加代码示例,FWIW
我的OpenHelper:
public class MyDBHelper extends SQLiteOpenHelper {
private static final String LOG_TAG = MyDBHelper.class.getName();
public static final String DB_NAME = "my_db";
public static final int DB_V1 = 1;
public static final int DB_V2_UNIQUE_IDS = 2;
public static final int DB_V3_METADATAS = 3;
public static final int DB_V4_CORRUPTED_IDS = 4;
public static final int DB_V5_USAGE_TABLE = 5;
public static final int DB_VERSION = DB_V5_USAGE_TABLE;
public MyDBHelper(final Context …Run Code Online (Sandbox Code Playgroud) 这让我疯狂了好几天了.我有一个非常复杂的Android应用程序.它使用多个线程从服务器提取数据并填充SQLite数据库.我正在使用单例来引用我的SQLiteOpenHelper扩展.我在每个活动中打开和关闭数据库.
该错误仅发生在我4次活动深度然后尝试退出的情况下.我已经尝试了各种方法来打开和关闭数据库,包括将关闭从onDestroy()移动到onPause()方法,还添加另一个打开到onResume().
另外值得注意的是,我的活动大量使用了ListViews和ExpandableListViews,据我所知,这可能会导致数据库关闭,基于这篇文章:http: //darutk-oboegaki.blogspot.com/2011/03/sqlitedatabase-is-closed- automatically.html
我已经完成了代码并确保我要么关闭所有游标,要么将它们分配给适配器,调用startManagingCursor().
有没有人知道发生了什么?
java.lang.RuntimeException: Unable to resume activity {com.fieldone/com.fieldone.DispatchActivity}: java.lang.IllegalStateException: database /data/data/com.fieldone/databases/InterstateAirConditioning-1602814322.db already closed
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3347)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3362)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2162)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:144)
at android.app.ActivityThread.main(ActivityThread.java:4937)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.IllegalStateException: database /data/data/com.fieldone/databases/InterstateAirConditioning-1602814322.db already closed
at android.database.sqlite.SQLiteProgram.bindString(SQLiteProgram.java:237)
at android.database.sqlite.SQLiteQuery.requery(SQLiteQuery.java:145)
at android.database.sqlite.SQLiteCursor.requery(SQLiteCursor.java:567)
at android.app.Activity.performRestart(Activity.java:3836)
at android.app.Activity.performResume(Activity.java:3857)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3337)
... 10 more
Run Code Online (Sandbox Code Playgroud)
更新: 我已经修复了问题,但不确定为什么要修复它.所以,也许有人知道或可以解释.
当我处于活动堆栈的第4个活动时,我试图通过db.close()关闭数据库.无论我把它放在哪里,在我得到我需要的数据之后的onCreate中,或者在onStop或onDestroy中,它都会产生这个错误.如果我不关闭数据库,我没有问题.因此,导致数据库自动关闭的原因.奇怪的是,虽然我在最后的活动中使用了expandableListView,但我没有使用cursorAdapter.有人有什么想法?很想明白这一点.
database sqlite android illegalstateexception sqliteopenhelper
我正在制作一个数据库应用程序,我的程序正常工作,我已经理解了我一直关注的大部分教程.但是,有一方面我不清楚.
有一个内部类的MyDBHelper扩展了SQLiteOpenHelper.外部变量包括名为d的SQLiteDatabase.MyDBHelper的代码是:
private static class MyDBHelper extends SQLiteOpenHelper {
MyDBHelper(Context c) {
super(c, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
try {
db.execSQL(DATABASE_CREATE);
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVers, int newVers) {
Log.w(TAG, "Upgrading database from version " + oldVers + " to " + newVers + ", which will destroy all old data.");
db.execSQL("DROP TABLE IF EXISTS GM");
onCreate(db);
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是这是如何实际创建初始数据库的.它出现在onCreate()方法中,但据我所知,从未调用过.我知道它是在第一次创建数据库时调用的,但在哪里?而且,它如何通过SQLiteDatabase数据库?我还没有将任何数据库传递给该方法.我的SQLiteDatabase db变量如何从 …
我正在制作我的第一个Android应用程序,我首先学习了一些sqlite教程,这教我使用扩展SQLiteOpenHelper的databaseHelper.所以我的databaseHelper确实扩展了SQLiteOpenHelper.我在Logcat中收到了一个sqlite连接泄漏警告,所以想要了解如何解决这个问题.
我收到此错误:
02-01 21:39:50.740: W/SQLiteConnectionPool(32061): A SQLiteConnection object for database '/data/data/com.btf271.fashionassistant/databases/clothingManager' was leaked! Please fix your application to end transactions in progress properly and to close the database when it is no longer needed.
Run Code Online (Sandbox Code Playgroud)
我的databaseHelper函数在发生泄漏时被调用:
public List<Sticker> getObjectsByGenderAndCategory(String gender, String category) {
List<Sticker> objects = new ArrayList<Object>();
String selectQuery = String.format(
"SELECT * FROM %s WHERE %s = \"%s\" AND %s = \"%s\"",
TABLE_OBJECT, KEY_GENDER, gender, KEY_CATEGORY, category);
Log.e(LOG, selectQuery);
SQLiteDatabase db = this.getReadableDatabase();
Cursor c = db.rawQuery(selectQuery, null);
try{ …Run Code Online (Sandbox Code Playgroud)