Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to create a library in haxe that can be called natively on iOS and Android?

Tags:

android

ios

haxe

I want to make some common service calls, data models, etc, to use as a library on my iOS and Android apps, I was thinking that maybe Haxe is capable of doing this but I can't find any example. Can someone shed some light on whether this is possible and how to begin?

like image 972
Gustavo Parrado Avatar asked Feb 12 '16 21:02

Gustavo Parrado


1 Answers

This is a very important topic, and it's possible. However it is likely that you will have to expose host-specific APIs because Java and Objective-C/C++ have different native types.

For iOS, you can find a beginning of answer here: How to create iOS- & OSX- library from Haxe and use it in native application?

For Android it is straightforward enough to expose an API following the usual listener interface pattern. But you generally can't pass function references in Java so Haxe-java uses a similar pattern generalized using Closure/Function objects which are awkward to use from Java.

Write Haxe code for Java:

Make sure to add @:nativeGen meta to all the exposed classes - Haxe reflection won't work but it will be cleaner when consumed from Java.

package com.foo;

@:nativeGen
class MyModel {
    public function new() {
    }
    public function doSomething(listener:SomethingListener) {
        Timer.delay(function() {
            listener.onResult(cpt);
        }, 2000);
    }
}

@:nativeGen
interface SomethingListener {
    function onResult(value:Int):Void;
}

The basics are simple, but the devil is in the details: to consume/return Java native types you will have to do some conversion work:

  • use java.Lib functions to consume Java types: http://api.haxe.org/java/Lib.html
  • use java.NativeArray to make Java arrays: http://api.haxe.org/java/NativeArray.html

Generate a JAR from Haxe:

# generates java source under /MyAPI and a corresponding /MyAPI/MyAPI.jar
haxe -cp src -java MyAPI -D no-root com.foo.MyModel

Notes:

  • -main is omitted because we don't want a static entry point
  • -D no-root will generate a native-looking package, otherwise things are under the haxe package.

On the Java side:

You can import this JAR and use it transparently.

From IntelliJ/Android Studio you can create a module: Project Structure > Add Module > Import JAR/AAR Package.

It's important to note that IntelliJ copies the JAR inside the project so you must update the JAR there when you rebuild your Haxe project. IntelliJ will pick up the changes immediately.

import com.foo.MyModel;
import com.foo.SomethingListener;

MyModel myModel = new MyModel();
myModel.doSomething(new SomethingListener() {
    @Override
    public void onResult(int value) {
        // Got something from Haxe
    }
});
like image 52
Philippe Avatar answered Nov 16 '22 04:11

Philippe