About the author
In XE5, Embarcadero introduced a new object oriented way of calling into any Android API. Before looking at it, let's look at the old way of doing it.
var
Cls: JClass;
Mid: JMethodID;
...
Cls := JNIEnv
.
FindClass(
'TestClass'
);
if
Cls =
nil
then
begin
WriteLn
(
'Can'
't find class: TestClass'
Exit;
end
;
Mid := JNIEnv
GetStaticMethodID(Cls,
'printHello'
,
'()V'
Mid =
't find method: printHello'
JNIEnv
CallStaticVoidMethod(Cls, Mid, []);
// [] - no parameters
Imagine the tedium involved when there's plenty of methods to be called. In XE5, a class known as TJavaGenericImport takes two interfaces, one declaring all the Java methods for a class, and one declaring all the class methods, and allow them to be called directly. See my previous posting for further details.
So, if in Java, you have an instance of TestClass in tc, and you call it like this:
tc.printHello();
in Delphi, you can do the same thing as well!
All you have to do is write two interfaces, one describing the class methods, and one describing the instance methods and then create a new class that inherits from TJavaGenericImport and specify the two interfaces as generic parameters. So, given the following Java class that was seen earlier:
public
class
TestClass {
TestClass() {
}
TestClass(String msg) {
void
printHello() {
static
float
[] getTestFloat() {
long
[] getTestLong() {
the following would be what you would need to write:
JTestClassClass =
interface
(JObjectClass)
[
'{6E1DA723-41BE-4E0A-8103-B2FDED2E9307}'
]
{ Constructors }
function
init: JTestClass; cdecl; overload;
init(msg: JString): JTestClass; cdecl; overload;
{ Class Methods }
getTestFloat: TJavaArray<
Single
>; cdecl;
getTestLong: TJavaArray<
Int64
[JavaSignature(
'cx/ath/journeyman/TestClass'
)]
JTestClass =
(JObject)
'{6D521D7D-863C-43E7-A7CF-EB57A7D3378F}'
{ Instance Methods }
procedure
printHello; cdecl;
TJTestClass =
(TJavaGenericImport<JTestClassClass, JTestClass>)
The Java way:
TestClass tc =
new
TestClass();
// or new TestClass("Hello");
tc.getMinLong();
To construct an instance of TestClass, call TJTestClass.Create, or TJTestClass.JavaClass.init. Here's the Delphi way,
LTestClass: JTestClass;
LTestClass := TJTestClass
Create;
// or LTestClass := TJTestClass.JavaClass.init(StringToJString('Hello'));
LTestClass
getMinLong;
The call StringToJString transforms the given Delphi string to its Java equivalent. Since XE5 came out, I've been working on writing an application that can convert any Java class to its equivalent Delphi/Android interface as there are some Android classes that were not declared, and I'm pleased to announce that the effort is now completed. To purchase the tool, visit the Android2DelphiImport tool site. To load an external JAR, see my other post.
Generating the import unit for Google Cloud Messaging for Delphi.
I've tested this out for importing Android APIs and it works fabulously! What a great resource!