本文假设读者使用cmake方式编写jni代码,并且已经学会jni基本操作!
JNI集成三方so库支持分为两种情况:
- java层代码直接使用三方so库,此时直接编写native函数调用即可
package com.jni.demo.jni_demo_data;
public class DemoDataJni {
static {
System.loadLibrary("soName");//加载so库,此处soName替换为你要使用的so库名称
}
public native static Object nativeDemoFunction(Object param);//同理,此处替换为你使用的so库函数
}
重点!!!这里的jni加载类,放置的位置非常重要,必须要与so库中RegisterNative函数中 findClass的class全路径类名保持一致,否则so库无法加载会抛找不到so库的异常,一般我们照搬so库的包名结构放置jni加载类,包括参数的传递如果有Object类型,也须如此处理
- 需要自己编写jni代码,在cpp文件中加载三方库
这里插入几点:
①我们选择编写的是32位的库还是64位的库是在gradle.build文件中设置,为方便看到位置,把这个文件全部拿过来了
apply plugin: 'com.android.application'
android {
compileSdkVersion 30
buildToolsVersion "30.0.2"
defaultConfig {
applicationId "com.example.jnidemo"
minSdkVersion 26
targetSdkVersion 30
versionCode 1
versionName "1.0"
externalNativeBuild {
cmake {
//生成多个版本的so文件
abiFilters 'arm64-v8a', 'armeabi-v7a'//输出指定三种abi体系结构下的so库。
}
}
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
externalNativeBuild {
cmake {
path "src/main/cpp/CMakeLists.txt"
version "3.10.2"
}
}
}
②编译生成的so库,默认是在app/build目录下,为方便拿到so库,我们可以在CMakeLists.txt文件中设置so库的生成路径,并且$美元符合后跟的路径可以根据你的需求随意替换指定
cmake_minimum_required(VERSION 3.4.1)
# 指定so生成到libs目录
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/libs/${ANDROID_ABI})
add_library(JNIDemo SHARED JNIDemo.cpp)
find_library(log-lib log)
target_link_libraries(JNIDemo ${log-lib})
下面来说在自己编译的JNI代码体系中集成三方so库的方式(差别其实只在CMakelists.txt文件中):
#CMakeLists.txt
cmake_minimum_required(VERSION 3.4.1)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/jni_demo/include/)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/jni_demo/)
#添加自己的so
add_library(jni_demo
SHARED
${CMAKE_CURRENT_SOURCE_DIR}/jni_demo/JniResult.cpp
${CMAKE_CURRENT_SOURCE_DIR}/jni_demo/JniResultImpl.cpp)
find_library( log-lib
log )
#设置so库的输出路径
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/xapi_jni_impl/libs/)
#2.添加第三方库
add_library(libtest_calib SHARED IMPORTED)
set_target_properties(libtest_calib
PROPERTIES IMPORTED_LOCATION
${CMAKE_CURRENT_SOURCE_DIR}/xapi_jni_impl/libs/arm64-v8a/libtest_calib.so)
#添加链接三方库
target_link_libraries(jni_demo
libtest_calib
${log-lib})