NDK(Native Development Kit)是一系列工具的集合,帮助开发者快速开发C(或C++)的动态库,并能自动将so和java应用一起打包成apk。
环境搭建略过,Windowds下用cygwin+ndk+ADT
实现步骤:
1.创建一个Android工程
跟普通的Android应用一样。
2.在Java代码中写声明native方法 public native hello();
//定义一个native方法
private native String hello();
3.在工程目录下创建jni文件夹,在该目录下添加一个C的文件
内容:
[codesyntax lang="c"]
#include <stdio.h> #include <stdlib.h> #include <jni.h> jstring Java_com_znn_hellondk_MainActivity_hello(JNIEnv* env, jobject clazz) { return (*env)->NewStringUTF(env,"hello NDK, I am from c Code!!"); }
[/codesyntax]
jni.h位于NDK\android-ndk-r9d\platforms\android-18\arch-arm\usr\include/下
作用是进行数据类型翻译,将Java语言的数据类型用C的语法重新定义,实现两种不同语言之间的数据类型转换。
class _jstring : public _jobject {};来说明jstring类型是Java中的Object类型。
在此本地方法返回的是String 类型的数据
重写Java中的本地方法的格式是Java_方法做咋U的全类名_方法名,方法所在的全类名中的”.”用”_”来代替,“Java_“说明与Java数据类型的映射关系
struct JNINativeInterface {
…
jstring (*NewStringUTF)(JNIEnv*, const char*);
…
}
env是一个指针类型(其实是Java虚拟机的指针,其中有对虚拟机环境的各种引用)。
第一个参数是JNIEnv 指针,第二个参数是要转换的字符串,用char *引用。
4.在jni目录下添加一个Android.mk,
可以从NDK/android-ndk-r9d/docs/ANDROID-MK.html文档中拷贝一下,或者从samples下面找一个修改一下。
#用于通知工具链(NDK)怎么去编译C代码
LOCAL_PATH := $(call my-dir) #my-dir 是一个宏 相当于获取到宏方法的烦返回值(就是Android.mk文件所在的目录)
include $(CLEAR_VARS) #类似于工具初始化的操作 清除掉LOCAL_XXX的变量 但不会清除LOCAL_PATH
LOCAL_MODULE := hello-ndk #将文件编译成的的一个名字 相当于一个别名(库的名字) 是唯一的不能有空格
LOCAL_SRC_FILES := hello-ndk.c #需要编译的C文件
include $(BUILD_SHARED_LIBRARY) #将C文件编译成一个动态库(.so) BUILD_STATIC_LIBRARY是编译成一个静态库 (.a)
#是注释
其他的注释里挺详细
5.NDK编译生成动态库
默认只生成ram下的库,还可以加入Application.mk来指定生成那些平台下的库,如
APP_ABI := all
则对所有平台下都会生成单独的一个库。
然后刷新一下工程,在libs下会多出几个文件
然后运行程序就可以啦!
工程代码:https://github.com/qduningning/HelloNDK
[onebox url="https://github.com/qduningning/HelloNDK"]