一、下载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');`
`