Жизненный цикл активности и путаница в базе данных

У меня есть действие, в котором я открываю базу данных, вызывая конструктор SQLiteOpenHelper.

dbHelper = new DBHelper(this); //DBHelper class extends SQLiteOpenHelper

Затем по нажатию кнопки я открываю другое действие и закрываю dbHelper.

int cuisineId = HelperUtils.getCuisineIdByName(dbHelper,cuisine);
SingletonGlobalClass.getInstance().setCuisineId(cuisineId);
String restaurantNameSearchStr = restaurantName.getText().toString().trim();
Intent intent = new Intent();
intent.setComponent(new ComponentName("ctnxa.android", ctnxa.android.SearchResultActivity"));
intent.putExtra("searchStr", restaurantNameSearchStr);
intent.putExtra("option", R.string.restaurant);
startActivity(intent);
dbHelper.close();

Теперь, когда я нажимаю кнопку «Назад», он возвращается к этому действию. Когда я снова пытаюсь нажать кнопку поиска, он использует dbHelper и работает как обычно без каких-либо ошибок. Я ожидаю, что это не должно работать, поскольку dbHelper уже был закрыт ранее, и его можно повторно создать только при вызове метода onCreate(), который не вызывается в этом случае, поскольку я только нажимаю кнопку «Назад» (он должен вызвать при возобновлении ()). Я действительно смущен. Может ли кто-нибудь объяснить, что здесь происходит.

Изменить: вот как я реализовал dbHelper.close()

@Override
public synchronized void close() {
    super.close();
}

person Sush    schedule 25.12.2011    source источник
comment
в методе close() для класса DBHelper вы правильно закрываете базу данных? Пожалуйста, напечатайте метод close(). И как вы объявили свою первую активность в манифесте какими-либо дополнительными параметрами? вроде режим запуска...   -  person Rick    schedule 26.12.2011
comment
@Rabgs: обновленный вопрос с методом закрытия.   -  person Sush    schedule 26.12.2011
comment
Вы должны вызывать метод закрытия SQLiteDatabase в методе закрытия DBHelpber. Пример здесь code.google.com/p/android-notes/source/browse/trunk/src/com/   -  person Rick    schedule 26.12.2011
comment
Согласно документам разработчика SQLiteOpenHelper.close() должен закрыть любой открытый объект базы данных. Таким образом, вызов dbHelper.close() должен закрыть любой открытый объект базы данных.   -  person Sush    schedule 26.12.2011


Ответы (2)


Когда вы запускаете новый Activity, первый Activity может пройти или не пройти различные этапы «выхода», но нет гарантии, через какие из них он пройдет. Это полностью зависит от доступных ресурсов и других факторов на отдельном устройстве.

Первый Activity может просто приостановиться, и когда вы вернетесь, он возобновится. Тем не менее, первая Активность, скорее всего, может быть остановлена ​​или даже уничтожена. Нет никакой гарантии, что ОС Android сделает с первым Activity.

В вашем случае кажется, что первый IS фактически уничтожается и воссоздается, когда вы возвращаетесь из второго Activity.

Единственный способ проверить это — переопределить все методы, такие как onPause, onStop и onDestroy, и заставить каждый из них использовать Log, чтобы показать, через какие этапы проходит первый Activity.

person Squonk    schedule 25.12.2011
comment
Я проверил, поставив точки останова, чтобы увидеть, воссоздается ли он. Но нет, он не воссоздается. - person Sush; 26.12.2011
comment
Итак, что делает HelperUtils.getCuisineIdByName(dbHelper,cuisine)? Из того, что вы объясняете, dbHelper.close() не освобождает / не делает недействительным сам dbHelper - он по-прежнему будет ссылаться на экземпляр вашего SQLiteHelper. Если HelperUtils.getCuisineIdByName(...) вызывает getReadbleDatabase() или getWritableDatabase, то поведение имеет смысл. - person Squonk; 26.12.2011
comment
да. он неявно вызывает getReadableDatabase().rawQuery. Тогда, пожалуйста, объясните, как это имеет смысл. - person Sush; 26.12.2011
comment
В порядке. Может быть, я понимаю, что вы пытаетесь объяснить. Согласно документам, вызов getReadableDatabase() создает и/или открывает базу данных. Таким образом, он повторно открывает базу данных. Это правильно? - person Sush; 26.12.2011
comment
Да исправить. Вызов dbHelper.close() просто закрывает базу данных, но если вы говорите, что первая Activity не уничтожена, dbHelper по-прежнему будет содержать действительную ссылку, когда вы вернетесь из второй Activity. Пока это так, вызов HelperUtils.getCuisineIdByName(dbHelper,cuisine) получит еще одну ссылку на базу данных, потому что он вызывает getReadableDatabase для вызова rawQuery. Однако не ожидайте, что это поведение будет последовательным - как я сказал в своем ответе, вы не можете полагаться на то, что первый Activity выживет после того, как вы запустите второй. - person Squonk; 26.12.2011
comment
Спасибо. Это очень помогло мне понять концепцию. - person Sush; 26.12.2011

вы можете избежать большой путаницы, обеспечив наличие только одного SQLiteOpenHelper на протяжении всего жизненного цикла приложения. ознакомьтесь с этим ответом для получения дополнительной информации.

person Alex Lockwood    schedule 17.01.2012