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)
quastion vor 5min gefragt und Sie Ihre eigene Frage sofort beantworten? –
@VygintasB er schrieb diese Frage, weil es jemand helfen wird, der sich diesem ähnlichen Problem stellen wird, wir müssen es schätzen :) – Redman
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