JNI

来源:互联网 发布:unity 删除数组 编辑:程序博客网 时间:2024/06/06 13:08

NDK:Native Development Kit原生开发工具

NDK能干什么:NDK使得在android中,java可以调用C函数库。

为什么要用NDK:我们都知道,java是半解释型语言,很容易被反汇编后拿到源代码文件,在开发一些重要协议时,我们为了安全起见,使用C语言来编写这些重要的部分,来增大系统的安全性。还有,在一些接近硬件环境下,相信大家都清楚C与java的优劣。顺带提一下:NDK并不能显著提升应用效率。why?我们都觉得C语言比起java来说效率要高出很多,一方面,随着jdk的不断更新,java的效率也随之提高;另一方面,即便使用C语言编码提高了应用效率,但是在java与C相互调用时平白又增大了开销。


何时使用NDK?

Google仅在极少数情况下建议使用NDK,有如下使用场景:

  • 必须提高性能(例如,对大量数据进行排序)。
  • 使用第三方库。举例说明:许多第三方库由C/C++语言编写,而Android应用程序需要使用现有的第三方库,如Ffmpeg、OpenCV这样的库。
  • 底层程序设计(例如,应用程序不依赖Dalvik Java虚拟机)。


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

Android NDK 开发入门环境配置与小例子

至此,eclipse就可以使用ndk了,如果是想使用命令行模式下使用ndk,可以将ndk目录添加到环境变量中

例如我的是 NDK_HOME = E:\android-ndk-r9d 然后在Path最后面添加%NDK_HOME%(注意与前面的变量用分好隔开)

Android NDK 开发入门环境配置与小例子

打开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

Android NDK 开发入门环境配置与小例子

这个操作会自动地帮你的工程添加ndk所需的文件夹目录,并且生成对应的.mk .cpp文件(看以前的教程总是要手动添加,蛋疼不已。。)如下图,是不是很方便呢~~哈哈

Android NDK 开发入门环境配置与小例子

接下来就是我们的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主目录)

Android 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文件那样会报错

然后就大功告成~

运行你的项目,就会出现类似下面的画面

Android NDK 开发入门环境配置与小例子
0 0