Android 活动生命周期和数据库混乱

Android 活动生命周期和数据库混乱,android,android-activity,sqliteopenhelper,Android,Android Activity,Sqliteopenhelper,我有一个活动,通过调用SQLiteOpenHelper的构造函数打开数据库 dbHelper = new DBHelper(this); //DBHelper class extends SQLiteOpenHelper 然后单击一个按钮,打开另一个活动并关闭dbHelper int cuisineId = HelperUtils.getCuisineIdByName(dbHelper,cuisine); SingletonGlobalClass.getInstance().setCuisin

我有一个活动,通过调用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以前已经关闭过,只有在调用activity onCreate()方法时才能重新实例化它,在本例中,该方法没有被调用,因为我只按了后退按钮(它应该调用onResume())。我真的很困惑。谁能解释一下这里发生了什么事

编辑:这就是我实现dbHelper.close()的方式


当您开始一个新的
活动时,第一个
活动可能会也可能不会经历不同的“退出”阶段,但无法保证它会经历哪些阶段。它完全取决于单个设备上的可用资源和其他因素

第一个
活动
可能只是暂停,当您返回时,它将继续。然而,第一个活动很可能会被停止,甚至被破坏。无法保证Android操作系统将如何处理第一个
活动

在您的情况下,当您从第二个
活动返回时,第一个活动似乎实际上正在被销毁和重新创建


验证这一点的唯一方法是覆盖所有方法,例如
onPause
onStop
onDestroy
,并让他们每个人使用
Log
来显示第一个
活动
所经过的阶段。

通过确保在应用程序的整个生命周期中只存在一个SQLiteOpenHelper,可以避免很多这种混淆。更多信息,请查看此文件。

我通过设置断点来测试它是否正在重新创建。但是没有,它不会被重新创建。好吧,那么
HelperUtils.getCuisineIDyname(dbHelper,courine)
做什么呢?根据您的解释,
dbHelper.close()
不会释放/失效
dbHelper
本身-它仍然会引用
SQLiteHelper
的实例。如果
HelperUtils.getCuisineIDyname(…)
调用
getReadableDatabase()
getWritableDatabase
,则该行为有意义。是。它隐式调用getReadableDatabase().rawQuery。那么请解释一下它的意义。也许我明白你想解释什么。根据文档,调用getReadableDatabase()创建和/或打开一个数据库。所以它会重新打开数据库。对吗?对,对。调用dbHelper.close()只会关闭数据库,但如果您说第一个
活动
未被销毁,那么当您从第二个
活动
返回时,
dbHelper
仍将保留有效引用。在这种情况下,对
HelperUtils.getCuisineIDyname(dbHelper,courine)
的调用将获得对数据库的另一个引用,因为它正在调用
getReadableDatabase
,以便调用
rawQuery
。但是,不要期望这种行为是一致的——正如我在回答中所说的,在启动第二个
活动之后,您不能依靠第一个
活动
生存。在DBHelper类的close()方法中,您是否正确关闭了数据库?请打印close()方法。您如何在清单中声明您的第一个活动以及其他选项?像launchMode…@rabbs:用close方法更新了问题。您应该在DBHelpber close方法中调用SQLiteDatabase close方法。根据开发人员文档,这里的示例SQLiteOpenHelper.close()应该关闭任何打开的数据库对象。因此,对dbHelper.close()的调用应该关闭任何打开的数据库对象。
@Override
public synchronized void close() {
    super.close();
}