2ГИС всегда стремится удовлетворять запросы пользователей, стараясь присутствовать на всех ключевых платформах. Особенно, если речь идёт о странах, в которые мы в дальнейшем планируем выходить.
12 ноября число платформ, на которых есть 2ГИС, пополнился ещё одной — Blackberry 10.
В связи с этим знаменательным событием, хочется поделиться некоторыми моментами, связанными с опытом портирования.
Задача была поставлена просто и лаконично: «попробовать портировать имеющуюся кодовую базу на новую платформу».
Понимая, что адаптация большой кодовой базы под новую платформу, как правило, связана с различным набором трудностей, начинаешь невольно просчитывать страшные картины долгой кропотливой работы и полной безысходности. Но это поначалу. Глаза боятся, а руки делают.
Пройдя на сайт с документацией, можно приятно удивиться поддержке сразу нескольких популярных платформ для разработки. А именно AIR SDK, WebWorks SDK, Android SDK и Native SDK.
Первые две по, надеюсь, понятным причинам не рассматривались.
Имея готовое приложение для Android, смотрим, что же можно сделать.
На поверку выясняется, что возможность BlackBerry OS 10.1 запускать Android-приложения, к сожалению, не распространяется на программы, написанные с использованием NDK.
А ни для кого уже не секрет, что большинство наших мобильных продуктов в той или иной степени завязаны на фреймворк Qt, что напрочь лишает возможности запуска приложения после банальной перепаковки установочного пакета.
Изучив возможности «нативных» инструментов, понимаем, что задача портирования значительно упрощается, так как BlackBerry 10 включает большой набор библиотек, в том числе и фреймворк Qt.
Вообще BlackBerry 10 предлагает 2+1 основных способа создания нативного приложения.
Native core предлагает расширенные возможности взаимодействия с системной и аппаратной частью, но в нашем случае нет смысла его использовать, так как есть неплохая обертка в виде Qt.
К сожалению, при ближайшем рассмотрении всплывают неприятные нюансы.
BlackBerry создали потрясающий графический фрэймворк Cascades на базе Qt который чуть менее чем полностью не совместим с QApplication.
Интерфейс 2ГИС, в целом, самодостаточен и может пережить недостаток нативных механизмов взаимодействия с пользователем. По крайней мере на первых порах.
Но не Cascades единым. К счастью, в BlackBerry 10 осталась несправедливо обделенная вниманием возможность создания приложений на базе QtGui. В нашем случае данный инструментарий удобен тем, что нет необходимости кардинально перерабатывать кодовую базу. Остается гибкая возможность взаимодействия с core native компонентами или с некоторыми частями Cascades.
Сам процесс портирования оказался относительно прост. В качестве сборочной среды используется:
- Linux Ubuntu 12.04 64-bit
- bbndk 10.1.0.4651
- QtCreator 2.8
- Эмуляторы blackberry в ассортименте: 10.1 …… 10.2
Про настройку сборочной среды говорилось уже много, так что сильно повторяться не буду, только еще раз напомню, что NDK — 32-bit. Для linux 64-bit необходимо наличие 32-битных библиотек. На Убунту это решается так: «sudo apt-get install ia32-libs».
Так как приложение изначально проектировалось как кроссплатформенное, большая часть работ сводится к добавлению нужных библиотек и подкручиванию настроек. Например, из-за медленной работы QGLWidget пришлось временно отказаться от сглаживания в виде мультисэмплинга, но благодаря высокому dpi это не мешает.
Небольшое количество проблем пришлось на особенности QNX, такие как использование gulliver.h вместо endian.h.
В целом, большая часть времени ушла на поиск платформенных настроек, равномерно разбросанных по всему коду различными командами.
После первого успешного запуска оптимизма значительно прибавилось.
Коррекции темы потребовали только «квадратные» экраны 720х720. Таким экраном сейчас оснащаются два устройства из серии Bold: Q10 и Q5. Программа автоматически выбирает заранее подложенную стартовую заставку, с этим тоже особо никаких проблем не возникло.
Портирование существующей кодовой базы это дело большое, но это только полдела. Программа должна уметь получать информацию от различных сенсоров, систем позиционирования и уметь взаимодействовать с пользователем через некоторые системные инструменты, такие как «отправить SMS» или «набрать номер».
Работа с сенсорами очень удобно реализована через Qt Mobility. Подробнее о работе с компасом и другими сенсорами можно ознакомиться на этой странице.
Позиционирование осуществляется через API QtLocationSubset.
Благодаря удобной Qt обертке вокруг нативных методов, работа с навигацией также не вызывает проблем.
Для взаимодействия с встроенными приложениями используется Invocation framework.
Механизм вызовов достаточно прост.
Например, для предпросмотра и отправки e-mail можно использовать следующий код:
bool SendMail(QString addr, QString subject, QString text)
{
InvokeRequest request;
request.setTarget("sys.pim.uib.email.hybridcomposer");
request.setAction("bb.action.SENDEMAIL");
request.setMimeType("text/plain"); request.setUri(QUrl(QString("mailto:%1?&subject=%2&body=%3").arg(addr,subject,text)));
InvokeManager invokeManager;
return invokeManager.invoke(request);
}
В целом, несмотря на большинство положительных сторон, есть пара ложек дегтя некоторое количество проблем, связанное с недоработками/особенностями работы QPA плагина.
Первая проблема — это не работающий/отсутствующий «cover frame» (миниатюра окна в свернутом состоянии) в QtGui приложениях, что наряду с общей стилистикой выбивается из колеи.
Поняв что проблемы кроются где-то в недрах плагина ищем и находим следующие строчки кода:
case NAVIGATOR_WINDOW_STATE: {
const navigator_window_state_t state = navigator_event_get_window_state(event);
const QByteArray id(navigator_event_get_groupid(event));
switch (state) {
case NAVIGATOR_WINDOW_FULLSCREEN:
mNavigatorEventHandler->handleWindowGroupStateChanged(id, Qt::WindowFullScreen);
break;
case NAVIGATOR_WINDOW_THUMBNAIL:
mNavigatorEventHandler->handleWindowGroupStateChanged(id, Qt::WindowMinimized);
break;
case NAVIGATOR_WINDOW_INVISIBLE:
mNavigatorEventHandler->handleWindowGroupDeactivated(id);
break;
}
break;
}
Если нет желания пересобирать плагин, данную проблему можно обойти с помощью QAbstractEventDispatcher.
#include <bps/bps.h>
#include <bps/navigator.h>
#include <bps/screen.h>
#include <QAbstractEventDispatcher>
#include <QApplication>
static QAbstractEventDispatcher::EventFilter previous_event_filter = 0;
static bool blackberry_event_filter(void *message)
{
bps_event_t* const event = static_cast<bps_event_t*>(message);
if (event && bps_event_get_domain(event) == navigator_get_domain())
{
if (bps_event_get_code(event) == NAVIGATOR_WINDOW_STATE)
{
if(navigator_event_get_window_state(event) == NAVIGATOR_WINDOW_THUMBNAIL)
{
return false;
}
}
}
if (previous_event_filter)
{
return previous_event_filter(message);
}
else
{
return false;
}
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
previous_event_filter = QAbstractEventDispatcher::instance()->setEventFilter(blackberry_event_filter);
/*
Что-то делаем
PROFIT!!!!!
*/
return a.exec();
}
Вторая проблема — это клавиатура. Вернее, поддержка физической клавиатуры, а еще точнее — смена раскладки. Смена раскладки просто не поддерживается в QtGui приложениях. Спасение приходит со стороны костылей, коими, если очень надо, можно не брезговать. Суть костыля сводится к перехвату комбинаций клавиш и транслированию событий нажатий с нужной локалью.
Несмотря на мелкие неудобства и недоработки со стороны QPA-плагина, платформа оставляет множество положительных эмоций. В качестве доказательства состоятельности этой платформы можно сказать, что основная работа по портированию и доведения до альфа-релиза заняла меньше двух недель усилий одного разработчика.
Приложение доступно в BlackBerry App World, а 29 ноября для него вышло первое обновление.
Скачать приложения под остальные платформы можно в соответствующих сторах: iOS, WP, Android.
Если вы случайно пропустили тот факт, что у нас вышел Новый 2ГИС (бета-версия), то предлагаем ознакомиться и с ним.
И да, Киев тоже будет, но позже.
Автор: zsilas