转载:http://blog.csdn.net/sunylat/article/details/41414785
本文使用工具和全部源码下载:
为什么我们要在Delphi XE7的安卓程序调用JAVA的JAR,使用JAVA的类?如果能够这样做,那么就意味着我们把Delphi开发的安卓程序扩展到了一个更大的开发范围了,理论上可以调用任意JAVA编写的代码,对于同时精通Delphi和JAVA的程序员来说,简直如虎添翼!!
我差不多用了一天时间吧,最终在老猫的帮助下,成功实现了在Delphi XE7的安卓程序中调用JAVA的JAR,使用JAVA的类!在此表达对老猫的谢意,同时经过老猫允许,提供老猫开发的JAVA转PAS工具,谢谢老猫的无私分享!!
我为大家提供的JAR,是我自己编写的一个极其简单的JAVA类,只提供了两个属性。为什么要自己编写一个JAVA类呢?我觉得自己对自己编写的代码最了解,也最容易尽快调试好程序,所以自己弄了这么一个简单的JAVA类。
我总结,Delphi XE7的安卓程序调用JAVA的JAR,要经过这么三个步骤:
一,设置工程属性。目前来看,因为Delphi工具的原因,导致按照默认属性,无法正常运行编译好的安卓程序,我觉得这应该是Delphi工具的BUG。
二,生成“Native Bridge File”。这是Delphi和JAVA通讯的接口文件,在Delphi中通过引入这个接口文件来使用JAR里面的JAVA类,这个文件是必须有的。
三,写实际调用JAVA类的代码。这是最终需要做的工作。
假设你现在是Delphi和JAVA都精通的程序员,那么我现在对上面三个步骤做详细说明,如果你不熟悉JAVA也不要紧,在最后面,我会把我写的JAVA类和导出JAR的过程详细讲解一下。下面是上面的三个步骤了:
一,设置工程属性。目前来看,因为Delphi工具的原因,导致按照默认属性,无法正常运行编译好的安卓程序,我觉得这应该是Delphi工具的BUG。
1,在你建立完工程之后,点击"Project"->"Deployment"。
2,设置属性。
做完这些,你的工程配置正确了,如果下面两个步骤你都做好了,那么你的Delphi XE7开发的安卓程序应该能正常调用你JAR里面的JAVA类了!
二,生成“Native Bridge File”。这是Delphi和JAVA通讯的接口文件,在Delphi中通过引入这个接口文件来使用JAR里面的JAVA类,这个文件是必须有的。
Delphi公司提供了一个JAVA转PAS工具,叫“java2op”,在我实际使用时候,感觉不怎么好,有两点:A,不能自动生成接口的GUID;B,生成的接口文件名称和JAVA 类名 称不匹配。所以最终我也没有使用它。这个工具在window虚拟机VMware 中可以正常使用,如果你在VMware 中安装了XE7,你可以尝试一下。
我使用两个工具成功生成Native Bridge File:
A,老猫的工具:
B,Java2Pas:
我认为老猫的工具更友善,更容易使用,也应该更完善,因为老猫一直在使用,不断在改进中!所以我推荐大家使用老猫的工具!!
下面是生成Native Bridge File过程:
1,把要生成Native Bridge File的JAR拷贝到老猫工具目录中。我的JAR名称是“Test.jar”。
2,用老猫工具生成Native Bridge File。
A,选择我们要生成Native Bridge File的JAR文件。
B,选择Native Bridge File的输出路径。
C,生成Native Bridge File。
把这个生成的Native Bridge File拷贝到工程目录,在工程里面加入。
三,写实际调用JAVA类的代码。这是最终需要做的工作。
两个个人观点:
1,接口的作用是为了定义和实现分离,那么我们使用时候,应该定义变量为接口,实际实例化应该用实现这个接口的类。
2,我们不需要释放被调用的JAVA类,这个类被安卓虚拟机管理,应该自动释放。
下面是实现的Delphi全部代码:
unit Unit1;interfaceuses System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.StdCtrls, FMX.Controls.Presentation, FMX.Edit, FMX.Layouts, FMX.Memo, Test; // 这个Test是我们刚才生成的Native Bridge File单元type TForm1 = class(TForm) Panel1: TPanel; Label1: TLabel; nameEdt: TEdit; Label2: TLabel; ageEdt: TEdit; Panel2: TPanel; Memo1: TMemo; Button1: TButton; Button2: TButton; Button3: TButton; procedure Button3Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end;var Form1: TForm1; testClass: JTest; // 要调用的JAVA类变量implementation{$R *.fmx}uses Androidapi.Helpers, // JStringToString Androidapi.JNI.JavaTypes;// 设置JAVA类属性procedure TForm1.Button1Click(Sender: TObject);var name: string; // 名字属性值 age: string; // 年龄属性值begin // 得到名字 name := Trim(nameEdt.Text); // 得到年龄 age := Trim(ageEdt.Text); if name = '' then begin ShowMessage('名字属性不能为空!'); nameEdt.SetFocus; end else if age = '' then begin ShowMessage('年龄属性不能为空!'); ageEdt.SetFocus; end else begin // 设置我们调用JAVA类里的name属性值 testClass.setName(StringToJString(name)); // 设置我们调用JAVA类里的age属性值 testClass.setAge(TJInteger.JavaClass.init(StringToJString(age))); end;end;// 得到设置的JAVA类属性procedure TForm1.Button2Click(Sender: TObject);begin // 清空原有显示数据 Memo1.Text := ''; // 显示得到的被调用JAVA类里的name属性值 Memo1.Lines.Add(JStringToString(testClass.getName)); // 显示得到的被调用JAVA类里的age属性值 Memo1.Lines.Add(JStringToString(testClass.getAge.toString));end;// 清空显示内容procedure TForm1.Button3Click(Sender: TObject);begin Memo1.Text := '';end;// 实例化J要调用的AVA类procedure TForm1.FormCreate(Sender: TObject);begin // 实例化要调用的JAVA类 testClass := TJTest.JavaClass.init; // 设置名字属性值 testClass.setName(StringToJString('TestName')); // 设置年龄属性值 testClass.setAge(TJInteger.JavaClass.init(StringToJString('20')));end;end.
此例子中的Eclipse操作全过程: