2017-02-16 1 views
0

Ich habe Database Backup und Restore in meine App integriert. Dies alles funktioniert gut, außer dass, wenn ich die Datenbank wiederherstelle, aufgrund der Verwendung eines Singleton DBHelper zusammen mit dem Schließen der Datenbank nur, wenn die App geschlossen wird, die In-Memory-Kopie der Datenbank nach der Wiederherstellung weiterhin verwendet wird.Wie kann ich eine SQLite-Datenbank nach der Wiederherstellung aktualisieren/öffnen, wenn ich einen Singleton für den Datenbankhelfer verwende

Schließen der App und neu starten verwendet die neue Datenbank. Jedoch, anstatt dem Benutzer zu sagen, dies zu tun. Ich möchte nahtlos auf die wiederhergestellte Datenbank zugreifen.

Dies ist der Code, und dann wiederherstellen, berichtet über eine erfolgreiche erkennt: -

   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 

Dies ist der DBHelper (beachten Sie erweitert Methode verwendet wird, um die Tabellen zu erstellen/ändern)

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); 
    } 
    ....... 

Denken Sie daran, dass Sie die Datenbank schließen und erneut öffnen sollten. Ich habe versucht, ein Verfahren, in dem DBHelper wieder öffnen Zugabe wie folgt: -

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

und diese dann aufgerufen aus dem Code, wenn das war in Ordnung wiederherstellen (per Kommentar). Dies führt jedoch in dem folgenden: -

java.lang.IllegalStateException: Versuch, wieder zu öffnen ein bereits geschlossen Objekt: 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)  

Antwort

1

Der Trick ist sehr einfach, Schließen Sie die Datenbank nicht, setzen Sie einfach die DBHelper zurück.

die Methode könnte wieder öffnen Also: -

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

Natürlich können Sie auch mit dem Text den Benutzer erklären, abschaffen, die App zu schließen und neu zu starten.

So ist der Code, und Berichte über eine erfolgreiche erkennt könnte wiederherstellen: -

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

quastion vor 5min gefragt und Sie Ihre eigene Frage sofort beantworten? –

+0

@VygintasB er schrieb diese Frage, weil es jemand helfen wird, der sich diesem ähnlichen Problem stellen wird, wir müssen es schätzen :) – Redman

+0

Das Beantworten Ihrer eigenen Fragen kann hilfreich sein. Nachdem Sie eine Suche durchgeführt und nichts gefunden und dann die Auflösung bestimmt haben, könnte dies anderen helfen. Aus diesem Grund gibt es ein Kontrollkästchen "Eigene Frage anfragen", wenn Sie eine Frage wie folgt stellen: "Beantworten Sie Ihre eigene Frage - teilen Sie Ihr Wissen, Q & A-Stil" * – MikeT

Verwandte Themen