Android JNI- und NDK-Lernen (1): NDK-Lernen

Überblick

Wenn Sie JNI und NDK lernen möchten, müssen Sie zuerst wissen, was JNI und NDK sind und was sie tun, damit Sie JNI und NDK besser lernen und verstehen können. Dieser Artikel wird hauptsächlich als Studiennotiz verwendet, falls Sie ihn vergessen die Zukunft.

JNI Einführung

Definition: JNI ist die Java Native Interfacelokale Java-Schnittstelle

Rolle: Erlauben Sie Java, mit anderen Arten von Sprachen (wie C und C ++) zu interagieren.

Hinweis: JNI gehört zu Java und hat nichts mit Android zu tun

NDK Einführung

Definitionen: NDK Das Native Development Kitist ein Android eines Development Kits

Funktion: Schnelle Entwicklung der dynamischen C / C ++ - Bibliothek und automatisches Packen dieser und Anwendungen in APK

Hinweis: NDK gehört zu Android und hat nichts mit Java zu tun

Die Verbindung zwischen JNI und NDK

 可以通过NDK工具  在Android中使用JNI与本地代码(C、C++)进行交互
 
 JNI是实现的目的,NDK是实现JNI的手段
 
 即在Android 的开发环境中(Android Studio)通过NDK实现JNI的功能

Verwenden Sie Android Studio, um ein NDK-Projekt zu erstellen

Da Android Studio 2.2 und höher NDK intern integriert hat, muss es nur in Android Studio konfiguriert werden. Die Version, die ich derzeit demonstriere, ist 3.5.3

Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein

Nach diesen drei Schritten kann automatisch ein NDK-Projekt generiert werden
Fügen Sie hier eine Bildbeschreibung ein

Im Vergleich zu normalen Projekten ist dieser Ordner mehr, der native-lib.cppC-, C ++ - Code und CMakelist.txtKompilierungsskripte enthält.

Lassen Sie uns dieses Projekt analysieren

Hauptaktivität

public class MainActivity extends AppCompatActivity {
    
    

    // Used to load the 'native-lib' library on application startup.
    static {
    
    
        System.loadLibrary("native-lib");
    }

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

        // Example of a call to a native method
        TextView tv = findViewById(R.id.sample_text);
        tv.setText(stringFromJNI());
    }

    /**
     * A native method that is implemented by the 'native-lib' native library,
     * which is packaged with this application.
     */
    public native String stringFromJNI();
}

Laden Sie zuerst native-lib.so, rufen Sie dann die stringFromJNIMethode so auf und zeigen Sie schließlich den von dieser Methode zurückgegebenen Wert TextViewan

Unter diesen native-lib.sowird der Name dieser Bibliothek in CMklist.txt angegeben, stringFromJNIeiner Java- nativeMethode, und ihre eigentliche Implementierung befindet sich native-lib.cppin

native-lib.cpp

#include <jni.h>
#include <string>

extern "C" JNIEXPORT jstring JNICALL
Java_com_taobao_alinnkit_ndk1_MainActivity_stringFromJNI(
        JNIEnv *env,
        jobject /* this */) {
    
    
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}

Die obige public native String stringFromJNI()Implementierung ist hier, also wie man bestimmt, welcher Methode in Java die native Methode in C entspricht, hier ist statische Registrierung, dh Java包名类名_方法名das Formular, und dann weiter über andere Registrierungsmethoden sprechen

Der gesamte Anrufverlauf

  • Gradle ruft das externe Build-Skript CMklist.txt auf
  • CMake native-lib.cppkompiliert die C ++ - Quelldatei gemäß den Befehlen im Skript in eine native-lib.sodynamische Bibliothek und kompiliert sie in die APK
  • Laden Sie zuerst zur Laufzeit native-lib.so, rufen Sie dann die stringFromJNIMethode so auf und zeigen Sie schließlich den von dieser Methode zurückgegebenen Wert TextViewan

Konfigurieren Sie Gradle für die Unterstützung von NDK

Schauen wir uns zunächst den Gradle des oben erstellten Projekts an

Fügen Sie hier eine Bildbeschreibung ein

In der roten Box, in der NDK konfiguriert ist, muss diese konfiguriert werden externalNativeBuild {}, um sie zu gradle hinzuzufügen und cmake {}zur Konfiguration zu verwenden

Wir können sehen, dass in Gradle zwei Stellen verwendet werden externalNativeBuild {}, eine defaultConfiginnen und eine defaultConfigaußen

  • In der defaultConfigAußenseite des externalNativeBuild {}Codeblocks cmakeentwickelte CMakeList.txtPfad
  • In defaultConfigdem der externalNativeBuild {}Codeblock cmakehauptsächlich CMakeBefehlsparameter füllen soll

CMakeLists.txt-Dateianalyse

# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html

# Sets the minimum version of CMake required to build the native library.

cmake_minimum_required(VERSION 3.4.1)

# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.

add_library( # Sets the name of the library.
        native-lib

        # Sets the library as a shared library.
        SHARED

        # Provides a relative path to your source file(s).
        native-lib.cpp)

# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.

find_library( # Sets the name of the path variable.
        log-lib

        # Specifies the name of the NDK library that
        # you want CMake to locate.
        log)

# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.

target_link_libraries( # Specifies the target library.
        native-lib

        # Links the target library to the log library
        # included in the NDK.
        ${log-lib})

cmake_minimum_required (VERSION 3.4.1)

Legen Sie die Mindestversion von CMake fest

add_library

Der erste Parameter:
Legen Sie den Namen der Bibliothek fest. Der zweite Parameter: Legen Sie den Bibliothekstyp, die dynamische Bibliothek SHARE .so Suffix, die statische statische Bibliothek .a Suffix fest.
Dritter Parameter: Der relative Pfad der Quelldatei

Sie können mehrere Bibliotheken definieren, CMake erstellt sie und Gradle fügt die gemeinsam genutzten Bibliotheken automatisch in die APK ein

find_library

Suchen Sie eine NDK-Bibliothek und speichern Sie den Pfad der Bibliothek in einer Variablen. Suchen Sie beispielsweise in diesem Beispiel eine Protokollbibliothek in NDK (einer Protokollbibliothek, die Android unterstützt) und speichern Sie die Variable in der Variablen log-lib.

target_link_libraries

Bibliothek zuordnen, ordnen Sie die angegebene Bibliothek zu, wie im obigen Beispiel, dem ersten Parameter: der Zielbibliothek und dem zweiten Parameter: Verknüpfen Sie die Zielbibliothek mit der Protokollbibliothek und fügen Sie sie in das NDK ein.

Dies ist die grundlegendste CMakeLists.txt. Sie kann sehr leistungsfähig sein. Sie können beispielsweise Befehle anpassen, Dateien suchen, Variablen festlegen usw. Es wird empfohlen, das CMAKE-Handbuch zu lesen

Referenz:

https://blog.csdn.net/carson_ho/article/details/73250163

https://blog.csdn.net/afei__/article/details/80897404

https://www.jianshu.com/p/b4431ac22ec2

Ich denke du magst

Origin blog.csdn.net/qq_34760508/article/details/106478299
Empfohlen
Rangfolge