Dyo*_*sos 10
该问题已从API级别11开始修复.现在存在一个接口:DatabaseErrorHandler,您可以实现它来定义自己的onCorruption()方法.在数据库打开时,您可以将此DatabaseErrorHandler作为参数传递给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();
Run Code Online (Sandbox Code Playgroud)
对于API级别低于11的系统,对于那些不想使用此方法的系统,有几种选择.
1. Android数据备份
Android提供备份服务,可自动将应用程序数据复制到远程"云"存储.如果数据库损坏或在出厂重置后重新安装应用程序.可以从远程数据恢复应用程序数据.
有关详细信息,请参阅:http: //developer.android.com/guide/topics/data/backup.html
2. JDBC(sqldroid)
一种方法可能是实现您自己的数据库连接器,本机JDBC或sqldroid库.谷歌官方不支持它,你不能确定它是否仍然可以在未来的Android版本中使用.
3. Berkley DB Java版
Berkley DB Java版是一种有趣的方法,也是一种处理大量数据的性能处理方法.
以下是如何在Android中使用它的教程:http://download.oracle.com/docs/cd/E17277_02/html/HOWTO-Android.html
4.自定义android库
另一种更危险的方法是通过从android源代码复制或扩展SQLiteDatabase.java来实现自己的数据库类,并重新实现或覆盖以下关键部分:
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;
}
Run Code Online (Sandbox Code Playgroud)
和:
/* 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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
关于这一点的危险部分是,您还必须重新实现访问SQLiteDatabase的帮助程序类,例如SQLiteOpenHelper.由于SQLiteDatabase课程使用工厂方法,您可能会遇到意想不到的副作用.