1.新建MyJni.java
public class MyJni {
static {
System.loadLibrary("MyJni");
}
public native static String getString();
}
2.生成MyJni的.class文件
点击一下 make project 会在app的build目录下面生成MyJni.class文件,不同版本的AS,生成的路径也不同,只要找到对应生成的路径并记录
3.生成 xxx.h 文件
在app/src/main文件夹下新建一个jni文件夹,然后打开Android Studio的终端,cd到这个jni目录,然后输入下面的指令:
javah -jni -classpath xxx.xxx.xxx.MyJni(第二步中生成的MyJni.class路径)
就会在这个jni文件夹下生成一个.h文件,包名_MyJni.h,文件内容如下:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class 包名_MyJni */
#ifndef _Included_包名_MyJni
#define _Included_包名_MyJni
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: 包名_MyJni
* Method: getString
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_包名_MyJni_getString
(JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif
4.生成test.c实现上面的.h文件
在jni目录下新建一个c/c++source file ,取名test.c 实现上面.h文件中的方法
#include "jni.h"
#include "包名_MyJni.h"
JNIEXPORT jstring JNICALL Java_包名_MyJni_getString
(JNIEnv *env, jclass jz){
return (*env)->NewStringUTF(env,"此处填写需要获取的字符串");
}
5.生成Android.mk和Application.mk文件
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := MyJni
LOCAL_SRC_FILES := test.c
LOCAL_LDLIBS +=-L$(SYSROOT)/usr/lib -lm -llog
include $(BUILD_SHARED_LIBRARY)
Application.mk
APP_STL := c++_static
APP_CPPFLAGS := -frtti -fexceptions
APP_ABI := all
APP_PLATFORM := android-16
6.下载Android Studio中的NDK
1.直接在工具包中下载
2.我的AS下载不了,不知道为什么。所以直接去官网下载了NDK地址
3.下载完成后在project structure中配置NDK路径
4.配置环境变量
7.生成so文件
然后在终端进入到jni目录,输入指令 ndk-build,就会生成相应的so文件
8.调用so文件
在app目录下的build.gradle的android{}闭包中添加如下代码:
sourceSets {
main() {
jniLibs.srcDirs = ['src/main/libs']
jni.srcDirs = [] //屏蔽掉默认的jni编译生成过程
}
}
调用方法
String text = MyJni.getString();
获取到的text就是第四步中填写的字符串
9.遇到的坑
1.寻找MyJni.class文件,因为AndroidStudio版本的不同,build的目录结构不一样
2.终端切换目录:cd 路径
3.生成.mk文件:实在找不到哪个file的类型是.mk结尾,直接在桌面新建一个记事本,改格式为mk然后复制到项目中
4.ndk-build提示:不是内部或外部命令,是因为没有在环境变量配置NDK
5.输入ndk-build之后提示:Android NDK: WARNING: APP_PLATFORM android-16 is higher than android:minSdkVersion 1 in AndroidManifest.xml。在AndroidManifest.xml文件中加入:
<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="29" />
这里填写的最小和目标版本应该是和build.gradle中一致(没去研究)
在Application.mk中APP_PLATFORM := android-16这个版本号 不能比你的最小SDK版本大
APP_PLATFORM := android-16这里的可填版本号是看NDK路径下的platforms