当前位置: 首页 > news >正文

Flutter 与 Android NDK 集成实战:实现高性能原生功能

Flutter 与 NDK 集成实现

Flutter 可以通过 Platform Channels 与原生代码(包括使用 NDK 编写的 C/C++ 代码)进行交互。以下是实现 Flutter 与 NDK 集成的步骤:

基本步骤

1. 创建 Flutter 项目

flutter create flutter_ndk_example
cd flutter_ndk_example

2. 添加 Android NDK 支持

android/app/build.gradle 中添加 NDK 配置:

android {// ...defaultConfig {// ...externalNativeBuild {cmake {cppFlags "-std=c++17"}}ndk {abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'}}externalNativeBuild {cmake {path "CMakeLists.txt"}}
}

3. 创建 CMakeLists.txt 文件

android/app 目录下创建 CMakeLists.txt

cmake_minimum_required(VERSION 3.4.1)add_library(native-libSHAREDsrc/main/cpp/native-lib.cpp
)find_library(log-liblog
)target_link_libraries(native-lib${log-lib}
)

4. 创建 C++ 源文件

android/app/src/main/cpp 目录下创建 native-lib.cpp

#include <jni.h>
#include <string>extern "C" JNIEXPORT jstring JNICALL
Java_com_example_flutterndkexample_MainActivity_stringFromJNI(JNIEnv* env,jobject /* this */) {std::string hello = "Hello from C++";return env->NewStringUTF(hello.c_str());
}

5. 创建 Method Channel 接口

lib/main.dart 中:

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';void main() {runApp(MyApp());
}class MyApp extends StatelessWidget {static const platform = MethodChannel('com.example.flutterndkexample/channel');Future<String> _getNativeString() async {try {return await platform.invokeMethod('getNativeString');} on PlatformException catch (e) {return "Failed to get string: '${e.message}'.";}}Widget build(BuildContext context) {return MaterialApp(home: Scaffold(appBar: AppBar(title: Text('Flutter NDK Example')),body: Center(child: FutureBuilder<String>(future: _getNativeString(),builder: (BuildContext context, AsyncSnapshot<String> snapshot) {if (snapshot.hasData) {return Text(snapshot.data!);} else if (snapshot.hasError) {return Text("Error: ${snapshot.error}");}return CircularProgressIndicator();},),),),);}
}

6. 实现 Android 端的 Method Channel

android/app/src/main/kotlin/.../MainActivity.kt 中:

package com.example.flutterndkexampleimport io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannelclass MainActivity: FlutterActivity() {private val CHANNEL = "com.example.flutterndkexample/channel"override fun configureFlutterEngine(flutterEngine: FlutterEngine) {super.configureFlutterEngine(flutterEngine)MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler {call, result ->if (call.method == "getNativeString") {result.success(stringFromJNI())} else {result.notImplemented()}}}external fun stringFromJNI(): Stringcompanion object {init {System.loadLibrary("native-lib")}}
}

更复杂的 NDK 功能示例

1. 添加数学计算函数

native-lib.cpp 中添加:

extern "C" JNIEXPORT jint JNICALL
Java_com_example_flutterndkexample_MainActivity_addNumbers(JNIEnv* env,jobject /* this */,jint a,jint b) {return a + b;
}

2. 更新 Kotlin 代码

external fun addNumbers(a: Int, b: Int): Int// 在 MethodCallHandler 中添加
if (call.method == "addNumbers") {val a = call.argument<Int>("a") ?: 0val b = call.argument<Int>("b") ?: 0result.success(addNumbers(a, b))
}

3. 更新 Dart 代码

Future<int> _addNumbers(int a, int b) async {try {return await platform.invokeMethod('addNumbers', {'a': a, 'b': b});} on PlatformException catch (e) {print("Failed to add numbers: '${e.message}'.");return 0;}
}

iOS 平台的 NDK 实现(使用 Objective-C/Swift 调用 C++)

对于 iOS,Flutter 可以直接与 Objective-C/Swift 交互,后者可以调用 C++ 代码:

  1. ios/Runner 目录下创建 C++ 文件
  2. 创建对应的头文件
  3. AppDelegate.swift 中实现 Method Channel

最佳实践

  1. 尽量减少平台通道的调用次数(批量处理数据)
  2. 对于性能敏感的操作使用 NDK
  3. 错误处理要完善
  4. 考虑不同 Android ABI 的兼容性
  5. 对于复杂的 C++ 代码,考虑使用 FFI(Dart 2.12+ 支持)

通过以上步骤,你可以成功地将 Flutter 应用与 NDK 编写的原生代码集成,实现高性能的计算或访问特定的原生功能。

http://www.lryc.cn/news/615683.html

相关文章:

  • Vue3 组件化开发
  • Solana上Launchpad混战:新颖性应被重视
  • 一个“加锁无效“的诡异现象
  • BGP 笔记
  • Python 中的 Mixin
  • 第4章 程序段的反复执行2 while语句P128练习题(题及答案)
  • 【动态数据源】⭐️@DS注解实现项目中多数据源的配置
  • Datawhale AI夏令营第三期,多模态RAG方向 Task2
  • 深度学习入门Day8:生成模型革命——从GAN到扩散模型
  • pytorch llm 计算flops和参数量
  • Busybox编译、制作initramfs,并在QEMU中运行
  • 束搜索(Beam Search):原理、演进与挑战
  • Java -- 日期类-第一代-第二代-第三代日期
  • NLP:Transformer输出部分
  • 第十九天-输入捕获实验
  • AI编程工具 | Trae介绍
  • Linux高级编程-文件操作
  • SpringBoot 集成 MapStruct
  • Vue 3.6 Vapor模式完全指南:告别虚拟DOM,性能飞跃式提升
  • 使用GTX ip core + SDI IP core实现SDI设计
  • Vue3 路由
  • C++算法练习:单词识别
  • 决策树技术详解:从理论到Python实战
  • 【ref、toRef、toRefs、reactive】
  • 多级缓存详解
  • 《励曼旋耕》Liman Rotary Tillage
  • Python如何合并两个Excel文件
  • 花生4CL基因家族鉴定及对干旱与盐胁迫响应分析--文献精读157
  • 本地进行语音文字互转
  • CVPR中深度学习新范式:通用性、鲁棒性与多模态的创新突破