2016-04-19 4 views
0

Сейчас я использую статический экземпляр класса SQLOpenHelper класса как так:Правильный способ открытия/закрытия базы данных?

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

    //... 
} 

а затем DatabaseProcessor класс следующим образом:

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

    //... 
} 

Так что, если я хочу, чтобы получить доступ к своей базе данных, я что-то вроде этого:

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

Это правильный способ сделать это? Или лучше открыть базу данных в базе Activity onResume() и закрыть ее во время onPause()? Как правильно ошибаться в случаях, когда база данных не открывается при попытке выполнить запрос?

EDIT Refactored версия:

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

Обычно ответ: вы никогда не закрываете базу данных. Поскольку ввод/вывод базы данных необходимо выполнять по фоновым потокам, и поскольку вы можете работать с базой данных за пределами какого-либо одного действия (например, несколько видов деятельности, возможно, службы или два), часто бывает трудно узнать, когда все делается с базой данных. Вы не хотите закрывать его, пока часть вашего приложения все еще работает с ним. – CommonsWare

+0

Будет ли держать его открытым, увеличить риск повреждения данных? Я вспоминаю некоторое время назад, случайная ошибка Logcat сообщила мне, что у меня была утечка в базе данных и что я должен закрыть ее, когда она не используется (или что-то в этом роде). – KaliMa

+0

В противном случае: я предполагаю, что в своей деятельности Launcher создайте экземпляр базы данных, 'open()' it и никогда не называть 'close()' на ней когда-либо? И просто используйте 'newInstance()' везде, где мне нужен доступ к базе данных? – KaliMa

ответ

0

Лучше всего было бы положить ваши заявления запросов/транзакций в try-catch, а затем освободить все ресурсы и закрыть соединение в finally блоке.

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

Не ловите общие исключения, которые считаются сомнительными? – KaliMa

+0

Я просто привел вам пример. Определенно вам нужно поймать определенные исключения в соответствии с вашим кодом. –