问题描述
此链接描述了我的问题正是:http://old.nabble.com/Android-database-corruption-td28044218.html#a28044218
有大约300人在使用我的Android应用程序,现在,每一次,当我得到这个堆栈跟踪到服务器的崩溃报告:
android.database.sqlite.SQLiteDatabaseCorruptException:数据库磁盘映像格式不正确
在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2596)
在android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2621)
在android.app.ActivityThread.access $ 2200(ActivityThread.java:126)
在android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1932)
在android.os.Handler.dispatchMessage(Handler.java:99)
在android.os.Looper.loop(Looper.java:123)
在android.app.ActivityThread.main(ActivityThread.java:4595)
在java.lang.reflect.Method.invokeNative(本机方法)
在java.lang.reflect.Method.invoke(Method.java:521)
在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:860)
在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
在dalvik.system.NativeStart.main(本机方法)产生的原因:android.database.sqlite.SQLiteDatabaseCorruptException:数据库磁盘映像格式不正确
在android.database.sqlite.SQLiteQuery.native_fill_window(本机方法)
在android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:75)
在android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:295)
在android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:276)
在android.database.AbstractCursor.moveToPosition(AbstractCursor.java:171)
在android.database.AbstractCursor.moveToFirst(AbstractCursor.java:248)
其结果是应用程序崩溃和在DB中的所有数据丢失。
有一点需要注意的是,每次我读出或写入到数据库中,我得到一个新的SQLiteDatabase并立即关闭,因为我做的。我企图prevent这类腐败的错误这样做。
我也试过同步所有数据库读取和写入使用单一的静态对象,而且似乎并没有帮助。
是否有可能这只是一个SQLite的错误?
我发现了内置这里电子邮件应用程序类似的错误:<一href="http://$c$c.google.com/p/android/issues/detail?id=5610">http://$c$c.google.com/p/android/issues/detail?id=5610.
下面是我的code:
公共类KeyValueTableAdapter扩展BaseTableAdapter {
私人字符串tablename;如果
私人字符串keyColumnName;
私人字符串valueColumnName;
公共KeyValueTableAdapter(上下文的背景下,字符串tableName值,字符串keyColumnName,字符串valueColumnName){
超(上下文);
this.tableName = tablename;如果
this.keyColumnName = keyColumnName;
this.valueColumnName = valueColumnName;
}
保护字符串向GetStringValue(INT键){
光标光标= NULL;
SQLiteDatabase DB = NULL;
字符串值;
尝试 {
DB = dbOpenHelper.getReadableDatabase();
光标= db.query(真中,TableName,新的String [] {} valueColumnName,keyColumnName +=+键,NULL,NULL,NULL,NULL,NULL);
如果((cursor.getCount()== 0)||!cursor.moveToFirst()){
值= NULL;
} 其他 {
值= cursor.getString(0);
}
} 最后 {
如果(光标!= NULL)cursor.close();
如果(DB!= NULL)db.close();
dbOpenHelper.close();
}
返回值;
}
}
公共抽象类BaseTableAdapter {
保护DbOpenHelper dbOpenHelper;
公共BaseTableAdapter(上下文的背景下){
this.dbOpenHelper =新DbOpenHelper(背景下,DatabaseSettings.DATABASE_NAME,空,DatabaseSettings.DATABASE_VERSION);
}
}
您应该尝试使用共享preferences:它存储键 - 值对(在后台,它使用的文件)。存储值:
共享preferences SP = MyActivity.getShared preferences(名称,Context.MODE_PRIVATE);
共享preferences.Editor编辑器= sp.edit();
editor.putString(钥匙,值);
editor.putBoolean(另一个,真正的);
editor.commit();
检索数据:
sp.getString(钥匙,未找到);
//未发现是默认值
//如果SP不包含指定键
sp.getBoolean(另一个,假);
// false是默认值
//如果SP不包含指定键
请参阅 getShared preferences 和共享preferences 获取更详细的说明
This link describes my problem exactly: http://old.nabble.com/Android-database-corruption-td28044218.html#a28044218
There are about 300 people using my Android App right now and every once and while I get a crash report to the server with this stack trace:
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)
The result is the app crashing and all the data in the DB being lost.
One thing to note is that every time I read or write to the database I get a new SQLiteDatabase and close it as soon as I'm done. I did this in an attempt to prevent these kind of corruption errors.
I also tried synchronizing all DB reads and writes using a single static object and that didn't seem to help.
Is it possible this is just a SQLite bug?
I found a similar bug with the built-in email app here: http://code.google.com/p/android/issues/detail?id=5610.
Here is my code:
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, null, 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, null, DatabaseSettings.DATABASE_VERSION);
}
}
You should try using SharedPreferences: it stores key-value pairs (in the background, it uses a file).Storing values:
SharedPreferences sp=MyActivity.getSharedPreferences("Name", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.putString("key", value);
editor.putBoolean("another", true);
editor.commit();
Retrieving data:
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
See getSharedPreferences and SharedPreferences for a more detailed description.
这篇关于Android的SQLite数据库被损坏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!