Реклама

четверг, 6 марта 2014 г.

Qt на Android
Приложение на Qt для Android состоит из двух частей:
  1. Native-часть, которая содержит одну или несколько .so-библиотек, в которые компилируется ваше приложение. Если вы хотите, чтобы у приложения не было внешних зависимостей, здесь также будут находиться библиотеки Qt.
  2. Android-часть. Она включает в себя несколько разделов:
  • Android manifest. Это точка входа вашего приложения. Android использует этот файл, чтобы определить, какие Приложения или Activity запустить, какие вашему приложению установлены разрешения (permissions), определяет минимальную версию Android API, необходимую для приложения и так далее.
  • Два Java-класса, которые загружают зависимости и ваше приложение.
  • Файлы .aidl сервиса Ministro. Эти два интерфейса используются для обмена сообщениями с сервисом Ministro. Этот сервис является одним из решений для развёртывания (о нём будет сказано позже).
  • Остальные ресурсы (строки, изображения и прочее).

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

При открытии приложения, Android использует manifest-файл для запуска activity. Эта кастомная activity представляет собой кусочек магии в мире Java вашего приложения. Для того, чтобы была возможность обновления библиотек Qt без переустановки существующего приложения, Java-часть разделена надвое: очень маленькая часть, которая хранится вместе с приложеним (как его часть) и другая часть (библиотека Java, файл .jar), которая содержит всю логику для плагина QPA.

Первая Java-часть, которая поставляется вместе с приложением, отвечает за поиск необходимых библиотек (Qt и Java) и загружает их. Кроме этого, она пересылает все события (нажатия, изменения состояния приложения, изменения экрана и так далее) во вторую Java-часть.

Вторая Java-часть ответственна за связь с Qt. Она содержит всю необходимую логику QPA-плагина для Android, например, создание поверхности для рисования и управление ею, обработку виртуальной клавиатуры и так далее.

Таким образом, первая (Java) часть находит и загружает все необходимые библиотеки и ваше приложение, после чего перенаправляет события второй части, но кто же тогда вызывает метод «main»? Это делает QPA плагин. Нет, я не сумасшедший! И да, плагин QPA загружается до запуска вашего приложения (вообще, он загружается даже до того, как ваше приложение будет загружено).

Позвольте мне объяснить, чем вызван такой безумный дизайн.

Моей мечтой было найти способ, при котором разработчики смогли бы всего лишь откомпилировать их существующие приложения для Android, так что я был вынужден каким-то образом вызывать метод «main» (я не хочу заставлять вас создавать другую входную точку в приложение, наподобие «WinMain»).

Проблема заключается в том, что для того, чтобы вызвать метод из Java, кто-то должен сперва этот метод зарегистрировать, иначе вызвать его будет нельзя. Здесь на сцене и появляется QPA. После загрузки, плагин QPA регистрирует несколько нативных функций, которые используются Java-частью для вызовов в нативной среде. После завершения загрузки всех библиотек и вашего приложения, Java-часть вызывает метод «startQtApplication», зарегистрированный ранее плагином QPA. Этот метод ищет символ метода «main», после чего создаёт поток и вызывает в нём выполнение метода «main». Создание параллельного потока здесь необходимо потому, что вызов «main» блокирует остальные вызовы, пока продолжает существовать, а мы должны сохранять UI-поток Android свободным для нормального функционирования цикла обработки событий Android.

В следующей статье я расскажу о том, как использовать JNI для вызовов в/из Java в/из нативную (C/C++) среду.

В заключение, взглянем на текущее состояние Qt на Android, что вы получите в Qt 5.2 и каковы планы на Qt 5.3 для Android.

Статус Qt Essentials:


Статус Qt Add-Ons:

Комментариев нет:

Отправить комментарий