English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Einführung
Was ist JNI
Die vollständige Bezeichnung von JNI ist Java Native Interface: Java lokale Entwicklungsschnittstelle, die verschiedene API bereitstellt, um die Kommunikation zwischen Java und anderen Sprachen zu ermöglichen (hauptsächlich C und C++Zweck ist es, dass Java C oder C aufrufen kann++Funktionen, die entwickelt werden, C oder C++也能调用Java的方法。这样有很多有点,其一就是效率,C/C++也能调用Java的方法。这样有很多优点,其一就是效率,C/C++是本地语言,比Java更高效;其二就是可以复用已经存在的C
什么是NDK和CMake
NDK全称是Native Development Kit,NDK提供了一系列的工具,帮助开发者快速开发C(或C++)代码;其三是Java反编译比C语言容易,一般加密算法都是用C语言编写,不容易被反编译。++)的动态库,并能自动将so和Java应用一起打包成apk。NDK集成了交叉编译器,并提供了相应的mk文件隔离CPU、平台、ABI等差异,开发人员只需要简单修改mk文件(指出“哪些文件需要编译”、“编译特性要求”等),就可以创建出so。
CMake是一个比make更高级的编译配置工具,它可以根据不同平台、不同的编译器,生成相应的Makefile或者vcproj项目。
通过编写CMakeLists.txt,可以控制生成的Makefile,从而控制编译过程。CMake自动生成的Makefile不仅可以通过make命令构建项目生成目标文件,还支持安装(make install)、测试安装的程序是否能正确执行(make test,或者ctest)、生成当前平台的安装包(make package)、生成源码包(make package_source)、产生Dashboard显示数据并上传等高级功能,只要在CMakeLists.txt中简单配置,就可以完成很多复杂的功能,包括写测试用例。如果有嵌套目录,子目录下可以有自己的CMakeLists.txt。
使用流程
1、在java文件中创建本地方法
2、build项目后自动生成“.h”文件
3、创建.cpp文件,实现.h文件中的方法
4、配置Cmake文件,生成“.so”文件
笔者项目目录如下:
测试实例
public class MyJNI { private static final String TAG = MyJNI.class.getName(); @Test public void test() { JNITest jniTest = new JNITest(); Log.d(TAG, jniTest.nativeCalculate(2)+""); } }
1、调用native方法nativeCalculate,传入参数2.
1、获取Java对象number,初始值为0。
2, rufen Sie die Java-Methode javajavaCalculate auf, geben Sie den Wert von number ein, erhalten Sie den Rückgabewert10.
3, den Rückgabewert mit dem Parameter addieren2, zurückgeben, erhalten12.
Das endgültige Ergebnis ist wie folgt:
Erstellen Sie lokale Methode
public class JNITest { private int number = 0; public int javaCalculate(int num){ number=num+10; Geben Sie number zurück; } public native int nativeCalculate(int num); static { System.loadLibrary("jni_test"); } }
Generieren Sie automatisch ».h-Datei«
Erstellen Sie zunächst das Projekt und navigieren Sie in den Ordner app\build\intermediates\classes\debug.
Geben Sie im Terminal den Befehl javah com.example.xujiajia_sx.jnitest.JNITest ein (d.h. die Klasse mit der native Methode)
Das Ergebnis ist wie folgt:
Der maschinell generierte ».h«-Datei wie folgt, können Sie ihn nach eigenem Ermessen umbenennen oder Inhalte hinzufügen oder entfernen.
/* BEDIEN THIS FILE NICHT - Es ist maschinell generiert */ #include <jni.h> /* Header für die Klasse com_example_xujiajia_sx_jnitest_JNITest */ #ifndef _Included_com_example_xujiajia_sx_jnitest_JNITest #define _Included_com_example_xujiajia_sx_jnitest_JNITest #ifdef __cplusplus extern "C" { #endif /* * Klasse: com_example_xujiajia_sx_jnitest_JNITest * Methode: nativeCalculate * Signatur: (I)I */ JNIEXPORT jint JNICALL Java_com_example_xujiajia_1sx_jnitest_JNITest_nativeCalculate (JNIEnv *, jobject, jint); #ifdef __cplusplus } #endif #endif
Erstellen Sie eine cpp-Datei, um die native Methode zu implementieren
Der Autor des cpp-Datei ist wie folgt:
#include "jni_test.h" JNIEXPORT jint JNICALL Java_com_example_xujiajia_1sx_jnitest_JNITest_nativeCalculate(JNIEnv *env, jobject obj,jint num) { //Erhalten Sie das Class-Objekt des Objekts in obj jclass clazz = env->GetObjectClass(obj); //Erhalten Sie die ID des Felds number in clazz jfieldID id_number = env->GetFieldID(clazz, "number", "I"); jmethodID id_java_calculate=env->GetMethodID(clazz, "javaCalculate", "(I)I"); //Erhalten Sie erneut den Wert von number in java jint number = env->GetIntField(obj, id_number); jint result=env->CallIntMethod(obj,id_java_calculate,number); env->SetIntField(obj,id_number,result+num); //Erhalten Sie erneut den Wert von number in java und geben Sie ihn zurück return env->GetIntField(obj, id_number); }
Der Hauptlogik ist es, den Wert von number in java zu erhalten und dann die Methode javaCalculate() aufzurufen, gefolgt von der native-Methode-Parameter num.
Stellen Sie die Cmake-Datei ein, um ».so«-Dateien zu generieren
Zunächst, fügen Sie die Cmake-Konfiguration in build.gradle hinzu:
android { ... defaultConfig { ... externalNativeBuild { cmake { cppFlags "" //Erstellung mehrerer Versionen von so-Dateien abiFilters 'armeabi','armeabi-v7a','x86' } } } buildTypes { ... } externalNativeBuild { cmake { path "CMakeLists.txt" } } }
Cmake-Datei schreiben:
#CMakeLists.txt cmake_minimum_required(VERSION 3.4.1) add_library( # Legt den Namen der Bibliothek fest. jni_test # Sets the library as a shared library. SHARED # Provides a relative path to your source file(s). src/main/jni/jni_test.cpp) include_directories(src/main/jni/) 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 ) target_link_libraries( # Specifies the target library. # Defines the target library. jni_test # Links the target library to the log library # included in the NDK. ${log-lib} )
Nachdem cmake konfiguriert und das Projekt neu erstellt wurde, kann das test.“.so”-Datei ausgeführt werden:
Das ist der gesamte Inhalt dieses Artikels. Wir hoffen, dass er Ihnen bei Ihrem Lernen hilft und dass Sie die呐喊教程 unterstützen.
Erklärung: Der Inhalt dieses Artikels wurde aus dem Internet übernommen und gehört dem Urheber. Der Inhalt wurde von Internetnutzern freiwillig beigesteuert und hochgeladen. Diese Website besitzt keine Eigentumsrechte und hat den Inhalt nicht von Hand bearbeitet. Sollten Sie urheberrechtlich geschützte Inhalte entdecken, sind Sie herzlich eingeladen, eine E-Mail an notice#w zu senden.3codebox.com (Bitte ersetzen Sie # durch @, wenn Sie eine E-Mail senden, und geben Sie relevante Beweise an. Sobald nachgewiesen wird, dass Inhalte urheberrechtlich geschützt sind, wird diese Website die fraglichen Inhalte sofort löschen.)