最近在做一个项目,需要挂接其它部门提供的so库,android纯小白,在网上找了一堆资料,走了很多弯路终于初步挂接成功,整个流程给大家分享一下
基本工具androidstudio,google官方提供的开发工具,迭代了很多版本了,确实有很多弊端,但是开发用起来的确顺手许多。
基本基础由于挂接的so库是c++编译的,需要c++基础,JNI的基本知识也要懂些,不懂的童鞋可以去查其他资料,不需要学多深,jni的内存机制、类型转换学懂了就差不多了。
第一步 建立项目在androidstudio里建立一个Native C++项目,没错,androidstudio自带示例。
第二步 编写CMkelistandroidstudio的目录结构这里就不多讲了,打开main-cpp目录下一个叫CMakelist的文件,androidstduio将所有的负责操作流程都浓缩在这个txt文件里面了,没多少复杂的工作,只要按照固定的格式填写,androidstudio就会自动执行命令,生成so文件链接动态静态库。
add_library( # Sets the name of the library.
native-lib
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
native-lib.cpp )
这是你自己生成的so库,这里没什么可以修改的地方,native-lib.cpp是你自己编译的cpp文件,涉及到第三方库的调用都在这里面,这也是为什么android编程需要c++基础的原因。
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log )
这段也没什么好说的,无需修改,这里是定位lib的位置。
接下来是我们自己需要添加的
target_include_directories(native-lib
PRIVATE
${CMAKE_SOURCE_DIR}/include
)
这段是添加头文件,并告知工程头文件的位置。
add_library( # Sets the name of the library.
abc
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
IMPORTED)
set_target_properties(abc
PROPERTIES IMPORTED_LOCATION
${PROJECT_SOURCE_DIR}/../jniLibs/${ANDROID_ABI}/libabc.so)
addlibrary添加第三方库,并告知第三方库的类型,SHARED是静态库,STATIC是静态库。
set_target_properties是告知第三方库的位置,${ANDROID_ABI}是自动获取手机的架构,如arm64-v8a。
如何需要导入多个第三方库,就按照add_library()、set_target_properties()继续添加即可。
target_link_libraries( # Specifies the target library.
native-lib abc abc1 abc2
# Links the target library to the log library
# included in the NDK.
${log-lib} )
最后一个target_link_libraries(),将所有的第三方库连接到我们自己的native-lib库上。
第三步 编译native-lib.cpp文件在这里我们将第三方的头文件导入进来,就可以调用第三方的方法了。
int sum(int i,int j)
{
return i+j;
}
例如第三方库中有这样一个函数,我们想把它封装成java的函数
extern "C" JNIEXPORT jint JNICALL
Java_com_example_test_math_sum(JNIEnv* env,jobject /* this */,jint i ,jint j)
{
jint sum_ = i+jj
return sum_;
}
JNI函数规范是这样定义的,函数名是由包名+类名+函数名构成的,传入的参数必须是jni类型的,同时返回的参数也必须是jni类型的,由于int和jint可以直接转换,所以函数中省略了类型转换的过程。
package com.example.test;
public class math{
static {
System.loadLibrary("native-lib");
}
public int java_math(int i,int j)
{
return math(i,j);
}
public native long math(int i ,int j);
}
同时在我们的java中也要有对应的类和对应的函数,这样一个简单的由C++实现的java的math()函数就封装好了。