2016-04-19 10 views
0

Momentan verwende ich eine statische Instanz der SQLOpenHelper Klasse wie folgt:Richtiger Weg zum Öffnen/Schließen der Datenbank?

public class DatabaseHelper extends SQLiteOpenHelper { 
    private static DatabaseHelper mInstance = null; 
    private final Context mContext; 

    //... 

    public static synchronized DatabaseHelper getInstance(Context context) { 
     /** 
     * use the application context as suggested by CommonsWare. 
     * this will ensure that you don't accidentally leak an Activity's 
     * context (see this article for more information: 
     * http://android-developers.blogspot.nl/2009/01/avoiding-memory-leaks.html) 
     */ 
     if (mInstance == null) { 
      mInstance = new DatabaseHelper(context.getApplicationContext()); 
     } 
     return mInstance; 
    } 

    private DatabaseHelper(Context context) { 
     super(context, DB_NAME, null, DB_VERSION); 
     mContext = context; 
    } 

    //... 
} 

Und dann ein DatabaseProcessor Klasse wie folgt:

public class DatabaseProcessor { 

    private SQLiteDatabase mDatabase; 
    private DatabaseHelper mSQLHelper; 
    private Context mContext; 

    public DatabaseProcessor(Context context) { 
     mContext = context; 
     mSQLHelper = DatabaseHelper.getInstance(mContext); 
    } 

    public void open() throws SQLException { 
     mDatabase = mSQLHelper.getWritableDatabase(); 
    } 

    public void close() { 
     mDatabase.close(); 
    } 

    //... 
} 

Also, wenn ich meine Datenbank zugreifen will, muss ich tun etwas wie das:

DatabaseProcessor mDatabaseProcessor = new DatabaseProcessor(this); 
mDatabaseProcessor.open(); 
mSomeList = mDatabaseProcessor.doSomeQueryAndReturnResults(); 
mDatabaseProcessor.close(); 

Ist dies der richtige Weg, dies zu tun? Oder ist es besser, die Datenbank in der base Activity onResume() -Methode zu öffnen und sie während onPause() zu schließen? Wie kann ich Fehler in Situationen, in denen die Datenbank nicht geöffnet ist, korrekt ausgeben, wenn ich versuche, eine Abfrage auszuführen?

EDIT Überarbeitete Version:

public class DatabaseHelper extends SQLiteOpenHelper { 
    private static SQLiteDatabase mDatabase; 
    private static DatabaseHelper mInstance = null; 
    private static Context mContext; 

    // ... 

    public static synchronized DatabaseHelper getInstance(Context context) { 
     /** 
     * use the application context as suggested by CommonsWare. 
     * this will ensure that you don't accidentally leak an Activity's 
     * context (see this article for more information: 
     * http://android-developers.blogspot.nl/2009/01/avoiding-memory-leaks.html) 
     */ 
     if (mInstance == null) { 
      mInstance = new DatabaseHelper(context.getApplicationContext()); 
     } 
     return mInstance; 
    } 

    private DatabaseHelper(Context context) { 
     super(context, DB_NAME, null, DB_VERSION); 
     mContext = context; 
    } 

    @Override 
    public void onCreate(SQLiteDatabase db) { 
     db.execSQL(DB_CREATE_SOME_TABLE); //some SQL expression 
    } 

    @Override 
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
     db.execSQL(DB_ALTER); 
    } 

    public void open() throws SQLException { 
     mDatabase = getWritableDatabase(); 
    } 

    public void close() { 
     mDatabase.close(); 
    } 

    public boolean isOpen() { 
     return mDatabase.isOpen(); 
    } 

    //below this would be various CRUD functions operating on mDatabase 
    // ... 
    // ... 
} 
+1

Normalerweise lautet die Antwort: Sie schließen nie die Datenbank. Da Datenbank-I/O auf Hintergrund-Threads ausgeführt werden muss, und da Sie möglicherweise mit der Datenbank über eine einzelne Aktivität hinaus arbeiten (z. B. mehrere Aktivitäten, vielleicht ein oder zwei Dienste), ist es oft schwierig zu wissen, wann alle fertig sind mit der Datenbank. Sie möchten es nicht schließen, während Teile Ihrer App noch damit arbeiten. – CommonsWare

+0

Wird die Offenlegung der Daten das Risiko der Datenbeschädigung erhöhen? Ich erinnere mich, dass vor einiger Zeit ein zufälliger Logcat Fehler mich informierte, dass ich ein Leck in der Datenbank hatte und dass ich es schließen sollte, wenn es nicht benutzt wird (oder etwas in diesem Sinne). – KaliMa

+0

Sonst: Ich nehme an, dass in meiner Launcher Aktivität Datenbank, 'open()' es, und nie 'close()' jemals darauf aufrufen? Und benutze 'newInstance()' einfach überall dort, wo ich auf die Datenbank zugreifen muss? – KaliMa

Antwort

0

Der beste Weg wäre, um Ihre Abfrage/Transaktionsanweisungen in try-catch zu setzen und dann alle Ressourcen freigeben und die Verbindung in finally Block zu schließen.

try{ 
     mSomeList = mDatabaseProcessor.doSomeQueryAndReturnResults(); 
} catch(Exception exc){ 
    //Catch exceptions here 
} 
finally{ 
    if(mDatabaseProcessor != null) 
     mDatabaseProcessor.close(); 
} 
+1

Fängt generische Ausnahmen nicht als fraglich ein? – KaliMa

+0

Ich habe dir nur ein Beispiel gegeben. Definitiv müssen Sie bestimmte Ausnahmen nach Ihrem Code abfangen. –

Verwandte Themen