百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

Qt安卓开发经验001-010

bigegpt 2024-08-07 17:51 6 浏览

  1. pro中引入安卓拓展模块 QT += androidextras 。
  2. pro中指定安卓打包目录 ANDROID_PACKAGE_SOURCE_DIR = $PWD/android 指定引入安卓特定目录比如程序图标、变量、颜色、java代码文件、jar库文件等。
  • AndroidManifest.xml 每个程序唯一的一个全局配置文件,里面xml格式的数据,标明支持的安卓版本、图标位置、横屏竖屏、权限等。这个文件是最关键的,如果没有这个文件则Qt会默认生成一个。
  • android/res/drawable-hdpi drawable-xxxhdpi 等目录下存放的是应用程序图标。
  • android/res/layout 目录下存放的布局文件。
  • android/res/values/libs.xml 存储的一些变量值。
  • android/libs 目录下存放的jar库文件。
  • android/src 目录下存放的java代码文件,可以是根据包名建立的一层层子目录,也可以直接在src目录下。
  • 其他目录自行搜索安卓目录规范。
  • 后面的说明统一用的android目录举例,其实你可以改成任意目录,比如你的代码目录下是xxoo存放的安卓相关的打包文件,你就写成 ANDROID_PACKAGE_SOURCE_DIR = $PWD/xxoo 。
  1. java类名必须和文件名完全一致,区分大小写。
  2. java类必须在android/src目录下不然不会打包到apk文件,可以是子目录比如 android/src/com/qt 。
  3. Qt代码中的QAndroidJniObject指定传入的java包名,必须严格和java文件package完全一致,不然程序执行到此处会因为找不到而崩溃。
  • android/scr/MainActivity.java 顶部 没有 package 则代码中必须是 QAndroidJniObject javaClass("MainActivity");
  • android/scr/MainActivity.java 顶部 package com.qandroid; 则代码中必须是 QAndroidJniObject javaClass("com/qandroid/MainActivity");
  • android/scr/com/example/MainActivity.java 顶部 package com.qandroid; 则代码中必须是 QAndroidJniObject javaClass("com/qandroid/MainActivity");
  • android/scr/com/example/MainActivity.java 顶部 package com.example.qandroid; 则代码中必须是 QAndroidJniObject javaClass("com/qandroid/example/MainActivity");
  • 总之这个包名是和代码中的package后面一段吻合,而不是目录路径。为了统一管理方便查找文件,建议包名和目录路径一致。
  1. Qt只能干Qt内部类的事情,做一些简单的UI交互还是非常方便,如果涉及到底层操作,还是需要熟悉java会如虎添翼,一般的做法就是写好java文件调试好,提供静态方法给Qt调用,这样通过QAndroidJniObject这个万能胶水可以做到Qt程序调用java中的函数并拿到执行结果,也可以接收java中的函数。
  2. pro中通过 OTHER_FILES += android/AndroidManifest.xml OTHER_FILES += android/src/JniMessenger.java 引入文件其实对整个程序的编译打包没有任何影响,就是为了方便在QtCreator中查看和编辑。
  3. 在Qt中与安卓的java文件交互都是用万能的QAndroidJniObject,可以执行java类中的普通函数、静态函数,可以传类对象jclass、类名className、方法methodName、参数,也可以拿到执行结果返回值。 (I)V括号中的是参数类型,括号后面的是返回值类型,void返回值对应V,由于String在java中不是数据类型而是类,所以要用Ljava/lang/String;表示,其他类作为参数也是这样处理。
  • 调用实例方法:callMethod、callObjectMethod。
  • 调用静态方法:callStaticMethod、callStaticObjectMethod。
  • 不带Object的函数名用来执行无返回值或者常规返回值int、float等的方法。
  • 如果返回值是String或者类则需要用带Object的函数名来执行,返回QAndroidJniObject类型再转换处理拿到结果,比如toString拿到字符串。
  1. 各种参数和返回值示例。
package org.qt;
import org.qt.QtAndroidData;

public class QtAndroidTest
{
    //需要通过实例来调用 测试发现不论 private public 或者不写都可以调用 我擦
    private void printText()
    {
        System.out.println("printText");
    }

    public static void printMsg()
    {
        System.out.println("printMsg");
    }

    public static void printValue(int value)
    {
        System.out.println("printValue:" + value);
    }

    public static void setValue(float value1, double value2, char value3)
    {
        System.out.println("value1:" + value1 + " value2:" + value2 + " value3:" + value3);
    }

    public static int getValue()
    {
        return 65536;
    }

    public static int getValue(int value)
    {
        return value + 1;
    }

    public static void setMsg(String message)
    {
        System.out.println("setMsg:" + message);
    }

    public static String getMsg()
    {
        return "hello from java";
    }

    public static void setText(int value1, float value2, boolean value3, String message)
    {
        System.out.println("value1:" + value1 + " value2:" + value2 + " value3:" + value3 + " message:" + message);
    }

    public static String getText(int value1, float value2, boolean value3, String message)
    {
        //同时演示触发静态函数发给Qt
        QtAndroidData.receiveData("message", "你好啊 java");

        //下面两种办法都可以拼字符串
        return "value1:" + value1 + " value2:" + value2 + " value3:" + value3 + " message:" + message;
        //return "value1:" + String.valueOf(value1) + " value2:" + String.valueOf(value2) + " value3:" + String.valueOf(value3) + " message:" + message;
    }
}
```

```cpp
#include "androidtest.h"

//java类对应的包名+类名
#define className "org/qt/QtAndroidTest"

void AndroidTest::test()
{
    jint a = 12;
    jint b = 4;
    //可以直接调用java内置类中的方法
    jint max = QAndroidJniObject::callStaticMethod<jint>("java/lang/Math", "max", "(II)I", a, b);

    //jclass javaMathClass = "java/lang/Math";
    jdouble value = QAndroidJniObject::callStaticMethod<jdouble>("java/lang/Math", "random");

    qDebug() << "111" << max << value;
}

void AndroidTest::printText()
{
    QAndroidJniEnvironment env;
    jclass clazz = env.findClass(className);
    QAndroidJniObject obj(clazz);
    obj.callMethod<void>("printText");
}

void AndroidTest::printMsg()
{
#if 0
    //查看源码得知不传入jclass类的函数中内部会自动根据类名查找jclass
    QAndroidJniEnvironment env;
    jclass clazz = env.findClass(className);
    QAndroidJniObject::callStaticMethod<void>(clazz, "printMsg");
#else
    //没有参数和返回值可以忽略第三个参数
    QAndroidJniObject::callStaticMethod<void>(className, "printMsg");
    //QAndroidJniObject::callStaticMethod<void>(classNameTest, "printMsg", "()V");
#endif
}

void AndroidTest::printValue(int value)
{
    QAndroidJniObject::callStaticMethod<jint>(className, "printValue", "(I)I", (jint)value);
}

void AndroidTest::setValue(float value1, double value2, char value3)
{
    QAndroidJniObject::callStaticMethod<void>(className, "setValue", "(FDC)V", (jfloat)value1, (jdouble)value2, (jchar)value3);
}

int AndroidTest::getValue(int value)
{
    //java类中有两个 getValue 函数 一个需要传参数
    //jint result = QAndroidJniObject::callStaticMethod<jint>(className, "getValue");
    jint result = QAndroidJniObject::callStaticMethod<jint>(className, "getValue", "(I)I", (jint)value);
    return result;
}

void AndroidTest::setMsg(const QString &msg)
{
    QAndroidJniObject jmsg = QAndroidJniObject::fromString(msg);
    QAndroidJniObject::callStaticMethod<void>(className, "setMsg", "(Ljava/lang/String;)V", jmsg.object<jstring>());
}

QString AndroidTest::getMsg()
{
    QAndroidJniObject result = QAndroidJniObject::callStaticObjectMethod(className, "getMsg", "()Ljava/lang/String;");
    return result.toString();
}

void AndroidTest::setText(int value1, float value2, bool value3, const QString &msg)
{
    QAndroidJniObject jmsg = QAndroidJniObject::fromString(msg);
    QAndroidJniObject::callStaticMethod<void>(className, "setText", "(IFZLjava/lang/String;)V", (jint)value1, (jfloat)value2, (jboolean)value3, jmsg.object<jstring>());
}

QString AndroidTest::getText(int value1, float value2, bool value3, const QString &msg)
{
    QAndroidJniObject jmsg = QAndroidJniObject::fromString(msg);
    QAndroidJniObject result = QAndroidJniObject::callStaticObjectMethod(className, "getText", "(IFZLjava/lang/String;)Ljava/lang/String;", (jint)value1, (jfloat)value2, (jboolean)value3, jmsg.object<jstring>());
    return result.toString();
}
  1. 在原生Android开发中,不同页面会定义不同的Activity。但使用Qt Quick、Flutter等采用Direct UI方式实现的第三方开发框架则只定义了一个Activity。里面不同页面实际都是使用OpenGL等直接绘制的。https://blog.csdn.net/LCSENs/article/details/100182235

项目作品37-安卓综合应用示例 https://qtchina.blog.csdn.net/article/details/123940153

相关推荐

php-fpm的配置和优化

目录概述php-fpm配置php-fpm进程优化配置慢日志查询配置php7进阶到架构师相关阅读概述这是关于php进阶到架构之php7核心技术与实战学习的系列课程:php-fpm的配置和优化学习目标:理...

成功安装 Magento2.4.3最新版教程「技术干货」

外贸独立站设计公司xingbell.com经过多次的反复实验,最新版的magento2.4.3在oneinstack的环境下的详细安装教程如下:一.vps系统:LinuxCentOS7.7.19...

十分钟让你学会LNMP架构负载均衡

业务架构、应用架构、数据架构和技术架构一、几个基本概念1、pv值pv值(pageviews):页面的浏览量概念:一个网站的所有页面,在一天内,被浏览的总次数。(大型网站通常是上千万的级别)2、u...

php从远程URL获取(mp4 mp3)音视频的流媒体数据

/***从远程URL中获取媒体(如mp4mp3)的内容*@parammixed$file_url*@parammixed$media_type...

Zabbix5.0安装部署

全盘展示运行状态,减轻运维人员的重复性工作量,提高系统排错速度,加速运维知识学习积累。1.png1、环境安装关闭SELinux并重启系统2.png安装httpd、mariadb、php运行yum-...

php 常见配置详解

以下是PHP常见的配置项及其含义:error_reporting:设置错误报告级别,可以控制PHP显示哪些错误。例如,设置为E_ALL将显示所有错误,而设置为0将禁止显示任何错误。displa...

实践分享|基于基石智算 DeepSeek API + WordPress 插件自动生成访客回复

基石智算举办的DeepSeek案例大赛汇集了不少基于CoresHubDeepSeekAPI服务或模型部署服务的精彩实践。本次我们将分享个人实践:通过DeepSeekAPI+Word...

如何在Eclipse中搭建Zabbix源码的调试和开发环境

Zabbix是一款非常优秀的企业级软件,被设计用于对数万台服务器、虚拟机和网络设备的数百万个监控项进行实时监控。Zabbix是开放源码和免费的,这就意味着当出现bug时,我们可以很方便地通过调试源码来...

MySQL自我保护参数

#头条创作挑战赛#之前(MySQL自我保护工具--pt-kill)提到用pt-kill工具来kill相关的会话,来达到保护数据库的目的,本文再通过修改数据库参数的方式达到阻断长时间运行的SQL的目...

Python闭包深度解析:掌握数据封装的高级技巧

闭包作为Python高级编程特性之一,为开发者提供了一种优雅的方式来实现数据封装和状态保持。这一概念源于函数式编程理论,在现代Python开发中发挥着重要作用。理解和掌握闭包的使用不仅能够提升代码的表...

Java服务网格故障注入与熔断实战

在分布式系统的高可用性挑战中,服务网格的故障注入与熔断机制是检验系统韧性的终极试金石。以下是10道逐步升级的"地狱关卡",每个关卡都对应真实生产环境中可能遇到的致命场景,并附具体场景示...

MySQL数据库性能优化全攻略:程序员必知的七大核心策略

作为程序员,我们每天都要与数据库打交道。当系统用户量突破百万级时,数据库往往成为性能瓶颈的首要怀疑对象。本文将深入探讨MySQL优化的七大核心策略,并提供可直接落地的优化方案,助您构建高效稳定的数据库...

如何在 Windows 11 上使用单个命令安装 XAMPP

XAMPP是一种广泛使用的软件,用于在Windows操作系统上快速运行LAMP服务器包,包括Windows11。尽管LAMP通常用于Linux系统,但XAMPP并不使用Li...

uTorrent怎样将bt种子转换为磁力

如何用uTorrent把BT种子转为磁力链接?以下方法希望能帮到你。1、在uTorrent窗口里,点击工具栏的按钮,所示。2、在打开窗口里,选取要转为磁力的种子文件,然后点击打开按钮,参照图示操作...

支持向量机SVM 分类和回归的实例

支持向量机(SupportVectorMachine)是Cortes和Vapnik于1995年首先提出的,它在解决小样本、非线性及高维模式识别中表现出许多特有的优势,并能够推广应用到函数拟合等其他...