So funktioniert Qt für Android
Wenn Sie als Entwickler einen allgemeinen Überblick darüber suchen, wie Qt die Android-Plattform unterstützt, sind Sie auf dieser Seite genau richtig.
Starten der Qt-Anwendung
Ähnlich wie bei nativen Android-Apps wird die Methode `onCreate()` der Qt-Haupt-Activity frühzeitig aufgerufen, wenn die App gestartet und die Activity erstellt wird. Dort findet der Großteil der Initialisierung der Android Qt Platform Abstraction (QPA) statt. Die wichtigsten Schritte sind:
- Das Laden von Qt und der Bibliotheken der Hauptanwendung.
- Initialisierung der Delegaten, die für die Initialisierung der Rendering-Oberflächen und des Layouts der obersten Ebene zuständig sind sowie für die Registrierung verschiedener Listener wie Eingabe-, Anzeige- und Touch-Handler u. a.
Beim Laden der Qt-Bibliotheken wird die JavaVM zwischengespeichert, während zunächst „ QtCore “ geladen wird. Dies geschieht im Rahmen der Funktion `JNI_OnLoad()`, die synchron aufgerufen wird, wenn eine Bibliothek über den Aufruf `System.load()` geladen wird. Jedes Qt-Modul kann eine Implementierung dieser Funktion enthalten, um modul-spezifische Initialisierungen durchzuführen, wie beispielsweise die Registrierung nativer 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 vollständig geladen hat, wird der „ main() “-Handle der Qt-Anwendung gesucht und aufgerufen. Dadurch wird die C++-Qt-Anwendung gestartet und in der Regel die Hauptereignisschleife initiiert.
Das Android-QPA
Das Android-QPA ist dafür zuständig, die Android-Seite (Java/Kotlin) mit der nativen Qt-Seite (C++) zu verbinden. Er verwaltet die Weiterleitung verschiedener Ereignisse und Signale sowohl von Qt zu Android als auch in umgekehrter Richtung. Diese Aufgabe umfasst die Signalverarbeitung, Touch-Ereignisse, UI-Elemente und das Rendering usw. Diese Ebene ist außerdem für die Initialisierung beim App-Start sowie für die Bereinigung beim Beenden oder Löschen der App zuständig.
Threads
Bei Qt-Apps für Android gibt es in der Regel zwei Threads, die von Interesse sind. Der erste ist der von Qt gestartete „ QtThread “. Der zweite ist der Android-UI-Thread.
QtThread
Dieser Thread wird von der Qt-App als Erstes implementiert und gestartet, noch bevor beispielsweise die Bibliotheken geladen werden. Dieser Thread wird als „ qtMainLoopThread “ bezeichnet. Alle folgenden Vorgänge werden in diesem Thread ausgeführt:
- Laden der Qt-Bibliotheken.
- Vorgänge, die innerhalb von ` JNI_OnLoad()` ausgeführt werden.
- Starten der nativen Anwendung.
- Die Ausführung von `
main()`.
Android-UI-Thread
Ähnlich wie bei Android-Apps wird erwartet, dass Operationen, die sich auf die Benutzeroberfläche auswirken, im UI-Thread ausgeführt werden. Qt sorgt intern dafür, dass alle internen Aufrufe, die in der Benutzeroberfläche ausgeführt werden sollen, dort auch tatsächlich ablaufen. Außerdem bietet Qt eine API ` runOnAndroidMainThread()` an, um Operationen aus C++-Code heraus in diesem Thread auszuführen. Mithilfe dieser API steuert Qt, wann die Aufrufe direkt an den Thread gesendet werden, wenn die App aktiv ist, oder in die Warteschlange gestellt werden, wenn die App angehalten wurde oder im Hintergrund läuft.
Architektur
Qt-Klassen
In den folgenden Abschnitten werden die verschiedenen Qt-für-Android-Klassen sowie ihre Funktionalität und Rolle in Qt-Anwendungen behandelt.
Die öffentlichen Java-Bindings
Bei diesen Klassen handelt es sich um öffentliche Klassen, die die internen Implementierungsdetails der benutzerseitigen Klassen wie `Activity`, `Service` und `Application` verkapseln. Diese Klassen werden standardmäßig für Qt-Android-Apps verwendet und in der Android-Manifest-Datei referenziert. Das Build-System und die Bereitstellungstools sorgen dafür, dass sie in den Build einbezogen werden.
Benutzer können diese Klassen nutzen, um das Standardverhalten zu ändern oder zu erweitern. Beispielsweise erweitert „QtActivity“ die Klasse „ Activity “ und implementiert die Logik, die zum Laden der Qt-Bibliotheken oder zur Verarbeitung von Ereignissen und nativen Aufrufen zwischen Android und Qt erforderlich ist.
Eine Erweiterung von ` QtActivity ` ist in der Regel erforderlich, wenn Sie die Qt-Implementierung für verschiedene Ereignisse und Aufrufe zwischen Qt und Android benötigen. Andernfalls sollte eine Erweiterung von ` Activity ` ausreichen.
Um benutzerdefinierte Logik unter `onCreate()` hinzuzufügen, können Sie Folgendes verwenden:
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.
Ein Thema festlegen
Wenn Sie `QtActivity` erweitern, können Sie mit `setTheme()` ein bestimmtes Android-Theme festlegen. Dieser Aufruf muss jedoch vor dem Aufruf von `onCreate()` der übergeordneten Klasse erfolgen, damit er wirksam wird, da Qt standardmäßig das Theme festlegt. Sie können beispielsweise Folgendes verwenden:
@Override
protected void onCreate(Bundle bundle)
{
setTheme(android.R.style.Theme_DeviceDefault_DayNight);
super.onCreate(bundle);
}Standardmäßig legt Qt für Android 10 und höher das Theme „Theme_DeviceDefault_DayNight Style“ fest, für frühere Versionen das Theme „Theme_Holo_Light Style “.
Einen Anwendungsparameter anhängen
Um einen zusätzlichen Anwendungsparameter anzuhängen – also ein Argument, das von Java/Kotlin an die Funktion ` (main()) ` der Anwendung übergeben wird –, können Sie nach der Erweiterung von `QtActivity` Folgendes tun:
@Override
protected void onCreate(Bundle bundle)
{
appendApplicationParameters("--flag value");
super.onCreate(bundle);
}Dies entspricht der direkten Verwendung der CMake-Variablen ` QT_ANDROID_APPLICATION_ARGUMENTS `. Bei beiden Methoden werden Leerzeichen oder Tabulatoren als Trennzeichen akzeptiert, und die endgültige Liste der an die Anwendung übergebenen Parameter wird mithilfe von ` QProcess::splitCommand` geparst.
Laden von Qt-Bibliotheken mit QtLoader
Jede Qt-für-Android-App muss sicherstellen, dass alle nativen Qt- oder Drittanbieter-Bibliotheken zuerst geladen werden, bevor Funktionen aus diesen Modulen aufgerufen werden. Das Build-System verwaltet eine Liste verschiedener Qt-Bibliotheksabhängigkeiten, des QPA-Plugins, der Hauptanwendungsbibliothek und aller Bibliotheken von Drittanbietern in der Ressourcen-Datei „libs.xml“ der Anwendung. Sobald alle in den folgenden Abschnitten genannten vorbereitenden Schritte abgeschlossen sind, werden die Bibliotheken mit `System.load()` geladen.
Der Klassenlader
Das Class-Loader-Objekt wird frühzeitig von der „ QtLoader “ festgelegt, bevor Qt-Bibliotheken geladen oder die Delegaten initialisiert werden. Der Grund dafür ist, dass der Class-Loader von „ QJniObject “ zum Auffinden von Java-Klassen verwendet wird und für jeden JNI-Aufruf mit „ QJniObject “ erforderlich ist.
Festlegen von Umgebungsvariablen und Anwendungsparametern
Vor dem Laden der Bibliotheken muss Qt sicherstellen, dass Umgebungsvariablen als Metadaten im Android-Manifest an `set` übergeben werden. Dieser Schritt ermöglicht die Initialisierung einiger Module auf der Grundlage der als Manifest-Metadaten festgelegten Konfigurationsflags. Ein Teil dieser Metadaten wird auch an die Liste der Anwendungsparameter weitergegeben, die beim Start an die Anwendung übergeben wird.
`setActivity()`, `setContext()` und `setService()`
Verschiedene Qt-Module müssen möglicherweise von der Java-Seite aus Initialisierungsaufgaben durchführen, für die der Kontext der Activity oder des Service erforderlich ist. Diese Module implementieren dann eine statische Methode, die eine Activity, einen Service oder einen Context als Parameter entgegennimmt:
void setActivity(Activity activity)
{
m_activity = activity;
// Other logic
}Anschließend ruft der „ QtLoader “ diese Methoden mit dem übergeordneten Kontext des Loaders auf, unmittelbar bevor die nativen gemeinsam genutzten Bibliotheken geladen werden.
Wie Qt für Android den Lebenszyklus von Android-Activities handhabt
Qt für Android stellt keine API zur direkten Verarbeitung der Callbacks des Android-Activity-Lebenszyklus wie onCreate(), onStart(), onResume(), onPause(), onStop() und onDestroy() bereit. Stattdessen übernimmt es diese Aufgaben im Hintergrund für den Benutzer. Das Verhalten wird in den folgenden Abschnitten beschrieben.
Hinweis: Diese Lebenszyklusereignisse werden in das Signal ` QGuiApplication::applicationStateChanged ` übersetzt.
Kontextbehandlung
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 eine `Activity` vorhanden ist, handelt es sich um die zuletzt gestartete `Activity`, unabhängig davon, ob `Services` vorhanden sind. Sind nur `Services` vorhanden, handelt es sich um den zuletzt gestarteten `Service`.
Hinweis: Qt für Android unterstützt keine mehreren Aktivitäten.
Callbacks
Die Klasse `QtActivityBase` ist so konzipiert, dass die Implementierungsdetails der verschiedenen Funktionen einer `Activity` innerhalb des Qt for Android-Pakets privat bleiben. Diese Klasse fungiert als 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. Dazu gehören das Laden der Qt-Bibliotheken, das Einrichten des von ` QJniObject ` verwendeten Klassenladers, das Parsen der Metadaten der App und die Vorbereitung der Qt-Anwendung für die Ausführung. Dadurch wird sichergestellt, dass alle für die Activity erforderlichen Initialisierungen durchgeführt werden.
onStart()
Ruft „Activity.OnStart()“ von Android auf.
onResume()
Wenn die Aktivität in den Vordergrund wechselt, setzt QtActivityBase die Qt-Anwendung fort. Es stellt sicher, dass angehaltene Prozesse oder Vorgänge fortgesetzt werden und die Anwendung wieder für Benutzerinteraktionen bereit ist. Es registriert den durch onPause() angehaltenen Display-Manager-Listener erneut.
onPause()
Wenn eine andere Aktivität die Activity teilweise verdeckt, pausiert QtActivityBase die Qt-Anwendung. Dabei wird der Anwendungsstatus gespeichert oder es werden Ressourcen freigegeben, die nicht benötigt werden, solange sich die Anwendung nicht im Vordergrund befindet.
onStop()
Wenn die Aktivität nicht mehr sichtbar ist, beendet QtActivityBase die Qt-Anwendung. Dies beinhaltet eine umfassendere Speicherung des Zustands und die Freigabe von Ressourcen, um die Anwendung auf eine mögliche Beendigung vorzubereiten.
Hinweis: Der QtThread wird an dieser Stelle angehalten.
onDestroy()
Wenn die Aktivität beendet wird oder vom System zerstört wird, bereinigt QtActivityBase alle mit der Qt-Anwendung verbundenen Ressourcen. Es stellt ein ordnungsgemäßes Herunterfahren sicher und sorgt dafür, dass alle erforderlichen Bereinigungsvorgänge 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äten im Hintergrund verwaltet.
Verwaltung des Startbildschirms
QAndroidApplication kann den Startbildschirm mit einem Überblendungseffekt ausblenden, der zeitlich auf die 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 einer Agenda mit einem Link zu einem YouTube-Video“
© 2026 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.