Overview of JNI and NDK Development

 

 

1. Overview of JNI and JDK

1. What is JNI?

  • Java Native Interface, the Java native development interface
  • A protocol that acts as a bridge between Java and C or C++
  • Java can be implemented to call C or C++ code, and C or C++ can also be implemented to call Java code

2. What is the use of JNI?

  • It can expand the functions of Android mobile phones, such as WIFI hotspot, NFC, etc.
  • C or C++ code (native code) is more efficient to execute: heavy calculations, universal decoding (ffmpeg) and 3D rendering (OpenGL), etc.
  • Code reuse: ffmpeg, onencv (face recognition), 7-zip, etc.
  • The incremental upgrade of software or system requires the use of JNI technology
  • Usage scenarios: special cases (efficiency/operational hardware) should always be considered

3. How to use JNI?

  • learn C language
  • JNI development process: NDK
    • NDK (Native Develop Kits), the local development kit
    • Android-provided toolkit for JNI development
    • Function: Improve the efficiency of JNI development (code generation, code hints, multi-platform cross-compilation)

2. Eclipse-based NDK integrated development process

1. Install and configure NDK
1). Unzip the NDK zip package to a non-Chinese directory
2). Configure the Path environment variable

2. Associate NDK with Eclipse
Window-->Preferences-->Android-->NDK-->Configure the root directory of NDK

3. Automatically generate c files and mk files for the current application
1). Right-click the current application-->Android Tools-->Add Native Support
2). Change the generated .cpp file to .c file
3). Modify the mk file : Change .cpp to .c

4. 配置关联jni.h
1). 选中当前应用右键-->Properties-->C/C++ General-->Paths and Symbols
2). 选择add-->选择File System-->选择文件夹android-ndk-r9\platforms\android-18\arch-arm\usr\include
3). 点击ok-->点击apply

5. 定义naitve方法
public native String helloNDK();

6. 实现native方法对应的JNI函数
1). 使用javah命令, 生成JNI头文件, 将其复制到jni文件下
2). 在c文件中实现h文件中的函数声明
3). 利用*的NewStringUTF()函数, 返回字符串

7. 一锤编译生成so文件
1). 使用工具栏中的"Build"工具点击锤子按钮生成
2). 文件路径: /libs/armeabi/libNDKTest.so

8. 加载动态库, 并调用native方法

static {  
    System.loadLibrary("NDKTest");  // 加载动态链接库
}  
String result = helloNDK();  // 使用

9. 运行应用安装到ARM模拟器

补充说明:

  • 修改C函数, 不需要再单独编译生成so文件, 可直接运行安装
  • APK只是将so打包了, 本质并不需要jni文件夹下的相关文件
  • 多平台交叉编译(arm、intel和mips)
  • Android.mk详细介绍
    • 编写Android.mk
    • 配置关联jni.h文件
    • 编写Application.mk

三、基于Eclipse的JNI原生开发流程 ##

1. 在Java类中定义native方法

Activity类中声明: public native String helloJNI();  

2. 生成包含对应JNI函数声明的头文件
1). 在命令行窗口中执行: javah Activity全类名(在src下执行)
说明:有的电脑可能会提示GBK的不可映射字符: 添加 -encoding utf-8
2). 在src下会生成一个头文件: com_atguigu_hellojni_MainActivity.h
3). 头文件中包含一个native方法对应的JNI函数声明(需要后面实现)

3. 实现生成的JNI函数
1). 在应用下创建一个文件夹: jni
2). 将刚才生成的头文件复制到此文件夹下
3). 创建一个c文件来实现生成的JNI函数声明: test.c

4. 借助NDK编译生成动态链接库文件(.so)
1). 解压NDK包, 配置NDK文件夹到path(不能包含空格) 2). 借助NDK下的文档(ANDROID-MK.html)编写用于编译的文件(jni/Android.mk)

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE    := hello-jni #指定生成的so文件的唯一标识
LOCAL_SRC_FILES := test.c  #指定包含JNI函数的c文件名
include $(BUILD_SHARED_LIBRARY)

3). 在命令行窗口中进入应用根目录, 执行ndk-build命令, 生成so动态链接库文件(so文件路径: /libs/armeabi/libhello-jni.so)

5. 在Java类中加载动态连接库并调用native的方法

// 1). 在静态代码块中加载so文件:
static {
    System.loadLibrary("hello-jni");
}
// 2). 调用native方法:
String result = helloJNI();

6. 运行安装到ARM模拟器上

补充说明:
JNIEXPORT:在Jni编程中所有本地语言实现Jni接口的方法前面都有一个"JNIEXPORT",这个可以看做是Jni的一个标志,至今为止没发现它有什么特殊的用处。
JNICALL:这个可以理解为Jni和Call两个部分,和起来的意思就是 Jni调用XXX(后面的XXX就是JAVA的方法名)。

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326446770&siteId=291194637