编辑环境
系统:windous 10
NDK : android-ndk-r10d
JDK : “1.8.0_45”
建议在学习之前,先看一下有关.mk文件的介绍 链接
新建项目
- 这里我在C:/project/project 下见了一个名为N 的新项目,包名为package com.jour.st.n 后续会用到。
- 在MainActivity 中添加代码,作为我们等一下要实现的函数
public static native int add(int a, int b);
jni文件
- 在项目的根目录下,新建jni文件夹,并添Android.mk和Application.mk文件(名字不可更改,也不能忽略大小写)。
- 在Android.mk中添加如下代码
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := test
LOCAL_SRC_FILES := test.cpp
include $(BUILD_SHARED_LIBRARY)
LOCAL_C_INCLUDES:= $(LOCAL_PATH)/include
- 在Application.mk文件中,添加如下代码
APP_STL := stlport_static
,在网上找了各种出错的原因,最后才发现是这个问题,没有的话,可能会抛出许多STL的头文件不能使用的错误
local.properties
找到local.properties文件,添加ndk的路径(sdk路径是自动填写完的),输入刚刚下载完后,ndk放置的路径,注意斜杠。如下图所示
.h文件
下面我们就要开始生成.h文件了,首先进入该项目的目录,比如我这里的是C:/project/project
- 简单的命令
ls :显示该文件夹里的所有文件
cd:打开文件夹
网上有许多方法,我这里用一种相对简单一点的,在项目的根目录下,打开app/src/main/java ,然后执行javah -jni 包名.要编译的java文件,比如我这里是 javah -jni com.jour.st.n.MainActivity
结果会在包下生成一个.h的文件,把它移到jni文件下即可。
.cpp文件
这方面可以参考 《JNI编程指南》,可以大致看一下前三章。
注意引用jni.h 和生成的.h文件,实现的函数可以从.h文件那边拷贝一下。
代码如下:
#include<iostream>
#include<jni.h>
#include"com_jour_st_n_MainActivity.h"
JNIEXPORT jint JNICALL Java_com_jour_st_n_MainActivity_add
(JNIEnv *env, jclass cla, jint a, jint b){
return a + b;
};
打开cygwin,进入项目的根目录下,运行ndk-build,然后会生成libs,obj的文件夹。
可能遇到的问题,Cannot find ‘make’ program. 你可以查看是否已经安装了make 的选项,点击下载过来的cygwin,找到相关的,进行下载。
调试
- 在src/main 下建立一个jniLibs文件夹,将生成的armeabi文件夹拷到该目录下
- 在MainActivity中,添加调用的语句
static {
System.loadLibrary("test");
}
- 再在layout下添加一个textview 以便测试是否可以成功调用刚写的函数
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
((TextView)findViewById(R.id.tv)).setText("a + b = " + add(1,3));
}
public static native int add(int a, int b);
static {
System.loadLibrary("test");
}
}
结果
总结
在网上找了许许多多的资料,总体方法是一样的,可能在操作上有点不一样。也许在第一次写NDK时,你是迷迷糊糊的,但写完最好理一下思路,再稍微深入一下理论,这样会更有助于学习。