Разработка на Delphi под Android. Краткие впечатления.
Почти год тому назад вышла Delphi XE5. Первая версия Delphi, которая позволяет осуществлять разработку приложений для Android.
Многие Delphi разработчики практически сразу же начали осваивать новую для себя область. Одновременно с этим в их адрес посыпались вопросы со стороны коллег, которые по тем или иным причинам ещё не были с ней знакомы. Разработка под Android на Delphi? Как это? Каково это? Стоит ли этим заниматься? И ряд других подобных вопросов. Эти вопросы периодически возникают как в публичных обсуждениях на форумах и других web ресурсах, так и в приватных разговорах.
Причина этому не столько новизна и перспективность самой возможности разработки под Android на Delphi или популярность данной операционной системы, сколько, в первую очередь, отсутствие достаточного объёма информации. Даже сейчас её количество более чем скудное.
В интернете в основном это официальная документация Embarcadero, а также по большей части отрывочные материалы различных блогов и форумов. В отношении литературы ситуация ещё сложнее. На момент написания этой статьи, единственной книгой по данной тематике на русском языке была книга Дмитрия Леонидовича Осипова «Delphi. Программирование для Windows, OS X, iOS и Android». Прочитав эту книгу, могу сказать, что книга просто отличная. По крайней мере, по моему личному мнению (убедительная просьба не считать это рекламой). Однако недостаток литературы всё равно ощущается.
Поэтому нет ничего удивительного в том, что многие вопросы, в том числе самого общего плана, продолжают возникать.
Сразу хочу подчеркнуть, что данная статья не преследует цель дать исчерпывающий обзор разработки под Android на Delphi. В силу того, что данная область достаточно широка и многогранна, для этого будет недостаточно даже нескольких статей. Однако дать некоторую общую характеристику, описать общее впечатление, с точки зрения одного отдельно взятого разработчика вполне реально.
«Плюсы»
Первая из сильных сторон разработки под Android на Delphi это само наличие такой возможности. После выхода версии XE5 Delphi окончательно перестал быть языком программирования «только для компьютеров».
Конечно, возможность создания мобильных приложений как таковая появилась значительно раньше, в версии XE2. Однако она была доступна только для операционной системы iOS компании Apple и во многом благодаря этому первое время не была особо востребована. Всё-таки, по сравнению со многими аналогичными устройствами на базе Android, iPhone и iPad стоят не дёшево. Это уже само по себе уменьшает возможный спрос и увеличивает стоимость разработки. Также, помимо этого, своё определённое влияние оказывала и продолжает оказывать политика самой Apple по отношению к разработчикам.
С появлением возможности писать программы для Android ситуация резко изменилась и разработка мобильных приложений на Delphi начала интенсивно набирать обороты.
Так же как и для iOS разработка для Android осуществляется средствами кроссплатформенной библиотеки FireMonkey. Поэтому, для тех, кто и раньше использовал эту библиотеку, даже несмотря на особенности мобильных приложений, очень многое окажется знакомым.
Необходимо отметить, что библиотека FireMonkey достаточно дружественна по отношению к разработчику. Это позволяет эффективно разрабатывать приложения иногда даже вопреки её серьёзным недостаткам. Каким именно будет описано позднее, при рассмотрении слабых сторон.
Очень обрадовало то, что многие библиотеки компонентов и технологии, которые изначально были разработаны для VCL, также имеют реализацию для FireMonkey и доступны при разработке для Android. Среди них хотелось бы отметить dbExpress, FireDAC, DataSnap. Также реализацию для FireMonkey под Android имеет и широко известная библиотека для работы с сетью Indy.
Однако тех, кто привык использовать эти компоненты и технологии в «обычных» приложениях ждут два серьёзных разочарования.
- Реализация FireDAC, DataSnap и Indy для Android ограничена. То есть при разработке под Android доступны не все компоненты.
- Операционная система Android поддерживает достаточно небольшое количество СУБД. При этом многие распространённые СУБД, к сожалению, в их число не входят.
В прочем, если СУБД имеет драйвер или хотя бы возможность его сборки под Android (как, например, MySQL), то последнее, скорее всего, будет не актуально. В противном случае, при написании клиентского приложения придётся всерьёз позаботиться о реализации его взаимодействия с сервером.
Следует отметить, что в FireMonkey очень удачно реализована возможность адаптации приложения к различным устройствам с различным разрешением экрана. Что позволяет достаточно легко разрабатывать приложения, которые предназначены как для смартфонов, так и для планшетов.
Возможности по работе с мультимедиа, включая камеру, и датчиками (начиная с версии XE6) также проработаны на достаточно высоком уровне.
«Минусы»
Самое первое, что бросается в глаза это работа эмулятора. В силу своего несовершенства, эмулятор, по крайней мере, в случае RAD Studio вообще и Delphi в частности, не всегда оказывается способен запустить даже обычный «Hello, World!». Поэтому о возможности его использования лучше всего сразу забыть. Запускать и отлаживать программы для Android, вероятнее всего, придётся непосредственно на устройстве, со всеми вытекающими последствиями и рисками. Не говоря уже о том, что Android устройство придётся покупать (при его отсутствии).
Также процесс разработки существенно осложняется по причине многочисленных изъянов и недоработок в библиотеке FireMonkey. Многие из них сохранились ещё со времён версии XE2.
Вообще, складывается впечатление, что начиная с версий XE2 и XE3, Embarcadero делает основной упор на частое обновление и расширение функционала и списка поддерживаемых платформ. Это, само по себе, не плохо. Плохо то, что при выходе новый функционал часто оказывается ещё совсем «сырым». По этой причине, разработка с его использованием столь же часто сопровождается значительными сложностями и необходимостью использовать далеко не самые эффективные решения с целью просто обеспечить работоспособность программы. Положение ещё больше усугубляется тем, что с выходом новых версий, Embarcadero далеко не всегда устраняет издержки предыдущих версий.
Буквально около трёх месяцев назад на одном из форумов обсуждался один из таких недостатков FireMonkey. Оказалось, что в этой библиотеке функционал для работы с массивами даже к моменту выхода версии XE5 так и не был в достаточной степени проработан. В результате решение, основанное на использовании таких функций как Low и High, в FireMonkey оказалось не работоспособным (страница с обсуждением). Полагаю, выводы о том, как подобные особенности библиотеки сказываются на процессе разработки с её использованием, напрашиваются сами собой.
«Итог»
Библиотека FireMonkey имеет достаточно большой потенциал. Хочется верить, что её недостатки, в том числе описанные в этой статье, это всего лишь на всего, так называемые «детские болезни», которые уйдут в прошлое в ходе её дальнейшего развития. Что со временем Embarcadero наконец-то начнёт уделять должное внимание не только вопросам, связанным с её расширением и продвижением на рынок, но и вопросам, связанным с работоспособностью этой библиотеки. Однако это пока только оптимистичные надежды относительно будущего.
Что касается реальной ситуации, на сегодняшний день. Разрабатывать приложения с использованием FireMonkey, в том числе под Android вполне возможно. Даже несмотря её существующие издержки. Однако до момента своего полного устранения они, так или иначе, будут работать как против разработчика, так и против самой Embarcadero.
Ссылки
2.Разработка Qt-приложения с доступом к MySQL под Android – В этой статье помимо всего прочего приведено краткое описание процесса сборки драйвера для MySQL под Android. Поэтому данная статья может оказаться весьма полезной и для Delphi разработчиков.
Источник
Delphi XE5 + Android: первые впечатления
Возвращение к истокам
Delphi XE5 я взял в руки по случаю конкурса «Осенняя Мобилизация». Идея (и возможность) писать под Андроид не на си-шарпе или яве, а на знакомом вдоль и поперёк паскале мне определённо понравилась. Расскажу тут о своих впечатления, проблемах, которые встретились, а также развенчаю некоторые «городские легенды».
Использовал триал-версию Update-1. Теперь уже вроде второй апдейт вышел и, возможно, что-то поменялось. Сразу замечу, что менять в установке настройки по умолчанию лучше не стоит. Установленный до этого Андроид-SDK прицепить к Делфи не удалось, поэтому ставил заново с тем, который к ней прилагается. После первого запуска выяснилось, что не работает Хелп. Нашёл решение
support.embarcadero.com/article/43035
Хелп оказался толковый и довольно подробный. Содержит не только свойства и методы, но и примеры и даже описание методик разработки. В общем, возвращение к истокам, как оно было ещё у Борланда.
Cама среда мне очень нравится. В Визуал Студио всё какое-то аморфное и невнятное. Юнити визуально неплох, но там совсем другая специфика. Короче – язык программиста всё равно не опишет то, что видит глаз эстета, даже если они принадлежат одному человеку…
Интерфейс пользователя
FireMonkey порадовал своей гибкостью. На любой контрол можно повесить другой, на тот ещё один, и так далее, достигая очень интересных результатов. По сравнению с VCL стандартизовано именование свойств. Никаких больше Caption’ов и прочего, если где-то есть текст – это всегда Text. Позиция – всегда Position. Масса способов выравнивания. Кроме того, есть TLayout – нечто «невещественное» (об этом будет и ниже), невидимое, на что можно положить контролы и выравнивать их «в пустоте», а не обязательно на какой-нибудь панели.
Когда много всего на форме, становится очень полезным свойство DesignVisible – скрыть в дизайн-тайме. Набор стилей для Андроида прилагался только один, но очень элегантный – белым по чёрному, как мне нравится.
В инете ходят слухи, что ссылки на стиль для контрола (StyleLookup) иногда «не сохраняются». Для многих типов контролов (а может и для всех) существует для каждого своя ссылка «по умолчанию», которая будет назначена, даже если не указана, и которая-то и не сохраняется, как я понимаю, для экономии места в ресурсе формы.
Контролу можно добавить анимацию, и даже несколько, и даже одновременно. И это не только перемещение по экрану, но и изменение любых вещественно-численных свойств (размеров, цвета, масштаба и т.д.). Для каждой анимации можно указать временную задержку её начала, что очень удобно в сложных случаях, т.к. можно обойтись без дополнительных таймеров, просто запустив все нужные анимации одновременно из одного блока кода.
Теперь о жестах. В принципе всё просто – назначаем контролу Touch.GestureManager, галочками помечаем интересующие жесты, назначаем искусственное расширение границ ловли жестов (если контрол мелкий) в TouchTargetExpantion, создаём для него событие OnGesture и ловим там по EventInfo.GestureID нужный жест. Но есть тонкости.
Например, на большом TLayout мы разместили какие-то мелкие (относительно него) контролы и независимо от того, насколько «попал» пользователь пальцем по этим контролам своим жестом, надо что-то там делать. Замечу – если всё описанное в абзаце выше сделано для этого TLayout, то мы поймаем только те жесты, начало которых приходится на «видимые» объекты – т.е. на один из тех самых мелких контролов. Это я определил экспериментально. В принципе ничего удивительного – лайоута-то как бы и нет, он невидим и виртуален, и все «экранные сообщения», которые он может получить – от положенных на него «видимых» объектов. Можно сделать по-другому — не лениться, назначить менеджера и создать событие для формы (как и делается в демках) и гарантированно его всегда получать – но тогда придётся вручную разбираться с координатами, чтобы определить, к какому контролу какой жест относится.
Ещё именно под Андроидом я бы настоятельно порекомендовал явно проверять GestureID каждого пойманного жеста и реагировать только на те, которые интересуют (независимо от того, какие жесты помечены галочками).
И пример. Долго не мог сообразить, как показать баннер в TWebBrowser. Решение нашёл на одном форуме и творчески переработал. Но, если быть уж совсем точным, не до конца. Практикующие перфекционисты могут поразвлечься и этот недочёт поискать. Однако код при этом абсолютно рабочий и именно его я использую:
HTML тут – это код этого самого банера.
Базы данных
В XE5 включён набор компонентов для универсального доступа к базам данных – FireDAC. В принципе все названия свойств и методов как у других аналогичных наборов, так что тут всё ясно. Я использовал его для общения с SQLite. Всё настолько просто и обычно, что даже не знаю, что рассказать. К тому же и не помню ничего – в это время смотрел что-то по медиаплейеру, руки сами всё сделали.
Чтобы почувствовать разницу, желающие могут для сравнения после FireDAC сделать что-нибудь с базой данных из программы на той же Юнити. Да ладно Юнити, она игровая, – вон из той же Визуал Студии. После этого начинаешь понимать, где пули свистят, а где туземки коктейли разносят…
Ну и для любителей делать всё своими руками приведу небольшой пример, как заполнять ListBox без Bindings:
Кроме всего прочего, в зависимости от кода в столбце d_result в строчку лист-бокса помещается та или иная картинка:
Главное, что тут не забыть – это aList.AddObject(aItem);
Ну и Next, конечно, чтобы не зависло.
Манипуляции с формами
То, к чему приучает Делфи – это каждому действию свою форму. Под Андроидом в ней можно точно так же, как и под Виндоуз, создавать, показывать и закрывать формы. Каждая новая так или иначе созданная и показанная форма будет как бы «модальной», т.е. закрывающей всё пространство приложения. Однако Form.ShowModal делать не следует (Андроид этого «не понимает»), а следует по старинке просто вызывать Form.Show. По системной кнопке Back автоматом вызывается Form.Close и самая верхняя на данный момент форма закрывается. Можно её потом опять использовать. При закрытии главной (первой) формы приложение, как и следовало ожидать, закрывается. Замечу, что не следует закрывать форму с параметром caFree либо явно её уничтожать (Free, Release) – не любит Андроид этого!
Читал в инете про проблемы у людей с ARC. Уверен, дело не в этом. Если всё правильно спроектировано, то вообще без разницы, считаются ссылки или нет, ходит там сборщик мусора с косой по расписанию как в .Net или уничтожается сразу как в Delphi. Я всё писал по-старинке:
и работало как часы и под Андроидом, и под Виндами.
Если же возникают какие-либо проблемы с пониманием этого процесса, без всякого стёба рекомендую немного пописать на си-шарпе. Там вообще деструкторы явно вызывать не принято, просто или выходишь из процедуры, где данный объект был локальной переменной, или присваиваешь (глобальной) переменной значение null. Через некоторое время уже спинным мозгом начинаешь чувствовать момент, когда ладьи с объектами отправляются в Вальгаллу, причём безо всякого с твоей стороны толчка.
Массивы
При разработке под мобильный компилятор в руководстве по адаптации кода сказано «не использовать статические массивы». Указано также одно исключение – когда статический массив является членом структуры. И всё. Не совсем ясно, относится ли это к константам-массивам. Например, таким как
Не исключено, что так делать можно, хотя я такого старался избегать и формировал массивы строк в initialization динамически. В си-шарпе там хоть это можно в описании делать… Короче, вопрос требует дальнейшего исследования и разъяснения.
Следует также помнить, что элементы строки (string) в мобильном компиляторе нумеруются с нуля.
Операторы
Появился (уж не знаю в какой версии) новый оператор
Похоже, все языки стремятся к общему знаменателю. Кстати, перебирать им в паскале можно не только массивы, но и множества.
Источник