前言:Qt开发Android程序时,之前踩了TCP通讯的坑,那就是不能用官方自带的QModbusClient库,只能用QTcpSocket库手搓。
现在又遇到了连接mysql数据库的问题,官方的安装包中只给出了sqlLite数据库的编译好的库文件,如果自己编译手机端的mySQL数据库驱动难度很大,因此,经过很几天的不懈努力研究,成功通过Qt调用java程序实现手机端连mySQL数据库,现做详细记录。
- 确保Qt已经配置好了安卓的开发环境,将空窗体能在安卓端运行
- 我的环境是
– Qt 5.14.2
– Windows 10系统
– 夜神模拟器
– SDK NDK见下图
– Android 8.0.26
1. 第一步 新建工程
具体新建过程不再记录,效果如图
2. 创建Android模板
出现下图,直接点完成
效果如下图 会在项目中自动添加如下内容
根据上图箭头指示,添加两个东西
添加完以后直接Ctrl+s保存
第三步 添加Android模块
在.pro文件中加入如下内容
第四步 新建java文件作为中间层
最后的项目结构如下图所示,注意:java文件的目录最好严格按照下面的路径进行设置,否则后面会报找不到java类的错误, 这是踩的第一个坑
在java文件中编写如下代码,先进行简单的测试
package org.qtproject.example;
public class SqlTest{
public SqlTest() {}
public static void printFromJava(String x){
System.out.println(x);
}
}
这三个位置必须严格一致,至少我的项目是这样,以后熟练了以后自己改
第五步 导包 这里踩坑了
Qt5和Qt6导以下两个包的方法不一样
Qt5这样导 Qt6自己去查一下
第六步 编辑C++文件
在ui文件里放一个按钮控件,跳转到槽
输入以下代码
QString message = "this is from c++";
QAndroidJniObject javaMessage = QAndroidJniObject::fromString(message);
// if ( !javaClass.isValid() ) {
// qDebug() << "Java 类加载失败";
return -2;
// }
// else {
// qDebug() << "Java 类加载成功";
// }
QAndroidJniObject::callStaticMethod<void>("org/qtproject/example/JTest",
"printFromJava",
"(Ljava/lang/String;)V",
javaMessage.object<jstring>());
第七步 下载MySQL的jar包并放置在指定目录
jar包请自己去下载,下载好以后放在android目录下的libs文件夹(没有的话自己建)中即可,这里也踩坑了,因为不知道jar包往哪里放。
第八步 初步运行
点击构建
接下来就是错误处理了
错误1
解决办法:去掉 shadow build
错误2
解决办法
在build.gradle中增加以下代码
//指定jdk版本
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
构建成功
以上只是qt成功调用java,下面实现连接数据库
错误1 客户端和服务器的字符集不合适
错误2 远程服务器未打开
错误3 MySQL驱动器版本太高 下载了5.0.6的驱动
## 连接成功
连接代码
package org.qtproject.example;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.lang.reflect.Method;
public class SqlTest {
public SqlTest() {}
private static final String url = "jdbc:mysql://ip地址:端口号/数据库名?useUnicode=true&characterEncoding=UTF-8";
private static final String user = "root";
private static final String password = "123456789";
public static String getData() {
String result = "";
try {
// 加载 MySQL JDBC 驱动
Class.forName("com.mysql.jdbc.Driver"); // 老版本驱动一定要加
// 建立连接
Connection conn = DriverManager.getConnection(url, user, password);
if (conn != null)
{
result = "连接成功";
}
// // 创建 Statement 对象
// Statement stmt = conn.createStatement();
// ResultSet rs = stmt.executeQuery("SELECT * FROM livedata");
// // 处理结果集
// while (rs.next()) {
// result += rs.getString("余氯") + "\n";
// }
// // 关闭连接
// rs.close();
// stmt.close();
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
}
注释的都是调试代码 不用管
#include "widget.h"
#include "ui_widget.h"
#include <QtAndroidExtras/QAndroidJniObject>
#include <QtAndroidExtras/QAndroidJniEnvironment>
#include <jni.h>
#include <QDebug>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_pushButton_clicked()
{
// QString message = "this is from c++";
QAndroidJniObject javaClass("org/qtproject/example/SqlTest");
if ( !javaClass.isValid() )
{
qDebug() << "Java 类加载失败";
}
else
{
qDebug() << "Java 类加载成功";
}
QAndroidJniObject result = QAndroidJniObject::callStaticObjectMethod("org/qtproject/example/SqlTest", "getData", "()Ljava/lang/String;");
if (result.isValid()) {
QString data = result.toString();
qDebug() << "Data from Java:" << data;
} else {
qDebug() << "Failed to call Java method";
}
// qDebug() << result.toString();
// QAndroidJniObject::callStaticMethod<void>("org/qtproject/example/JTest",
// "printFromJava",
// "(Ljava/lang/String;)V",
// javaMessage.object<jstring>());
// jint result = javaClass.callMethod<jint>(
// "getData", // Java 方法名
// "(Ljava/lang/String;)V" // 方法签名
// );
// QAndroidJniEnvironment env;
// if (env->ExceptionCheck())
// {
// env->ExceptionClear();
// qWarning() << "JNI 调用失败";
// }
// 创建Java对象的实例
// QAndroidJniObject javaObject = QAndroidJniObject::callStaticObjectMethod("org/qtproject/example/SqlTest", "getData");
// if (javaObject.isValid()) {
// // 调用实例方法
// QAndroidJniObject result = javaObject.callObjectMethod("myInstanceMethod", "(I)Ljava/lang/String;", 42);
// if (result.isValid()) {
// qDebug() << "Result from instance method:" << result.toString();
// } else {
// qDebug() << "Failed to call instance method";
// }
// } else {
// qDebug() << "Failed to create Java object instance";
// }
}
没有找到列
查询成功
能做到qt开发android程序这一步说明读者对qt的基础以及qtcreator的使用已经熟悉,想进一步深度学习,所以本文没有对基础的配置操作进行详细论述。