【问题标题】:Can you use the SQLite R-Tree Module with Android Room?你可以在 Android Room 中使用 SQLite R-Tree 模块吗?
【发布时间】:2019-09-12 12:17:30
【问题描述】:

我有一个 Android 应用程序,它使用 SQLite 数据库将二维数据存储在带有 SQLite R*-Tree Module 的 R-Tree 中。

随着June 2017 的更新,SQLite 的预构建版本现在默认启用此模块,因此我不必再自己构建它了。我正在使用那个 SQLite 库而不是 android.database.sqlite 库。

我现在的问题是,我可以使用Android Room library 访问我的数据库,假设它在内部使用另一个 SQLite 库吗?

当我尝试查询已被另一个进程填充的现有数据库时,我收到以下异常:

android.database.sqlite.SQLiteException: no such module: rtree (code 1): , while compiling: SELECT * FROM r_tree WHERE minX <= ? AND maxX >= ? AND minY <= ? AND maxY >= ?
at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:889)
at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:500)
at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:37)
at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:44)
at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1318)
at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1293)
at androidx.sqlite.db.framework.FrameworkSQLiteDatabase.query(FrameworkSQLiteDatabase.java:161)
at androidx.room.RoomDatabase.query(RoomDatabase.java:305)
at androidx.room.util.DBUtil.query(DBUtil.java:54)
at at.mycompany.app.android.myfeature.persistance.RTreeDao_Impl.getObjectsInBoundingBox(RTreeDao_Impl.java:36)
at at.mycompany.app.android.myfeature.ReadmyfeatureDatabaseTest.readRTreeObjects(ReadmyfeatureDatabaseTest.java:133)
at java.lang.reflect.Method.invoke(Native Method)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at androidx.test.internal.runner.junit4.statement.RunBefores.evaluate(RunBefores.java:80)
at androidx.test.internal.runner.junit4.statement.RunAfters.evaluate(RunAfters.java:61)
at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:48)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at androidx.test.ext.junit.runners.AndroidJUnit4.run(AndroidJUnit4.java:104)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at androidx.test.internal.runner.TestExecutor.execute(TestExecutor.java:56)
at androidx.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:392)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:2074)

因此,Room 似乎在内部使用了另一个 SQLite 库,而不是我包含在我的应用程序中的那个。有没有可能交换这个?或者任何其他方式使 Room 能够从 R-Tree 表中读取数据,或者我是否必须为该请求编写原始查询?

【问题讨论】:

  • 你做到了吗?
  • 是的,按照下面的答案,对现有的包装类做一些复制粘贴编辑。
  • 我确实做到了,但是 aar 包中的 SQLiteOpenHelper 在可写时无法从上下文解析数据库路径,并且我的应用程序每次都崩溃。
  • 您将不得不替换所有这些导入/加载 SQL 数据库模块的帮助类。基本上,继续,抓住现有的实现并替换所有的 import 语句,然后使用你自己的 SQLiteOpenHelper 实现。你已经完成了,一旦你的代码中不再有 import android.database.sqlite 而只有 import org.sqlite.database.sqlite

标签: android sqlite android-sqlite android-room


【解决方案1】:

看来 Room 在内部使用了另一个 SQLite 库,而不是我在我的应用中包含的那个

your linked-to instructions 的第 8 步是“将 SQlite 导入替换为 org.sqlite.database.sqlite.xxxxxx”。 Room 不会以某种方式自动执行此操作。

这个可以换吗?

您需要编写连接到 SQLite 库的SupportSQLite* 接口集的实现。其中之一是SupportSQLiteHelper.Factory,您需要通过openHelperFactory() 向您的RoomDatabase.Builder 提供该实例。

您可以在以下位置查看它的实现:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-05
    • 2011-12-19
    • 2019-01-06
    • 1970-01-01
    • 2019-07-15
    相关资源
    最近更新 更多