老套路先上图:
1.环境要求:(本人环境:Android Studio 4.2.2)
AS得先安装好ndk环境,也很简单 可以看我以前的帖子很老了:NDK的下载和安装附加一个图最新的图吧
2.开始新建项目编写代码
先编写调用JNI方法的工具类
package cn.yhsh.songlib;
/**
* @author xiayiye5
* @date 2022/3/2 11:12
*/
public class SongUtils {
static {
System.loadLibrary("songLib");
}
public static native String duration();
public static native int length();
public static native byte[] songIo();
public static native byte[] coverSong(byte[] data);
}
然后可以将上面的java工具类编程成class文件
3.退回到java目录
4.开始将class文件编译成c文件 javah -jni cn.yhsh.songlib.SongUtils(javah -jni SongUtils.class文件的包名全路径)
5.在新建main目录新建一个文件夹jni
6.将上面生成的C代码文件赋值到jni文件夹并且改后缀为.c
打开c代码,开始编辑对应的JNI方法
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class cn_yhsh_songlib_SongUtils */
#ifndef _Included_cn_yhsh_songlib_SongUtils
#define _Included_cn_yhsh_songlib_SongUtils
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: cn_yhsh_songlib_SongUtils
* Method: duration
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_cn_yhsh_songlib_SongUtils_duration(JNIEnv *env, jclass objt) {
//返回一个字符串类型,对应SongUtils.java文件里面的方法
return (*env)->NewStringUTF(env, "Android 我来了!");
}
JNIEXPORT jint JNICALL Java_cn_yhsh_songlib_SongUtils_length(JNIEnv *env, jclass clazz) {
//返回一个int类型,对应SongUtils.java文件里面的方法
return 100;
}
JNIEXPORT jbyteArray JNICALL Java_cn_yhsh_songlib_SongUtils_songIo(JNIEnv *env, jclass clazz) {
// jbyteArray result = (*env)->NewByteArray(env, 100);
// (*env)->SetByteArrayRegion(result, 0, 10, 23, (const jbyte *) 13);
// return result;
//返回一个byte数组类型,对应SongUtils.java文件里面的方法
return (*env)->NewByteArray(env, 101);
}
JNIEXPORT jbyteArray JNICALL
Java_cn_yhsh_songlib_SongUtils_coverSong(JNIEnv *env, jclass clazz, jbyteArray data) {
// jbyteArray d = (*env)->NewByteArray(env, 132);
//返回一个byte数组类型,对应SongUtils.java文件里面的方法
return data;
}
#ifdef __cplusplus
}
#endif
#endif
7.开始编辑CMake文件内容如下
cmake_minimum_required(VERSION 3.4.1)
add_library(
# 设置so文件名称.下面的名字得跟SongUtils里面的System.loadLibrary("songLib");名字保持一致
songLib
# 设置这个so文件为共享.
SHARED
# 指向要编译的c文件.
src/main/jni/cn_yhsh_songlib_SongUtils.c)
find_library(
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log )
# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.
target_link_libraries(
# Specifies the target library.
# 指定目标库.下面的名字得跟SongUtils里面的System.loadLibrary("songLib");名字保持一致
songLib
# Links the target library to the log library
# included in the NDK.
${log-lib} )
CMake文件里面的配置最主要就是2点,一个是c文件的路径,一个是so库的名字
8.设置生成so库的版本
在app下面的defaultConfig中添加如下
externalNativeBuild {
cmake {
cppFlags ""
//生成多个版本的so文件
// abiFilters 'armeabi', 'armeabi-v7a', 'x86'
abiFilters 'arm64-v8a', 'armeabi-v7a', 'x86', 'x86_64'
}
}
//配置CMakeList.txt路径
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
9.开始生成so库文件
10.复制so库给别人调用
11.so库的引用和调用JNI方法就不用说了吧,可查看引用so库说明:so库引用说明
当然也可自行百度哦
直接使用SongUtils.方法名字即可调用(注意:个人建议将SongUtils.java打包成aar或者jar库文件这种形式给别人调用,否则别人引用之前得新建SongUtils.java这个文件的全路径,然后将SongUtils.java这个文件粘贴进去,要保持路径一致,否则会报错so库找不到!!!!)
如有看不明白:本人提供一份源码 生成so库源码
在此感谢原博主:博主直达