как правильно открыть и закрыть базу данных - PullRequest
7 голосов
/ 15 июня 2011

У меня есть приложение, которое хранит некоторые данные в базе данных SQLite. Также я выполняю большой запрос в моем приложении. У меня есть около 15 действий. И почти все используют БД для запроса данных. Но я открываю свою БД в каждом действии и закрываю в onDestroy {...} каждого действия.

Проблема в том, что onDestroy {...} может никогда не вызываться, и иногда мое приложение остается включенным в течение длительного времени, и я переключаюсь с активности на другое открытие во много раз мою БД.

И иногда я получаю сообщения об ошибках, например, слишком много раз открываю и никогда не закрываю.

Я бы попытался закрыть свою БД точно после того, как получу от нее свои данные и закрою ее ... перейдя к следующему действию и снова открыв и так далее ..... Но проблема в том, что в некоторых действиях я возвращаюсь из других действий ... закрытие базы данных и возвращение к этому занятию приводят к большому закрытию силы.

Что я хочу сделать, так это открыть мою БД в начале моего приложения и закрыть ее в конце, но я сталкиваюсь с 2 проблемами:

1. Должен ли я сделать свой класс SQLiteOpenHelper одноэлементным? ... получить экземпляр этого ... открыть его в моем первом действии, а затем в моих следующих действиях просто получить экземпляр моей БД, который уже открыт / ???

2. Где конец моего приложения? Как я должен знать, где находится конец моего приложения и где закрыть мою БД.

EDIT:

public class DBAdapter extends SQLiteOpenHelper {

    public DBAdapter(Context context) {
        super(context, DATABASE_NAME, null, 1);
        this.myContext = context;

    }


    public void openDataBase() throws SQLException {




        String myPath = DATABASE_PATH + DATABASE_NAME;
        db = SQLiteDatabase.openDatabase(myPath, null,
                SQLiteDatabase.OPEN_READWRITE);


    }

}

Это фрагмент кода из моего класса, который управляет моей базой данных. Чтобы создать этот синглтон, я должен использовать конструктор, такой:

private DBAdapter()
{



//nothing in here

}

Но это не определено для SQLiteOpenHelper

Редактировать финал: Вот как я это сделал в соответствии с советами Зираэля:

пакет com.Server_1;

import android.app.Application;

открытый класс MyApplication расширяет приложение {

private static DBAdapter db;

public void onCreate()
{

    db=new DBAdapter(getApplicationContext());
    db.createDatabase();
    db.openDataBase();
}

public static DBAdapter getDatabaseAdapter()
{
    return db;
}


}

В каждом задании, где мне нужно подключение к БД, я делаю это:

MyApplication myApplication = (MyApplication) this.getApplication ();

DBAdapter db = myApplication.getDatabaseAdapter ();

И, наконец, мой манифест выглядит так:

<application  android:icon="@drawable/icon"  
android:label="@string/app_name"
  android:name=".MyApplication" 
  android:debuggable="true">

Ответы [ 5 ]

9 голосов
/ 15 июня 2011

В моем приложении я открываю соединение с базой данных в классе myApplication (ваш пользовательский класс, который расширяет Application - должен называться так же, как ваше приложение в androidManifest).

AndroidManifest.xml

<application android:label="@string/app_name" 
    android:name="com.mypackage.MyApplication " android:debuggable="true">

MyApplication .java

public class MyApplication extends Application {

    private DatabaseAdapter dbAdapter;


    @Override
    public void onCreate() {
        dbAdapter = new DatabaseAdapter(getApplicationContext());
        dbAdapter.open();
    }

И в каждом классе, который требует подключения к базе данных, я просто использую:

MyApplication myApplication = (MyApplication) this.getApplication();
DatabaseAdapter dbAdapter= myApplication.getDatabaseAdapter();

MyApplication запускается автоматически при каждом запуске приложения.Таким образом, я сохраняю только одно соединение с БД, поэтому оно закрывается, когда приложение удаляется из памяти без проблем.

3 голосов
/ 15 июня 2011

Когда вы извлекаете dbAdapter из своего класса MyApplication, делайте это лениво, создавая его только при необходимости. В моей реализации я также открываю его в это время.

public static DbAdapter getDbAdapter() {
    if (dbAdapter == null) {
        dbAdapter = new DbAdapter();
    }
    dbAdapter.open();
    return dbAdapter;
}

Рекомендуется использовать getReadableDatabase () или getWriteableDatabase () в методе open вашего адаптера базы данных.

Кроме того, я думаю, что он лучше работает для извлечения вашего адаптера в onStart () и закрытия его в onStop () тех операций, в которых он используется, вместо использования onCreate () и onDestroy ().

@Override
protected void onStop() {
    super.onStop();
    MyApp.closeDatabase();
}

А в классе MyApp ...

public static void closeDatabase() {
    dbAdapter.close();
}
2 голосов
/ 15 июня 2011

Если вы не управляете своей базой данных в соответствии с рекомендациями Google, почему бы и нет - обычно есть веская причина, почему вещи такие, какие они есть ...

В любом случае вы можете использовать getReadableDatabase () и getWriteableDatabase () - эти функции при необходимости откроют базу данных, но просто вернут существующий объект базы данных, если он уже открыт, что не позволит вам открыть базу данных несколько раз.

0 голосов
/ 26 июля 2017

Есть хороший ответ на другой вопрос Лучшее место для закрытия соединения с базой данных

"Согласно этому сообщению инженера Google, нет ничего плохого в том, чтобы оставить соединение с базой данных открытым:

Android принял взвешенное дизайнерское решение, которое может показаться удивительным, просто отказавшись от идеи чистого выхода приложений и вместо этого позволив ядру очистить свои ресурсы. В конце концов, ядро ​​должно бытьв любом случае это возможно. Учитывая этот дизайн, держать что-либо открытым в течение всего срока службы процесса и никогда не закрывать его - это просто не утечка. Оно будет очищено при очистке процесса.

Итак, для простоты я бы расширил класс Application, чтобы обеспечить единую четко определенную точку входа для вашего кода, и открыл бы соединение с базой данных в его onCreate (). Сохраните соединение с БД как поле в вашем Application и предоставьтеметод доступа, чтобы сделать соединение доступным для остальныхода.

Тогда не беспокойтесь о его закрытии. "

0 голосов
/ 15 июня 2011

Что-то, что вы можете попробовать, это использовать синглтон, к которому каждое действие будет прикрепляться в своем обратном вызове onResume (), и отсоединяться от него в обратном вызове onPause ().Когда счетчик отсоединения достигнет нуля, установите таймер, который будет отменен в методе attach.Если время таймера истекло, закройте базу данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...