gpt4 book ai didi

android - 在 SQLite DatabaseErrorHandler 中需要做什么

转载 作者:行者123 更新时间:2023-11-29 19:29:34 25 4
gpt4 key购买 nike

我一直在努力完善一个有效的 SQLite 数据库恢复。更具体地说,当数据库损坏时(我一直在使用其中包含 SQL 的文件并将其复制到数据库文件而不是数据库的副本)。

通过使用 SQL 查看 sqlite_master,我可以在没有处理程序的情况下处理这个问题(没有表检测到损坏)。

当我在研究技术时遇到 DatabaseErrorHanlder,我想我会涉足 DatabaseErorHandler

我已经到了触发 DataBaseErrorHandler 的阶段(处理程序中的日志被调用(由于第二次尝试读取而调用了两次))。但是,与使用 null 而不是处理程序相比,我收到的错误报告更多,并且应用程序崩溃(好像让处理程序关闭了 SQLite 的自动化,我相信,删除了损坏的文件,因此对处理程序的任何调用都会重新创建它) .崩溃不是问题,因为很明显 SQLite 试图绕过损坏,但似乎处理程序阻止了它做它本来会做的事情。)

在没有处理程序的情况下运行会导致以下消息(第一个由应用程序编写为路标):-

11-03 16:36:13.414 10959-10959/? I/mjt.shopper: Thu Nov 03 16:36:13 AEDT 2016 Activity=dataBaseIntegrityCheck Method=MainDataHandling MSG=restore Database Integrity Check - IC Database created
11-03 16:36:13.415 10959-10959/? E/SQLiteLog: (26) file is encrypted or is not a database
11-03 16:36:13.416 10959-10959/? E/DefaultDatabaseErrorHandler: Corruption reported by sqlite on database: /data/data/mjt.shopper/databases/ICShopper
11-03 16:36:13.416 10959-10959/? E/DefaultDatabaseErrorHandler: deleting the database file: /data/data/mjt.shopper/databases/ICShopper

与我得到的处理程序一起运行(相同的路标 + 处理程序发出的路标):-

11-03 16:58:23.923 12265-12265/? I/mjt.shopper: Thu Nov 03 16:58:23 AEDT 2016 Activity=dataBaseIntegrityCheck Method=MainDataHandling MSG=restore Database Integrity Check - IC Database created
11-03 16:58:23.925 12265-12265/? E/SQLiteLog: (26) file is encrypted or is not a database
11-03 16:58:23.925 12265-12265/? I/mjt.shopper: Thu Nov 03 16:58:23 AEDT 2016 Activity=MainDataHandling Method=dataBaseIntegrityCheck MSG=DB onCorruption error handler invoked
11-03 16:58:23.925 12265-12265/? E/SQLiteLog: (26) file is encrypted or is not a database
11-03 16:58:23.927 12265-12265/? E/SQLiteDatabase: Failed to open database '/data/data/mjt.shopper/databases/ICShopper'.
android.database.sqlite.SQLiteDatabaseCorruptException: file is encrypted or is not a database (code 26): , while compiling: PRAGMA journal_mode
.............
11-03 16:58:23.928 12265-12265/? E/SQLiteOpenHelper: Couldn't open ICShopper for writing (will try read-only):
android.database.sqlite.SQLiteDatabaseCorruptException: file is encrypted or is not a database (code 26): , while compiling: PRAGMA journal_mode
'''''''''''''
11-03 16:58:23.929 12265-12265/? E/SQLiteLog: (26) statement aborts at 1: [PRAGMA user_version;] file is encrypted or is not a database
11-03 16:58:23.930 12265-12265/? I/mjt.shopper: Thu Nov 03 16:58:23 AEDT 2016 Activity=MainDataHandling Method=dataBaseIntegrityCheck MSG=DB onCorruption error handler invoked
11-03 16:58:23.934 12265-12265/? D/AndroidRuntime: Shutting down VM
11-03 16:58:23.934 12265-12265/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: mjt.shopper, PID: 12265
android.database.sqlite.SQLiteDatabaseCorruptException: file is encrypted or is not a database (code 26)

DatabaseHelper 代码是:-

public class IntegrityCheckDBHelper extends SQLiteOpenHelper implements DatabaseErrorHandler{

public static final String DATABASE_NAME = "IC"+ShopperDBHelper.DATABASE_NAME;
public static final int DATABASE_CORRUPTED = 1;
private static int databasestate = 0;
private Context context;

public IntegrityCheckDBHelper(Context context,
String name,
SQLiteDatabase.CursorFactory factory,
int version, DatabaseErrorHandler errorHandler) {
super(context, DATABASE_NAME,factory,1,errorHandler);
this.context = context;

};

public void onCreate(SQLiteDatabase db) {};
public void onUpgrade(SQLiteDatabase db, int oldversion, int newversion) {};
public void onCorruption(SQLiteDatabase db) {
}
public boolean checkDB() {
SQLiteDatabase icdb = this.getReadableDatabase();
String icsqlstr = " PRAGMA quick_check";
Cursor iccsr;
iccsr = icdb.rawQuery(icsqlstr,null);
return false;
}
public static void setDatabaseCorrupted() {
databasestate = DATABASE_CORRUPTED;
}
public boolean isDatabaseCouurpted() {
if(databasestate != 0) return false;
return true;
}
}

注意!这个助手专门用于检查恢复文件是否可以被用户使用(所以不需要 onCreate/onUpgrade 做任何事情我认为)。

这是相关代码,即 dataBaseIntegrityCheck 方法(即从要恢复的备份创建数据库文件以检查备份是否创建有效数据库):-

private boolean dataBaseIntegrityCheck() {

final String THIS_METHOD = "dataBaseIntegrityCheck";
String sqlstr_mstr = "SELECT name FROM sqlite_master WHERE type = 'table' AND name!='android_metadata' ORDER by name;";
Cursor iccsr;
boolean rv = true;
DatabaseErrorHandler myerrorhandler = new DatabaseErrorHandler() {
@Override
public void onCorruption(SQLiteDatabase sqLiteDatabase) {
mjtUtils.logMsg(mjtUtils.LOG_INFORMATIONMSG,"DB onCorruption error handler invoked",THIS_ACTIVITY,THIS_METHOD,true);
dbcorrupted = true;
}
};
mjtUtils.logMsg(mjtUtils.LOG_INFORMATIONMSG,"Restore Databae Integrity Check - Starting",THIS_METHOD,THIS_ACTIVITY,true);
try {
FileInputStream bkp = new FileInputStream(backupfilename);
OutputStream ic = new FileOutputStream(icdbfilename);
while ((copylength = bkp.read(buffer)) > 0) {
ic.write(buffer, 0, copylength);
}
ic.close();
bkp.close();

mjtUtils.logMsg(mjtUtils.LOG_INFORMATIONMSG,"restore Database Integrity Check - IC Database created",THIS_METHOD,THIS_ACTIVITY,true);

//Note SQLite will actually check for corruption and if so delete the file
IntegrityCheckDBHelper icdbh = new IntegrityCheckDBHelper(this,null,null,1,myerrorhandler);

//>>>>>>>>>>>>> Errors all point here (the getReadableDatabase)
SQLiteDatabase icdb = icdbh.getReadableDatabase();

if(dbcorrupted) {
mjtUtils.logMsg(mjtUtils.LOG_INFORMATIONMSG,"DB corrupted",THIS_ACTIVITY,THIS_METHOD,true);
return false;
}

//Check to see if there are any tables, if wrong file type shouldn't be any
iccsr = icdb.rawQuery(sqlstr_mstr,null);
if(iccsr.getCount() < 1) {
errlist.add("Integrity Check extract from sqlite_master returned nothing - Propsoed file is corrupt or not a database file.");
rv = false;
}
iccsr.close();
icdb.close();

} catch (IOException e) {
e.printStackTrace();
errlist.add("Integrity Check Failed Error Message was " + e.getMessage());
}

if(!rv) {
// AlertDialog removed.
}
return rv;
}

重申一下,问题主要是关于 DatabaseErrorHandler 以及我能做什么、不能做什么和/或应该做什么。

我找到的文档以及我看过的许多帖子似乎都没有帮助。

最佳答案

SQLiteDatabase.open()中的相关代码如下所示:

        try {
openInner();
} catch (SQLiteDatabaseCorruptException ex) {
onCorruption();
openInner();
}

因此您的onCorruption() 处理程序必须在返回之前恢复数据库;这不能拖到以后。

如果您实际上不想恢复您尝试打开的数据库,则使用 onCorrupt() 处理程序没有意义。

关于android - 在 SQLite DatabaseErrorHandler 中需要做什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40395192/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com