【问题标题】:Activity life cycle and database confusionActivity生命周期和数据库混淆
【发布时间】:2011-12-25 20:06:31
【问题描述】:

我有一个活动,我通过调用 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() 方法时重新实例化,在这种情况下不会被调用,因为我只是按下后退按钮(它应该调用onResume())。我真的很困惑。任何机构都可以解释这里发生了什么。

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

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

【问题讨论】:

  • 在 DBHelper 类的 close() 方法中,您是否正确关闭了数据库?请打印 close() 方法。你是如何在清单中声明你的第一个 Activity 任何额外选项的?像launchMode ...
  • @Rabgs:使用 close 方法更新问题。
  • 您应该在 DBHelpber 关闭方法中调用 SQLiteDatabase 关闭方法。这里的例子code.google.com/p/android-notes/source/browse/trunk/src/com/…
  • 根据开发人员文档 SQLiteOpenHelper.close() 应该关闭任何打开的数据库对象。所以对 dbHelper.close() 的调用应该关闭任何打开的数据库对象。

标签: android android-activity sqliteopenhelper


【解决方案1】:

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

第一个Activity 可能只是暂停,当您返回时它会恢复。但是,第一个 Activity 很可能会被停止甚至销毁。无法保证 Android 操作系统会对第一个 Activity 执行什么操作。

在您的情况下,当您从第二个Activity 返回时,似乎第一个 IS 实际上被销毁并重新创建。

验证这一点的唯一方法是覆盖所有方法,例如onPause、onStop 和onDestroy,并让它们每个都使用Log 来显示第一个Activity 经历的阶段。

【讨论】:

  • 我通过放置断点来测试它是否被重新创建。但不,它没有被重新创建。
  • 好的,那么HelperUtils.getCuisineIdByName(dbHelper,cuisine) 是做什么的?根据您的解释,dbHelper.close() 本身不会释放/使dbHelper 无效-它仍将引用您的SQLiteHelper 的实例。如果HelperUtils.getCuisineIdByName(...) 调用getReadbleDatabase() 或getWritableDatabase,那么这种行为是有道理的。
  • 是的。它隐式调用 getReadableDatabase().rawQuery。然后请解释它的意义。
  • 好的。可能我明白你想解释什么。根据文档,调用 getReadableDatabase() 创建和/或打开数据库。所以它重新打开数据库。对吗?
  • 是的,正确的。调用 dbHelper.close() 只会关闭数据库,但如果您说第一个 Activity 未销毁,则当您从第二个 Activity 返回时,dbHelper 仍将保持有效引用。只要是这种情况,对HelperUtils.getCuisineIdByName(dbHelper,cuisine) 的调用将获得对数据库的另一个引用,因为它调用getReadableDatabase 是为了调用rawQuery。做,不要指望这种行为是一致的 - 正如我在回答中所说,你不能依靠第一个 Activity 在你开始第二个之后生存。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 2018-07-18
    • 2012-09-21
    • 2019-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-06
    • 2015-05-13
    • 1970-01-01
    相关资源
    最近更新 更多