NDK系列(一)-AS使用javah生成so文件
NDK系列(二)-AS使用CmakeLists生成so文件
NDK系列(三)-AS编写C文件没有提示和不识别NULL
NDK系列(四)-AS生成jar包、导入so库并使用方法
接着捣鼓ndk,我们在开发的时候,不可避免的需要使用一些三方库,提高自己的开发效率,同时也可以避免自己在某一方面的缺点和短板,这是我们在做安卓原生开发的套路,那么ndk开发呢,也是同样如此,需要导入一些so文件的三方库,来方便我们的开发。以NDK系列一、二的两个demo为例子,比如我们需要那个so文件的方法,在系列一的demo jnilibarary的C文件中添加一个add方法,我们想要在系列二的C文件中调用这个方法(假设这个方法逻辑很复杂,重写需要很浪费时间或者你不会这方面的知识,需要三方库来补充),那么就需要把系列一生成的C文件导入系列二的项目中(后面我会把项目放在git上,需要的自己去down)
在main.c的文件中添加一个add方法,传入两个参数,返回他们的和。其他的不需要修改什么,直接生成so文件就Ok了,至于怎么生成so文件,请参考系列一的介绍。
这里需要额外注意的是,要记住生成的so库的名字,也就是gradle ndk 设置的那个名字。
上个文章我导入so库放在默认目录jniLibs下的,这次我放在libs文件下,做个对比。
在gradle中加入
sourceSets.main{
jniLibs.srcDirs = ['libs']
jni.srcDirs = []
}
把三方的so库放在libs的目录下。接下来编写CmakeList.txt文件,这个比较麻烦了。
我先把我的文件展示出来,在解释。
# Sets the minimum version of CMake required to build the native
# library. You should either keep the default value or only pass a
# value of 3.4.0 or lower.
cmake_minimum_required(VERSION 3.4.1)
# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds it for you.
# Gradle automatically packages shared libraries with your APK.
#设置生成的so动态库最后输出的路径
#set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/../jniLibs/${ANDROID_ABI})
find_library(
log-lib
log )
#设置so库
set(my_lib_path ${CMAKE_SOURCE_DIR}/libs)
add_library( nativeUtil
SHARED
IMPORTED )
set_target_properties( nativeUtil
PROPERTIES IMPORTED_LOCATION
${my_lib_path}/${ANDROID_ABI}/libnativeUtil.so )
add_library(
native-lib
SHARED
src/main/cpp/native-lib.c )
target_link_libraries(
native-lib
nativeUtil
${log-lib} )
1、set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/../jniLibs/${ANDROID_ABI})
这句被我注释了,是用来设置生成so文件的路径。我设置生成的so文件放在了jniLibs下。如果不设置,是有一个默认的路径的。文件夹名是cmake开头。
默认位置在图示这个位置。
2、find_library( log-lib log )
这个是Camakelist项目生成时默认导入的打印三方库。
3、set(my_lib_path ${CMAKE_SOURCE_DIR}/libs)
这个是为了下面使用方便,设置了一个参数,my_lib_path代表的是我当前Cmakelist所在根目录下的libs这个文件夹。
4、add_library( nativeUtil SHARED IMPORTED )
添加名为nativeUtil的三方库,这个名字就是我们生成so文件时设置的名字。
5、set_target_properties( nativeUtil PROPERTIES IMPORTED_LOCATION ${my_lib_path}/${ANDROID_ABI}/libnativeUtil.so )
设置nativeUtil库的连接位置,在CmakeList根目录的libs文件夹下的所有android abi平台的名叫libnativeUtil.so的文件。全部连接入项目。
6、add_library( native-lib SHARED src/main/cpp/native-lib.c )
这个是创建项目时自动生成的,该项目的so库取名为native-lib,当然也可以换成其他的名字,注意不要与导入三方库重名。后面的是该项目对应的c文件位置。
7、target_link_libraries( native-lib nativeUtil ${log-lib} )
开始链接库,这里有个着重注意的点,就是放在第一个的库名称必须是当前的库名称,也就是native-lib,不能将nativeUtil放在前面。
手动创建一个h文件,extern 做前缀,extern意思是从别的库导入的方法。
extern int add(int a,int b);
接下来就是,编写当前项目的C文件。
将头文件直接导入C文件,然后在MainActivity创建一个jni方法,在MainActivity导入两个库,调用方法就ok了。
点击运行,就ok了。
好啦,这就是使用别人的so文件,编写自己的so文件。踩坑踩着踩着就成长了,哈哈~~
系列一javah创建的demo git:https://github.com/SingleShu/JniJavahTest
系列二cmakelist创建的git : https://github.com/SingleShu/JniCmakeTest
感谢动脑学院NDK专题资源