安卓集成三方so库第一弹
最近整理了下安卓jni使用三方so库的资料。简单写几句。
使用环境win10,Android studio 3.5
1.新建安卓native c++工程(默认使用CMakeList方式使用jni),如图:

一路默认next,直到finish建立新工程。建好的工程目录如下:

build一下(点击小锤子),如果多次构建失败,可在工程buildgradle文件添加阿里云仓库如下图:

添加后重新构建,到build文件夹下找cmake文件夹,可以看到生成native-lib的一组so库。

关注一下module的build gradle文件中的两处externalNativeBuild,以后在旧项目改造jni时会使用到。
运行一下APP可以在手机上看到jni层写的回调string数据显示在界面。至此新建native(CMakeLists模式)工程跑通了。
备注1:此时使用so库是jni转换层so库,在转换文件native-lib.cpp中直接返回java可用的jstring数据,想要使用三方so库需要引入,具体操作在下方标题2引入三方so库中介绍。
备注2:此时使用的so库并没有专门指定索引so文件路径,为方便以后使用可以将生成的不同CPU架构下的so拷贝到主module(当前运行使用app)的libs文件夹下。并在gradle中android方法内配置sourceSets的srcDirs使用libs路径:
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
再配置packagingOptions使用先遇到的lib下对应so库:
packagingOptions {
// pickFirsts:当出现重复文件,会使用第一个匹配的文件打包进入apk,防止build下的同名so文件与libs下的so冲突
pickFirst'lib/armeabi-v7a/libnative-lib.so'
pickFirst'lib/arm64-v8a/libnative-lib.so'
}
配置如图:

初建native工程的基本使用就这样子。
2.引入三方so库
备注1:(重要的提示放最前)导入三方so库并配置后,build构建的时候出现这个错误,一定是so库引用路径问题。需要认真核实。

2.1 为验证方便,使用visualStudio2017建立只有int返回值的so库,方法名getTest。visual使用请参照该文章(大牛写的vs使用很详细易用):VS2019 C++的跨平台开发——Android .so开发_移动开发_luoyu510183的博客-CSDN博客
将打包好的三房so库libSharesObject.so考到src->main->jniLibs(新建)文件夹下,并将头文件拷贝到cpp文件夹下。

2.2 再修改CMakeLists文件,修改好的内容如下:
# Sets the minimum version of CMake required to build the native library.
cmake_minimum_required(VERSION 3.4.1)
file(GLOB native_srcs "src/main/cpp/*.cpp") #设置全局native源文件
include_directories(src/main/cpp) #引入头文件路径
add_library(# Sets the name of the library.
native-lib
SHARED
${native_srcs}
native-lib.cpp)
target_include_directories(
native-lib
PRIVATE
${CMAKE_SOURCE_DIR}/../cpp) #引入头文件
add_library(
sharedObject1
SHARED
IMPORTED) #以这个名字引入三方so库
set_target_properties(
sharedObject1
PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/../jniLibs/${ANDROID_ABI}/libSharedObject1.so) #设置so库的实际路径和文件名
find_library(# Sets the name of the path variable.
log-lib
log)
target_link_libraries(# Specifies the target library.
native-lib sharedObject1
${log-lib})
配置完成后在native-lib.cpp文件引入libSharedObject1.h,生成so库的类即可调用类中方法:
extern "C" JNIEXPORT jint JNICALL
Java_com_me_nativejni_MainActivity_getTest(JNIEnv *env,jobject /* this */) {
SharedObject1 *share =new SharedObject1();
int a = share->getTest();
return a;
}
#CMakeLists 修改完成
2.3 在APP module的build gradle文件配置生成不同CPU架构下的so文件和使用CMakeLists方式

2.4 配置好后点击gradle同步一下代码,在native-lib.cpp文件中就能引入三方so库对应的头文件,有头文件就可以引用三方so库中的类和方法

2.4 配置完成后点击build(右上角小锤子),如果CMakeLists中编译文件依赖路径书写对的话就会在build->intermediates->cmake->debug文件下找到生成的对应CPU架构的so库,将这些so库拷贝到module下的libs,并且将jnilibs下的三方so库也拷贝到libs下(一定要把三方库跟jni库考到同样的文件夹,否则在加载库时会报好不到三方方法的错误),运行APP在主界面即可调用三方so库中的getTest()方法,测试结果获得三方so库中的int返回值2020。
最值得总结的一点是:jni调用三方so库文件路径方法命名一定要细心。错误路径和名称导致编译失败非常耗时。

网友评论