当前位置: 首页 > news >正文

另辟奚径-Android Studio调用Delphi窗体

大家都知道Delphi能调用安卓SDK,比如jar、aar等,

但是反过来,能在Android Studio中调用Delphi开发的窗体吗?

想想不太可能吧,

Delphi用的是Pascal,Android Studio用的是Java,这两个怎么能混用呢?

而且用Delphi就能开发好APP,为啥还要用到Android Studio?

搞这个的人,得是有多闲!

就让我这个闲得蛋疼的人来尝试一下。

首先用Delphi建一个工程,

如下Delphi工程,

名为EmptyDelphi:

图片

差不多是一个空的工程,就只有一个很简单的窗体,上面放了按钮,点击弹出:

“Hello,我是Delphi窗体。”    

图片

图片

将它在Android 64位平台下Build一下,

会生成我们后面需要的文件,

它是Android64\Release目录中的libEmptyDelphi.so,

so文件是安卓下的动态链接库,

Delphi将工程的窗体和代码都编译到它里面了:    

图片

在手机上跑一下看看:    

图片

注意顶部状态栏,是灰黑色的。

          

再用Android Studio来新建一个工程(简单看看即可):    

图片

填入APP名称、应用包名等:

图片

可以新建一个Activity来玩下原生开发(在安卓下的窗体叫Activity):    

图片

窗体名设置为MainActivity,

默认勾上Generate a Layout File,表示新建一个窗体布局文件,就像Delphi中的窗体是一对.pas+.fmx文件,而安卓下窗体是一对.java+.xml文件,

如果勾上Launcher Activity,表示它是主窗体,程序一打开就显示它,

如下图所示:

图片

    

双击res\layout\activity_main.xml来在窗体上添加控件:

图片

双击就能打开窗体设计器:    

图片

从左边拖个按钮进去,这种可视化的方式和Delphi一样:

图片

如果建Activity的时候没有勾上Launcher Activity,

那么需要编辑AndroidManifest.xml,

AndroidManifest.xml是安卓程序清单文件,里面登记着所有安卓窗体、服务等,

打开左边manifests节点里面的AndroidManifest.xml进行编辑:    

图片

在Activity节点里面加入如下XML节点,

表示它是一个主窗体,app一运行首先打开它,如下图所示:    

图片

点击下右上角的绿色小箭头就能直接运行在手机上:

图片

效果如下图所示:    

图片

    

          

          

接下来把Delphi开发的窗体集成进来作为主窗体:

要想在安卓应用中打开页面,就需要在AndroidManifest.xml中注册一个Activity,

那么我们Delphi开发的窗体有Activity吗?

它叫什么呢?

我们可以打开Android64\Release\AndroidManifest.xml找到答案:

(或者工程目录中的AndroidManifest.template.xml中)

图片

    

图片

如上图,Delphi开发的窗体Activity为com.embarcadero.firemonkey.FMXNativeActivity,它是固定的,只是其中meta-data节点中的value值会变,是需要一个动态库文件名,为工程名称。

那我们把这一段复制到Android Studio工程中的AndroidManifest.xml中去:

并把Android Studio工程中原来的MainActivity注释掉:

图片

但是可以看到我们Delphi的FMXNativeActivity粘到Android Studio中之后,

都标红了,应该是出错了,鼠标移上去,    

提示“Class referenced in the manifest,com.embarcadero.firemonkey.FMXNativeActivity was not found in the project or the libraries”,

意思是在工程或库中不存在这个FMXNativeActivity,

那它在哪里?

答案是fmx.jar

Delphi开发的app需要使用fmx.jar来实现一些底层的安卓功能,

我们平常可以在Delphi 工程视图中Android平台下的Libraries节点中看到它:

图片

fmx.jar它在Delphi的安装目录中:

C:\Program Files (x86)\Embarcadero\Studio\22.0\lib\android\release

图片

fmx.dex.jar则是fmx.jar编译之后的文件。

fmx.jar的源码都在Delphi的源码目录中,

C:\Program Files (x86)\Embarcadero\Studio\22.0\source\rtl\androiddex\java\fmx    

图片

这个目录一看就是一个Eclipse项目,

找到FMXNativeActivity这个类,它是Embarcadero用java写的,    

图片

图片

所以要想在Android Studio中使用Delphi的页面,那么就需要引用fmx.jar。    

          

在Android Studio中引用fmx.jar

将它拷到安卓工程app目录中的libs目录里面,

图片

          

找到工程app模块的安卓配置文件 build.gradle,它是安卓应用的打包配置文件:

图片

编辑它,在它的dependencies(依赖)中加入如下一行,

implementation fileTree(include: ['*.jar','*.aar'], dir: 'libs')

表示app需要引用libs目录中的所有jar和aar:    

图片

改了build.gradle之后,右上角会有“Sync Now”,需要点击:

图片

你的APP如果用到了别的aar、jar也都放到libs目录中来。

图片

因为FMXNativeActivity在创建的时候会加载libEmptyDelphi.so这个文件,    

我们需要将它布署到library\lib\arm64-v8a目录中,

先将libEmptyDelphi.so拷到安卓项目app\libs\arm64-v8a目录中,

图片

把这个so布署进去,

编辑app模块中的build.gradle,在android节点中加入:

    sourceSets {

        main {

            jniLibs.srcDirs = ['libs']

        }

}

如下图所示:

图片

              

好了,在Android Studio中运行工程到手机:    

图片

    

看看顶部状态栏,它是蓝色的。

现在我们成功的用Android Studio将Delphi窗体打包进去了,

其实就类似在Windows平台将Delphi窗体封装进DLL,然后给C#调用来显示它们。

这么做有什么好处呢?

1.集成aar方便稳定,特别是遇到实在解决不了的闪退卡死等情况

如果Delphi APP引用了太多的aar,我们不仅需要自己处理依赖包的下载、资源的合并,编译R.jar,除此之外经常会遇到闪退卡死等问题,非常难排查,

用Android Studio就不会有这种问题的产生,直接在build.gradle中编辑好:

图片

Gradle插件直接帮你自动完成全部工作。

          

2.打包安卓应用快

当你的Delphi APP引用了太多了aar之后,要布署相当多的资源文件,用Delphi打包APK的过程就会显示相当的漫长,我有一个项目打包一次在五分钟左右,

而用Android Studio打包,则一分钟都不到。    

          

3.与安卓原生协同开发

你可以将你的工程编译为安卓链接库给原生java他们调用。

          

当然Delphi也可以使用Gradle插件来自动集成aar,后面有时间整理好分享给大家。

          

相关文章:

另辟奚径-Android Studio调用Delphi窗体

大家都知道Delphi能调用安卓SDK,比如jar、aar等, 但是反过来,能在Android Studio中调用Delphi开发的窗体吗? 想想不太可能吧, Delphi用的是Pascal,Android Studio用的是Java,这两个怎么能混用…...

SOLID 原则,程序设计五大原则,设计模式

SOLID 是让软件设计更易于理解、更加灵活和更易于维护的五个原则的简称。 单一职责(Single Responsibility Principle):修改一个类的原因只能有一个。开闭原则(Open/Closed Principle):对于扩展,类应该是“开放”的;对于修改&…...

Java基础——数组(一维数组与二维数组)

文章目录 一维数组声明初始化与赋值内存图解 二维数组声明初始化与赋值内存图解 数组练习 数组是多个相同类型的数据按一定顺序排列的集合。 说明: 数组是引用数据类型,数组的元素是同一类型的任何数据类型,包括基本数据类型和引用数据类型…...

Python爬虫抓取微博数据及热度预测

首先我们需要安装 requests 和 BeautifulSoup 库,可以使用以下命令进行安装: pip install requests pip install beautifulsoup4然后,我们需要导入 requests 和 BeautifulSoup 库: import requests from bs4 import BeautifulSou…...

Qt QTableWidget表格的宽度

默认值 QTableWIdget的表格宽度默认是一个给定值,可以手动调整每列的宽度,也不填满父窗口 MainWindow::MainWindow(QWidget *parent): QMainWindow(parent) {this->resize(800,600);QStringList contents{"11","111111111111",&…...

OpenCV(opencv_apps)在ROS中的视频图像的应用(重点讲解哈里斯角点的检测)

1、引言 通过opencv_apps,你可以在ROS中以最简单的方式运行OpenCV提供的许多功能,也就是说,运行一个与功能相对应的launch启动文件,就可以跳过为OpenCV的许多功能编写OpenCV应用程序代码,非常的方便。 对于想熟悉每个…...

常见排序算法之插入排序类

插入排序,是一种简单直观的排序算法,工作原理是将一个记录插入到已经排好序的有序表中,从而形成一个新的、记录数增1的有序表。在实现过程中,它使用双层循环,外层循环对除了第一个元素之外的所有元素,内层循…...

Dubbo服务消费端远程调用过程剖析

1 Dubbo服务消费端远程调用过程概述 (1)当消费方调用远程服务的方法时,会被InvokerInvocationHandler拦截,执行其invoke()方法,创建RpcInvocation对象; (2)接着会选择远程调用的负…...

华硕荣获“EPEAT Climate+ Champion”永续先驱称号

华硕持续深耕永续理念,努力提供低碳排放、高效能产品,并被全球电子委员会授予“EPEAT Climate Champion”称号。这一荣誉再次表明了华硕在永续管理方面的承诺,并凸显了华硕在追求永续发展上的决心。 华硕通过设立“科学基础减碳目标”、“再生…...

基于QT使用OpenGL,加载obj模型,进行鼠标交互

目录 功能分析(需求分析)技术点分析OpenGL立即渲染模式可编程渲染管线模式 QOpenGLWidget派生类 glwidget逻辑glwidget.hglwidget.cpp 鼠标交互功能obj格式介绍 效果bunnyCayman_GT 功能分析(需求分析) 基于QT平台,使…...

三大赛题指南发布!2023 冬季波卡黑客松本周末开启 Workshop

2023 年一众黑客松赛事中,为什么我们建议您选择波卡黑客松大赛?或许答案在于——作为开发者极度友好的技术生态,波卡能够从参赛者的立场出发,为大家提供从 0 到 1 实现项目孵化成长的机会。这里聚集了一线技术专家的资源力量&…...

数据结构与算法(Java版) | 算法的空间复杂度简介

关于算法的空间复杂度,下面我给大家作一个简单介绍。 类似于时间复杂度的讨论,一个算法的空间复杂度(Space Complexity)定义为该算法所耗费的存储空间,同样,它也是问题规模n的一个函数。 其实&#xff0c…...

大数据-之LibrA数据库系统告警处理(ALM-12037 NTP服务器异常)

告警解释 当NTP服务器异常时产生该告警。 当NTP服务器异常消除时,该告警恢复。 告警属性 告警ID 告警级别 可自动清除 12037 严重 是 告警参数 参数名称 参数含义 ServiceName 产生告警的服务名称。 RoleName 产生告警的角色名称。 HostName 异常N…...

烟草5G智慧工厂数字孪生可视化平台,赋能烟草工业数字化智慧转型

随着卷烟工厂提质增效需求增强,信息化建设推进及生产制造系统智能化改革发展,各生产单元逐步升级完善数字化,最终实现智能制造成为必然趋势。因此,5G卷烟加工工厂的数字化转型迫在眉睫。中国烟草制造行业正迈向全新的市场经济时代…...

PHP编写采集药品官方数据的程序

在 PHP 中编写爬虫程序,首先我们需要引入一些必要的库,如 curl 和 file_get_contents。然后,我们需要设置爬虫ip信息,以便我们可以从指定的爬虫ip服务器上获取数据。 // 引入必要的库 require_once curl.php;// 设置爬虫ip信息 $p…...

解决Jenkins执行git脚本时报错:No such device or address问题

问题现象: Jenkins执行BeanShell脚本时,报错:jenkins fatal: could not read Username for http://112.11.120.1: No such device or address 解决方案: 解决服务器拉取git仓库的代码权限,使用高级子模块克隆功能。…...

LCD英文字模库(16x8)模拟测试程序

字模 字模,就是把文字符号转换为LCD能识别的像素点阵信息。 电子发烧友可能都熟悉字模的用途。就是调用者通过向LCD模块发送字模数据,LCD根据字模数据在LCD面板上相应的像素描绘出图形或文字。 现在,大部分的LCD都内置了字模库&#xff0c…...

二分法

文章目录 二分法概述二分 > value最左的位置二分 < value最右的位置局部最小值问题 二分法概述 什么是二分法呢&#xff1f;相信大家都有所了解&#xff0c;举个最经典的二分的例子。 ​ 给定一个整型有序数组&#xff0c;和一个值 v a l u e value value&#xff0c;如…...

Linux文件类型与权限及其修改

后面我们写代码时&#xff0c;写完可能会出现没有执行权限什么的&#xff0c;所以我们要知道文件都有哪些权限和类型。 首先 就像我们之前目录结构图里面有个/dev,它就是存放设备文件的&#xff0c;也就是说&#xff0c;哪怕是一个硬件设备&#xff0c;例如打印机啥的&#xf…...

RPC 框架 openfeign 介绍和学习使用总结

一、基本概念 RPC 远程过程调用&#xff08;Remote Procedure Call&#xff09;的缩写形式 Birrell 和 Nelson 在 1984 发表于 ACM Transactions on Computer Systems 的论文《Implementing remote procedure calls》对 RPC 做了经典的诠释。 RPC 是指计算机 A 上的进程&am…...

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...

零基础设计模式——行为型模式 - 责任链模式

第四部分&#xff1a;行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习&#xff01;行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想&#xff1a;使多个对象都有机会处…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)

船舶制造装配管理现状&#xff1a;装配工作依赖人工经验&#xff0c;装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书&#xff0c;但在实际执行中&#xff0c;工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...

使用LangGraph和LangSmith构建多智能体人工智能系统

现在&#xff0c;通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战&#xff0c;比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...

[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】&#xff0c;分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...

高防服务器价格高原因分析

高防服务器的价格较高&#xff0c;主要是由于其特殊的防御机制、硬件配置、运营维护等多方面的综合成本。以下从技术、资源和服务三个维度详细解析高防服务器昂贵的原因&#xff1a; 一、硬件与技术投入 大带宽需求 DDoS攻击通过占用大量带宽资源瘫痪目标服务器&#xff0c;因此…...

篇章二 论坛系统——系统设计

目录 2.系统设计 2.1 技术选型 2.2 设计数据库结构 2.2.1 数据库实体 1. 数据库设计 1.1 数据库名: forum db 1.2 表的设计 1.3 编写SQL 2.系统设计 2.1 技术选型 2.2 设计数据库结构 2.2.1 数据库实体 通过需求分析获得概念类并结合业务实现过程中的技术需要&#x…...

数据结构:泰勒展开式:霍纳法则(Horner‘s Rule)

目录 &#x1f50d; 若用递归计算每一项&#xff0c;会发生什么&#xff1f; Horners Rule&#xff08;霍纳法则&#xff09; 第一步&#xff1a;我们从最原始的泰勒公式出发 第二步&#xff1a;从形式上重新观察展开式 &#x1f31f; 第三步&#xff1a;引出霍纳法则&…...

解密鸿蒙系统的隐私护城河:从权限动态管控到生物数据加密的全链路防护

摘要 本文以健康管理应用为例&#xff0c;展示鸿蒙系统如何通过细粒度权限控制、动态权限授予、数据隔离和加密存储四大核心机制&#xff0c;实现复杂场景下的用户隐私保护。我们将通过完整的权限请求流程和敏感数据处理代码&#xff0c;演示鸿蒙系统如何平衡功能需求与隐私安…...

信息系统分析与设计复习

2024试卷 单选题&#xff08;20&#xff09; 1、在一个聊天系统(类似ChatGPT)中&#xff0c;属于控制类的是&#xff08;&#xff09;。 A. 话语者类 B.聊天文字输入界面类 C. 聊天主题辨别类 D. 聊天历史类 ​解析 B-C-E备选架构中分析类分为边界类、控制类和实体类。 边界…...