Android NDK(Native Development Kit,原生态开发包),支持开发者用C/C++语言开发Android程序。Android虚拟机Dalvik支持JNI编程方式,也就是第三方应用完全可以通过JNI通用自己的C动态库。
1、NDK是一系列工具的集合
A、 NDK包含了一套交叉编译工具,可生成Linux, MAC和Windows(用Cygwin)上的原生ARM的二进制码。
B、 NDK提供了一系列的工具,帮助开发者快速开发C或C++的动态度,并能自动将so和Java应用一起打包成apk。
C、 NDK集成了交叉编译器,并提供了相应的mk文件隔离CPU、平台、ABI等差异,开发人员只需要简单修改mk文件(指出“哪些文件需要编译”、“编译特性要求”等),就可以创建出so(windows下是Dll文件)
2、NDK提供了一套原生API的系统头文件
A、libc(C library) headers:C标准库
B、 libm(math library) headers:标准数学库
C、JNI interface headers:JNI接口
D、 Libz(Zlib compression) headers:压缩库
E、 liblog(Android logging) header:Log库
F、 A Minimal set of headers for C++ support:一部分C++库
系统需求
1、Android SDK 1.5或以上版本
2、Andriod NDK http://dl.google.com/android/ndk/android-ndk-1.6-r1-windows.zip
3、GNU Make 3.81或更高版本。Windows上需要安装较新版本的Cygwin,包括gmake和gcc包。
4、交叉编译器,Linux下面,可以自己编译一个交叉编译环境,Windows下面可以通过Cygwin编译一个交叉编译环境,也可以下载一个现成的,如CodeSourcery编译器。
编程步骤:
1、JNI接口设计
(1)、按”android-ndk-1.6_r1\apps\HelloNDK\project”目录创建一个NDK工程,其中HelloNDK为NDK工程文件夹,project存放Java工程和C\C++代码
(2)、创建android工程,指定创建到”android-ndk-1.6_r1\apps\HelloNDK\project”目录。
(3)、创建一个JNI的Java类,用来声明要调用的本地方法,关键字native,这里只需要声明,不需要具体实现。
// Jni.java
package com.yarin.android.HelloNDK;
public class Jni
{
public native int getCInt();
public native String getCString();
}
(4)、将工程目录下”src\com\yarin\android\HelloNDK”目录中的Jni.java文件复制到工程目录中bin文件夹下面
(5)、从命令行进入该工程的bin目录,输入”javac Jni.java”命令,生成Jni.class文件。
(6)、复制上一步生成的Jni.class文件到”project\bin\com\yarin\android\HelloNDK”目录,覆盖以前的Jni.class文件。
(7)、再次从命令行进入该工程的bin目录,输入”javah –jni com.yarin.android.HelloNDK.Jni”命令,此时将在bin目录中生成一个名为com_yarin_android_HelloNDK_Jni.h的C头文件。在android工程中创建一个jni文件夹,将生成的c文件复制到该文件夹下
// \HelloNDK\project\jni\com_yarin_android_HelloNDK_Jni.h
#include<jni.h> //该文件主要用来转化java和C\C++中的差别,如数据类型
#ifndef _Included_com_yarin_android_HelloNDK_Jni
#define _Included_com_yarin_android_HelloNDK_Jni
#ifdef __cplusplus
Extern “C”{
JNIEXPORT jint JNICALL Java_com_yarin_android_HelloNDK_Jni_getCInt(JNIEnv *env, jobject thiz);
JNIEXPORT jstring JNICALL Java_com_yarin_android_HelloNDK_Jni_getCString (JNIEnv *env, jobject thiz);
#ifdef __cplusplus
}
#endif
#endif
2、使用C\C++实现本地方法
在jni文件夹下新建一个com_yarin_android_HelloNDK_Jni.c文件,用来实现这些原生方法。
// \HelloNDK\project\jni\com_yarin_android_HelloNDK_Jni.c
#include<stdio.h>
#include<stdlib.h>
#include “com_yarin_android_HelloNDK_Jni.h”
int add2()
{
int x, y;
x = 1000;
y = 8989;
return x + y;
}
JNIEXPORT jint JNICALL Java_com_yarin_android_HelloNDK_Jni_getCInt(JNIEnv *env, jobject thiz)
{
return add2();
}
JNIEXPORT jstring JNICALL Java_com_yarin_android_HelloNDK_Jni_getCString (JNIEnv *env, jobject thiz);
{
(*env)->NewStringUTF(env, “ HelloNDK---->>”);
}
3、Android.mk
// \HelloNDK\project\jni\Android.mk
LOCAL_PATH := $(call my-dir)
Include $(CLEAR_VARS)
LOCAL_MODULE := HelloNDK
LOCAL_SRC_FILES := com_yarin_android_HelloNDK_Jni.c
Include $(BUILD_SHARED_LIBRARY)
最后会生成lib$(LOCAL_MODELE).so文件,即libHelloNDK.so
如果使用BUILD_STATIC_LIBRARY,则会生成ib$(LOCAL_MODELE).a文件
4、光有Android.mk不够,还要用一个Application.mk文件,处于NDK工程的根目录,用来描述应用程序中所需要的原生的模块(也就是静态库和动态链接库)
// \HelloNDK\Application.mk
APP_PROJECT_PATH :=$(call my-dir)/project
APP_MODULES := HelloNDK
APP_MODULES变量是强制性的,并且会列出所有你的应用所需要的模块
APP_PROJECT_PATH变量也是强制性的,并且会给应用程序工程的根目录一个绝对路径。这是用来复制或者安装一个没有任何版本限制的JNI库,从而给APK生成工具一个详细的路径。
APP_OPTIM变量是可选的变量,可以定义为“发布版” 或者是 “测试版”。发布版的二进制文件更加优化,“测试版”的二进制文件更容易用来测bug
5、将c文件编译成so或dll文件
启动Cygwin,进入NDK根目录,输入 make APP=HelloNDK 命令。则会生成libHelloNDK.so文件,并安装到工目录下\libs\armeabi目录中
6、使用动态库
public class HelloNDK extends Activity
{
static //装载动态库
{
System.loadLibrary(“HelloNDK”); //不需要加后缀名,系统自动判断,并肯不需要加入前缀lib
}
@Override
public void onCreate(Bundle savedInstanceState)
{
Super.onCreate(savedInstanceState);
Jni jni = new Jni();
TextView textView = new TextView(this);
textView.setText(jni.getCString() + Interger.toString(jni.getCInt()));
setContentView(textView);
}
}