一、JNI规范so库调用
在 Android Studio生成自己的so库 中已经创建了自己的so库,这是一个JNI规范的so库,可以直接将so库放到libs中,并按照上面文章中MainActivity中的调用方法使用。
1、build.gradle(app)配置
android {
defaultConfig {
// 加载so类型
ndk {
abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
}
}
// so库路径
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
}
2、加载so库中方法
public class NativeImpl {
// 加载so库
static {
System.loadLibrary("native_xiaoxu");
}
/**
* 添加 native 方法
*/
public static native String getUserName();
}
在Sudio中方法名虽然显示红色,但不影响使用。
3、Activity中调用方法
NativeImpl.getUserName();
二、非JNI规范的so库调用
在 Android Studio生成自己的so库 中如果我们没有使用 native-lib.cpp 对命名进行规范化,我们如何直接调用 cpp 中的方法?这时,这时我们需要创建一个自己的so库,在自己的so库中调用三方so库,再在自己的程序中调用自己的so库。
我们还是在之前项目的基础上进行修改,并使用之前生成的so库。
1、放入so库
gradle 4.0开始就对jni的预编译依赖引用方式做出了修改,原来的直接放在“src/main/jniLibs”中的方法已经作废了,所以要把jniLibs里的预编译库换个位置,比如把jniLibs改为mylibs,当然,CMakeLists.txt中的IMPORTED路径也要做出相应修改。
2、CMakeLists.txt
# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html
# Sets the minimum version of CMake required to build the native library.
cmake_minimum_required(VERSION 3.10.2)
# Declares and names the project.
project("nativetestdemo")
# 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 them for you.
# Gradle automatically packages shared libraries with your APK.
add_library( # Sets the name of the library.
new_xiaoxu
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
native-lib.cpp)
# 添加so库存放位置
set(distribution_DIR ${CMAKE_SOURCE_DIR}/../../../../mylibs)
# 添加一个库,它链接我们的so文件
add_library(sotest
SHARED
IMPORTED )
# 给sotest这个库设置so文件链接的位置
set_target_properties( sotest
PROPERTIES IMPORTED_LOCATION
../../../../mylibs/${ANDROID_ABI}/libnative_xiaoxu.so )
# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.
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)
# 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.
new_xiaoxu
sotest
# Links the target library to the log library
# included in the NDK.
${log-lib})
主要代码就在注释部分。
3、添加.h文件
将上篇文章中的NativeImpl.h放到cpp文件夹下。
4、native-lib.cpp
#include <jni.h>
#include <string>
#include "NativeImpl.h"
/* 获取NativeImpl */
NativeImpl nativeImpl;
NativeImpl* getNativeImpl(){
return &nativeImpl;
}
extern "C" JNIEXPORT jstring JNICALL
Java_com_wm_auto_nativetestdemo_NativeImpl_getUserName(
JNIEnv* env,
jclass clazz) {
char* c = getNativeImpl()->getUserName();
return env->NewStringUTF(c);
}
这里的代码基本没有变化,但之前getUserName()是cpp下NativeImpl.cpp中的方法,而这里是so库中里NativeImpl.cpp中的方法。
5、Java代码NativeImpl
public class NativeImpl {
// 加载so库
static {
System.loadLibrary("new_xiaoxu");
}
/**
* 添加 native 方法
*/
public static native String getUserName();
}
只修改了加载库
整体代码结构
项目源码
参考:Android NDK开发: 通过C/C++调用第三方so库
PS:参考代码中,要记得修改so路径。