首先来看一下什么是NDK
NDK 提供了一系列的工具,帮助开发者快速开发C(或C++)的动态库,并能自动将so 和java 应用一起打包成apk。这些工具对开发者的帮助是巨大的。
为什么要用NDK
我们都知道,java是半解释型语言,很容易被反汇编后拿到源代码文件,在开发一些重要协议时,我们为了安全起见,使用C语言来编写这些重要的部分,来增大系统的安全性。还有,在一些接近硬件环境下,相信大家都清楚C与java的优劣。顺带提一下:NDK并不能显著提升应用效率(值得探讨)。我们都觉得C语言比起java来说效率要高出很多,一方面,随着jdk的不断更新,java的效率也随之提高;另一方面,即便使用C语言编码提高了应用效率,但是在java与C相互调用时平白又增大了开销。
还有一个重要的一条,很多library或者框架都是用C/C++完成的,如果要重新改成JAVA去写工程量巨大而且没有必要,这时候我们就可以使用JDK技术在android环境下调用这些C/C++的库,极大的方便开发。
NDK环境搭建
首先,去 http://developer.android.com/tools/sdk/ndk/index.html 下载你对应平台的开发工具。如果上不去,可以去百度上搜索国内的下载点下载,楼主下载的是android-ndk32-r10b-windows-x86.zip包,下载后解压到E:\android-ndk32-r10b-windows-x86。
然后,为了更好的使用NDK,将NDK路径配置到环境变量中。打开windows系统的环境变量配置,新建一个NDK_ROOT变量:
然后在path的路径中添加NDK_ROOT的变量:
这样环境就配置好了,下面就可以直接用eclipse新建android工程去使用JNI了!而不是像网上说的还需要安装本地linux环境去编译.so库,现在eclipse中可以直接编译jni中附带的c/c++程序。
Android JNI调用C库实现相加功能demo
下面我们就使用JNI技术,新建一个android demo,实现调用本地语言(C)实现相加功能的接口。
1)新建一个android project ,楼主的project名字是HelloWorld_JNI。新建工程后,需要在项目上添加一个jni文件夹。如图所示:
2)在android的MainActivity中添加代码,其中click为按钮事件的响应函数,add函数前面的native方法表明它为一个本地方法:
package com.example.helloworld_jni;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
public class MainActivity extends Activity {
//注意要加载libhello.so库!
static {
System.loadLibrary("hello");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void click(View v){
Toast.makeText(this, "3 + 5 = " + add(3,5), 0).show();
}
//本地函数接口声明
public native int add(int i,int j);
}
3)在activity_main.xml中添加一个button,响应事件为click:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.helloworld_jni.MainActivity" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="调用C方法计算相加"
android:onClick="click"/>
</RelativeLayout>
4) 进入到android项目的workspace目录下,使用如下的javah命令执行,会自动产生出JNI的文件。运行后,刷新eclipse project,可以看到jni目录下出现了hello.cpp和android.mk文件,由于我们使用的语言是C,所以将hello.cpp rename成hello.c,android.mk文件也做同样的改变。
5)在eclipse的Windows-Preference中,将NDK的路径配置上去:
6)在JNI下面的hello.c中添加两个int型数据相加的本地方法实现。注意java和C语言类型的不一致,详细的可以查阅jni.h文件的定义。
#include <jni.h>
JNIEXPORT jint JNICALL Java_com_example_helloworld_1jni_MainActivity_add(JNIEnv *env, jobject obj, jint x, jint y)
{
return (x + y);
}
运行效果
运行的时候可以看出,系统自动编译成libhello.so库,供android调用:
可以看到效果出来了。只是一个简单的例子,供各位参考!