Evgenii Legotckoi
Evgenii Legotckoi19 лютого 2018 р. 02:13

Android. Java проти Qt QML - Підручник 001. Hello World

Заради цікавості вирішив порівняти два варіанти написання додатків під Андроїд. Колись давно починав займатися програмуванням під Андроїд Java, але згодом перейшов на розробку Desktop додатків на Qt QML. Але тепер знову вирішив освіжити у пам'яті деякі аспекти, щоб переконатися, що Qt QML мені подобається більше.

Відразу наведу результат двох Hello world`ів. Вони звичайно не будуть на 100 відсотків ідентичні, але мають бути схожими. Як базовий приклад візьму порожню Activity, яка створюється в Android Studio.

Перший зразок – це Hello World на Java


Другий зразок – це Hello World на Qt QML

Загалом додатки схожі, зовнішній вигляд відрізняється трохи в рендерингу тексту, та у додаткових ефектах. У решті програми однакові.

Для початку почнемо з Java програми.

Створення проекту на Java

Крок 1 - Виберемо пункт створення нового проекту

Крок 2 - Дамо ім'я проекту

Крок 3 - виберемо мінімальний SDK проекту

Крок 4 - Виберемо тип проекту - Empty Activity

Крок 5 - Налаштування Activity

На цьому проект буде створено та налаштовано. Можете одразу його зібрати та запустити на вашому смартфоні. У мене розмір apk , зібраного в режимі debug склав приклад 170 кБ.

Програмний код

А тепер подивимося на те, як виглядає програмний код програми.

Програми під Андроїд Java складаються з двох програмних шарів:

  1. XML-верстка програми, яка представляє собою інтерфейс програми, його зовнішній вигляд. І фактично не має жодної програмної логіки.
  2. Java-логіка програми, яка відповідає саме за всю логіку бізнесу і т.д. і т.п.

XML-версія

Якщо чесно... верстка всіх властивостей зовнішнього вигляду програми в XML виглядає досить громіздкою, при тому, що немає можливості використовувати будь-яку програмну логіку для зміни властивостей чи тексту елементів. Ця складність особливо очевидна, коли доводиться описувати досить складні інтерфейси.

Але подивимося xml-код.

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.evileg.javahelloworld.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

Тут можна побачити, що описується саме поле з текстом Hello World, але не описується зовнішній вигляд ToolBar

а, який є активітом. Наявність ToolBar
а визначається через контекст активіті, що використовується в даному випадку.

А ось у QML на жаль доведеться писати такий самий ToolBar самостійно.

Код Java

Сам Java код буде невеликим, оскільки знадобиться лише перевизначити метод створення Activity , щоб встановити в неї XML верстку. А те, яку активувати стартувати, визначаємо в AndroidManifest.xml .

package com.evileg.javahelloworld;

import android.app.Activity;
import android.os.Bundle;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

Створення проекту на Qt QML

Крок 1 - Виберемо створення порожнього Qt Quick програми

Крок 2 - Виберемо місце розташування проекту

Крок 3 - вибір системи складання

Можете вибрати за смаком:

  • qmake
  • cmake
  • qbs

Не знаєте, що вибрати, вибирайте qmake

Крок 4 - Вибір версії бібліотеки Qt

Вибирайте останню стабільну версію (вона має бути у вас встановлена)

Крок 5 - Вибір комплекту збирання

Ось чим мені подобається Qt, так це тим, що програми на QML можна збирати як під Desktop, так і під Android пристрої. Тобто, якщо ви не тестуєте платформозалежний функціонал, то можна сміливо збирати під робочий стіл і вести все тестування на вашому ПК і лише періодично перевіряти, як програма працює на Android пристрої.

Крок 6 - Вибір системи контролю версій

Для Hello World`а нам не знадобиться система контролю версій.

Програмний код

Проекти на Qt QML зазвичай складаються з двох програмних шарів, як і у випадку з Java.

  • C++ шар - на ньому може бути написана основна бізнес-логіка, складні розрахунки, робота з мережею і т.д.
  • QML шар - на ньому реалізується зовнішній вигляд програми, а також деяка логіка, втім ніщо не заважає реалізувати всю бізнес-логіку на QML, якщо додаток та можливості дозволятиму. Також QML досить добре підтримує JavaScript, на якому і реалізовуватиметься ця логіка.

Тобто в деяких випадках ніщо не заважає взагалі використовувати C++.

main.cpp

Цей файл створюється за замовчуванням. У цьому випадку ми запускаємо двигун QML і малюємо вміст main.qml файлу.

#include <QGuiApplication>
#include <QQmlApplicationEngine>

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}

QMLHelloWorld.pro

Проектний файл Qt, в ньому прописуються всі ресурси, а також вихідні файли проекту з налаштуванням збирання. Він також потрібний тут крім файлу AndroidManifest.xml

QT += quick
CONFIG += c++11

# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += main.cpp

RESOURCES += qml.qrc \
    images.qrc

# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH =

# Additional import path used to resolve QML modules just for Qt Quick Designer
QML_DESIGNER_IMPORT_PATH =

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

DISTFILES += \
    android/AndroidManifest.xml \
    android/gradle/wrapper/gradle-wrapper.jar \
    android/gradlew \
    android/res/values/libs.xml \
    android/build.gradle \
    android/gradle/wrapper/gradle-wrapper.properties \
    android/gradlew.bat

ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android

main.qml

А ось і найцікавіше. У цьому файлі знадобиться створити не лише текст HelloWorld, а й створити ToolBar з іконкою та ім'ям програми. Я взяв іконку з проекту на Java і додав її в ресурси проекту на Qt QML.

import QtQuick 2.10
import QtQuick.Window 2.10
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.3
import QtQuick.Controls.Material 2.1

ApplicationWindow {
    visible: true
    width: 360
    height: 520
    title: qsTr("Hello World")

    header: ToolBar {
        height: 48

        Rectangle {
            anchors.fill: parent
            color: "#080808"

            Image {
                id: ico
                height: 36
                width: 36
                anchors {
                    left: parent.left
                    leftMargin: 10
                    top: parent.top
                    topMargin: 6
                }
                source: "qrc:/images/ic_launcher.png"
            }


            Text {
                anchors {
                    verticalCenter: parent.verticalCenter
                    left: ico.right
                    leftMargin: 4
                }

                text: qsTr("QmlHelloWorld")
                font.pixelSize: 18
                color: "white"
            }
        }
    }

    Label {
        anchors.centerIn: parent
        text: qsTr("Hello World!")
        font.pixelSize: 14
    }
}

Код вийшло однозначно більше, ніж у файлі верстки XML для програми на Java. Але давайте розберемося. Так вийшло тому, що в Qt QML спочатку немає ніяких активів. Взагалі робота всього докладання відбувається в одній єдиній активіті, і немає жодної необхідності перемикатися між цими активіти. Зробити поведінку програми, подібну до зміни Активіті, можна за допомогою Loader, StackView, SwipeView та багатьох інших компонентів. А тут використовується компонент вікна, який має місце для розміщення ToolBar

а, потрібно лише написати верстку даного ToolBar
а

Так от, якби подібний ToolBar був спочатку, то написання тексту Hello World виявилося б менш громіздким, ніж у випадку з Java. Тобто було б таким

import QtQuick 2.10
import QtQuick.Window 2.10
import QtQuick.Controls 2.3
import QtQuick.Controls.Material 2.1

ApplicationWindow {
    visible: true
    width: 360
    height: 520

    Label {
        anchors.centerIn: parent
        text: qsTr("Hello World!")
        font.pixelSize: 14
    }
}

Проти цього в XML

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.evileg.javahelloworld.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

І, якщо чесно, варіант з QML виглядає більш читаним.

Система складання та AndroidManifest.xml

Система складання в обох випадках використовувалася Gradle.

Що стосується AndroidManifest.xml, то у випадку з Java жодних додаткових маніпуляцій не було. Тоді як у випадку з Qt потрібно додати іконки запуску. Про роботу з AndroidManifest.xml у Qt можна прочитати докладніше у цій статті .

Висновок

В обох випадках можна отримати дві однакові програми, а ось в нюансах розробки можна буде визначитися, що і кому буде зручніше.

Обидва варіанти пропонують працювати у двох шарах

  • Java + XML
  • QML + C++

Але у випадку з QML/C++ всю логіку можна написати тільки на QML, а в першому випадку в XML можна написати лише верстку.

Початковий Hello World буде написаний досить швидко на Java. Достатньо буде лише створити проект, а щоб отримати подібний результат на Qt QML, то доведеться ще трохи коду написати. Однак, у ряді випадків доведеться писати значно менше коду на QML, ніж Java/XML.

З мінусів Qt я б відразу відзначив те, що є платформозалежні моменти, які все одно доведеться вирішувати через Java, наприклад події від ОС Android. Однак... також деякі проблемні частини проекту вирішують через C++, у проекті Java, тому тут швидше буде паритет.

З плюсів Qt наголосив би на тому, що в останніх версіях вони підтримують Material Design , що також полегшить розробку програми, коли дизайнера немає як такого в проекті.

Розмір зібраного APK, тут звичайно виграє Java. У debug режимі вихідний APK з Java вийшов всього 170 кБ, тоді як APK від Qt вийшов 10 мБ, в реліз складання розмір APK Qt буде приблизно 5-6 мБ, але я б не назвав це настільки критичним, оскільки багато великих програм у Google Play важать 40-60 мБ і в результаті розміри зрівняються.

Інші аспекти розглянемо у наступних статтях.

Рекомендуємо хостинг TIMEWEB
Рекомендуємо хостинг TIMEWEB
Стабільний хостинг, на якому розміщується соціальна мережа EVILEG. Для проектів на Django радимо VDS хостинг.

Вам це подобається? Поділіться в соціальних мережах!

ГВ
  • 16 листопада 2019 р. 16:16

Разрешите узнать, как вы получили qt+qml приложение размером в 10мб(даже релизных). Дело в том, что пустое приложение, хоть и со стек вью, обходится мне на все 40мб пространства. Или же вы воспользовались ministro? Спасибо за ответ!

Evgenii Legotckoi
  • 18 листопада 2019 р. 02:44

Добрый день. На тот момент ничего не использовал дополнительно и никаких специальных настроек не делал. Просто собрал и получилось 10 мб.

Коментарі

Only authorized users can post comments.
Please, Log in or Sign up
AD

C++ - Тест 004. Указатели, Массивы и Циклы

  • Результат:50бали,
  • Рейтинг балів-4
m
  • molni99
  • 26 жовтня 2024 р. 08:37

C++ - Тест 004. Указатели, Массивы и Циклы

  • Результат:80бали,
  • Рейтинг балів4
m
  • molni99
  • 26 жовтня 2024 р. 08:29

C++ - Тест 004. Указатели, Массивы и Циклы

  • Результат:20бали,
  • Рейтинг балів-10
Останні коментарі
ИМ
Игорь Максимов22 листопада 2024 р. 19:51
Django - Підручник 017. Налаштуйте сторінку входу до Django Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
Evgenii Legotckoi
Evgenii Legotckoi31 жовтня 2024 р. 21:37
Django - Урок 064. Як написати розширення для Python Markdown Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
A
ALO1ZE19 жовтня 2024 р. 15:19
Читалка файлів fb3 на Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
ИМ
Игорь Максимов05 жовтня 2024 р. 14:51
Django - Урок 064. Як написати розширення для Python Markdown Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
d
dblas505 липня 2024 р. 18:02
QML - Урок 016. База даних SQLite та робота з нею в QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
Тепер обговоріть на форумі
Evgenii Legotckoi
Evgenii Legotckoi24 червня 2024 р. 22:11
добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
t
tonypeachey115 листопада 2024 р. 14:04
google domain [url=https://google.com/]domain[/url] domain [http://www.example.com link title]
NSProject
NSProject04 червня 2022 р. 10:49
Всё ещё разбираюсь с кешем. В следствии прочтения данной статьи. Я принял для себя решение сделать кеширование свойств менеджера модели LikeDislike. И так как установка evileg_core для меня не была возможна, ибо он писался…
9
9Anonim25 жовтня 2024 р. 16:10
Машина тьюринга // Начальное состояние 0 0, ,<,1 // Переход в состояние 1 при пустом символе 0,0,>,0 // Остаемся в состоянии 0, двигаясь вправо при встрече 0 0,1,>…

Слідкуйте за нами в соціальних мережах