NDK:Native Development Kit原生开发工具
NDK能干什么:NDK使得在android中,java可以调用C函数库。
为什么要用NDK:我们都知道,java是半解释型语言,很容易被反汇编后拿到源代码文件,在开发一些重要协议时,我们为了安全起见,使用C语言来编写这些重要的部分,来增大系统的安全性。还有,在一些接近硬件环境下,相信大家都清楚C与java的优劣。顺带提一下:NDK并不能显著提升应用效率。why?我们都觉得C语言比起java来说效率要高出很多,一方面,随着jdk的不断更新,java的效率也随之提高;另一方面,即便使用C语言编码提高了应用效率,但是在java与C相互调用时平白又增大了开销。
对于这些问题,这里就不多说了,希望详细了解的,请各位自行搜索。
NDK开发,第一步,当然是搭建环境
首先,去http://developer.android.com/tools/sdk/ndk/index.html下载你对应平台的开发工具
以上内容来自
ndk有什么用想必要用的人都知道, 但是像其他工具一样。ndk的开发需要搭建环境,搭建环境这个东西,找不到路子就很麻烦,找到了路子就很容易。以前想学习android上opencv开发,但是当时一直找不到好路子搭建ndk,然后就不了了之了。
今天又来了兴趣搭建ndk,在历经的一段波折之后,终于如愿以偿了。
现在就和大家分享一下我的经历。
1.首先下载了NDK之后,直接解压到指定的目录就可一了,例如我的ndk主目录是 E:\android-ndk-r9d
本来老版本是需要安装cygwin的,但是新版本的可以不用装cygwin(我的是 ndk-r9d),直接用ndk的ndk-build.cmd(cygwin安装比较麻烦,等待时间也很久,有兴趣的同学可以自行百度,http://www.cygwin.com/)
2.然后就是将ndk的主目录添加到eclipse中,如下图
window->preferences->android->ndk
至此,eclipse就可以使用ndk了,如果是想使用命令行模式下使用ndk,可以将ndk目录添加到环境变量中
例如我的是 NDK_HOME = E:\android-ndk-r9d 然后在Path最后面添加%NDK_HOME%(注意与前面的变量用分好隔开)
打开cmd,输入ndk-build 出现下面字样说明成功
C:\Users\Tomorrow>ndk-build
Android NDK: Could not find application project directory !
Android NDK: Please define the NDK_PROJECT_PATH variable to point to it.
E:\android-ndk-r9d\build/core/build-local.mk:148: *** Android NDK: Aborting Stop.
然后就是我们的小例子时间
创建android工程TestJni
一切默认,创建完成之后,右键工程,选中Andriod Tools -> Add Native Support..(最下面)
接下来会让你给你的本地库起一个名字 我的是 test-jni,点击确定,ok
这个操作会自动地帮你的工程添加ndk所需的文件夹目录,并且生成对应的.mk .cpp文件(看以前的教程总是要手动添加,蛋疼不已。。)如下图,是不是很方便呢~~哈哈
接下来就是我们的java代码了
package com.xmt.testjni;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class TestJni extends Activity {
static{
System.loadLibrary("test-jni");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView t = new TextView(this);
t.setText(stringFromJNI());
setContentView(t);
}
public native String stringFromJNI();
}
代码很简单,主要就是这个
static{
System.loadLibrary("test-jni");
}
和
public native String stringFromJNI();
链接库名字一定要对应,要不然找不到
ok,java这边写完了,再看 jni目录下的文件
首先是Android.mk,这个例子很简单,也没有这么文件直接默认
LOCAL_PATH := $(call my-dir)//当前路径
include $(CLEAR_VARS)
LOCAL_MODULE := test-jni //要生成的.so库名
LOCAL_SRC_FILES := test-jni.cpp //你的.cpp文件名字
include $(BUILD_SHARED_LIBRARY)
接下来是cpp文件 (开始的时候只有#include<jni.h>)
#include <jni.h>
extern "C"
{
jstring Java_com_xmt_testjni_TestJni_stringFromJNI(JNIEnv *env ,
jobject thiz){
return env->NewStringUTF("Hello from test-jni !");
}
}
上面的代码就是返回一个字符串,但是有几点需要注意(我也是找了很久才知道。。。)
首先,一般会提示你找不带 jni.h (我的是警告),说明你的工程还没添加include目录,如果你看着不爽,想去掉他,就右键工程->属性->c/c++ Genenral->paths and symbols 选中里面的includes标签页,选择c/c++ 然后点击add
输入 ${NDK_HOME}:/platforms/android-14/arch-arm/usr/include(${NDK_HOME}是你的ndk主目录)
然后点击确定,之后在清理一下项目,然后构建一下项目,警告就没了~:)
第二点就是那个
extern "C"{//你的方法}
不能少(我看ndk samples下面那个hello-jni的cpp就没有,我模仿它写,就一直报
java.lang.UnsatisfiedLinkError:Native method not found:com.xmt.testjni.TestJni.stringFromJNI......错误,这个错误我找了好久才知道问题所在T^T)
第三就方法的名字
Java_com_xmt_testjni_TestJni_stringFromJNI//必须是 Java_packagename_classname_methodname格式
最后就是那个
env->NewStringUTF("Hello from test-jni !");
//ndk samples下面那个hello-jni里面是(*env),.c文件可以那样写,.cpp文件那样会报错
然后就大功告成~
运行你的项目,就会出现类似下面的画面
ok,配置和例子都到这里(如有什么不对的地方请给我留言觉得好的话就点个赞吧还是第一次写呢)