一、下载NDK CMake
- NDK : 26.2.11394342 或 23.1.7779620
- CMake : 3.22.1
二、新建android\app\CMakeLists.txt
文件CMakeLists.txt内容
cmake_minimum_required(VERSION 3.4.1)
#mker为项目名称
project('mker')
#设置生成的so动态库最后输出的路径
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/libs/${ANDROID_ABI})
#生成动态库.so
add_library(
#c/cpp代码将要编译成为so库的名称,dart代码加载库文件要用这个名称
native_lib
SHARED #动态库
#cpp代码文件路径 可以在下面接着随意添加c、c++文件
cpp/native_lib.cpp )
#生成静态库.a
add_library(
#静态库.a的名称
mystatic
STATIC #静态库
#cpp代码文件路径 可以在下面接着随意添加c、c++文件
cpp/native_lib.cpp )
三、app/build.gradle配置
defaultConfig {
。。。。。。
//新增
externalNativeBuild {
cmake {
targets 'mystatic','native_lib'
}
// > [CXX1201] ABIs [armeabi] are not supported for platform. Supported ABIs are [arm64-v8a, armeabi-v7a, x86, x86_64].
// ndk {
// abiFilters 'x86_64','x86','arm64-v8a', 'armeabi-v7a'
// }
}
}
//新增:编译自己的CMake进项目
externalNativeBuild {
// Encapsulates your CMake build configurations.
cmake {
path "../CMakeLists.txt"
}
}
四、放c++代码:/android/app/cpp/native_lib.cpp
#include <stdint.h>
#include <cstring>
extern "C" {
__attribute__((visibility("default"))) __attribute__((used))
int32_t native_add(int32_t x, int32_t y) {
return x + y;
}
__attribute__((visibility("default"))) __attribute__((used))
int32_t native_add2(int32_t x, int32_t y) {
return x + y;
}
__attribute__((visibility("default"))) __attribute__((used))
char* concat(const char* str1, const char* str2) {
int len1 = strlen(str1);
int len2 = strlen(str2);
char* result = new char[len1 + len2 + 1];
strcpy(result, str1);
strcat(result, str2);
return result;
}
}
extern "C" __attribute__((visibility("default"))) __attribute__((used))
int32_t native_add3(int32_t x, int32_t y) {
return x + y;
}
五、生成动态库.so和静态库.a
项目根目录下执行命令:flutter build apk后app文件夹下会自动生成libs文件夹,里面放的是不同cpu下的.so文件
.a存放的位置:android/app/.cxx/RelWithDebInfo/5p5v2i3r/arm64-v8a/libmystatic.a
注:生成的.a文件好像不能使用,通过命令行lipo -info xxx.a 查不出cpu架构类型
六、动态库.so验证:
1.pubspec.yaml文件下添加依赖 ffi: ^2.1.2
2.项目lib文件夹下放native_add.dart
import 'dart:ffi' as ffi;
import 'dart:ffi';
import 'dart:io'; // For Platform.isX
import 'package:ffi/ffi.dart';
final DynamicLibrary nativeAddLib = Platform.isAndroid
? DynamicLibrary.open("libnative_lib.so")
: DynamicLibrary.process();
final int Function(int x, int y) nativeAdd = nativeAddLib
.lookup<NativeFunction<Int32 Function(Int32, Int32)>>("native_add")
.asFunction();
final int Function(int x, int y) nativeAdd2 = nativeAddLib
.lookup<NativeFunction<Int32 Function(Int32, Int32)>>("native_add2")
.asFunction();
final int Function(int x, int y) nativeAdd3 = nativeAddLib
.lookup<NativeFunction<Int32 Function(Int32, Int32)>>("native_add3")
.asFunction();
typedef A2 = Pointer<Utf8> Function(ffi.Pointer<Utf8>, ffi.Pointer<Utf8>);
String concatStr(String str1, String str2) {
final privateKeyPtr = str1.toNativeUtf8();
final hexCidMessagePtr = str2.toNativeUtf8();
final concat =
nativeAddLib.lookup<ffi.NativeFunction<A2>>('concat').asFunction<A2>();
return concat(privateKeyPtr, hexCidMessagePtr).toDartString();
}
bool isExistSymbol(String symbol) {
final isOk = nativeAddLib.providesSymbol(symbol);
return isOk;
}
3.flutter调用.so里的方法
int result = nativeAdd(1, 2);
int result2 = nativeAdd2(1, 2);
int result3 = nativeAdd3(1, 2);
print(
'-------------------------result:$result---result2:$result2---result3:$result3');