在一个线程中关闭SQLite数据库会破坏在另一个线程上打开的数据库。

3

我们都知道,诸如数据库连接之类的资源应该尽可能晚地获取并尽早释放。

然而,将此原则应用于Android上的SQLite数据库连接却给我带来了一些头疼。

我有一个应用程序,在后台工作的服务中从后端服务器下载更新,并定期将更新写入数据库。当发生以下序列时,我遇到了问题:

  1. 服务打开可写数据库连接
  2. 某些活动打开可读数据库连接
  3. 服务与读取数据的活动同时关闭其数据库连接
  4. 活动因其数据库连接被关闭而失败

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

为了解决这个问题,我最终没有关闭数据库对象,只关闭了打开的游标。这似乎有效,但我不确定是否存在内存泄漏的情况。
这里有什么明显的问题吗?

“concurrently”是什么意思?这个服务是否在后台运行一个线程? - Graham Borland
@Graham:是的,正如所提到的,该服务正在后台的单独线程上工作。 - Peter Lillevold
是的,通过并发,我指的是“同时进行”。 - Peter Lillevold
你是否正在实例化两个SQLiteOpenHelper的子类? - Tim
@Peter:在Android中,一个类的实例和该类的子类的实例之间是否存在功能上的差异? - Tim
显示剩余2条评论
1个回答

1
这里有什么明显的问题我忽略了吗?
我认为没有。查看SQLiteOpenHelper的源代码,我看不出两个实例如何共享一个SQLiteDatabase对象。
一些诊断建议:
  • 转储每个SQLiteDatabasetoString()值,这应该给您一个Java实例ID。如果它们相同,那就是您的问题所在,您需要向上游工作,以找出这是如何发生的(例如,您确实正在使用SQLiteOpenHelper的同一实例)。
  • 在数据库处于稳定状态时(即无需创建或升级),将你的两个数据库位置之一翻转到直接使用SQLiteDatabase,而不是通过SQLiteOpenHelper,并查看是否改变了事情。

感谢您的输入。由于我正在使用Roboguice来注入实例,我已经进行了测试以确保Roboguice实际上为每个依赖提供唯一的实例。我将尝试按照您的建议进行更为独立的测试,测试对象是SQLiteOpenHelper和SQLiteDatabase。 - Peter Lillevold

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接