1、正常创建一个需要的android项目
2、右键项目->Android Tools->Add Native Support(添加本地支持)
3、按需要创建相关的本地支持(创建成功项目会出现jni文件夹、Android.mk文件等)
4、向jni文件中添加需要用到的C++文件【包括需要用到的头文件!!】
5、根据需要调用的C++文件中的函数,在src中创建相关的Java类使用本地方法(类一般如下:)
//创建单独一个的客户端类来调用所有需要用到的C++函数
//此方式是比较好的,因为调用C++中的方法与Java的包、类都有关系,在任何类中调用JniClient不需要对项目做太大的修改
public class JniClient{
//静态加载库文件(在构造函数调用之前被调用)
//取出编译生成的函数库
static{
System.loadLibary("Model_Name");
}
//声明本地方法,不一定要静态全局的,但一定要有native
//方法名一般与C++文件中要调用的函数名相同
public static native void cplusMethod();
}
6、编译JniClient对应的C++文件的头文件
使用cmd进入当前项目的classes文件夹下
使用命令编译生成头文件
//javah 包名.类名,此处类为JniClient
//如需要编译的类为com.example.jni.JniClient
命令为:->进入项目的classes文件夹下 ->javah com.example.jni.JniClient
生成头文件名为:包名_JniClient.h(包名之间的.变为_),如上面的类生成的头文件为com_example_jni_JniClient.h
该头文件存在于classes文件夹下,头文件名可以随意更改,但如果更改需要将Android.mk文件中的LOCAL MODEL该项改为与头文件名相同
Android.mk文件中的LOCAL MODEL项就是标志着要编译成的so库文件的名(最终编译出来的so库文件名将会添加上lib,如以上模块名为JniClient的话,则最终的so库为libJniClient.so)
这一部分在之前编写的Java的本地类中是非常重要的,因为在Java调用C++函数的类中需要加载模块,这个就是就是加载的模块名,加载模块名时不需要添加上lib,跟Android.mk文件中的LOCAL MODEL一样就可以了。
7、将头文件拷贝到项目的jni文件夹下(该头文件名可以更改,但是名字必须和Android.mk文件中的model名统一)
8、创建与头文件名相同的源文件.cpp
9、将头文件中的所有内容拷贝到.cpp中,保留函数体(后面完成这些函数就是我们要调用的了),其余可以删除
10、向.cpp文件中添加引用生成的头文件.h
11、向.cpp文件中添加需要使用的C++文件及其头文件(就是拷贝过去的文件)
12、为项目添加自动编译C++文件
右键->Build Path->Configuration(设置Build Path)->Builders->New->Program
在Main页面下:
Location:选择NDK环境文件,添加ndk-builder.cmd
Working Directory:Browse Workspace->选择当前的项目
在Refresh页面下:
勾选:Refresh resources upon completion
选择:the entire workspace(第一项)
勾选:Recursively include sub-folders(最后一项)
在Build Options页面下:
勾选:Allocate Console
勾选:After a "Clean"
勾选:During manual builds
勾选:During auto builds
勾选:Specify working set of relevant resources
单击:Specify Resources
选择:当前项目
可以在最上面给添加的Builder设置名字:NDK-Builder
13、Java调用C++文件时函数的命名规则
13、Java调用C++文件时函数的命名规则
Java_包名_类名_方法名(JNIEnv *env, jclass obj);
如Java中调用C++中方法名为Method的类为:com.example.jni.JniClient
对应方法的命名为:
Java_com_example_jni_JniClient_Method(JNIEnv *env, jclass obj);
//首部分声明的Java第一个字母最好是大写,C++必须使用大写
//使用C++时应该使用extern "C"{}包括C++代码;
//如果头文件中已经完成这一部分(应该可以不用)
//Java调用的时候,必须包类、类名、方法名与相同才可以