1、方法声明
public class MyJni {
static {
System.loadLibrary("MyJni");
}
public native static String getString();
}
2、实现在Android中声明的Native方法
a、使用javah工具生成头文件
我们的NDK模块源代码由C/C++的头/源文件和make文件组成,这些文件必须放在jni目录下
理论上,jni目录可以放在任何地方,例如我们放在xx/jni/下,在xx/jni/下执行ndk-build之后会在xx/下(即jni同级目录下)产生编译结果(即libs和obj文件)在Android Studio项目里,我们一般把jni目录放在main目录下(即java同级目录),这样我们编译出来的libs和obj将会在main目录下。
打开Terminal终端,输入以下命令:
//此种情况此刻进入main目录下,jni是jni的相对目录,java是MyJni .java的相对目录
//终端在运行命令前需配置
如下:
#sdk
export ANDROID_SDK_HOME=/opt/android/android-sdk-linux
export PATH=$PATH:${ANDROID_SDK_HOME}/tools
export PATH=$PATH:${ANDROID_SDK_HOME}/platform-tools
#android-ndk
export ANDROID_NDK=/opt/android/android-sdk-linux/ndk-bundle
export PATH=$ANDROID_NDK:$PATH
#android-jdk
export JAVA_HOME=/opt/android/android-studio/jre
export JRE_HOME=/$JAVA_HOME/jre
export PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin
export CLASSPATH=.:$JRE_HOME/lib:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export JAVA_BIN=$JAVA_HOME/bin
然后在终端下输入命令 source profile //profile是保存配置的文件
配置成功后方可在终端下输入如下命令:
javah -d jni -classpath java com.sercomm.jnihelloworld.MyJni
运行后会在jni目录下生成com_sercomm_jnihelloworld_MyJni .h,内容如下:
#include
/* Header for class com_sercomm_jnihelloworld_MyJni */
#ifndef _Included_com_sercomm_jnihelloworld_MyJni
#define _Included_com_sercomm_jnihelloworld_MyJni
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_sercomm_jnihelloworld_MyJni
* Method: getString
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_sercomm_jnihelloworld_MyJni_getString
(JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif
b、创建本地代码文件
在jni目录下创建hello.c文件,内容如下:
#include "jni.h"
#include "com_sercomm_jnihelloworld_MyJni.h"
JNIEXPORT jstring JNICALL Java_com_sercomm_jnihelloworld_MyJni_getString
(JNIEnv *env, jclass jz){
// 1. JNIEnv:代表了VM里面的环境,本地的代码可以通过该参数与Java代码进行操作
// 2. jobject:定义JNI方法的类的一个本地引用(this)
return (*env)->NewStringUTF(env,"this is the first time for me to use jni");
}
注:
方法名的格式:Java_包名_类名_Java需要调用的方法名,对于包名,包名中的 . 要改成 _ ,_ 要改成 _1
3、创建Android.mk文件和Application.mk文件
Android.mk文件是一个负责向NDK构建系统描述NDK项目的GNU Makefile片段,是每一个NDK项目的必备组件,根据GNU Make的命名规则,变量名要大写:
LOCAL_PATH :=$(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE :=MyJni
LOCAL_SRC_FILES :=hello.c
include $(BUILD_SHARED_LIBRARY)
Application.mk文件配置编译平台相关的内容
APP_ABI := all
编译上述文件,生成.so库文件
经过上述步骤,在main/jni文件夹中已经有4个文件(hello.c、Android.mk、Application.mk,com_sercomm_jnihelloworld_MyJni.h)
打开终端,进入src/main/jni目录,输入以下命令
ndk-build
编译成功后,会在jni的同级目录中生成libs和obj两个文件夹,其中libs下存放的是.so库文件
此时,我们已经将本地代码文件编译成.so库文件。
在app的bulid文件中加入如下代码,然后build project
android {
...
sourceSets {
main() {
jniLibs.srcDirs = ['src/main/libs']
}
}
}
在MainActivity中调用
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView hello = findViewById(R.id.hello);
hello.setText(MyJni.getString());
}
}
到此项目已经可以运行了,由版本不同,具体执行的命令目录也需要改变一下,但过程是相同的。如果执行命令的过程找不到javah或ndk-build命令,这是由于环境没配置的问题,参考2(a)应该就可以了。