我正在尝试使用 SQLite 将 Java 项目迁移到 android,当实例化新的 MapleDBHelper 类时,出现以下异常:
尝试写入只读数据库(代码1032 SQLITE_READONLY_DBMOVED)
我在网上搜索过,但没有任何线索,是什么云的原因?
代码:
try (MapleDBHelper mapledb = MapleDBHelper.getInstance(this.context);
SQLiteDatabase db = mapledb.getWritableDatabase()) {
// Code Modifying DB
} catch (SQLiteException sqle) {
Log.e("Failed to run all startup-bound database tasks", sqle.toString());
throw new IllegalStateException(sqle);
}
DBHelper类:
public class MapleDBHelper extends SQLiteOpenHelper {
public Context context;
private static final String DATABASE_NAME = "cosmic";
private static final int DATABASE_VERSION = 1;
private static MapleDBHelper sInstance;
private MapleDBHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
this.context = context;
}
@Override
public void onCreate(SQLiteDatabase db) {
File databaseFile = context.getDatabasePath(DATABASE_NAME);
if (databaseFile.exists()) {
// Delete the existing database file
SQLiteDatabase.deleteDatabase(databaseFile);
}
try {
AssetManager assetManager = context.getAssets();
InputStream db_database = assetManager.open("sql/1_db_database.sql");
InputStream db_drops = assetManager.open("sql/2_db_drops.sql");
InputStream db_shopupdate = assetManager.open("sql/3_db_shopupdate.sql");
InputStream db_admin = assetManager.open("sql/4_db-admin.sql");
db.execSQL(convertInputStreamToString(db_database));
db.execSQL(convertInputStreamToString(db_drops));
db.execSQL(convertInputStreamToString(db_shopupdate));
db.execSQL(convertInputStreamToString(db_admin));
db_database.close();
db_drops.close();
db_shopupdate.close();
db_admin.close();
} catch (FileNotFoundException e) {
throw new RuntimeException("Could not read database file : " + e.getMessage());
} catch (IOException e) {
throw new RuntimeException("Could not successfully parse database file " + e.getMessage());
}
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public static synchronized MapleDBHelper getInstance(Context context) {
if (sInstance == null) {
sInstance = new MapleDBHelper(context.getApplicationContext());
}
return sInstance;
}
}
Stacktrace:
0 = {StackTraceElement@17117} "android.database.sqlite.SQLiteConnection.nativeExecuteForChangedRowCount(Native Method)"
1 = {StackTraceElement@17118} "android.database.sqlite.SQLiteConnection.executeForChangedRowCount(SQLiteConnection.java:890)"
2 = {StackTraceElement@17119} "android.database.sqlite.SQLiteSession.executeForChangedRowCount(SQLiteSession.java:756)"
3 = {StackTraceElement@17120} "android.database.sqlite.SQLiteStatement.executeUpdateDelete(SQLiteStatement.java:66)"
4 = {StackTraceElement@17121} "android.database.sqlite.SQLiteDatabase.executeSql(SQLiteDatabase.java:1920)"
5 = {StackTraceElement@17122} "android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1841)"
6 = {StackTraceElement@17123} "android.database.sqlite.SQLiteDatabase.setVersion(SQLiteDatabase.java:1102)"
7 = {StackTraceElement@17124} "android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:419)"
8 = {StackTraceElement@17125} "android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:316)"
9 = {StackTraceElement@17126} "net.server.Server.init(Server.java:897)"
10 = {StackTraceElement@17127} "net.server.Server.main(Server.java:1017)"
11 = {StackTraceElement@17128} "com.mapleserver.MainActivity.startMapleServer(MainActivity.kt:34)"
12 = {StackTraceElement@17129} "com.mapleserver.MainActivity.onCreate(MainActivity.kt:28)"
您正在删除数据库,您不应该这样做。
当调用
onCreate
方法时,实际的数据库(除了 sqlite_master 和 android_metadata 之外是空的)已经被创建。所以它会存在,所以你总是删除它而不是创建它(如果你这样做了,无论如何都不会被指向,因为它将是另一个文件句柄)。
如果你查看 onCreate 的参数,它会将数据库传递给它。
删除代码块:-
if (databaseFile.exists()) {
// Delete the existing database file
SQLiteDatabase.deleteDatabase(databaseFile);
}
我认为资产名称中的
/
也可能存在问题。
\
,在字符串中需要 "\\"
。最好还是使用 File.separator
而不是 "\\"
如果没有,我建议从文件名中删除
/
。