动态库和静态库
动态库: libxxx.so
运行的时候,才会去加载,加载一次就在内存中存在副本,其他地方使用就都是公用的。使用场景就是 高德百度sdk对外开房
静态库: libxxx.a
编译期把静态库完整的copy一份去执行,使用场景是如果不需要对外开放就使用静态库
编译静态库、动态库
先编写一个get.c 和 get.h文件
localhost:test01 dsh$ cat test_get.h
#include <stdio.h>
int test_get();
localhost:test01 dsh$ cat test_get.c
#include "test_get.h"
int test_get(){
return 1991;
}
cat是一个linux查看文件内容的命令
ndk编译动态库:
$NDK_GCC_arm $NDK_CFIG_arm -fPIC -shared get.c -o libget.so
ndk编译静态库: 必须使用 arm-linux-androideabi-ar
必须先,用交叉编译打出来的 .o,不能使用gcc
$NDK_GCC_arm $NDK_CFIG_arm -fPIC -c get.c -o get.o
NDK_AR_arm="/root/android-ndk-r17c/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-ar"
$NDK_AR_arm rcs -o libget.a *.o
$NDK_GCC_arm $NDK_CFIG_arm $NDK_AR_arm 是自己配置的环境变量名字,根据自己的喜好定义
下面是我的定义
#NDK 交叉编译 环境配置
export NDK_GCC_arm="/Users/xxx/Downloads/android/NDK/android-ndk-r17c/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-gcc"
export NDK_CFIG_arm="--sysroot=/Users/xxx/Downloads/android/NDK/android-ndk-r17c/platforms/android-21/arch-arm -isystem /Users/xxx/Downloads/android/NDK/android-ndk-r17c/sysroot/usr/include -isystem /Users/xxx/Downloads/android/NDK/android-ndk-r17c/sysroot/usr/include/arm-linux-androideabi"
export NDK_AR_arm="/Users/xxx/Downloads/android/NDK/android-ndk-r17c/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-ar"
mk环境动态库 和 静态库使用
1、创建mk环境AS项目
创建一个普通的AS项目,然后在build.gradle 文件上中添加下面注释部分的代码
android {
compileSdkVersion 28
buildToolsVersion "29.0.2"
defaultConfig {
applicationId "com.example.ndk_mk_01"
minSdkVersion 19
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
//设置NDK支持的环境
externalNativeBuild{
ndkBuild{
abiFilters 'armeabi-v7a'
}
}
ndk {
//设置支持的SO库架构
//abiFilters 'armeabi', 'x86', 'armeabi-v7a', 'x86_64', 'arm64-v8a'
abiFilters "armeabi-v7a"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
//指定mk文件的位置
externalNativeBuild{
ndkBuild{
path 'src/main/ndkDir/Android.mk'
}
}
}
2、编写Android.mk文件
标准的配置 1 2 3 4步
# 1、 源文件路径在哪
# LOCAL_PATH 其实就是Android.mk文件的位置
LOCAL_PATH := $(call my-dir)
$(info "LOCAL_PATH:======== ${LOCAL_PATH}")
# 2、清理
include $(CLEAR_VARS)
# todo 预编译库的引入 提前编译好的库
LOCAL_MODULE := test_get
LOCAL_SRC_FILES := libtest_get.a
#LOCAL_SRC_FILES := libtest_get.so
#告诉构建工具是静态库
include $(PREBUILT_STATIC_LIBRARY)
#include $(PREBUILT_SHARED_LIBRARY)
# 清理自己的库
include $(CLEAR_VARS)
# 3、指定库的名字
LOCAL_MODULE := test_get_jar
LOCAL_SRC_FILES := test01.c \
test02.c
# todo 链接进来
# 静态库链接
LOCAL_STATIC_LIBRARIES := test_get
# 动态库的链接
# LOCAL_SHARED_LIBRARIES := test_get
# 导入log
LOCAL_LDLIBS := -lm -llog
# 4、构建库
include $(BUILD_SHARED_LIBRARY)
引入静态库或者动态库的步骤
第一步、引入预编译库 上面我们使用ndk环境编译处理 .a 或者 .so 文件
LOCAL_MODULE := test_get
LOCAL_SRC_FILES := libtest_get.a
#LOCAL_SRC_FILES := libtest_get.so
第二步、告诉构建工具使用的是静态库还是动态库
include $(PREBUILT_STATIC_LIBRARY)
#include $(PREBUILT_SHARED_LIBRARY)
第三步、清理(必须步骤)
include $(CLEAR_VARS)
第四步、把静态库或者动态库链接进来 跟谁链接 就是LOCAL_MODULE(test_get_jar)
# 静态库链接
LOCAL_STATIC_LIBRARIES := test_get
# 动态库的链接
# LOCAL_SHARED_LIBRARIES := test_get
3、静态库 动态库调用
编一个c文件 叫test01.c
#include <jni.h>
#include <android/log.h>
#define TAG "dsh"
#define LOGD(...)__android_log_print(ANDROID_LOG_DEBUG,TAG,__VA_ARGS__)
extern int test_get();
//extern "C"
JNIEXPORT void JNICALL
Java_com_example_ndk_1mk_101_MainActivity_testGet(JNIEnv * env,jobject instance) {
LOGD("Java_com_example_ndk_1mk_101_MainActivity_testGet %d",test_get());
}
在MainActivity中调用
static {
System.loadLibrary("test_get_jar");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
testGet();
}
public native void testGet();
cmake环境动态库静态库使用
1、新建一个c++的as项目。一定要是c++
2、配置cmake的gradle配置文件
android {
compileSdkVersion 28
buildToolsVersion "29.0.2"
defaultConfig {
applicationId "com.example.ndk_cmake_01"
minSdkVersion 19
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
//cppFlags "" 默认支持四大平台
abiFilters 'armeabi-v7a'
}
}
ndk{
abiFilter 'armeabi-v7a'
}
}
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"
}
}
}
3、配置CMakeLists.txt文件
cmake_minimum_required(VERSION 3.4.1)
message("Camke 路径地址 ${CMAKE_SOURCE_DIR}")
file(GLOB allcpp *.cpp)
add_library(
native-lib
SHARED
${allcpp}
)
#[[# 导入静态库
add_library(test_get STATIC IMPORTED)
set_target_properties(test_get PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/libtest_get.a)]]
# 导入动态库
add_library(test_get SHARED IMPORTED)
set_target_properties(test_get PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/../jniLibs/${CMAKE_ANDROID_ARCH_ABI}/libtest_get.so)
#${CMAKE_SOURCE_DIR}/../jniLibs/${CMAKE_ANDROID_ARCH_ABI}/libget.so
find_library(
log-lib
log)
target_link_libraries(
native-lib
${log-lib}
test_get
)
4、调用静态 或者动态库方法
static {
//如果是动态库 必须添加加一次
System.loadLibrary("test_get");
System.loadLibrary("native-lib");
}