Wie Qt für Android funktioniert

Wenn Sie als Entwickler einen Überblick darüber suchen, wie Qt die Android-Plattform unterstützt, ist diese Seite genau das Richtige für Sie.

Starten der Qt-Anwendung

Ähnlich wie bei nativen Android-Apps wird die Funktion onCreate() der Qt-Hauptaktivität bereits beim Start der Anwendung aufgerufen und die Aktivität erstellt. Hier findet der Großteil der Initialisierung der Android Qt Platform Abstraction (QPA) statt. Die wichtigsten Teile sind:

  • Das Laden von Qt und der Bibliotheken der Hauptanwendung.
  • Initialisierung der Delegates, die sich um die Initialisierung der Rendering-Oberflächen und des Top-Level-Layouts kümmern, sowie die Registrierung verschiedener Listener wie Input-, Display-, Touch-Handler und andere.

Beim Laden der Qt-Bibliotheken wird die JavaVM zwischengespeichert, während QtCore zuerst geladen wird. Dies geschieht mit der Funktion JNI_OnLoad(), die synchron aufgerufen wird, wenn eine Bibliothek mit dem Aufruf System.load() geladen wird. Jedes Qt-Modul kann eine Implementierung für diese Funktion haben, um einige modulspezifische Initialisierungen durchzuführen, wie z.B. die Registrierung von nativen JNI-Methoden.

Sobald alle Qt-Modulbibliotheken geladen sind, lädt Qt das Android QPA-Plugin und die Hauptanwendungsbibliothek. Nachdem das Layout der obersten Ebene QtLayout seinen Inhalt aufgeblasen hat, wird das Handle der Qt-Anwendung main() gefunden und aufgerufen. Dadurch wird die C++ Qt-Anwendung gestartet und normalerweise die Hauptereignisschleife in Gang gesetzt.

Die Android QPA

Die Android QPA ist dafür verantwortlich, die Android (Java/Kotlin) Seite mit der nativen Qt (C++) Seite zu verbinden. Sie kümmert sich um die Weitergabe von Ereignissen und Signalen an und von Qt an Android. Diese Verantwortung erstreckt sich auf die Behandlung von Signalen, Berührungsereignissen, UI-Elementen, Rendering usw. Diese Schicht ist auch für die Initialisierung beim Start der App und die Bereinigung beim Beenden oder Zerstören der App verantwortlich.

Threads

Bei Qt für Android-Apps hat Qt normalerweise zwei Threads, die von Interesse sind. Der erste ist der QtThread, den Qt startet. Der zweite ist der Android UI Thread.

QtThread

Dieser Thread wird von der Qt-App zuerst implementiert und gestartet, bevor z.B. die Bibliotheken geladen werden. Dieser Thread wird qtMainLoopThread genannt. Alle folgenden Operationen werden unter diesem Thread ausgeführt:

  • Laden der Qt-Bibliotheken.
  • Operationen, die innerhalb von JNI_OnLoad() ausgeführt werden.
  • Starten der nativen Anwendung.
  • Die Ausführung von main().

Android UI-Thread

Ähnlich wie bei Android-Anwendungen wird erwartet, dass Operationen, die die Benutzeroberfläche betreffen, im UI-Thread ausgeführt werden. Qt macht das unter der Haube für alle internen Aufrufe, von denen erwartet wird, dass sie in der UI ausgeführt werden. Außerdem bietet Qt eine API runOnAndroidMainThread(), um Operationen in diesem Thread von C++-Code auszuführen. Mit dieser API verwaltet Qt, wann die Aufrufe direkt an den Thread gesendet werden, wenn die Anwendung aktiv ist, oder in die Warteschlange gestellt werden, wenn die Anwendung pausiert oder im Hintergrund läuft.

Architektur

"An overview Qt for Android's Architecture"

Qt-Klassen

In den folgenden Abschnitten werden die verschiedenen Qt-Android-Klassen, ihre Funktionalität und ihre Rolle in Qt-Anwendungen erläutert.

Die öffentlichen Java Bindings

Bei diesen Klassen handelt es sich um öffentliche Klassen, die die internen Implementierungsdetails der benutzerorientierten Klassen wie Activity, Service und Application umhüllen. Diese Klassen werden standardmäßig für Qt-Android-Anwendungen verwendet und in der Android-Manifestdatei referenziert. Das Build-System und die Deployment-Tools sorgen dafür, dass sie in den Build aufgenommen werden.

Benutzer können diese Klassen verwenden, um das Standardverhalten zu ändern oder zu erweitern. Um zum Beispiel benutzerdefinierte Logik unter onCreate() hinzuzufügen, verwenden Sie die folgende:

public class MyActivity extends QtActivity
{
    @Override
    protected void onCreate(Bundle bundle)
    {
        // code before Qt is initialized
        super.onCreate(bundle);
        // code after Qt is initialized
    }
}

Hinweis: Sie müssen die Datei AndroidManifest.xml bearbeiten, um Ihre benutzerdefinierte Activity- oder Bindungsklasse zu verwenden, andernfalls wird weiterhin die Standardklasse verwendet.

Festlegen eines Themes

Wenn Sie QtActivity erweitern, können Sie ein bestimmtes Android Theme mit setTheme() setzen. Dieser Aufruf muss jedoch vor dem Aufruf von onCreate() der Elternklasse erfolgen, damit er wirksam wird, da Qt das Theme standardmäßig setzt. Zum Beispiel, können Sie verwenden:

@Override
protected void onCreate(Bundle bundle)
{
    setTheme(android.R.style.Theme_DeviceDefault_DayNight);
    super.onCreate(bundle);
}

Standardmäßig setzt Qt für Android 10 und höher das Theme Theme_DeviceDefault_DayNight Style, und Theme_Holo_Light Style für frühere Versionen.

Anhängen eines Anwendungsparameters

Um einen zusätzlichen Anwendungsparameter anzuhängen, d.h. ein Argument, das von Java/Kotlin an die (main()) Funktion der Anwendung übergeben wird, können Sie nach der Erweiterung von QtActivity wie folgt vorgehen:

@Override
protected void onCreate(Bundle bundle)
{
    appendApplicationParameters("--flag value");
    super.onCreate(bundle);
}

Dies ist ähnlich wie die direkte Verwendung der CMake-Variable QT_ANDROID_APPLICATION_ARGUMENTS. Parameter, die mit beiden Methoden übergeben werden, akzeptieren Leerzeichen oder Tabulatoren als Trennzeichen, und die endgültige Liste der an die Anwendung übergebenen Parameter wird mit QProcess::splitCommand geparst.

Laden von Qt-Bibliotheken mit QtLoader

Jede Qt-Android-Anwendung muss sicherstellen, dass alle nativen Qt- oder Drittanbieter-Bibliotheken zuerst geladen werden, bevor Funktionen aus diesen Modulen aufgerufen werden. Das Build-System führt eine Liste der verschiedenen Qt-Bibliotheksabhängigkeiten, des QPA-Plugins, der Hauptanwendungsbibliothek und aller Bibliotheken von Drittanbietern in der Ressourcendatei libs.xml der Anwendung. Sobald alle in den folgenden Abschnitten genannten Schritte abgeschlossen sind, werden die Bibliotheken mit System.load() geladen.

Der Klassenlader

Das Class-Loader-Objekt wird frühzeitig von QtLoader gesetzt, bevor die Qt-Bibliotheken geladen oder die Delegaten initialisiert werden. Dies liegt daran, dass der Class Loader von QJniObject verwendet wird, um Java-Klassen zu finden und für jeden JNI-Aufruf mit QJniObject benötigt wird.

Setzen von Umgebungsvariablen und Anwendungsparametern

Vor dem Laden der Bibliotheken muss Qt sicherstellen, dass Umgebungsvariablen als Metadaten im Android-Manifest übergeben werden, um sie zu setzen. Dieser Schritt ermöglicht die Initialisierung einiger Module basierend auf den Konfigurationsflags, die als Manifest-Metadaten gesetzt sind. Einige dieser Metadaten werden auch an die Liste der Anwendungsparameter weitergegeben, die der Anwendung beim Start übergeben wird.

setActivity(), setContext() und setService()

Verschiedene Qt-Module müssen möglicherweise einige Initialisierungsarbeiten von der Java-Seite aus durchführen, für die der Kontext der Activity oder des Service benötigt wird. Diese Module implementieren dann eine statische Methode, die eine Activity, einen Service oder einen Context als Parameter erhält:

void setActivity(Activity activity)
{
    m_activity = activity;
    // Other logic
}

Dann ruft QtLoader diese Methoden mit dem übergeordneten Kontext des Loaders auf, bevor die nativen Shared Libraries geladen werden.

Wie Qt für Android den Android-Activity-Lebenszyklus handhabt

Qt für Android bietet keine API, um die Android-Activity-Lebenszyklus-Callbacks wie onCreate(), onStart(), onResume(), onPause(), onStop() und onDestroy() direkt zu behandeln. Stattdessen werden diese unter der Haube für den Benutzer gehandhabt. Das Verhalten wird in den folgenden Abschnitten skizziert.

Hinweis: Diese Lebenszyklusereignisse werden in das Signal QGuiApplication::applicationStateChanged übersetzt.

Kontext-Behandlung

QAndroidApplication kann den Android-Kontext als QJniObject bereitstellen, der für die Interaktion mit dem Android-System unerlässlich ist. Dieser Kontext kann eine Activity oder ein Service sein. Wenn es eine Activity gibt, wird es die zuletzt gestartete Activity sein, unabhängig davon, ob es Dienste gibt. Wenn es nur Dienste gibt, wird es der zuletzt gestartete Dienst sein.

Hinweis: Qt für Android unterstützt nicht mehrere Aktivitäten.

Rückrufe

Die Klasse QtActivityBase wurde entwickelt, um die Implementierungsdetails der verschiedenen Funktionalitäten einer Activity innerhalb des Qt for Android-Pakets geheim zu halten. Diese Klasse ist ein Vermittler zwischen dem Android-Lebenszyklus und dem Qt-Framework und übersetzt Android-Lebenszyklus-Callbacks in Signale und Operationen, auf die die Qt-Anwendung reagieren kann.

onCreate()

Wenn die Activity erstellt wird, initialisiert QtActivityBase die Qt-Umgebung. Dies beinhaltet das Laden der Qt-Bibliotheken, das Einrichten des Klassenladers, den QJniObject verwendet, das Parsen der Metadaten der Anwendung und die Vorbereitung der Qt-Anwendung für die Ausführung. Es wird sichergestellt, dass alle notwendigen Initialisierungen, die für die Aktivität spezifisch sind, durchgeführt werden.

onStart()

Ruft Android's Activity.OnStart() auf.

onResume()

Wenn die Activity in den Vordergrund wechselt, setzt QtActivityBase die Qt-Anwendung fort. Es stellt sicher, dass angehaltene Prozesse oder Operationen fortgesetzt werden und die Anwendung wieder für Benutzerinteraktionen bereit ist. Sie registriert den Display Manager Listener, der durch onPause() gestoppt wurde, erneut.

onPause()

Wenn eine andere Aktivität die Activity teilweise verdeckt, pausiert QtActivityBase die Qt-Anwendung. Es speichert den Anwendungsstatus oder gibt Ressourcen frei, die nicht benötigt werden, während die Anwendung nicht im Vordergrund ist.

onStop()

Wenn die Activity nicht mehr sichtbar ist, stoppt QtActivityBase die Qt-Anwendung, was eine umfangreichere Zustandssicherung und Ressourcenfreigabe beinhaltet, um die Anwendung für eine mögliche Zerstörung vorzubereiten.

Hinweis: Der QtThread wird zu diesem Zeitpunkt angehalten.

onDestroy()

Wenn die Aktivität beendet ist oder vom System zerstört wird, bereinigt QtActivityBase alle mit der Qt-Anwendung verbundenen Ressourcen. Sie stellt sicher, dass die Anwendung ordnungsgemäß heruntergefahren wird und dass alle notwendigen Aufräumarbeiten durchgeführt werden.

Diese Integration ermöglicht es Entwicklern, sich auf die Erstellung ihrer Qt-Anwendung zu konzentrieren, ohne sich um die Feinheiten des Android-Lebenszyklus kümmern zu müssen, da QtActivityBase diese Komplexität unter der Haube verwaltet.

Splash Screen Management

QAndroidApplication QtActivityBase kann den Splash-Screen mit einem Fade-Effekt ausblenden, der zeitlich mit der Startsequenz der Anwendung abgestimmt werden kann, typischerweise nach onCreate().

Mehr über Qt für Android

Das Video vom Qt World Summit 2021 gibt einen Überblick über Qt für Android.

"Ein Bild der Agenda, das auf ein YouTube-Video verlinkt"

© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.