【问题标题】:Closing an SQLite database on one thread breaks the database opened on another thread在一个线程上关闭 SQLite 数据库会破坏在另一个线程上打开的数据库
【发布时间】:2011-02-10 11:22:34
【问题描述】:

我们都learn 认为数据库连接等资源应该晚获取,早释放。

然而,将这一原则应用于 Android 上的 SQLite 数据库连接让我有些头疼。

我有一个应用程序,它可以在后台运行的服务中从后端服务器下载更新,并定期将更新写入数据库。当以下顺序发生时,就会出现我遇到的问题:

  1. 服务打开一个可写的数据库连接
  2. 一些活动打开了一个可读的数据库连接
  3. 服务在读取数据的活动同时关闭其数据库连接
  4. 活动因数据库连接已关闭而失败

服务和活动都使用相同的SQLiteOpenHelper 类(尽管实例不同)来打开它们的连接。我最初的假设是这应该可以正常工作,但不知何故,底层连接似乎在两个数据库实例之间共享。

为了解决这个问题,我最终不关闭数据库对象,只关闭所有打开的游标。这似乎有效,但我不确定我没有在这里泄漏内存。

我这里有什么明显的遗漏吗?

【问题讨论】:

  • “并发”是什么意思?服务是否运行后台线程?
  • @Graham:是的,如前所述,该服务正在后台运行,在单独的线程上运行。
  • 是的,我的意思是“同时”。
  • 你是在实例化 SQLiteOpenHelper 的两个子类吗?
  • @Tim:是的,如前所述,助手类的实例不共享。

标签: android multithreading sqlite


【解决方案1】:

我这里有什么明显的遗漏吗?

我会说不。查看SQLiteOpenHelper 的源代码,我看不出两个实例如何共享SQLiteDatabase 对象。

一些诊断建议:

  • 转储每个SQLiteDatabasetoString() 值,这应该会为您提供一个Java 实例ID。如果它们相同,那就是您的问题所在,您需要按照自己的方式向上游工作以弄清楚这是怎么发生的(例如,您确实使用了相同的 SQLiteOpenHelper 实例)。李>
  • 当您的数据库处于稳定状态(即,无需创建或升级)时,翻转您的两个数据库点之一以直接使用SQLiteDatabase,而不是通过SQLiteOpenHelper,看看这是否重要。

【讨论】:

  • 感谢您的意见。由于我使用 roboguice 来注入实例,因此我进行了测试,断言 roboguice 实际上正在为每个依赖项提供唯一实例。我将尝试按照您的建议使用 SQLiteOpenHelperSQLiteDatabase 进行更孤立的测试。
猜你喜欢
  • 1970-01-01
  • 2011-12-22
  • 1970-01-01
  • 2010-12-05
  • 1970-01-01
  • 2015-06-14
  • 2017-04-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多