Прискорюємо налагодження та прототипування мобільних QML-додатків на живому пристрої

Привіт.

Хочу поділитися простим способом оптимізації свого робочого часу при розробці QML додатків під Android/iOS/Embedded.

Можливо, сказане мною комусь здасться бояном, але поки що про такий елементарний метод ніде не читав.

Суть проблеми — при розробці, налагодженні або прототипировании будь-якого мобільного додатку на будь-якій мові ми як правило завжди проходимо одні й ті ж етапи: редагування коду, деплой, запуск. І так до нескінченності. У випадку з мобільного розробкою, етап деплоя коду може розтягнутися на значний час — від 2 до 10 хвилин, протягом якого займатися в загальному-то нічим. Можливо для когось це і добре, але точно не для тих, хто цінує свій час. Загалом, думаю, не тільки мене выбешивает таке положення речей ;-)

Ситуація ускладнюється для нативних засобів розробки, наприклад, під Android, де нам завжди, без варіантів потрібно перекомпілювати Java-код перед наступним запуском на пристрої.

Qt на перший погляд володіє тією ж проблемою — кожен новий білд проекту також деплоится на пристрій тривалий час. От тільки є одна особливість — адже ми можемо писати програми не на Qt/C++, а на чистому QML. У цьому випадку, якщо ми не змінюємо логіку в C++ частини програми, нам нічого не треба компілювати під цільову платформу. А значить — було б круто просто оновлювати набір qml файлів програми і перезапускати додаток на пристрої. Адже економія часу на 10 запусків склала б не менше години!

Ну що ж, раз є потенційна можливість — гріх нею не скористатися. Читайте під катом, що у мене вийшло.

Почавши рити інформацію на тему, я по перше натрапив на колись подавав надії проект QML Live Preview (стаття на хабре), який дозволяв розробникам запускати режим відладки в Qt Creator, на льоту змінювати код і бачити свої правки на пристрої. Це було чаклунство і те що мені потрібно, ось тільки цей модуль Qt Creator-а виключили із загальної кодової бази (посилання на комміт). Може бути Digia щось мутить і перенесла його в комерційну версію, а може він був нестабільний. Не знаю. Головне — що його більше немає.

Загалом довелося шукати обхідний шлях. Він знайшовся на сторінки документації Qt, де розповідається про таку тему, як мережева прозорість при завантаженні ресурсів. Ідея в тому, що Qt і QML додаток пофігу, звідки завантажувати QML файли і ресурси типу шрифтів, зображень та іншого. Джерелом може бути локальний диск, ресурси Qt (qrc), smb-кулі або http-сервер.

Ідея реалізації виникла миттєво! Розгортаємо на локальній машині HTTP-сервер, кореневої директорій якого буде наш проект, міняємо сценарій завантаження ресурсів в C++ частини програми, перевіряємо працездатність на десктопі, збирає під мобілку, перевіряємо працездатність на мобілці, радіємо!

Повний опис алгоритму:
1) Переконуємося, що наш ПК і пристрій знаходяться в одній локальній мережі.

2) Подаємо проект до вимог Qt Network Transparent і певним шаблоном:
— всі ресурси в каталозі /assets;
— все qml файли в каталозі /qml;
— всередині каталогу qml структура файлів каталогів повинна бути максимум дворівневої;
— всі включення типу import «dir» приводимо до вигляду import «dir» ad Dir;
— усі звернення до компонентів в піддиректоріях наводимо від виду MyComp {… } до виду Dir.MyComp {… };

3) Викачуємо, налаштовуємо і запускаємо nginx. В налаштуваннях за замовчуванням потрібно поміняти всього два параметри — порт і root каталог. Потім запускаємо nginx. Приклад:
server {
listen 8085;
...
location / {
root D:/Dropbox/work/anyway;

4) У файлі main.cpp у місці завантаження qml-файлів міняємо на наступну логіку:
bool qmlDebug = true;

QString url = "http://192.168.1.22:8085/";
QString qmlLoadPrefix;
QString assetsLoadPrefix;

if (qmlDebug) {
qmlLoadPrefix = url+"qml/";
assetsLoadPrefix = url+"assets/";
} else {
qmlLoadPrefix = "qrc:/";
assetsLoadPrefix = "qrc:/";
}

engine.rootContext()->setContextProperty("qmlLoadPrefix", qmlLoadPrefix);
engine.rootContext()->setContextProperty("assetsLoadPrefix", assetsLoadPrefix);

engine.load(QUrl(qmlLoadPrefix+"main.qml"));

Тут ми задаємо URL нашого ПК в локальній мережі, а також дві змінні qmlLoadPrefix і assetsLoadPrefix. Як не складно здогадатися це просто префікси для доступу до ресурсів і qml-файлів програми в залежності від поточної програми. Так під час активної фази розробки ми зможемо швидко завантажувати необхідні ресурси через http, а при випуску програми — завантажувати файли ресурсів самого додатка.

5) Ну і останній крок — міняємо всі входження типу «qrc://myImg.png» на assetsLoadPrefix+«myImg.png» у всіх qml файлах проекту.

Ось власне і все. Залишилося відзначити, що тепер запускати додаток для налагодження потрібно не за допомогою великої зеленої кнопки «Play» на лівій панелі інструментів Qt Creator, а використовуючи маленьку кнопку «Play» на нижній панелі інструментів у розділі «Висновок додатки». Правда, ця кнопка буде недоступна відразу після запуску Qt Creator і потрібно буде запустити додаток вперше по-старому, але потім досить користуватися тільки її. При цьому в лог Qt Creator все також будуть сипатися всі необхідні debug повідомлення, а якщо Вам знадобиться повноцінна налагодження, то і вона буде працювати в штатному режимі.

Звичайно, це не ахті який хак і він все одно не врятує від перезбирання програми при написанні C++ коду, але навіть у такому вигляді ми отримуємо набагато більше зручності при розробці програм під будь-яку з платформ.

Пропоную в коментарях поділитися своїми думками і пропозиціями з приводу ще більшої оптимізації процесу розробки Qt-додатків і їх переваги перед нативними додатками для iOS і Android.

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.