В этой статье вы узнаете, как подключить свой JAVA-класс, как создаётся файл «classes.dex», как пишутся обёртки (об этом уже писал) и как потом использовать подключенный JAVA-код. Советую читать и изучать материал внимательно, чтобы все ваши вопросы решились сами собой.
Начнём!
Составим план того, что нам необходимо:
- Иметь сторонний JAVA-класс или написать самостоятельно
- Написать обёртку для выбранного JAVA-класса
- Создать файл "classes.dex" и склеить со стандартным файлом
- Написать приложение, в котором используется наш класс
1) Иметь сторонний JAVA-класс или написать самостоятельно
В данной статье, для примера, я написал собственный простейший Java-класс. Вы же можете попробовать подключить любой другой Java-класс, в интернете полно готового кода. Писать их можно где угодно, я делал это в среде «Eclipse» (Скачать можно тут Get the Android SDK).
О том, как писать код на языке Java читайте на просторах интернета.
Класс, который я написал, имеет два метода:
Один статический, второй обычный. Это сделано для того, чтобы потом (в последнем шаге) показать, как использовать их в коде.
Мой класс принадлежит к пакету «TestClassHello» и имеет имя «HelloWorld», хранится по такому пути «C:\Users\Пользователь\workspace\TestClass\src\TestClassHello\HelloWorld.java».
Код класса:
package TestClassHello; public class HelloWorld { /** * @param args */ public static String getStrStatic(String str) { String strAnswer; String strHelloDelphi = "hello from delphi!"; if (str.toLowerCase().equals(strHelloDelphi)) strAnswer = "Hello World!\nHello Delphi Community! ;)\n(JAVA! Static method)"; else strAnswer = str + "\n(JAVA! Static method)"; return strAnswer; } public String getStrNoStatic(String str) { return str + "\n(Java! Not a static method)"; } }
Что умеет класс.
Класс при использовании любого из двух методов, возвращает текст. Также в методы можно передавать любой текст, и он будет возвращён с добавлениями. А при определённой фразе, поздоровается со всем Delphi сообществом (хоть какое-то разнообразие :).
Теперь создадим папку (например, на рабочем столе) для нашего будущего приложения, пускай называется «testJAVA», в ней создадим папку «java» и скопируем в эту папку всё из «C:\Users\Пользователь\workspace\TestClass\».
Получим вот такое дерево папок:
В дальнейшем мы будем работать только с этой «testJAVA» папкой, поэтому можно забыть про всё остальное :)
Ну вот, первый пункт успешно выполнили. Быстренько переходим ко второму пункту, долго не задерживаемся.
2) Написать обёртку для выбранного JAVA-класса
Если вы посещаете/читаете мой блог, то скорее всего уже видели (и надеюсь читали) статью о том как создавать обёртки. Почти всё, что написано в той статье также справедливо и для обёрток сторонних Java-классов. Разница только в том, что список методов мы берём не с сайта, а из нашего JAVA-класса.
В классе всего два метода:
- статический «getStrStatic» – значит, пишем его в interface(JObjectClass)
- обычный «getStrNoStatic» – пишем в interface(JObject)
Оба метода принимают и возвращают строку.
Файл я так и назвал «TestClassHello».
Код обёртки для JAVA-класса:
unit TestClassHello; interface uses Androidapi.JNIBridge, Androidapi.JNI.JavaTypes; type JHelloWorld = interface; JHelloWorldClass = interface(JObjectClass) ['{77C14F6E-4D89-419B-A721-366D48D6A671}'] function getStrStatic(str: JString): JString; cdecl; end; [JavaSignature('TestClassHello/HelloWorld')] JHelloWorld = interface(JObject) ['{11121974-C65D-48B0-B9E2-B16E4F93B275}'] {Property Methods} {Methods} function getStrNoStatic(str: JString): JString; cdecl; {Properties} end; TJHelloWorld = class(TJavaGenericImport<JHelloWorldClass, JHelloWorld>) end; implementation procedure RegisterTypes; begin TRegTypes.RegisterType('TestClassHello', TypeInfo(TestClassHello.JHelloWorld)); end; initialization RegisterTypes; end.
Обёртка готова, кладём её в корень папки «testJAVA». Половину пути прошли, теперь уже ни как нельзя бросать всё из-за лени, например)) Продолжаем…
3) Создать файл classes.dex и склеить со стандартным файлом
Файл с java реализацией дополнительного функционала FireMonkey.
Шаги создания:
- Компилируем наш класс
- Создаём jar, содержащий наш класс
- Конвертируем jar в dex
- Склеиваем стандартный classes.dex с нашим classes.dex
Для того чтобы создавать всё автоматически, уважаемый Brian Long написал bat-файл. Этим файлом мы и воспользуемся, изменив его под себя. Этот bat-файл, необходимо создать и сохранить в папке «\testJAVA\java\».
У всех этот файл выглядит по-разному, но выполняет одинаковые функции, вот вам мой, ниже будет небольшое описание.
Код файла «build.bat»:
@echo off setlocal if x%ANDROID% == x set ANDROID=C:\Users\Public\Documents\Embarcadero\Studio\14.0\PlatformSDKs\adt-bundle-windows-x86-20131030\sdk set ANDROID_PLATFORM=%ANDROID%\platforms\android-19 set DX_LIB=%ANDROID%\build-tools\android-4.4\lib set EMBO_DEX="C:\Program Files\Embarcadero\Studio\14.0\lib\android\debug\classes.dex" set PROJ_DIR=%CD% set VERBOSE=0 echo. echo Compiling the Java service activity source files echo. mkdir output 2> nul mkdir output\classes 2> nul if x%VERBOSE% == x1 SET VERBOSE_FLAG=-verbose javac %VERBOSE_FLAG% -Xlint:deprecation -cp %ANDROID_PLATFORM%\android.jar -d output\classes src\TestClassHello\HelloWorld.java echo. echo Creating jar containing the new classes echo. mkdir output\jar 2> nul if x%VERBOSE% == x1 SET VERBOSE_FLAG=v jar c%VERBOSE_FLAG%f output\jar\test_classes.jar -C output\classes TestClassHello echo. echo Converting from jar to dex... echo. mkdir output\dex 2> nul if x%VERBOSE% == x1 SET VERBOSE_FLAG=--verbose call %DX_LIB%\dx.jar --dex %VERBOSE_FLAG% --output=%PROJ_DIR%\output\dex\test_classes.dex --positions=lines %PROJ_DIR%\output\jar\test_classes.jar echo. echo Merging dex files echo.com.android.dx.merge.DexMerger java -cp %DX_LIB%\dx.jar com.android.dx.merge.DexMerger %PROJ_DIR%\output\dex\classes.dex %PROJ_DIR%\output\dex\test_classes.dex %EMBO_DEX% echo Tidying up echo. del output\classes\TestClassHello\HelloWorld.class rmdir output\classes\TestClassHello rmdir output\classes del output\dex\test_classes.dex del output\jar\test_classes.jar rmdir output\jar echo. echo Now we have the end result, which is output\dex\classes.dex :Exit endlocal
Теперь разберём этот файл, процесс выполняется пошагово в соответствии с описанными выше шагами создания.
Что необходимо сделать, чтобы данный bat-файл заработал у вас:
а) Необходимо прописать глобальный путь до главной директории JAVA
- Жмёте «Пуск» -> «Компьютер», далее жмёте «Свойства системы», там жмёте «Дополнительные параметры системы»
- В открывшемся окне, выбираем вкладку «Дополнительно» и жмём на кнопку «Переменные среды…»
- В открывшемся окне, в «Системных переменных» ищем переменную «Path», выбераем её и жмём «Изменить»
- В конец строки добавляем путь до папки «bin», примерно такой «;C:\Program Files\Java\jdk1.7.0_25\bin», обратите внимание на точку с запятой в начале, это необходимо чтобы отделить добавляемый путь от уже указанных.
- Жмём «OK» и всё закрываем.
Теперь командная строка умеет работать с JAVA командами.
б) Далее необходимо в коде изменить пути, в самом начале файла.
У меня в файле это:
- ANDROID - Путь до SDK
- ANDROID_PLATFORM – Путь до модуля SDK Platform
- DX_LIB – каталог с библиотекой поддержки Dalvik, dx.jar
- EMBO_DEX – путь до стандартного файла «classes.dex»
Стандартный файл «classes.dex» бывает двух видов:
Debug – «C:\Program Files\Embarcadero\Studio\14.0\lib\android\debug\classes.dex»
Release – «C:\Program Files\Embarcadero\Studio\14.0\lib\android\release\classes.dex»
в) Далее в 18 строке, в конце, необходимо изменить путь на свой или оставить также (если вы придерживаетесь статьи). Этот путь берётся из папки «\testJAVA\java\», если вы не забыли, то там у нас лежит наш класс «Desktop\testJAVA\java\src\TestClassHello\HelloWorld.java», путь указывается, начиная с папки «\src\».
На 25 строчке, в конце укажите название папки, которая вложена в папку «src». В моём случае это «TestClassHello». На 41 и 42 строчках также измените названия папок и имя класса.
Если вы всё сделали правильно, то можете смело запускать файл и смотреть результат.
Результат будет таким: в папке «java» появится папка «output», в которой будет лежать новый файл «classes.dex».
Ну вот, кончились мучения, теперь у нас есть файл «C:\Users\Пользователь\Desktop\testJAVA\java\output\dex\classes.dex». Приступаем к последнему шагу.
4) Написать приложение, в котором используется наш класс
Приложение получилось простое:
Код:
- В uses подключаем два модуля, в том числе и нашу обёртку: Androidapi.Helpers, TestClassHello;
- Обращение к статическим методам происходит через "JavaClass", в коде это "Button1".
- Обычные методы – перед обращением необходимо создать объект, в коде это "Button2".
uses Androidapi.Helpers, TestClassHello; procedure TForm1.Button1Click(Sender: TObject); begin Label1.Text := 'Answer: ' + #13#10 + JStringToString(TJHelloWorld.JavaClass.getStrStatic(StringToJString(Edit1.Text))); end; procedure TForm1.Button2Click(Sender: TObject); var TestClass: JHelloWorld; begin TestClass := TJHelloWorld.Create; Label1.Text := 'Answer: ' + #13#10 + JStringToString(TestClass.getStrNoStatic(StringToJString(Edit1.Text))); end;
Также необходимо задеплоить новый файл «classes.dex», а со стандартного снять галочку.
Результат:
На этом всё. Как видите всё получилось хорошо. Статья получилась большой, но надеюсь читабельной.
Благодарю Anatoly Zakusilov, именно ваши вопросы подтолкнули меня на то чтобы дописать эту статью :)
Если у вас возникли вопросы, то пишите в комментарии.