Creating a Native Extension Library for OpenFL, Part Three

Published on July 24, 2013

Creating a Native Extension Library for OpenFL, Part Three

Original author: Laurent Bédubourg
  • Transfer
  • Tutorial

Foreword


This is a translation of the final, third part of a series of articles on creating native extension libraries for OpenFL . The second part described how to create an extension library for iOS. In this part, we will talk about creating an extension library for the Android platform, in the Java language, and, as will be seen later, for Android it is somewhat easier to do than for iOS.

Java, Haxe and everything, everything, everything!


For my next game, I came up with showing help in the form of an embedded HTML page and found the following project: NMEWebview . This project demonstrates well how we can use Java code in our haxe application.

It's time to check the interaction with Java code.

Create a directory for the extension:
cd project
mkdir android
mkdir android/testextension

And the file TestExtension.java
package testextension;
class TestExtension {
    public static String doSomething(String in){
        return in+"\n"+in;
    }
}

testextension.TestExtension.doSomething (String): String is our test function and we need to export it to haxe.

Since we write in Java, we can no longer use cpp.Lib.load to access the extension and must use openfl.utils.JNI for this.

This is how I wrapped haxe in TestExtension.hx :
#if android
// К сожалению, мы не можем использовать функции JNI до выполнения функции main.
// Я пробовал, верьте мне :)
private static var testextension_dosomething : Dynamic;
private static function init(){
    if (testextension_dosomething != null)
        return;
    testextension_dosomething = openfl.utils.JNI.createStaticMethod(
        "testextension/TestExtension",
        "doSomething",
        "(Ljava/lang/String;)Ljava/lang/String;"
    );
}
public static function doSomething(str:String) : String {
    init();
    return testextension_dosomething(str);
}
#end

openfl.utils.JNI.createStaticMethod works similarly to cpp.Lib.load. The first two parameters of this function are the class names and the name of the static method that we are going to use. But the third argument, the hardest part is the method signature.

We can say that () denote a method, and that inside the brackets are arguments, and that outside is the type of result.

(Ljava / lang / String;) Ljava / lang / String; matches String-> String in haxe.

You can read more about the signature designation in JNI (with examples) here , but I want to note that this is the first link I found on Google. I think there is more simple documentation.

We do not need to compile our Java extension before use, compilation will occur during the assembly of the application and we need to specify how to do it.

To do this, add the following line to the include.xml file in the directory with the extension:
<java path="project/android" if="android" />

After that, calling TestExtension.doSomething () in the TestApp application will work just fine.

You can find the code from this article in the repository on GitHub 'e.

Keep in mind that I also added the android / Tweet.cpp file (but did not implement the Tweet function) to avoid conditional compilation and adding #if ios throughout the code.

The next thing I want to do in the Java / haxe bundle is to learn how to pass HaxeObject and call functions here and there (currently openfl.utils.JNI is a bit limited, but I think we can export all the necessary C ++ methods from JNI to haxe).

From translator


This concludes the series of articles on creating native extension libraries from Laurent Bédubourg. The cycle describes the necessary minimum sufficient to begin work on its extension. When I started working on my set of extensions , there were no such articles and I had to look for information in various blogs.
If you want to create an extension for Android and you need the capabilities of the latest SDKs, here you can find an article on how to build an extension for the desired version of the SDK.