Blog

I write code, this blog is a dream.

2013.06.25OpenFL extension (3)

While looking for a way to show my next game's help as an embedded HTML page I encountered this project: https://github.com/SuatEyrice/NMEWebview

It is a good example of how we can write java code and use it from haxe on android.

Perfect timing to test a little bit of java interaction :)

cd project
mkdir android
mkdir android/testextension

android/testextension/TestExtension.java:

package testextension;

class TestExtension {
    public static String doSomething(String in){
        return in+"\n"+in;
    }
}

The idea is to export this testextension.TestExtension.doSomething(String) : String method so we can use it from haxe.

Since we are defining things in java, we cannot use cpp.Lib.load for this, we have to use openfl.utils.JNI.

This is how I created the binding in TestExtension.hx:

#if android
// Sadly we cannot use JNI here, we have to wait for the main() function to be executed.
// I tried but it failed :)
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 like cpp.Lib.load. You give the java class name and the static method your are looking for. The third argument is the difficult part, it's the method signature.

Basically () represents the method, what's inside are arguments and what's after is the result type.

(Ljava/lang/String;)Ljava/lang/String; is equal to haxe String -> String signature.

You can read more about JNI method signatures and examples here but this is just the first doc I found on Google. I imagine there's a more straightforward documentation somewhere…

We don't need to compile the java part before usage but we must tell user applications that they have to.

We edit the extension's include.xml file to add this information:

<java path="project/android" if="android" />

And that's it for this first baby step. Calling TestExtension.doSomething() in TestApp will work.

You can see this new addition on github.

Please note that I also created an android/Tweet.cpp file (but not the Tweet function implementation) to avoid having to add "#if ios" in the code.

The next step for java/haxe is certainly to study how we can pass HaxeObject around and call things here and there (the openfl.utils.JNI API is quite limited right now but after all we could write an extension to expose all C++ JNI methods to haxe I required).