Публикации FreePascal

Пишем на Pascal для Android: Android Native Controls

27.12.2014
Александр Савиных

Android и Java

Android устроен таким образом, что все приложения для него должны быть Java-приложениями. Поэтому чтобы профессионально разрабатывать приложения для Android, следует знать основы Java. Возможно ли сделать приложение для Android без Java? Да, возможно, но это будет уже не приложение а замысловатая модификация системы. Но как же разные другие средства разработки на которых можно создавать приложения для Android без Java, такие, например, как Delphi и Haxe? Они тоже включают в состав приложения часть на Java, просто делается это неявно, и таким образом разработчик огораживается от необходимости соприкасаться с Java. Если вы уже знаете Java - хорошо, если нет, то изучить основной синтаксис будет несложно если вы уже знаете один язык программирования, например, Pascal. Вовсе не обязательно вдаваться в подробности, особенно если писать на Java вы особенно и не собираетесь, достаточно для начала знать как объявляются классы и методы и иметь общее представление о Java. На Android приложения выполняются в виртуальной Java-машине Dalvik. На более новых Android'ах используется другая виртуальная Java-машина, которая называется ART, Android Runtime, которая "должна" быть совместима с Dalvik практически полностью. Тем не менее, не следует удивляться если приложение работает на одном Android-устройстве, но не работает на другом. Это - обычное дело.

APK-файлы

Приложения для Android могут распространяться в APK-файлах, которые являются zip-архивами. Таким образом, APK-файл можно открывать архиватором. Кроме того, можно и создавать APK-файл архиватором, но это уже сложнее, так как там требуется цифровая подпись, которую обычный архиватор делать не будет. Каким образом она формируется я не буду описывать потому, что не знаю, и потому, что создавать приложения для Android можно и не зная таких подробностей, так как подписанный файл можно создавать с помощью Eclipse ADT (Android Developer Tools). В этой статье будет описано как работать над Android-приложением используя две среды разработки, Eclipse и Lazarus, одновременно. Можно попробовать обойтись только лишь одним из этих двух, или даже обойтись совсем без среды разработки, но в статье будет, в основном, описан именно метод работы когда используются обе эти среды разработки. Когда вы соберёте свое приложение в APK, вы сможете скопировать его на телефон и установить. По умолчанию в Android запрещена установка приложений из APK (а разрешена без ограничений установка приложений из Google Play Market, он же Play Store), однако при попытке установить приложение из APK-файла Android должен сразу же предложить разрешить установку в настройках. Но на разных телефонах может быть по-разному. Возможно, некоторые производители блокируют установку приложений из APK более жёстко: например, включить настройку Android может и не предложить, тогда залезьте в стандартные настройки и найдите её там. А может такой настройки и не быть вообще. Можете заранее скачать из интернета какое-нибудь приложение в APK и попробовать установить его чтобы узнать, можно ли разрешить на вашем телефоне установку приложений из APK. Главное не накачать вирусов.

Все действия в данной статье описаны для Windows и делались мной на только что установленной системе Windows 8.1, 64-разрядной, в виртуальной машине. Кроме того, у меня были включены все администраторские права по умолчанию, и выключен UAC, то есть все действия у меня происходили сразу от имени администратора, так что, если у вас что либо не заработает, можете пытаться сделать то же самое "от администратора". Консоли тоже можно запускать от администратора.

Установка Java

Если у вас нет Java, то нужно установить Java. Заметьте что разрядность Eclipse и Java должна будет совпадать.

Заходим на java.com/ru и нажимаем большую красную кнопку "Загрузить Java бесплатно".

Java нужна той же разрядности, что и Eclipse, то есть, если загрузили 64-разрядный Eclipse ADT, то и Java должна быть 64-разрядная, иначе можно получить непонятную ошибку при старте Eclipse. Я устанавливаю 64-разрядную Java чтобы работал 64-разрядный Eclipse; для этого со страницы загрузки Java я перехожу по ссылке "Просмотрите все загружаемые файлы Java" и скачиваю там 64-разрядный установщик для Windows.

Установка Eclipse ADT

Итак, если у вас ещё нет Eclipse ADT, то следует скачать Eclipse ADT: developer.android.com/sdk. Скажу на всякий случай, что вообще все файлы и инструменты лучше скачивать с их официальных сайтов или с источников которым можно доверять.

(Те, у кого Eclipse ADT уже есть, могут этот шаг пропустить...)

Выбирать разрядность Eclipse ADT такую же, как разрядность установленной Java.

Загруженный архив распаковываем в любую папку, у меня это будет C:\PasAndroid

Android SDK Manager

Теперь посмотрим какие у нас SDK есть в Eclipse ADT. Для этого запускаем SDK Manager.exe из папки с Eclipse ADT. Если у вас есть установленная Java на компьютере, то он запустится. Иначе не запустится... В случае если SDK Manager не запустился (окно со списком пакетов не появляется) следует устанавливать Java.

Должен появиться список с пакетами для разработки. В случае если после установки Java не работает SDK Manager, можно попробовать перезагрузить Windows или иным способом донести до исполняемого файла изменившиеся переменные окружения, так как дело может быть в них.

Здесь вам предстоит выбрать начиная с какой версии Android будет работать ваше приложение. Я выбираю Android 4.0, а вы можете выбрать любую другую. Чем выше версия тем больше новых API доступно. На скриншоте есть пункт с названием ARM EABI v7a System Image. Если вы собираетесь запускать своё приложение только на телефоне, то отмечать его не обязательно. Это образ системы для эмулятора Android. Остальные пункты внутри Android 4.0 лучше устанавливать чем не устанавливать, особенно SDK Platform, без которой, скорее всего, работать не будет. Google APIs я думаю понятно зачем нужно. Когда выбрали пакеты для установки, нажимаем кнопку Install, затем нажимаем Accept License, затем нажимаем кнопку Продолжить. Ждём пока пакеты скачаются и установятся.

После успешной установки нужные пакеты должны отобразиться с состоянием Installed

Eclipse

Теперь закрываем SDK Manager и открываем Eclipse, который тоже требует наличия Java для работы. Как я уже написал, разрядность Eclipse и Java должна совпадать. Замечу что на одном компьютере можно установить несколько версий Java разной разрядности и разной степени древности. Если у вас несколько версий Java, то нужно либо надеяться что при запуске Eclipse выберется подходящая, либо настроить определённую версию Java через eclipse.ini. Кроме того, можно попробовать создать bat-файл для запуска Eclipse с нужной версией Java. Как именно настраивать Eclipse с конкретной версией Java уточнять здесь не буду (потому что не помню). Скорее всего, всё что требуется сделать в таком случае - это указать путь к нужному исполняемому файлу java: java.exe либо javaw.exe.

Запускать Eclipse следует через исполняемый файл eclipse.exe: adt-bundle/eclipse/eclipse.exe. У меня это C:\PasAndroid\adt-bundle-windows-x86_64-20140702\eclipse\eclipse.exe

При запуске Eclipse спросит расположение Workspace-каталога. Я буду делать всё в папке C:\PasAndroid, поэтому я вписываю C:\PasAndroid\space

И вот у нас Eclipse, в котором нельзя перемещать кнопки. На этом будем считать что Eclipse ADT настроен.

fpcup

Теперь поговорим о настройке FreePascal и Lazarus. Настраивать их я буду с помощью программы fpcup потому, что это просто. В первую очередь скачиваем fpcup с со страницы автора на bitbucket: https://bitbucket.org/reiniero

Нажимаем Downloads. Какую разрядность выбирать для fpcup не важно, главное чтобы для Windows. На самом деле лучше выбирать 32-разрядный fpcup, как мне кажется, но детального исследования на эту тему я не проводил. Многое что касается Free Pascal лучше выбирать 32-разрядное, так как 64-разрядное может не всегда работать как нужно (относится это замечание к Windows. На Linux всё наоборот: на 64-разрядный Линукс нужно 64-разрядное всё. Вообще всё). Я скачиваю fpcup в папку C:\PasAndroid\fpcup.

Теперь создаём BAT-скрипт для вызова fpcup с нужными параметрами. Вот код:

set C=C:\PasAndroid\FP
fpcup --lazURL=trunk --fpcURL=trunk --fpcDIR=%C%\FPC --lazDIR=%C%\L --primary-config-path=%C%\Conf --binutilsdir=%C%\BU --fpcbootstrapdir=%C%\FPCB --lazlinkname="Lazarus 1.3" --skip=helplazarus --anchordocking=1

Нужно чтобы весь текст после fpcup был в одну строку. Скрипт нужно сохранить в папку с fpcup. У меня это будет файл C:\PasAndroid\fpcup\up.bat.

На первой строке скрипт присваивает переменной C значение C:\PasAndroid\FP для того чтобы не писать ниже каждый раз этот путь, а писать вместо этого %C%. На следующей строке вызывается fpcup и назначаются его параметры. Вы можете устанавливать FPC и Lazarus в любую папку. Чтобы поменять папку, достаточно поменять только первую строку где написано set. Следует учесть что некоторые программы могут работать некорректно если в пути будут нестандартные символы или пробелы. Если в пути будут пробелы, то все пути нужно будет, вероятно, заключить в кавычки: --fpcDIR="%C%\Free Pascal". Можете пробовать пути с пробелами, я их не пробовал, поэтому не знаю точно, будет ли всё работать в таком случае или нет. Параметр lazlinkname задаёт имя ярлыка для лазаруса. Этот ярлык будет создан на рабочем столе. Если у вас уже есть лазарус 1.3 и есть ярлык, то ваш ярлык затрётся новым. В таком случае имеет смысл поменять lazlinkname на что-то вроде "Lazarus 1.3 for Android".

В параметр fpcURL надо назначать trunk так как поддержка Android реализована, в первую очередь, в разрабатываемой ветви компилятора, которая не добралась до релиза. В параметр lazURL нужно назначать trunk так как Lazarus-trunk работает лучше с FreePascal-trunk, а вот в стабильном лазарусе имеются проблемы с FreePascal-trunk, которые я имел счастье лично наблюдать не так давно. В общем, наверное, не ошибусь, если скажу что следует применять следующее правило: стабильный Lazarus использовать с стабильным FreePascal, а нестабильный Lazarus использовать с нестабильным FreePascal... Параметр anchordocking=1 нужен для того, чтобы установился лазарус-пакет для стыковки окон. Этот параметр можно не вписывать.

Открываем консоль Windows cmd.exe либо другую любую консоль для Windows и переходим в папку fpcup. У меня это C:\PasAndroid\fpcup. Надеюсь что объяснять как пользоваться консолью не нужно. Следует запустить скрипт для установки Free Pascal и Lazarus. Вначале у нас будет устанавливаться FreePascal и Lazarus для Windows так как он (лазарус) всё равно нужен. Набираем имя файла со скриптом, у меня это up.bat. Нажимаем Enter. Запустится fpcup, выведет параметры, спросит продолжить или нет, вводим Y, нажимаем Enter, ждём.

Ждать, скорее всего, придётся долго. Не следует прерывать процесс досрочно, так как я вас предупредил, что он может занять много времени. Если процесс завершился быстро, то, скорее всего, произошла ошибка. В этом случае читаем сообщение об ошибке и пытаемся поправить ситуацию. В случае успеха должен в конце появиться текст наподобие такого:

fpcup: info: ДАТА ВРЕМЯ: fpcup finished.

Однако, появляется такой текст и в случае если произошла ошибка, так что смотреть что пишется нужно всё равно.

У меня лично в fpcup в какой-то момент отказался скачиваться subversion. Опишу как с этим бороться на всякий случай. Появляется вот такой вот текст:

Здесь fpcup сообщает нам, что не может скачать Subversion. В таком случае можно перейти по выделенной ссылке самому через браузер и скачать архив. В архиве будет две папки: Bin и License. Содержимое папки Bin следует распаковать в папку BU/svn, которая у меня C:\PasAndroid\FP\BU\svn, а у вас она будет находиться в той же подпапке, но там, куда вы указали устанавливать FreePascal и Lazarus на первой строке в bat-скрипте. Будет у вас скачиваться svn-клиент автоматически или же нет я не знаю, так как у меня он вначале скачивался, а на следующей неделе уже нет; на той же машине с теми же настройками и папками. Скачивать Subversion отдельно нужно только если автоматическая загрузка не сработала, и вы получили "ERROR downloading SVN client".

Теперь на рабочем столе у вас должен появиться ярлык "Lazarus 1.3". Возможно, версия Lazarus с момента написания статьи несколько изменится, но ветка 1.3 должна быть доступна ещё долго. Не забываем проверить, работает ли Lazarus, если конечно он вам нужен. У кого Lazarus уже есть, тот может установку лазаруса пропустить и работать со своим лазарусом. Имейте в виду, что стандартный лазарус не имеет функции для быстрого автоматического переключения между несколькими компиляторами, так что, если ваш лазарус настроен на стабильный FreePascal 2.6.5 (в отличие от trunk он же 2.7.1), то, возможно, удобнее иметь для работы с trunk-компилятором отдельный лазарус. Кроме того, как я уже сказал, с нестабильным компилятором лучше работает нестабильный Лазарус. Если решите использовать дургой лазарус, то нужно вписать в настройках лазаруса правильные пути к компилятору.

Теперь нужно установить компилятор FreePascal для Android. Специальный Lazarus для Android не нужен.

Вначале нужно установить Android NDK (native development kit). Скачивать с официального сайта: developer.android.com/tools/sdk/ndk. Я скачиваю новейший доступный сегодня NDK r10c для 64-разрядной Windows. Скачается исполняемый файл который при запуске разархивируется в подпапку той же папки в которой его запустили. Я запускаю файл в папке C:\PasAndroid. Ждём пока распакуются кучи файлов...

Теперь нужно скопировать некоторые файлы из одной папки в другую. Нужно зайти в следующую папку в NDK: android-ndk-r10c\toolchains\arm-linux-androideabi-4.8\prebuilt\windows-x86_64\bin и скопировать оттуда все файлы в папку в которую установлен FreePascal и Lazarus с помощью fpcup (которая указывается у меня в BAT-скрипте set C=C:\PasAndroid\FP) в подпапку cross\bin\arm-android. Таким образом, я копирую файлы:

  • из C:\PasAndroid\android-ndk-r10c\toolchains\arm-linux-androideabi-4.8\prebuilt\windows-x86_64\bin
  • в C:\PasAndroid\FP\cross\bin\arm-android

Там должны быть исполняемые файлы. Теперь нужно ещё скопировать файлы:

  • из папки android-ndk-r10c\platforms\android-14\arch-arm\usr\lib
  • в папку FP\cross\lib\arm-android

... где FP это та же самая папка про которую речь шла выше, то есть, папка назначения для fpcup. Там должны быть файлы с динамическими и статическими библиотеками с расширениями .so и .a .

Обратите внимание на android-14 в пути к папке lib выше. Так как в начале я написал, что буду настраивать инструменты так, чтобы поддерживался Android начиная с 4.0, то я выбираю android-14 так как API level 14 соответствует Android 4.0. Соответствие API level и определённой версии Android можно посмотреть в статье Android Version History в википедии: en.wikipedia.org/wiki/Android_version_history. Конечно же, всегда есть риск что что-нибудь "не заведётся" из-за несоответствия версий чего-нибудь с чем-нибудь. К примеру, то что работало в NDK r9c может по каким либо причинам не сработать с NDK r10c.

Теперь создаём ещё один BAT-скрипт для запуска программы fpcup для подготовки компилятора FreePascal который будет компилировать динамические библиотеки для Android. Я сохраняю код в файл andro.bat в папке с исполняемым файлом fpcup. Вот код:

set C=C:\PasAndroid\FP
fpcup --fpcDIR=%C%\FPC --binutilsdir=%C%\BU --fpcbootstrapdir=%C%\FPCB --only=FPCBuildOnly --cputarget=arm --ostarget=android --crossopt="-CpARMv5 -CfSOFT"

Не забывайте что C:\PasAndroid\FP нужно поменять на свой путь. Но путь должен быть тот же самый, что и в предыдущем скрипте потому, что кросскомпилятор FreePascal для Android установится в ту же самую папку, что и FreePascal для Windows. Запускаем скрипт, Y, ждём. Ждать придётся не так долго как в прошлый раз потому, что не будет происходить закачивание утилит, закачивание исходного кода и сборка лазаруса. Будет происходить только лишь сборка FreePascal. Обратите внимание на параметр crossopt, здесь я устанавливаю минимальный поддерживаемый процессор ARM v5 без требований дополнительных инструкций для вычислений с плавающей запятой. Это, возможно, позволит коду работать на разных более старых устройствах, вообще же я бы рекомендовал ставить ARM v6 так как практически все современные телефоны имеют процессор не ниже v6.

Настройка Android Native Controls

Теперь переходим к рассмотрению библиотеки Android Native Controls, сделанной неким Simon, Choi. Вот ссылка на его блог: blog.naver.com/simonsayz. Так вот, Android Native Controls это такая вещь, которая в некотором роде позволяет создавать приложения для Android на FreePascal не зная Java, так как этот товарищ создал некое подобие фрэймворка, которое взаимодействует с Android API на Java. Вот ссылка на новейший на данный момент Android Native Controls: blog.naver.com/simonsayz/120204060881. В его проекте я сделал некоторые изменения.

1. Во-первых, пришлось переложить исходники на Java в другую подпапку чтобы пакеты, прописанные в исходниках, соответствовали папке. App.java и Controls.java должны быть в src/com/kredix, а не в src. Иначе не компилируется.

2. Во-вторых, я удалил в Lazarus-проекте все дополнительные опции компилятора вписанные в Project Options\Compiler Options\Other\Custom Options.

3. Я вписал нужные значения в Unit output directory и в Target file name. Там должно быть output и ..\libs\armeabi\libmain.so. Галочку Apply conventions нужно снять потому что проект у нас всё равно только для Android.

4. Из файла AndroidManifest.xml я убрал android:debuggable = "true", иначе не компилируется.

5. Выключил оптимизацию.

К статье я планирую приложить папку с проектом с внесёнными в него необходимыми изменениями. Так что вы можете либо скачать оригинальный архив и сделать изменения, либо скачать мой архив, и тогда изменения делать не придётся. Описанные мною изменения вы можете внести открыв проект в лазарусе. Нужно открывать тем лазарусом, который настроили для работы с Android-приложениями. Это Lazarus 1.3 из папки со всем остальным. Файлы лазарус-проектов лежат в папке с And_Controls в подпапке jni. Я менял файл win64_Android_ArmV6_VFPv2.lpi. Фактически у меня получился проект для ARMv5, так что название файла проекта после изменения становится неактуальным. Я лично считаю что нужно удалить дополнительные опции, вставленные автором в Custom Options, так как иначе получится что мы без причины усложняем себе жизнь. Не забудьте переложить .java-файлы в содержимом оригинального архива если вы его меняете.

При разработке приложения для Android вам придётся держать открытым Lazarus и Eclipse. Я делал именно так. В случае использования базовой функциональности Android Native Controls или другого готового фреймворка редактировать код в Eclipse не придётся, в таком случае будете использовать Eclipse только для запуска приложения на телефоне, просмотра логов и создания APK-файлов.

Теперь пришло время импортировать проект в Workspace Eclipse'а. Нажимаем File -> Import..., затем в группе General выбираем Existing Projects into Workspace, нажимаем Next. Теперь нужно указать папку с проектом. Если скачали оригинальный проект Android Native Controls, то импортировать его обязательно, а в случае с моей сборкой он уже импортирован, поэтому импортировать его второй раз не нужно. Однако всё же потребуется его импортировать если используете Eclipse не из сборки.

Нужно поставить галочку "Copy projects into workspace". Проект импортируется под именем App.

Теперь пришло время скомпилировать FreePascal-часть проекта. Открываем файл проекта в лазарусе. Нужно открыть основной файл проекта, который теперь в workspace Eclipse'а. У меня это C:\PasAndroid\space\App\jni\win64_Android_ArmV6_VFPv2.lpi . В общем, в папке которую вы выбрали как Eclipse workspace нужно найти проект App. Все исходники на FreePascal там лежат в подпапке jni.

Для начала можно проверить настройки проекта. Если вы взяли оригинальный Android Native Controls и ещё не поменяли то что я перечислил выше, то сейчас самое время поменять. Нажимаем в главном меню Project -> Project Options... Вот что будет на панели Compiler Options / Paths

Обратите внимание что вписано в Target file name. Должно быть: ..\libs\armeabi\libmain.so потому, что нативные динамические библиотеки в Android-приложении должны лежать в папке libs и в подпапке с названием архитектуры. Если вы решите поддерживать Android-устройства с процессором x86, то второй файл у вас будет сохраняться в ..\libs\x86\libmain.so . Файлы скомпилированных паскаль-модулей будут сохраняться в папку output, то есть, в workspace/App/jni/output .

Обратите внимание на панель Compiler Options / Config and Target.

Здесь у нас Target OS: Android, Target CPU family: arm. Если не работает автодополнение кода или парсер кода лазаруса не видит какой-нибудь из стандартных модулей (например, Math), то нужно нажать Tools -> Rescan FPC Source Directory.

Компиляция проекта

Теперь компилируем проект. Предварительно рекомендую очистить папки jni/output и libs в папке с проектом (App). Нажимаем Ctrl+F9. У меня компиляция назначена на F9 потому что запуском проекта с отладчиком я никогда не пользуюсь. Уж точно не придётся пользоваться отладчиком при разработке приложений для Android. В лучшем случае удастся посидеть в отладчике Eclipse для Java, а вот для кода на FreePascal придётся отлаживать всё логами. В случае успешной компиляции в папке libs/armeabi должен создаться новый файл libmain.so . В окне с сообщениями лазаруса появится такая зелёная полоса: Compile Project: ... Success.

В случае если проект у вас не компилируется придётся думать что не так...

Когда проект успешно скомпилирован, перейдите в Eclipse. Там у вас должен быть открыт проект App. Слева в Package Explorer выделите App и нажмите F5: обновить. По умолчанию в Eclipse активна автоматическая сборка. Это значит что проект компилируется каждый раз после того как он меняется. Нужно только нажимать обновить. В общем порядок компиляции любого проекта состоящего из двух частей (FreePascal-Lazarus и Java-Eclipse) такой: компилируем Lazarus-часть, затем нажимаем F5 в Eclipse. Если на каком-то этапе работы над проектом сделали изменения только в Java-части проекта в Eclipse, то F5 нажимать не обязательно. Если на каком-то этапе работы над проектом сделали изменения только в FreePascal-части проекта, то после компиляции проекта лазарусом нажать F5 в Eclipse нужно, иначе изменённые .so-файлы могут не обнаружиться. Здесь можно поэкспериментировать и попробовать включить в настройках Eclipse автоматическое обновление файлов из файловой системы и посмотреть будут ли файлы .so обновляться в нужный момент. Если вы сделали какое-то изменение, запустили свой проект, и у вас всё по-старому, значит в какой-то момент файлы не обновились, и нужно нажимать F5.

Если в Eclipse в нижней панели на вкладке Problems появляются какие либо ошибки значит проект не скомпилировался, и нужно их исправлять... Если какие либо ошибки остаются у вас в списке ошибок после того как их исправили, можно попробовать нажать в контекстном меню проекта: Android Tools -> Clear Lint Markers

Обратите внимание: у меня внизу 0 errors, значит можно запускать...

Напоминаю, что результирующий .so-модуль должен класться в libs\armeabi\libmain.so для ARM и в libs\x86\libmain.so для x86, иначе приложение не запустится на телефоне. Для x86 нужно будет таким же образом, как описано выше, собрать ещё один кросскомпилятор, опять же, в той же папке (я не пробовал). Делать x86-модуль не обязательно если вы не планируете запускать приложения на x86-устройствах с Android.

Запуск проекта

Есть два способа запуска проекта: прямо из Eclipse либо собрать APK-файл и установить его на телефоне. Обратите внимание на замечание по поводу APK-файлов в начале статьи. А вот чтобы запускать проект прямо из Eclipse, нужно установить для своего телефона драйвер ADB на компьютере и включить отладку по USB в настройках телефона (в настройках в разделе Для разработчиков).

Чтобы скомпилировать установочный APK-файл приложения, нужно в Eclipse нажать правой кнопкой на ваш проект App, в вылезшем меню выбрать пункт Android Tools -> Export Signed Application Package... Скажу на всякий случай, что если выбрать Export Unsigned Application Package..., то устанавливаться такой архив скорее всего не будет, телефон заругается. Кроме того, нельзя обновить приложение архивом с подписью отличающейся от первоначальной, но в таком случае можно удалить приложение и установить заново. Когда нажмёте Export Signed Application Package в первый раз, то сначала попросят создать или выбрать хранилище ключей. Для учебно-экспериментаторских целей это никакого значения не имеет. Создаём файл с ключами в любой папке. Это не APK-архив, это только файл с ключами. Тем кто собирается публиковать приложения в Play Маркете рекомендую почитать подробнее про эти ключи, я же про них ничего рассказать не могу кроме того что перед экспортом приложения нужно их создать и ввести там пароль, который лучше запомнить потому, что вводить его придётся при каждом экспорте приложения. Причём, паролей будет два: для хранилища ключей и для ключа, и вводить придётся их оба. Поэтому запомнить их надо оба, либо установить их одинаковыми и запомнить один пароль. Если используете "мою сборку" то надо будет создать новый файл ключей несмотря на то, что я его уже создавал, так как пароль от моего файла ключей вы не знаете, да я и сам уже его не помню. Нажимаем Create new keystore, создаём ключи, продолжаем...

Нажимаем Finish, ждём, готово. Я сохраняю APK-файл на рабочий стол. Теперь нужно скопировать его на телефон, установить и запустить. Проделывать это каждый раз может надоесть.

Так что, переходим ко второму способу запуска программ, назовём его "быстрый запуск из Eclipse". Для быстрого запуска через Eclipse нужно подключить телефон к компьютеру проводом. У меня драйвер ADB для телефона установился автоматически. Если у вас это не произойдёт, придётся искать драйвер ADB для вашего телефона. Для начала надо проверить виден ли телефон в Eclipse. Нажимаем такую зелёную круглую кнопку с белым треугольником либо из меню: Run -> Run. Там нужно будет выбрать Run as Android application. Затем появится список телефонов. Телефон можно подключить и когда окно со списком уже появилось. Нужно чтобы на телефоне была включена отладка по USB в настройках.

Если ваш телефон там появился, значит всё, можно запускать, иначе искать драйвер для телефона. При запуске могут попросить удалить уже установленное приложение если вы до этого уже установили своё приложение через APK-файл. Это нормально, потому что подписи приложения в APK файле и во временном файле приложения сгенерированном через Eclipse могут не совпадать. Если спрашивают лог, выбираем Yes, Verbose.

После этого можем наблюдать отладочные сообщения от приложения.

Хочу заметить что у тех, кто будет пользоваться моим архивом, некоторые запросы, скорее всего, не будут появляться, так как запомнится то что я выбирал.

Запускать приложения "быстрым" способом лучше по двум причинам: во-первых, это быстрее. Если выбрать чтобы не спрашивали каждый раз на каком телефоне запускать, то для запуска нужно будет делать только одно нажатие кнопки. Во-вторых, отображается лог.

При желании можно изобрести другой, какой-нибудь нестандартный способ загрузки APK-файла на телефон, автоматизированной установки APK-файла и получения лога во время работы приложения.

Проект AndControls в действии:

Скриншоты сделал на своём телефоне.

Использование Android Native Controls

Как я написал выше, используя Android Native Controls, вы можете попробовать создать Android-приложение, не трогая его Java-часть совсем.

Как создать своё приложение с Android Native Controls? У нас есть проект, но сейчас он показывает какие-то демонстрационные экраны, фотографии, и прочее то, что нам не нужно. В первую очередь я бы рекомендовал сохранить существующий проект в его неизменном виде для его последующего использования в качестве шаблона. Таким образом у вас будет проект с нужной структурой каталогов, настройками и файлами, который можно будет просто скопировать когда понадобится создать ещё один проект. После того как скопировали проект, изменяйте его чтобы выполнять нужные вам действия. Обратите внимание на фрагмент кода:

Здесь создаётся окно которое будет показано при запуске приложения. Создайте новый модуль и начните работать над своим собственным окном, а в код Java_Event_pAppOnCreate подправьте так, чтобы он создавал экземпляр класса вашего окна вместо jFrom_Splash. Все остальные файлы-окна можно удалить. При работе используйте проект-шаблон в качестве справочника. Смотрите как делаются те или иные вещи, создаются визуальные элементы управления, кнопки, поля ввода и прочее.

Кратко про использование Java Native Interface для взаимодействия кода на Java и FreePascal

Взаимодействие кода на Java и FreePascal в деталях это тема для отдельной статьи. Поэтому сейчас поверхностно поизучаем взаимодействие по JNI (Java Native Interface) на примере проекта AndControls.

Это фрагмент кода из файла win64_ArmV6_VFPv2.pas:

Для того, чтобы некоторые функции исполняемого модуля написанного на FreePascal стали доступны из Java, нужно объявить их в секции exports library-файла. Здесь они только экспортируются, а объявлены функции могут быть в любом модуле.

Обратите внимание на объявление экспортируемых функций:

Для того чтобы экспортируемые функции корректно вызывались из Java, они должны быть объявлены с директивой cdecl; Заметьте, что начинаться код главного файла проекта на FreePascal должен с ключевого слова library, а не program. Это нужно для того чтобы компилировалась динамическая библиотека.

Когда Java-машина загружает динамическую библиотеку, то вызывается функция JNI_OnLoad, а перед тем как выгрузить динамическую библиотеку, вызывает функцию JNI_OnUnload. Лучше разрабатывать приложение так чтобы оно было готово завершить работу в любой момент по требованию системы так как Android может заставить приложение завершаться когда угодно. Если приложение должно работать постоянно длительное время, то следует сделать его сервисом или создать непропадающее уведомление (notification), об этом читаем в документации по Android API.

Для вызова Java-методов из кода на FreePascal с помощью JNI нужно использовать специальный API:

Здесь из кода написанного на FreePascal вызывается Java-метод getStrLength (не знаю зачем). Всё не так просто. Но если разобраться, то просто. Непредвиденные сложности могут ожидать тех, кто захочет организовать взаимодействие по JNI между разными потоками приложения.

А вот фрагмент кода на Java, который объявляет наличие некоторых функций в динамической библиотеке:

Этот фрагмент тоже взят из проекта Android Native Controls. Как видно, функции, которые должны браться из динамической библиотеки, объявляются с ключевым словом native. Кроме того заметьте, что перед тем как начать вызывать native-функции, в Java-коде должна быть вызвана функция loadLibrary:

Unload делать не надо; Java-машина должна выгрузить динамическую библиотеку сама.

Вызываются native-функции просто как обычные функции; основные сложности реализации сосредоточены на native-стороне.

Тем, кто хочет разобраться с JNI, рекомендую поизучать:

  • Android Native Controls - проект
  • ZenGL: в этом графическом движке используется JNI для приложений для Android
  • LCL for Android: примеры приложений в папке с Lazarus: examples\androidlcl

Организовать взаимодействие между частями программы по JNI можно по-разному. Вместо того чтобы экспортировать каждую нужную функцию, можно попробовать сделать общей одну единственную функцию (не считая JNI_OnLoad и JNI_OnUnLoad) и передавать через неё сообщения в виде XML-строк. Это избавит от необходимости более глубоко разбираться в JNI и от возможных проблем с многопоточностью. Если бы лично мне пришлось работать с JNI, я бы, скорее всего, выбрал бы именно такой подход.

Фреймворки

Самый лучший способ организации взаимодействия частей Android-приложения по JNI - это когда всё взаимодействие уже организовано за нас группой разработчиков, которая как следует в этом разобралась, создала библиотеку для разработки приложений для Android на данном конкретном языке программирования и хорошенько протестировала эту самую библиотеку с разными сценариями использования и с разными телефонами.

Вот несколько примеров таких библиотек:

  • Xamarin: для приложений на C# для Android
  • PhoneGap: для приложений на JavaScript для Android
  • kivy: для разработки приложений на Python для Android

Скажу на всякий случай что могу в чём-то ошибаться так как особо не разбирался и не работал с этими библиотеками. Думаю не ошибусь если скажу что все они они в разной степени удобны или неудобны, а так же предоставляют более или менее полный доступ к API системы Android. Разные фреймворки обеспечивают разную производительность написанных на них приложений. По крайней мере, по части производительности можно с довольно большой уверенностью сказать, что Free Pascal не плох, хотя глубоких тестов не проводил.

Для FreePascal у нас на сегодняшний день есть такие подобия Android-фреймворков:

Какие возможности предоставляют LCL for Android и Android Module Wizard я не знаю так как никогда не пользовался ими. Для приложений с GUI будет не плох Android Native Controls либо LCL for Android, либо JNI вручную. Для приложений-игр будет не плох ZenGL. Для работы с сетью пригодится библиотека Synapse. Не берусь сказать, в какой степени готовности находится сейчас LCL for Android.

Думаю что не ошибусь если скажу что все перечисленные FreePascal-Android средства сейчас очень сырые, и с большой вероятностью, останутся сырыми ещё очень надолго, если не навсегда. Связано это, на мой взгляд, с тем что желающих создавать фреймворк для Android + FreePascal мало. Создание полноценного фреймворка - сложная задача, на которую требуется куча времени. Кроме того, нужны те кто желает такой фреймворк использовать и тестировать.

Впрочем, справедливости ради отмечу, что Android Module Wizard выглядит солидно, и в состоянии разработки он находится уже больше года. Если возникают вопросы по поводу Android Module Wizard, заходим на forum.lazarus.freepascal.org и задаём свой вопрос в теме с Android Module Wizard на английском.

Отдельно отмечу что некоторые библиотеки для FreePascal могут неплохо работать если использовать их на Android. Это в первую очередь относится к библиотекам которые:

  • Не имеют ассемблерных вставок в коде
  • Используют минимум платформ-зависимого API. Если библиотека привязана к Windows, то работать на андроиде она скорее всего не будет.
  • Библиотеки которые уже были адаптированы для Android разработчиками этих самых библиотек.
  • Библиотеки которые вообще используют мало API

В качестве работающей на андроиде библиотеки можно привести Synapse.

Архив с настроенными инструментами

Когда вы распаковываете архив с настроенными инструментами, то можете сделать чтобы путь к папке с содержимым архива был в точности такой же какой был у меня: C:\PasAndroid. Но это делать не обязательно. В случае если путь будет другой, нужно будет сделать такие действия:

  • Нажимать в Eclipse: File -> Switch Workspace -> Other... и вписывать путь к папке PasAndroid\space (где она у вас оказалась после распаковки архива.
  • Путь к Android SDK придётся указать: <ВашПуть>\PasAndroid\adt-bundle-windows-x86_64-20140702\sdk. Его спросит Eclipse при первом открытии проекта.
  • В Lazarus при запуске придётся указать путь к разным частям FreePascal SDK, так сказать. Так, к примеру, если вы распакуете архив в D:\Dev\PasAndroid вместо C:\PasAndroid, то путь к FPC Sources будет D:\Dev\PasAndroid\FP\FPC, и так далее. Lazarus будет спрашивать пути при первом запуске.

В общем, пути в настройках должны всегда быть правильные. Напоминаю, что если анализатор кода Lazarus не видит некоторые модули из стандартной библиотеки FreePascal, то нужно в первую очередь попробовать нажать в меню Сервис -> Пересмотреть каталог исходного кода FPC

Заключение

Каким образом и для чего всё это использовать, как и в каких пропорциях комбинировать Pascal и Java, как делать взаимодействие, какие библиотеки использовать - решать вам.

Ещё раз кратко: как делать приложения на андроид с FreePascal:

  • Берём Lazarus trunk и FreePascal trunk
  • Компилируем FreePascal-кросскомпилятор с Windows на Android ARM +опционально x86
  • Берём Eclipse ADT и Android NDK
  • Генерируем в паскаль-проекте динамическую бибилотеку, организуем JNI
  • В Eclipse делаем Java-часть проекта и запускаем проект на телефоне

И вот таким вот примерно образом можно делать приложения на FreePascal для Android.

Если что-то не получается или что-то не понятно, ищем ответы в Google, кроме того, можно попробовать создать тему с вопросом касающемся Android-разработки на форуме freepascal.ru, и если я увижу ваш вопрос, то постараюсь на него ответить.

Скачать архив с программами 1.27 Gb (проверялось только на x64)

Актуальные версии
FPC3.0.2release
Lazarus1.6.4release
MSE4.4.2release
fpGUI1.4.1release
наши спонсоры ;)