使用单例作为数据库助手时,如何在还原后刷新/重新打开SQLite数据库 [英] How can I refresh/reopen an SQLite database after restoring it, when using a singleton for the database helper

查看:120
本文介绍了使用单例作为数据库助手时,如何在还原后刷新/重新打开SQLite数据库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已在我的应用程序中合并了数据库备份和还原.一切正常,除了在还原数据库时,由于使用单例DBHelper且仅在应用程序关闭时关闭数据库,因此还原后继续使用数据库的内存副本.

I have incorporated Database Backup and restore in my App. This all works fine except that when I restore the database, due to the use of a singleton DBHelper along with only closing the database when the App closes, the in-memory copy of the Database continues to be used after the restore.

关闭应用程序并重新启动,将使用新数据库.但是,而不是告诉用户执行此操作.我想无缝访问恢复的数据库.

Closing the App and re-starting uses the new database. However, rather than tell the user to do this. I would like to seamlessly access the restored database.

这是检测并成功还原后报告的代码:-

This is the code that detects and then reports upon a successful restore :-

                if(copytaken && origdeleted && restoredone) {
                    errlist.add("Database successfully restored." +
                            "\n\nYou should close the ShopWise App and then restart it.");
                    resulttitle = "Restore was successful.";
                    //DBHelper.reopen(context); <== implemented as below
                }
                ..... Displays dialog with text from above

这是DBHelper(注意,expand方法用于创建/修改表)

This is the DBHelper (note expand method is used to create/amend the tables)

class DBHelper extends SQLiteOpenHelper {

    private static final String DBNAME = DBConstants.DATABASE_NAME;

    /**
     * Consrtuctor
     *
     * @param context activity context
     * @param name    database name
     * @param factory cursorfactory
     * @param version database version
     */
    DBHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
    }

    /**
     * Instantiates a new Db helper.
     *
     * @param context the context
     */
    DBHelper(Context context) {
        super(context, DBConstants.DATABASE_NAME, null, 1);
    }

    private static DBHelper instance;

    /**
     * Gets helper.
     *
     * @param context the context
     * @return the helper
     */
    static synchronized DBHelper getHelper(Context context) {
        if(instance == null) {
            instance = new DBHelper(context);
        }
        return instance;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        expand(db, false);
    }
    .......

认为应该关闭数据库然后重新打开它.我尝试在DBHelper中添加重新打开方法,如下所示:-

Thinking that you should close the database an reopen it. I tried adding a reopen method in the DBHelper as follows:-

public static void reopen(Context context) {
        instance.close();
        instance = null;
        instance = new DBHelper(context);
    }

,然后在恢复正常时(根据注释)从代码中调用此方法.但是,这导致以下结果:-

and then invoked this from within the code when the restore was OK (as per comment). However, this results in the following :-

java.lang.IllegalStateException:尝试重新打开一个已经关闭的 对象:SQLiteDatabase:

java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase:

02-16 16:41:20.938 2683-3050/mjt.shopwise E/SQLiteLog: (28) file unlinked while open: /data/data/mjt.shopwise/databases/ShopWise
02-16 16:41:25.171 2683-2683/mjt.shopwise D/AndroidRuntime: Shutting down VM
02-16 16:41:25.171 2683-2683/mjt.shopwise E/AndroidRuntime: FATAL EXCEPTION: main
                                                            Process: mjt.shopwise, PID: 2683
                                                            java.lang.RuntimeException: Unable to resume activity {mjt.shopwise/mjt.shopwise.MainActivity}: java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase: /data/data/mjt.shopwise/databases/ShopWise
                                                                at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2986)
                                                                at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3017)
                                                                at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1347)
                                                                at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                at android.os.Looper.loop(Looper.java:135)
                                                                at android.app.ActivityThread.main(ActivityThread.java:5254)
                                                                at java.lang.reflect.Method.invoke(Native Method)
                                                                at java.lang.reflect.Method.invoke(Method.java:372)
                                                                at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
                                                                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
                                                             Caused by: java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase: /data/data/mjt.shopwise/databases/ShopWise
                                                                at android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:55)
                                                                at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1312)
                                                                at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1255)
                                                                at mjt.shopwise.DBCommonMethods.getTableRows(DBCommonMethods.java:106)
                                                                at mjt.shopwise.DBCommonMethods.getTableRows(DBCommonMethods.java:59)
                                                                at mjt.shopwise.DBCommonMethods.getTableRowCount(DBCommonMethods.java:29)
                                                                at mjt.shopwise.DBCommonMethods.getTableRowCount(DBCommonMethods.java:43)
                                                                at mjt.shopwise.DBShopMethods.getShopCount(DBShopMethods.java:44)
                                                                at mjt.shopwise.MainActivity.getDBCounts(MainActivity.java:207)
                                                                at mjt.shopwise.MainActivity.onResume(MainActivity.java:163)
                                                                at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1257)
                                                                at android.app.Activity.performResume(Activity.java:6076)
                                                                at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2975)
                                                                at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3017) 
                                                                at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1347) 
                                                                at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                                at android.os.Looper.loop(Looper.java:135) 
                                                                at android.app.ActivityThread.main(ActivityThread.java:5254) 
                                                                at java.lang.reflect.Method.invoke(Native Method) 
                                                                at java.lang.reflect.Method.invoke(Method.java:372) 
                                                                at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903) 
                                                                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698) 

推荐答案

诀窍很简单,只要重置DBHelper,就不要关闭数据库.

The trick is very simple, do not close the database just reset the DBHelper.

所以重新打开方法可能是:-

So the reopen method could be:-

public static void reopen(Context context) {
        instance = new DBHelper(context);
    }

当然,您也可以删除告诉用户关闭并重新启动应用程序的文本.

Of course, you could also do away with the text telling the user to close and restart the App.

因此,检测并报告成功还原的代码可能是:-

So the code that detects and reports on a successful restore could be:-

if(copytaken && origdeleted && restoredone) {
                    errlist.add("Database successfully restored.");
                    resulttitle = "Restore was successful.";
                    DBHelper.reopen(context); <== implemented as below
                }

这篇关于使用单例作为数据库助手时,如何在还原后刷新/重新打开SQLite数据库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆