当前位置: 首页 > 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.xdnf.cn/news/1274221.html

相关文章:

  • wordpress文章摘要调用的3种方法
  • AI(1)-神经网络(正向传播与反向传播)
  • String AOP、事务、缓存
  • Java数据结构——LinkedList
  • Python与MySQL数据库交互实践:自动化数据插入系统
  • Radiology:经颅交流电刺激调节轻度阿尔茨海默病皮层与海马功能连接
  • 【Docker实战】将Django应用容器化的完整指南
  • YOLOv8算法改进--通过yaml文件添加注意力机制【附代码】
  • 从Redisson源码角度深入理解Redis分布式锁的正确实现
  • JavaScript垃圾回收机制
  • 106-基于Flask的重庆充电桩投建数据可视化分析系统
  • Redis 监控与优化方案(C++项目)
  • ShadowKV 机制深度解析:高吞吐长上下文 LLM 推理的 KV 缓存“影子”方案
  • WSL创建虚拟机配置VNC
  • ADK【4】内置前端调用流程
  • Python数据分析常规步骤整理
  • [论文阅读] 人工智能 + 软件工程 | 大型语言模型对决传统方法:多语言漏洞修复能力大比拼
  • C# 中常用集合以及使用场景
  • 服务器硬件电路设计之 I2C 问答(三):I2C 总线上可以接多少个设备?如何保证数据的准确性?
  • Redis如何实现一个分布式锁?
  • ubuntu22.04安装autoware.universe
  • 进度、质量、安全的关系随笔
  • scala 样例类
  • 计算机视觉(CV)——图像相关基本概念
  • #C语言——刷题攻略:牛客编程入门训练(八):分支控制(二)
  • 7、西门子PLC基础术语:数据单位、存储区域、寻址方式、字节序
  • scanpy单细胞转录组python教程(二):单样本数据分析之数据质控
  • Spring Boot 开发三板斧:POM 依赖、注解与配置管理
  • 第三章 向量
  • 锂电池SOH预测 | 第35讲 Matlab基于BiLSTM的锂电池健康状态估计(锂电池SOH预测),附锂电池最新文章汇集