Konzepte

Hinweis

In diesem Leitfaden wird davon ausgegangen, dass Sie bereits mit den Konzepten native Programmierung und in der Android-Entwicklung.

Einführung

Dieser Abschnitt bietet eine allgemeine Erläuterung der Funktionsweise des NDK. Das Android-NDK ist eine Reihe von Tools, mit denen Sie C oder C++ ("nativen Code") in Ihre Android-Apps einbetten können. Die Möglichkeit, Nativer Code in Android-Apps ist besonders nützlich für Entwickler, die eine oder mehrere Folgendes:

  • Ihre Apps auf andere Plattformen zu portieren.
  • Sie können vorhandene Bibliotheken wiederverwenden oder eigene Bibliotheken zur Wiederverwendung bereitstellen.
  • Höhere Leistung in bestimmten Fällen, besonders rechenintensiv wie Spiele.

Funktionsweise

In diesem Abschnitt werden die Hauptkomponenten zum Erstellen nativer Anzeigen für Android und beschreibt den Entwicklungsprozess Verpackung.

Hauptkomponenten

Sie sollten mit den folgenden Komponenten vertraut sein, wenn Sie Ihren App:

  • Native gemeinsam genutzte Bibliotheken: Das NDK erstellt diese Bibliotheken bzw. .so-Dateien aus Ihren C/C++-Quellcode aus.

  • Native statische Bibliotheken: Das NDK kann auch statische Bibliotheken erstellen. .a -Dateien, die Sie mit anderen Bibliotheken verknüpfen können.

  • Java Native Interface (JNI): Die JNI ist die Schnittstelle, über die die Java- und C++-Komponenten kommunizieren miteinander. In diesem Leitfaden wird vorausgesetzt, dass Sie über JNI-Kenntnisse verfügen. Weitere Informationen finden Sie in der Spezifikation für native Java-Schnittstellen.

  • Application Binary Interface (ABI): Das ABI definiert genau, wie die dass Maschinencode zur Laufzeit mit dem System interagiert. Das NDK erstellt .so-Dateien anhand dieser Definitionen. Verschiedene ABIs entsprechen verschiedene Architekturen: Das NDK unterstützt ABI für 32-Bit ARM, AArch64, x86 und x86-64. Weitere Informationen finden Sie unter Android-Geräte ABIs.

  • Manifest: Wenn Sie eine App ohne Java-Komponente schreiben, die NativeActivity-Klasse in der Manifest. Weitere Informationen finden Sie unter Verwenden der native_activity.h-Schnittstelle.

Fließen

Der allgemeine Ablauf zur Entwicklung einer nativen App für Android sieht so aus:

  1. Entwerfen Sie Ihre App und entscheiden Sie, welche Teile in Java implementiert werden sollen und welche Teile Sie verwenden möchten. um sie als nativen Code zu implementieren.

  2. Erstellen Sie ein Android-App-Projekt genau wie für jedes andere Android-Projekt.

  3. Wenn Sie eine reine native App schreiben, deklarieren Sie die Klasse NativeActivity in AndroidManifest.xml Weitere Informationen finden Sie unter Native Aktivitäten und Apps.

  4. Erstelle eine Android.mk-Datei mit einer Beschreibung der nativen Bibliothek, einschließlich des Namens, Flags, verknüpfte Bibliotheken und Quelldateien, die in der JNI kompiliert werden. -Verzeichnis.

  5. Optional können Sie eine Application.mk-Datei erstellen, in der das Ziel konfiguriert wird ABIs, Toolchain, Release-/Debug-Modus und STL. Für alle nicht angeben, werden die folgenden Standardwerte verwendet:

    • ABI: alle nicht eingestellten ABIs
    • Modus: Loslassen
    • STL: System
  6. Platzieren Sie Ihre native Quelle im Verzeichnis jni des Projekts.

  7. Verwenden Sie ndk-build, um die nativen Bibliotheken (.so, .a) zu kompilieren.

  8. Erstellen Sie die Java-Komponente und generieren Sie dabei die ausführbare Datei .dex.

  9. Verpacke alles in einer APK-Datei, die .so, .dex und andere enthält Dateien, die für die Ausführung der App erforderlich sind.

Native Aktivitäten und Anwendungen

Das Android SDK bietet die Hilfsklasse NativeActivity, mit der du Folgendes tun kannst: eine komplett native Aktivität schreiben. NativeActivity zwischen dem Android-Framework und Ihrem nativen Code. erstellen oder ihre Methoden aufrufen. Du musst nur deine Bewerbung deklarieren um in Ihrer AndroidManifest.xml-Datei nativ zu sein, und beginnen Sie damit, Ihre native .

Eine Android-App, die NativeActivity verwendet, wird trotzdem in einer eigenen virtuellen und von anderen Anwendungen aus in einer Sandbox ausgeführt wird. Sie können daher weiterhin auf Android-Framework-APIs über JNI In bestimmten Fällen, z. B. bei Sensoren, Eingabeereignissen und Assets bietet das NDK native Schnittstellen, mit denen Sie anstatt über die JNI aufrufen zu müssen. Weitere Informationen über solche siehe Native APIs.

Unabhängig davon, ob Sie eine native Aktivität entwickeln oder nicht, dass Sie Ihre Projekte mit den traditionellen Build-Tools von Android erstellen. Vorgehensweise Android-Apps mit den richtigen Struktur.

Das Android NDK bietet Ihnen zwei Möglichkeiten, Ihre nativen Aktivitäten zu implementieren:

  • Der Header native_activity.h definiert die native Version der NativeActivity-Klasse. Es enthält die Callback-Oberfläche und Datenstrukturen, die Sie benötigen, Aktivitäten. Da der Hauptthread Ihrer Anwendung die Callbacks verarbeitet, dürfen deine Callback-Implementierungen nicht blockieren. Wenn sie blockiert werden, ANR-Fehler ("Application Not Responding") erhalten, da Ihr Hauptthread reagiert nicht, bis der Callback zurückkehrt.
  • Die Datei android_native_app_glue.h definiert eine statische Hilfsbibliothek, die auf der Schnittstelle native_activity.h auf. Es erzeugt einen weiteren Thread, verarbeitet Dinge wie Rückrufe oder Eingabeereignisse in einer Ereignisschleife. Umzug diese Ereignisse in einen separaten Thread zu verlagern, verhindert, dass Callbacks Ihre im Hauptthread.

Das <ndk_root>/sources/android/native_app_glue/android_native_app_glue.c Quelle ist auch verfügbar, sodass Sie die Implementierung ändern können.

Weitere Informationen zur Verwendung dieser statischen Bibliothek finden Sie in der Beispielanwendung für native Aktivität und die zugehörige Dokumentation. Weitere Lesematerialien findet ihr auch in den Kommentaren im <ndk_root>/sources/android/native_app_glue/android_native_app_glue.h -Datei.

Die Schnittstelle "native_activity.h" verwenden

So implementieren Sie eine native Aktivität mit der Schnittstelle native_activity.h:

  1. Erstellen Sie im Stammverzeichnis Ihres Projekts ein jni/-Verzeichnis. Dieses Verzeichnis Ihren gesamten nativen Code speichert.

  2. Deklarieren Sie Ihre native Aktivität in der Datei AndroidManifest.xml.

    Da Ihre Anwendung keinen Java-Code hat, setzen Sie android:hasCode auf false.

    <application android:label="@string/app_name" android:hasCode="false">
    

    Sie müssen das Attribut android:name des Aktivitäts-Tags auf NativeActivity:

    <activity android:name="android.app.NativeActivity"
              android:label="@string/app_name">
    

    Das Attribut android:value des meta-data-Tags gibt den Namen der der gemeinsam genutzten Bibliothek, die den Einstiegspunkt für die Anwendung enthält (z. B. C/C++ main), wobei das Präfix lib und das Suffix .so aus der Bibliothek weggelassen werden Namen.

    <manifest>
      <application>
        <activity>
          <meta-data android:name="android.app.lib_name"
                     android:value="native-activity" />
          <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
          </intent-filter>
        </activity>
      </application>
    </manifest>
    
  3. Erstellen Sie eine Datei für Ihre native Aktivität und implementieren Sie die Funktion, die in Variable ANativeActivity_onCreate Die App ruft diese Funktion auf, wenn der native Aktivität beginnt. Diese Funktion empfängt, analog zu main in C/C++, einen Verweis auf eine ANativeActivity-Struktur, die Funktionszeiger enthält Callback-Implementierungen beschrieben, die Sie schreiben müssen. Legen Sie die geeignete Callback-Funktionszeiger in ANativeActivity->callbacks die Implementierungen Ihrer Callbacks.

  4. Setzen Sie das Feld ANativeActivity->instance auf die Adresse einer beliebigen Instanz von Daten, die Sie verwenden möchten.

  5. Implementieren Sie zu Beginn alle weiteren Aktionen, die von den Aktivitäten ausgeführt werden sollen.

  6. Implementieren Sie die übrigen Callbacks, die Sie in ANativeActivity->callbacks Weitere Informationen dazu, wann Callbacks eintreten, Siehe Aktivitätslebenszyklus verwalten.

  7. Entwickeln Sie die restliche Anwendung.

  8. Erstellen Sie ein Android.mk file im Verzeichnis jni/ Ihres Projekts, um das native Modul im Build-System beschreiben. Weitere Informationen finden Sie unter Android.mk

  9. Sobald Sie über eine Android.mk-Datei verfügen, kompilieren Sie Ihren nativen Code mithilfe der ndk-build-Befehl.

    cd <path>/<to>/<project>
    $NDK/ndk-build
    
  10. Erstellen und installieren Sie Ihr Android-Projekt wie gewohnt. Wenn sich der native Code Verzeichnis jni/ enthält das Build-Skript automatisch das Paket .so in das APK eingebaute Dateien.

Zusätzlicher Beispielcode

Informationen zum Herunterladen von NDK-Beispielen finden Sie unter NDK-Beispiele.