English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

详解Android JNI的基本使用(CMake)

Introduzione

Cos'è JNI

JNI è l'acronimo di Java Native Interface: interfaccia di sviluppo nativa Java, che fornisce una serie di API per implementare la comunicazione tra Java e altri linguaggi (principalmente C e C++) con lo scopo di permettere a Java di chiamare funzioni sviluppate in C o C++ e a C o C++ di chiamare metodi Java. Questo ha molti vantaggi, tra cui: primo, l'efficienza, poiché C/C++ è un linguaggio nativo, più efficiente rispetto a Java; secondo, la possibilità di riutilizzare codice C/C++ esistente; terzo, la decompilazione di Java è più facile rispetto al linguaggio C, di solito gli algoritmi di crittografia sono scritti in C, che non è facile da decompilare.

Cos'è NDK e CMake

NDK è l'acronimo di Native Development Kit, che fornisce una serie di strumenti che aiutano gli sviluppatori a sviluppare rapidamente librerie dinamiche in C (o C++) e a pacchettare automaticamente so e applicazioni Java in apk. NDK integra il compilatore a croce e fornisce file mk corrispondenti per isolare le differenze di CPU, piattaforma e ABI, in modo che gli sviluppatori possano semplicemente modificare i file mk (indicando quali file devono essere compilati, le caratteristiche di compilazione richieste, ecc.) per creare 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、调用java方法javajavaCalculate,传入number值,获得返回值10。
3、将返回值加上参数2,返回,获得12。

最终效果如下:

创建本地方法

public class JNITest {
  private int number = 0;
  public int javaCalculate(int num){
    number=num+10;
    return number;
  }
  public native int nativeCalculate(int num);
  static {
    System.loadLibrary("jni_test");
  }
}

File '.h' generato automaticamente

Prima di tutto, eseguire make Project e entrare nella directory app\build\intermediates\classes\debug.

Inserire il comando nel terminale javah com.example.xujiajia_sx.jnitest.JNITest (cioè la classe con il metodo nativo)

L'effetto è il seguente:

 

Il file '.h' generato automaticamente è il seguente, può essere rinominato o modificato a piacimento.

/* NON MODIFICARE QUESTO FILE - è generato automaticamente */
#include <jni.h>
/* Header per la classe 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
/*
 * Classe: com_example_xujiajia_sx_jnitest_JNITest
 * Metodo: nativeCalculate
 * Firma: (I)I
 */
JNIEXPORT jint JNICALL Java_com_example_xujiajia_1sx_jnitest_JNITest_nativeCalculate
 (JNIEnv *, jobject, jint);
#ifdef __cplusplus
}
#endif
#endif

Creare un file cpp per implementare il metodo nativo

L'autore del file cpp è il seguente:

#include "jni_test.h"
JNIEXPORT jint JNICALL
Java_com_example_xujiajia_1sx_jnitest_JNITest_nativeCalculate(JNIEnv *env, jobject obj, jint num) {
  // Ottieni l'oggetto class dell'oggetto obj
  jclass clazz = env->GetObjectClass(obj);
  // Ottieni l'id del campo number nella classe clazz
  jfieldID id_number = env->GetFieldID(clazz, "number", "I");
  jmethodID id_java_calculate=env->GetMethodID(clazz, "javaCalculate", "(I)I");
  // Ottieni di nuovo il valore di 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);
  // Ottieni di nuovo il valore di number in java e restituiscilo
  return env->GetIntField(obj, id_number);
}

La logica principale è ottenere il valore di number in java, quindi chiamare il metodo javaCalculate(), poi aggiungere questo parametro del metodo nativo num.

Imposta il file Cmake per generare i file ».so«

Prima di tutto, aggiungi la configurazione Cmake nel file build.gradle:

android {
  ...
  defaultConfig {
    ...
    externalNativeBuild {
      cmake {
        cppFlags ""
        // Genera diverse versioni di file so
        abiFilters 'armeabi','armeabi-v7a','x86'
      }
    }
  }
  buildTypes {
    ...
  }
  externalNativeBuild {
    cmake {
      path "CMakeLists.txt"
    }
  }
}

Scrivi il file Cmake:

#CMakeLists.txt
cmake_minimum_required(VERSION 3.4.1)
add_library( # Imposta il nome della libreria.
    jni_test
    # Imposta la libreria come libreria condivisa.
    SHARED
    # Fornisce un percorso relativo ai tuoi file di origine.
    src/main/jni/jni_test.cpp)
include_directories(src/main/jni/)
find_library( # Imposta il nome della variabile di percorso.
    log-lib
    # Specifica il nome della libreria NDK che
    # che vuoi che CMake trovi.
    log
target_link_libraries( # Specifica la libreria obiettivo.
      # Definisci la libreria obiettivo.
      jni_test
      # Collega la libreria obiettivo alla libreria di log
      # incluso nel NDK.
      ${log-lib} )

Dopo aver configurato cmake, ricompila il progetto, è possibile eseguire il file test.“.so” viene generato come segue:


Questo è tutto il contenuto dell'articolo, speriamo che sia utile per la tua apprendimento, e ti preghiamo di sostenere e gridare tutorial.

Dichiarazione: il contenuto di questo articolo è stato raccolto da Internet, il copyright spetta agli autori originali, il contenuto è stato contribuito e caricato autonomamente dagli utenti di Internet, questo sito non detiene i diritti di proprietà, non è stato editato manualmente e non assume responsabilità legali correlate. Se trovi contenuti sospetti di violazione del copyright, ti preghiamo di inviare una e-mail a: notice#oldtoolbag.com (al momento dell'invio dell'e-mail, sostituisci # con @) per segnalare, fornendo prove pertinenti. Una volta verificata, questo sito rimuoverà immediatamente il contenuto sospetto di violazione del copyright.