安卓上的SQLite JDBC驱动程序

7

我试图在Android中使用xerial sqlite-jdbc管理我的数据库,但没有成功。我得到了一个java.lang.NoClassDefFoundError: org.sqlite.SQLiteConnection的异常。我已经在我的Gradle中导入了这个依赖项'org.xerial:sqlite-jdbc:3.18.0'

我的代码如下:

 try {

        Class.forName("org.sqlite.JDBC");
        Connection connection = DriverManager.getConnection("jdbc:sqlite:hs.db");

    } catch (ClassNotFoundException eString) {System.err.println("Could not init JDBC driver - driver not found");
    } catch (java.sql.SQLException e) {e.printStackTrace();}

在我的项目中使用android.database.sqlite不是一个选项,所以请不要将其作为答案建议。

根据文档,该库的官方支持似乎在这个Google Group中,详情请参见此处 - CommonsWare
4个回答

4

我需要在我的服务器数据库和手机数据库之间共享一些数据库代码,所以我花了很多时间编写通用代码来使用JDBC。

然而,当我已经深入探索这个问题时,我发现基本上在Android上没有可以正常工作的JDBC实现。我强烈建议您不要走这条路——Xerial和SQLDroid JDBC驱动程序都存在重大问题,我只能在测试期间才发现这些问题。

Xerial问题

它在Android上根本不起作用:) 它甚至无法加载——我遇到了这个问题,尝试了几个小时后也无法解决。

SQLDroid问题

  1. 请查看开放问题页面——其中一些问题对我来说非常可怕。对我来说不能容忍的是缺乏批量支持。
  2. 在开始之前,请查看已知问题页面

最后,我创建了一个java.sql接口和方法的小子集实现,使用android.database.sqlite类。这比我想象的要简单得多(对于我需要的功能子集,只用了几个小时),而且运行良好!


你能详细介绍一下“我所需的java.sql接口和方法的小子集的实现”吗?你在服务器上使用了相同的子集吗?你使用了哪个API来实现它?Java中是否有更直接的sqlite API? - dfrankow
对于我在服务器上使用的每个java.sql接口,我都在我的Android项目中创建了一个类。例如,对于java.sql.Connection接口,我创建了以下类: public final class SQLiteConnection implements Connection 然后在Android Studio中,我选择“实现方法”操作来创建每个方法的虚拟实现。然后,我只使用android.database.sqlite类实现了我实际使用的那些方法。希望这样能够澄清问题。有许多SQLite JDBC实现,但我在2019年找不到任何适用于Android的实现。 - Vijayendra Vasu
在页面https://github.com/xerial/sqlite-jdbc中写道:“从下载页面(或使用Maven)下载sqlite-jdbc-(VERSION)。jar,然后将此jar文件附加到您的类路径中。” 说“它在Android上根本无法工作”是不正确的。 - Kodomo

4

Gradle

 compile 'org.sqldroid:sqldroid:1.0.3'

JAVA

import java.sql.DriverManager;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.SQLException;

public class MainActivity extends AppCompatActivity {

    private Connection connection;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        try {
            DriverManager.registerDriver((Driver) Class.forName("org.sqldroid.SQLDroidDriver").newInstance());
        } catch (Exception e) {
            throw new RuntimeException("Failed to register SQLDroidDriver");
        }
        String jdbcUrl = "jdbc:sqldroid:" + "/data/data/" + getPackageName() + "/my-database.db";
        try {
            this.connection = DriverManager.getConnection(jdbcUrl);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void onDestroy() {
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
        super.onDestroy();
    }
}

https://github.com/SQLDroid/SQLDroid


就像我之前说过的,这个项目不能选择其他选项。我必须使用JDBC连接。 - tasgr86
谢谢。这就是我最近一直在使用的,但是在gradle和Android Studio最近的升级后,我遇到了这个异常“java.lang.NoClassDefFoundError: org.sqlite.SQLiteConnection”。所以现在我正在尝试xerial,但是我仍然遇到同样的问题。 - tasgr86
可能是xerial jdbc未安装,请尝试清理项目,如果不起作用,请尝试减少此行代码:Class.forName("org.sqlite.JDBC"),因为在github存储库中没有这一行。https://github.com/xerial/sqlite-jdbc - dherediat

3

这是我的方式:

  1. app/build.gradle 文件中进行一些配置,并复制一个so文件,看起来不太美观,但确实适用于我的Android 9.0系统。
android {
    defaultConfig {
        ndk {
            abiFilters "armeabi-v7a"
        }
    }
    sourceSets {
        main {
            jniLibs.srcDirs = ['libs']
        }
    }
}
dependencies {
    implementation 'org.xerial:sqlite-jdbc:3.34.0'
}
  1. 然后将此文件 sqlite-jdbc-3.34.0.jar!\org\sqlite\native\Linux\android-arm\libsqlitejdbc.so 复制到 app/libs/armeabi-v7a/ 目录中,目录结构如下所示:enter image description here

  2. 构建完成的 APK 文件如下图所示:enter image description here

  3. 现在您可以在 Android 上使用 javax.sql.DataSource 来访问 SQLite 数据库了。


在我的情况下,我必须在proguard规则文件中定义以下行: -keep class org.sqlite.** { ; } -keepnames class org.sqlite.* { *; } - Petterson
这应该是最正确的答案,因为xerial的指令写道:将so文件复制到项目路径中。 - Kodomo

0

更新Gradle插件版本和Gradle版本至最新版本

文件 -> 项目结构

项目结构图像


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