Eclipse下的 NDK 环境配置
JNI与NDK的开发准备
JNI原生开发流程(Eclipse)
基本流程
- 在Java类中定义native方法
- 生成包含对应JNI函数声明的头文件
- 实现生成的JNI函数
- 借助NDK编译生成动态链接库文件(.so)
- 在Java类中加载动态连接库并调用native的方法
- 运行安装到ARM模拟器上
详细流程
-
在Java类中定义native方法
在Activity类中声明: public native String helloJNI();
-
生成包含对应JNI函数声明的头文件
1). 在命令行窗口中执行: javah Activity全类名(在src下执行)
说明有的电脑可能会提示GBK的不可映射字符: 添加 -encoding utf-82). 在src下会生成一个头文件: com_atguigu_hellojni_MainActivity.h
3). 头文件中包含一个native方法对应的JNI函数声明(需要后面实现):
JNIEXPORT jstring JNICALL Java_com_atguigu_hellojni_MainActivity_helloJNI(JNIEnv *, jobject) -
实现生成的JNI函数
1). 在应用下创建一个文件夹: jni
2). 将刚才生成的头文件复制到此文件夹下
3). 创建一个c文件来实现生成的JNI函数声明: test.c
#include "com_atguigu_hellojni_MainActivity.h"
JNIEXPORT jstring JNICALL Java_com_atguigu_hellojni_MainActivity_helloJNI
(JNIEnv * env, jobject jobj) {
return (*env)->NewStringUTF(env, "Hello from C");
}
-
借助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
-
在Java类中加载动态连接库并调用native的方法
1). 在静态代码块中加载so文件:static { System.loadLibrary("hello-jni"); }
2). 调用native方法:
String result = helloJNI();
- 运行安装到ARM模拟器上
补充说明
-
JNIEXPORT :
在Jni编程中所有本地语言实现Jni接口的方法前面都有一个"JNIEXPORT",这个可以看做是Jni的一个标志,至今为止没发现它有什么特殊的用处。
-
JNICALL :
这个可以理解为Jni 和Call两个部分,和起来的意思就是 Jni调用XXX(后面的XXX就是JAVA的方法名)。
NDK集成开发流程(Eclipse)
基本流程
- 安装配置NDK
- 将NDK关联到eclipse
- 为当前应用自动生成c文件和mk文件
- 定义naitve方法
- 实现native方法对应的JNI函数
- 一键编译生成so文件
- 加载动态库, 并调用native方法
- 运行应用安装到ARM模拟器上
详细流程
-
安装配置NDK
1). 解压NDK的zip包到非中文目录
2). 配置path : 解压后NDK的根目录----->ndk-build
-
将NDK关联到eclipse
Window–>Preferences–>Android–>NDK–>配置NDK的根目录
-
为当前应用自动生成c文件和mk文件
1). 选中当前应用右键–>Android Tools–>Add Native Support
2). 将生成的.cpp文件改为.c文件
3). 修改mk文件: 将.cpp改为.c
-
配置关联jni.h (见"配置关联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
-
定义naitve方法
public native String helloNDK();
-
实现native方法对应的JNI函数
1). 使用javah命令, 生成JNI头文件, 将其复制到jni文件下
2). 在c文件中实现h文件中的函数声明
3). 利用* 的NewStringUTF()函数, 返回字符串
-
一锤编译生成so文件
1). 使用工具栏中的"Build"工具点击锤子按钮生成
2). 文件路径: /libs/armeabi/libNDKTest.so
-
加载动态库, 并调用native方法
static {
System.loadLibrary("NDKTest");
}
String result = helloNDK();
- 运行应用安装到ARM模拟器上
补充说明
-
修改C函数, 不需要再单独编译生成so文件, 可直接运行安装
-
APK只是将so打包了, 本质并不需要jni文件夹下的相关文件
-
多平台交叉编译
1、 arm
2、 intel
3、 mips -
Android.mk详细介绍
#必须定义好LOCAL_PATH变量。它用于在开发树中查找源文件 #宏函数’my-dir’,由编译系统提供,用于返回当前路径(包含c/c++文件) LOCAL_PATH := $(call my-dir) #清除除LOCAL_PATH之外的LOCAL_XXX变量 #CLEAR_VARS由编译系统提供 include $(CLEAR_VARS) #以标识你在Android.mk文件中描述的每个模块。名称必须是唯一的 #编译会产生的链接库文件(lib+名称+.so): libtest2-jni.so LOCAL_MODULE := test2-jni #指定将要编译打包进模块中的C或C++源代码文件 #如果有多个, 以空格隔开 LOCAL_SRC_FILES := test2.c #编译生成动态库(也就是.so文件) include $(BUILD_SHARED_LIBRARY) #编译生成静态库(也就是.a文件) #include $(BUILD_STATIC_LIBRARY)
重要配置
-
编写Android.mk
-
配置关联jni.h文件
-
编写Application.mk