您的位置:首页 > 其它

NDK 10分钟入门教程

2015-06-29 16:55 369 查看
本文首先发表在http://www.hikyson.cn/archives/771


你可以在http://download.csdn.net/detail/hikyson/8850293找到文章的实例demo。

准备工作

下载ndk r9d版本

地址:http://pan.baidu.com/s/1o6MKL2y 密码: usb2

r10版本的ndk会有些变化导致原来的一些库不能用

配置ndk环境变量

把下载的ndk解压到任意目录下,比如我解压到了
D:\application\AndroidDevelopTools\android-ndk-r9d
目录下

配置环境变量

计算机 -> 属性 -> 高级系统设置 -> 环境变量
下找到
path
。在后面追加
D:\application\AndroidDevelopTools\android-ndk-r9d;


path的每个环境变量配置都需要用
;
分隔开的

配置完成之后启动cmd,输入ndk-build。如果看到下面这样就说明成功了。



hello jni

接下来我们先拿ndk自带的sample练练手。

导入sample中的hellojni

hellojni
项目在
android-ndk-r9d\samples\hello-jni
目录下,导入到eclipse。

导入成功之后可以先看一下项目结构,这时候除了普通的项目文件外还有一个jni的文件夹,里面是mk文件和.c文件,如图:



打开cmd,cd到项目目录下

执行ndk-build命令



这个命令是用来编译我们的ndk项目的,编译之后就会生成可以用的so库文件

这时候我们刷新一下项目,会发现多了两个文件夹。一个是lib,一个是obj。如图:



运行hello-jni,如图:



注:如果是用genemotion运行的话需要安装arm-translation包,这个就自己网上找一个吧,很多。

注:如果刚才步骤出错了,可以运行
ndk-build clean
,删除不用的二进制文件(就是so之类的),重新编译。


到这里,我们没有自己写过代码,也不知道hello-jni做了什么,仅仅就是一步步编译了一下别人的项目。不急,接下来我们就要自己写一个简单的ndk项目了。

创建自己的NDK项目

1. 创建项目

创建一个普通的项目
HelloNative
,在
mainactivity
里添加一个
native
方法:

public static native String getStringFromNative();


这时候可以回头看看sample下的
hello-jni
了,你可以在它的代码中看到native方法
public native String  stringFromJNI();
public native String  unimplementedStringFromJNI();


2. 创建jni目录

在项目根目录下创建一个文件夹,叫
jni


3. 生成.h头文件

我们就需要用一个工具
javah
用来生成头文件。

在项目目录下,执行:

javah -classpath bin/classes;D:application\AndroidDevelopTools\sdktools\platform\android-22\android.jar -d jni com.example.hellonative.MainActivity


如图:



这个命令的确很麻烦,一个个参数解释下

-classpath
就是指定用于生成头文件的class文件,大家都知道java代码会首先编译成class文件,这边就是用的这个。android项目编译之后的class文件都放在bin下的。

-d
就是输出目录到jni。

最后一个指定需要编译的类路径,我们这里是编译的
MainActivity
类。

这里还需要指定android.jar,因为我们的mainactivity是在android开发包下的

运行完javah命令cmd不会打印任何信息就说明可以了。

这时候刷新项目,我们会惊喜地看到,jni文件夹下有了一个.h文件。文件是由包名+类名以下划线分隔组成的。

javah
应该在你安装java的时候就已经配置好了环境变量了的,如果cmd运行javah告诉你识别不了命令,就网上找个教程配置一下吧,这边不赘述了。

4. 编写C代码

我们从刚才生成的头文件中拷贝需要实现的函数头

JNIEXPORT jstring JNICALL Java_com_example_hellonative_MainActivity_getStringFromNative 

(JNIEnv * env, jclass jcls)


include需要的头文件

[code]#include <string.h>
#include <jni.h>
#include "com_example_hellonative_MainActivity.h"


实现函数
Java_com_example_hellonative_MainActivity_getStringFromNative


整个c文件的代码

[code]#include <string.h>
#include <jni.h>
#include "com_example_hellonative_MainActivity.h"
JNIEXPORT jstring JNICALL Java_com_example_hellonative_MainActivity_getStringFromNative
(JNIEnv * env, jclass jcls){
return (*env)->NewStringUTF(env, "www.hikyson.cn from native");
}


5. 编写mk文件

mk文件是用来编译c代码的脚本文件,一般来说我们直接把sample中的android.mk拿过来就可以了

android.mk是主要的配置,还有一个application.mk用来指定需要编译的平台。

android.mk拿过来之后需要修改一点东西,如下:

[code]LOCAL_MODULE    := hello-native
LOCAL_SRC_FILES := hello-native.c


LOCAL_MODULE
指定了生成的so文件名,最后生成的so文件是
lib+LOCAL_MODULE+.so


LOCAL_SRC_FILES
指定了需要编译的文件

6. 生成so库

前面已经有了头文件,根据头文件写好了对应的c代码,而且也有了mk编译脚本,所有事情都已经完备,只欠编译,就像上文编译sample一样,我们执行
ndk-build
命令。

我们也可以看出来,刚才的
hello-jni
sample是已经把当前步骤之前的所有东西都做了的。

编译得到so文件。

7. 使用so库

这个就比较简单了,看代码:

[code]    static{
        System.loadLibrary("hello-native");
    }


静态加载
hello-native
,这个名字是
LOCAL_MODULE
指定的,不要写错。

然后就可以调用我们写的native方法了,整个代码是这样的:

[code]public class MainActivity extends Activity {
    static {
        System.loadLibrary("hello-native");
    }

    public static native String getStringFromNative();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ((TextView) this.findViewById(R.id.text))
                .setText(getStringFromNative());
    }
}


运行结果如下:



写完收工~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: