如何强制SQLite数据库从磁盘重新加载

时间:2019-08-03 13:10:57

标签: android android-sqlite

我在Android应用程序中使用一个SQLite数据库,可以使用DBHelper和自定义ContentProvider访问该数据库。 我现在想导入数据库,方法是将当前数据库替换为我以前从应用程序导出的数据库,只需将其复制到另一个位置即可。

但是,替换数据库后,将继续使用旧数据库的内存副本,直到我关闭并重新启动该应用程序为止。

->如何强制重新加载数据库?

其他信息

当我将.db文件与.db-shm和.db-wal文件一起导出并导入所有3个文件而不只是.db文件时,效果很好。

但是,如果我在笔记本电脑上使用sqlite3打开.db文件,请将其关闭(以使.db文件包含所有必需的信息,并且.db-shm和.db-wal将被自动删除),然后尝试导入只是这个.db文件,其行为如上所述。

我的代码

DBHelper 类:

public class MyDbHelper extends SQLiteOpenHelper {

public static final String DATABASE_NAME = "mydb.db";
private static final int DATABASE_VERSION = 2;
private static MyDbHelper mInstance = null;

MyDbHelper(Context context) {
    super(context, DATABASE_NAME, null, DATABASE_VERSION);
}

@Override
public void onCreate(SQLiteDatabase db) {
    db.execSQL("CREATE TABLE table1 ...;");
    db.execSQL("CREATE TABLE table2 ...;");
}

@Override
public void onUpgrade(SQLiteDatabase db, int i, int i1) {
    db.execSQL("CREATE TABLE IF NOT EXISTS table3 ...;");
}

static MyDbHelper getInstance(Context context) {
    if (mInstance == null) {
        mInstance = new MyDbHelper(context.getApplicationContext());
    }
    return mInstance;
}}

ContentProvider onCreate()方法中,我以如下方式实例化DBHelper:

mDbHelper = MyDbHelper.getInstance(getContext());

,然后按照建议的here获取ContentProvider中每个方法内部的可写/可读数据库实例。

我已经尝试过的东西

我尝试在DBHelper中实现重新打开方法

public static void reopen(Context context) {
        mDBHelper = new MyDBHelper(context);
    }

如建议的here并在导入后调用它,但仍然只有在关闭并重新启动应用程序后才使用新数据库。

我也尝试过重置方法

public void reset(Context context) {
    mDBHelper.close();
    mDBHelper = new MyDBHelper(context);
}

here所述,但这会导致应用崩溃,

2019-08-03 14:58:13.091 21814-21887/? E/SQLiteLog: (522) statement aborts at 3: [SELECT _id, title, cover_path FROM albums ORDER BY CAST(title as SIGNED) ASC, LOWER(title) ASC] disk I/O error
2019-08-03 14:58:13.092 21814-21887/? E/SQLiteQuery: exception: disk I/O error (code 522 SQLITE_IOERR_SHORT_READ); query: SELECT _id, title, cover_path FROM albums ORDER BY CAST(title as SIGNED) ASC, LOWER(title) ASC
2019-08-03 14:58:13.115 21814-21887/? E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #4
    Process: com.mycompany.myapp, PID: 21814
    java.lang.RuntimeException: An error occurred while executing doInBackground()
        at android.os.AsyncTask$3.done(AsyncTask.java:354)
        at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)
        at java.util.concurrent.FutureTask.setException(FutureTask.java:252)
        at java.util.concurrent.FutureTask.run(FutureTask.java:271)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:764)
     Caused by: android.database.sqlite.SQLiteDiskIOException: disk I/O error (code 522 SQLITE_IOERR_SHORT_READ)
        at android.database.sqlite.SQLiteConnection.nativeExecuteForCursorWindow(Native Method)
        at android.database.sqlite.SQLiteConnection.executeForCursorWindow(SQLiteConnection.java:859)
        at android.database.sqlite.SQLiteSession.executeForCursorWindow(SQLiteSession.java:836)
        at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:62)
        at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:149)
        at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:137)
        at android.content.ContentResolver.query(ContentResolver.java:821)
        at android.content.ContentResolver.query(ContentResolver.java:752)
        at android.content.CursorLoader.loadInBackground(CursorLoader.java:68)
        at android.content.CursorLoader.loadInBackground(CursorLoader.java:45)
        at android.content.AsyncTaskLoader.onLoadInBackground(AsyncTaskLoader.java:319)
        at android.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:73)
        at android.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:61)
        at android.os.AsyncTask$2.call(AsyncTask.java:333)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) 
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) 
        at java.lang.Thread.run(Thread.java:764) 

0 个答案:

没有答案