为什么我的Android SQLite DB突然变得腐败?

为什么我的Android SQLite DB突然变得腐败?,android,database,sqlite,Android,Database,Sqlite,突然,我的应用程序使用的数据库似乎已经损坏。 我没有改变数据库的结构,但是我今天在我的设备上重新部署了好几次应用程序 它正在抛出以下异常 E/Database(14281): CREATE TABLE android_metadata failed err=26 .. E/Database(14281): Failed to setLocale() when constructing, closing the database E/Database(14281): android.databas

突然,我的应用程序使用的数据库似乎已经损坏。 我没有改变数据库的结构,但是我今天在我的设备上重新部署了好几次应用程序

它正在抛出以下异常

E/Database(14281): CREATE TABLE android_metadata failed err=26 ..
E/Database(14281): Failed to setLocale() when constructing, closing the database
E/Database(14281): android.database.sqlite.SQLiteException: file is encrypted or is not  a database
E/Database(14281):  at android.database.sqlite.SQLiteDatabase.native_setLocale(Native  Method)
E/Database(14281):  at android.database.sqlite.SQLiteDatabase.setLocale(SQLiteDatabase.java:1848)
E/Database(14281):  at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1798)
E/Database(14281):  at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:798)
E/Database(14281):  at   android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:857)
E/Database(14281):  at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:850)
E/Database(14281):  at android.app.ApplicationContext.openOrCreateDatabase(ApplicationContext.java:539)
E/Database(14281):  at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:193)
E/Database(14281):  at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:98)
E/Database(14281):  at com.ecs.android.gps.storage.DBAdapter.open(DBAdapter.java:75)

  • 我基本上是打开/关闭两个 每个服务器上的数据库和游标 手术
  • 一些文章指出 这是一条路要走,但对于一个 安卓应用程序,不会更有意义 保持数据库连接处于打开状态 一直以来
  • 我可以想象 需要更多的资源来 每次打开/关闭它
  • 有多种活动和服务 访问数据库。(可能同时)
  • 我从未在日志中看到过异常
你知道是什么原因导致了这种情况,如何从中恢复,以及如何在将来预防这种情况吗?
我觉得异常是由于一些并发问题(多个线程试图打开/关闭或读/写数据库)而产生的。我不知道当涉及多线程访问时,SQLite数据库在多大程度上与普通数据库(mysql-oracle)一样健壮,锁定,…

可能会以某种方式使数据库处于非法状态,尽管这通常会被标记并且一切正常

Ae sql lite DB文件不是文本可读格式?你不能解析数据库文件来重建它吗?还有locale属性,它不是安卓为您创建的元数据表上设置的。如果是这样的话,可能会出现这样的情况:删除该表并手动创建该表可能会恢复数据库

我基本上是在每次操作中打开/关闭数据库和游标。有多个活动和服务可以访问数据库。然而,我从未在日志中看到异常。这里的大问题是没有简单的方法可以从中恢复。您基本上需要卸载应用程序(导致它删除数据库)并重新安装以解除锁定。您可以尝试。转到sdk工具文件夹,运行shell工具。然后使用sqlite3浏览表。如果这不起作用,你可以从这里复制到你的本地机器上,用其他工具恢复它。这是一个将安装在多部手机上的应用程序,因此手动修复它不是一个选项。db文件永远不会损坏(前提是应用程序运行正常,并且不会经常被taskmanager或其他东西杀死)重新阅读您的初始帖子,我仍然无法给出具体的答案,说明您为什么会出现这种“损坏”。如果您认为这可能是线程问题,那么最好尝试通过线程安全队列访问所有DB调用。我总是倾向于在每次操作中打开和关闭数据库,这似乎不会增加太多开销,并有助于确保数据库始终处于良好状态。您是否考虑过使用数据提供程序在多个Actuvite之间共享数据?它在我的待办事项列表中,据我所知,这可能是一个选项,因为它为您提供了很多管道,然而,我只有一个表,可以读取和写入。我也无意将数据公开给其他应用程序。我只想知道它是如何损坏的,以及如何避免它(仍然使用std SQLiteDatabase和SQLiteOpenHelper类),除非您已经修复了它,否则我将进一步调查rostheboss的答案。您提到您有访问数据库的服务和活动。如果两个活动从未在同一时间真正处于活动状态,则可以假定存在安全(r)。但是,您提到的服务可能与活动同时运行。我不是java方面的专家,但我可以想象有一些方法可以帮助锁定/检查数据库上的锁。即已打开,或锁定/解锁数据库。这将允许您避免冲突,至少可以捕获错误。我的google联系人内容提供商数据库也有相同的错误。删除了联系人数据,并将其修复。正如建议的那样,我认为问题在于模拟访问数据库会破坏磁盘上的数据库。实现逻辑来重建数据库文件是我不想在这里实现的:)android_元数据确实是自动创建的,但是,从堆栈跟踪判断,我的感觉是,Android已经决定DB已经损坏,在这一点上,它删除数据库并重新创建它(我认为这是标准的Android SQLite行为)。在重建过程中,它失败了。我正试图找出我做错了什么导致了腐败。这样你就可以重复这个问题了?每次你重新安装应用程序时。评论中提到的重新创建并不是指数据库的初始创建(安装应用程序时),而是指Android检测到损坏的数据库文件时发生的重新创建。很难复制。。。我可以让应用程序运行几天,然后突然弹出。下次它可以在几个小时后弹出。
public DBAdapter(Context ctx) 
{
    this.context = ctx;
    DBHelper = new DatabaseHelper(context);
}

private static class DatabaseHelper extends SQLiteOpenHelper 
{
    DatabaseHelper(Context context) 
    {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) 
    {
        db.execSQL(DATABASE_CREATE);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, 
    int newVersion) 
    {
        Log.w(TAG, "Upgrading database from version " + oldVersion 
                + " to "
                + newVersion + ", which will destroy all old data");
        db.execSQL("DROP TABLE IF EXISTS location_history");
        onCreate(db);
    }
}