有什么可以做的事实,机器人自动删除损坏的SQLite的文件? [英] What can be done about the fact that Android automatically deletes corrupt SQLite files?

查看:138
本文介绍了有什么可以做的事实,机器人自动删除损坏的SQLite的文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Android的打开一个SQLite文件,该文件已损坏,安卓的删除文件。

When Android opens an SQLite file, and the file is corrupt, Android deletes the file.

由于令人惊讶的,因为它听起来,这种行为显然是在Android源$ C ​​$ C实现的,导致的惊愕并为此 Android的问题

As surprising as it may sound, this behavior is implemented clearly in the Android source code, leading to consternation and to this Android issue.

总之,作为应用开发者,我们只需要对付它。什么是打开一个SQLite文件时,最好的策略是什么?

Anyway, as app developers we just have to deal with it. What is the best strategy when opening an SQLite file?

  • 在损坏的文件实际上往往可恢复的,所以我们不能拿得起失去那些腐败的一个文件的风险。
  • 创建开幕前一个备份是非常耗时耗资巨大,而且将使应用程序启动非常缓慢,所以任何聪明的将是极大的AP preciated。

推荐答案

此问题已得到修复,从API级别11,从现在开始,存在一个接口: DatabaseErrorHandler ,你可以实现它来定义自己的 onCorruption()方式。在你的数据库的开放,你可以通过这个DatabaseErrorHandler作为参数的构造函数中的 SQLiteOpenHelper

The issue has been fixed starting from API level 11. Now there exists an interface: DatabaseErrorHandler which you can implement to define your own onCorruption() method. At the opening of your database you can pass this DatabaseErrorHandler as a parameter to the constructor of SQLiteOpenHelper.

例如。

public class MyDbErrorHandler implements DatabaseErrorHandler {
    @Override
    onCorruption(SQLiteDatabase db) {
        // Back up the db or do some other stuff
    }
}

SQLiteOpenHelper dbHelper = new SQLiteOpenHelper(context, "MyDbName", null, 1,
                                                 new MyDbErrorHandler());

SQLiteDatabase db = dbHelper.getWritableDatabase();


对于低于11,并为那些谁不想使用这种方法也有多种选择的API级别的系统。

1。 Android的数据备份

Android提供了自动copys应用数据到远程云存储备份服务。如果数据库被损坏或应用程序恢复出厂设置后重新安装。应用数据可以从远程数据被恢复。

Android offers a backup service which automatically copys the application data to a remote 'cloud' storage. If a database gets corrupted or the application is reinstalled after factory reset. The application data can be restored from the remote data.

有关更多信息,请参阅: http://developer.android.com/guide /topics/data/backup.html

For further information see: http://developer.android.com/guide/topics/data/backup.html

2。 JDBC(sqldroid)

一种方法可以实现自己的数据库连接器,无论是本地JDBC或在 sqldroid库 。这是官方不支持谷歌,你无法确定它是否会在未来的Andr​​oid版本仍然可用。

One approach could be implementing your own database connector, either native JDBC or with the sqldroid library. It is officially not supported by google and you cannot be sure whether it will be still available in future Android versions.

3。伯克利DB Java版

这是有趣的方法,也一起来看看吧性能处理大数据量,是在伯克利DB Java版

An interesting approach, also with a look to performance handling large data amounts, is the Berkley DB Java Edition.

下面是一个教程如何使用它的Andr​​oid版本: HTTP ://download.oracle.com/docs/cd/E17277_02/html/HOWTO-Android.html

Here is a tutorial how to use it in Android: http://download.oracle.com/docs/cd/E17277_02/html/HOWTO-Android.html

4。定制的Andr​​oid库

另外一个比较冒险的做法是通过复制或从Android源延伸SQLiteDatabase.java来实现自己的数据库类,并重新实现或覆盖哪些是关键的部分:

Another more risky approach is to implement your own database class by copying or extending the SQLiteDatabase.java from the android source and reimplement or override the critical parts which are:

public static SQLiteDatabase openDatabase(String path, CursorFactory factory, int flags) {
    SQLiteDatabase sqliteDatabase = null;
    try {
        // Open the database.
        sqliteDatabase = new SQLiteDatabase(path, factory, flags);
        if (SQLiteDebug.DEBUG_SQL_STATEMENTS) {
            sqliteDatabase.enableSqlTracing(path);
        }
        if (SQLiteDebug.DEBUG_SQL_TIME) {
            sqliteDatabase.enableSqlProfiling(path);
        }
    } catch (SQLiteDatabaseCorruptException e) {
        // Try to recover from this, if we can.
        // TODO: should we do this for other open failures?
        Log.e(TAG, "Deleting and re-creating corrupt database " + path, e);
        EventLog.writeEvent(EVENT_DB_CORRUPT, path);
        if (!path.equalsIgnoreCase(":memory")) {
            // delete is only for non-memory database files
            new File(path).delete();
        }
        sqliteDatabase = new SQLiteDatabase(path, factory, flags);
    }
    ActiveDatabases.getInstance().mActiveDatabases.add(
            new WeakReference<SQLiteDatabase>(sqliteDatabase));
    return sqliteDatabase;
}

/* package */ void onCorruption() {
    Log.e(TAG, "Removing corrupt database: " + mPath);
    EventLog.writeEvent(EVENT_DB_CORRUPT, mPath);
    try {
        // Close the database (if we can), which will cause subsequent operations to fail.
        close();
    } finally {
        // Delete the corrupt file.  Don't re-create it now -- that would just confuse people
        // -- but the next time someone tries to open it, they can set it up from scratch.
        if (!mPath.equalsIgnoreCase(":memory")) {
            // delete is only for non-memory database files
            new File(mPath).delete();
        }
    }
}

有关的危险部分,你也必须重新实现访问SQLiteDatabase如 SQLiteOpenHelper 的辅助类。因为 SQLiteDatabase 类使用工厂方法,你可能会面临意想不到的副作用。

The dangerous part about that is, that you also would have to reimplement the helper classes that access the SQLiteDatabase such as SQLiteOpenHelper. Since the SQLiteDatabase class uses factory methods you could face unexpected side effects.

这篇关于有什么可以做的事实,机器人自动删除损坏的SQLite的文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆