Предисловие
Это перевод заключительной, третьей части цикла статей о создании нативных библиотек расширения для OpenFL. Во второй части рассказавалось как создать библиотеку расширений для iOS. В данной части, будет рассказано о создании библиотеки расширений для платформы Android, на языке Java и, как будет видно далее, для Android сделать это несколько проще, чем для iOS.
Java, Haxe и все, все, все!
Для своей следующей игры, я придумал показывать справку в виде встроенной HTML страницы и нашел следующий проект: NMEWebview. Этот проект хорошо демонстрирует, как мы можем использовать код на Java в нашем приложении на haxe.
Пришло время проверить взаимодействие с кодом на Java 🙂
Создадим каталог для расширения:
cd project mkdir android mkdir android/testextension
И файл TestExtension.java
package testextension; class TestExtension { public static String doSomething(String in){ return in+"\n"+in; } }
testextension.TestExtension.doSomething(String):String наша тестовая функция и нам нужно экспортировать ее в haxe.
Так как мы пишем на Java, мы уже не можем использовать cpp.Lib.load для доступа к расширению и должны использовать для этого openfl.utils.JNI.
Вот таким образом я сделал обертку на haxe в 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 работает аналогично cpp.Lib.load. Первые два параметра этой функции это названия класса и название статического метода, который мы собираемся использовать. А вот третий аргумент самая сложная часть — это сигнатура метода.
Можно сказать, что () обозначают метод, и то что внутри скобок это аргументы, а то что снаружи — тип результата.
(Ljava/lang/String;)Ljava/lang/String; соответствует String->String в haxe.
Подробнее про обозначение сигнатур в JNI (с примерами) вы можете прочесть здесь, но хочу заметить, что это первая ссылка, которую я нашел в Google. Я думаю, что существует и более простая документация.
У нас нет необходимости компилировать наше Java расширение перед использованием, компиляция будет происходить при сборке приложения и нам нужно указать как это делать.
Для этого в файл include.xml в каталоге с расширением добавим следующую строчку:
<java path="project/android" if="android" />
После этого, вызов TestExtension.doSomething() в приложении TestApp будет прекрасно работать.
Код из этой статьи вы можете найти в репозитории на GitHub‘e.
Имейте в виду, что я также добавил файл android/Tweet.cpp (но не реализовал функцию Tweet), чтобы избежать условной компиляции и добавления #if ios по всему коду.
Следующее, что я хочу сделать в связке Java/haxe — научиться передавать HaxeObject и вызывать функции там и тут (на данный момент openfl.utils.JNI немного ограничен, но я думаю мы сможем экспортировать все необходимые C++ методы из JNI в haxe).
От переводчика
На этом заканчивается цикл статей о создании нативных библиотек расширений от Laurent Bédubourg. Цикл описывается необходимый минимум, достаточный, чтобы начать работу над своим расширением. Когда я начал работу над своим набором расширений, данных статей не было и информацию приходилось искать в различных блогах.
Если вы захотите создать расширение для Android и вам понадобятся возможности последних SDK, то вот здесь можно найти статью о том, как собрать расширение для нужной версии SDK.
ссылка на оригинал статьи http://habrahabr.ru/post/187594/
Добавить комментарий