此链接完全描述了我的问题:
http://old.nabble.com/Android-database-corruption-td28044218.html#a28044218
现在大约有300人使用我的Android应用程序,每次使用此堆栈跟踪向服务器发送崩溃报告时:
android.database.sqlite.sqliteDatabaseCorruptException: database disk image is malformed
at android.app.ActivityThread.performlaunchActivity(ActivityThread.java:2596)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2621)
at android.app.ActivityThread.access$2200(ActivityThread.java:126)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1932)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:4595)
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:860)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
at dalvik.system.NativeStart.main(Native Method) Caused by: android.database.sqlite.sqliteDatabaseCorruptException: database disk image is malformed
at android.database.sqlite.sqliteQuery.native_fill_window(Native Method)
at android.database.sqlite.sqliteQuery.fillWindow(sqliteQuery.java:75)
at android.database.sqlite.sqliteCursor.fillWindow(sqliteCursor.java:295)
at android.database.sqlite.sqliteCursor.getCount(sqliteCursor.java:276)
at android.database.AbstractCursor.movetoPosition(AbstractCursor.java:171)
at android.database.AbstractCursor.movetoFirst(AbstractCursor.java:248)
结果是应用程序崩溃并且数据库中的所有数据都丢失了.
需要注意的一点是,每次我读取或写入数据库时,我都会得到一个新的sqliteDatabase,并在完成后立即将其关闭.我这样做是为了防止这种腐败错误.
我还尝试使用单个静态对象同步所有数据库读取和写入,这似乎没有帮助.
这可能只是一个sqlite错误吗?
我在这里找到了与内置电子邮件应用程序类似的错误:http://code.google.com/p/android/issues/detail?id=5610.
这是我的代码:
public class keyvalueTableAdapter extends BaseTableAdapter {
private String tableName;
private String keyColumnName;
private String valueColumnName;
public keyvalueTableAdapter(Context context,String tableName,String keyColumnName,String valueColumnName) {
super(context);
this.tableName = tableName;
this.keyColumnName = keyColumnName;
this.valueColumnName = valueColumnName;
}
protected String getStringValue(int key) {
Cursor cursor = null;
sqliteDatabase db = null;
String value;
try {
db = dbOpenHelper.getReadableDatabase();
cursor = db.query(true,tableName,new String[] { valueColumnName },keyColumnName + "=" + key,null,null);
if ((cursor.getCount() == 0) || !cursor.movetoFirst()) {
value = null;
} else {
value = cursor.getString(0);
}
} finally {
if (cursor != null) cursor.close();
if (db != null) db.close();
dbOpenHelper.close();
}
return value;
}
}
public abstract class BaseTableAdapter {
protected DbOpenHelper dbOpenHelper;
public BaseTableAdapter(Context context) {
this.dbOpenHelper = new DbOpenHelper(context,DatabaseSettings.DATABASE_NAME,DatabaseSettings.DATABASE_VERSION);
}
}
解决方法
“the DB holds session information so
it’s not very feasible to do a backup.
The data changes by the minute”
您应该尝试使用SharedPreferences:它存储键值对(在后台,它使用文件).
存储值:
SharedPreferences sp=MyActivity.getSharedPreferences("Name",Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.putString("key",value);
editor.putBoolean("another",true);
editor.commit();
检索数据:
sp.getString("key","Not found");
// "Not found" is the default value
// if sp does not contain the specified key
sp.getBoolean("another",false);
// false is the default value
// if sp does not contain the specified key
有关更详细的说明,请参见getSharedPreferences和SharedPreferences.