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.pswp.cn/news/918338.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/918338.shtml
英文地址,请注明出处:http://en.pswp.cn/news/918338.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

elementui cascader 远程加载请求使用 选择单项等

背景&#xff1a;小程序与后端使用自定义表单渲染视图。发现若没有全选&#xff08;如&#xff1a;省市县全部选择&#xff0c;指定的市3级&#xff09;在pc端就会无法渲染出已经选择的区县名称。 解决方案&#xff1a;参考官方文档&#xff0c;设置属性可独立勾选element ui c…

Unity WebGL打包后启动方法,本地方法

引言&#xff1a;常见WebGL开启方法常需要重新打包点击Build and Run或者将游戏放到Unity的云服务器上&#xff0c;作为开发者而言这两个方案一个为了开启再次打包&#xff0c;另一个直接放到了公开环境都不太合适。所以我们需要一个能在本地开启测试的WebGL的方法。 解决方案 …

安全引导功能及ATF的启动过程(五)

安全引导功能及ATF的启动过程&#xff08;五&#xff09; ATF中bl32的启动 bl31中的runtime_svc_init函数会初始化OP-TEE对应的服务&#xff0c;通过调用该服务项的初始化函数来完成OP-TEE的启动。对于OP-TEE的服务项会通过DECLARE_RT_SVC宏在编译时被存放到rt_svc_des段中。该…

Numpy科学计算与数据分析:Numpy入门之多平台安装与基础环境配置

Numpy环境搭建与基础操作 学习目标 本课程将指导学员在Windows、macOS和Linux三种操作系统上安装Numpy&#xff0c;并配置开发环境&#xff0c;包括使用Jupyter Notebook和Spyder等IDE的基本操作。通过本课程的学习&#xff0c;学员将能够独立搭建Numpy开发环境&#xff0c;并…

内存溢出的原因有哪些,如何排查线上问题?

1. java.lang.OutOfMemoryError: ......java heap space..... 堆栈溢出&#xff0c;代码问题的可能性极大 2. java.lang.OutOfMemoryError: GC over head limit exceeded 系统处于高频的GC状态&#xff0c;而且回收的效果依然 不佳的情况&#xff0c;就会开始报这个错误&…

Cesium 无人机视角飞行漫游,截屏

1.实现Cesium模拟无人机离屏渲染&#xff0c;无人机视角飞行漫游。视锥体显示 具体效果如下地址&#xff1a; 【CESIUM无人机视角飞行截屏】 https://www.bilibili.com/video/BV1zQ89zGE14/?share_sourcecopy_web&vd_source8239ec37df07d6a5d56c9ece00146783

vscode 打开设置

目录 方法 1&#xff08;快捷键&#xff09;&#xff1a; 方法2&#xff0c;界面操作&#xff0c;有时没有 方法 1&#xff08;快捷键&#xff09;&#xff1a; 按下&#xff1a;Cmd Shift P 输入并选择&#xff1a;Preferences: Open Settings (JSON) 方法2&#xff0c;…

繁花深处:花店建设的时代意义与多元应用—仙盟创梦IDE

花店当第一缕晨光透过花店的玻璃窗&#xff0c;落在带着露水的玫瑰花瓣上时&#xff0c;这个空间便不再只是商品交易的场所。花店作为城市肌理中充满生命力的细胞&#xff0c;承载着远比销售鲜花更丰富的社会意义。在快节奏的现代生活中&#xff0c;一束鲜花的绽放不仅是自然之…

AtomicStampedReference解决方案

1、通过引入版本戳(stamp)机制解决ABA问题&#xff1a; 每次修改时递增版本号执行CAS时同时检查值和版本号即使值相同但版本不同&#xff0c;操作也会失败2、具体代码实现 import java.util.concurrent.atomic.AtomicStampedReference;public class AtomicStampedReferenceDemo…

版本控制的详细说明介绍(已有github账号版)

说明 如果已经有一个GitHub账号,这是一个很好的起点!版本控制是一个帮助你管理代码或其他文件变化的工具,就像给你的项目加了一个“时间机器”,可以随时回溯历史、协作编辑,而不会乱套。下面我将从基础开始,层层展开说明。整个内容分为几个部分:介绍、原理、用途、操作…

基于Github Pages搭建个人博客站点:hexo环境搭建、本地预览与发布

步骤确认 Hexo 博客的源文件在哪里安装 Hexo 命令行工具&#xff1a;npm install -g hexo-cli在源文件目录中使用 hexo new "文章标题" 创建新文章编辑生成的 Markdown 文件使用 hexo generate 生成静态文件使用 hexo deploy 部署到这个 GitHub Pages 仓库设置Hexo博…

Shell脚本实现自动封禁恶意扫描IP

iptables 简介我们使用iptables工具实现功能iptables 是 Linux 系统上最常用的防火墙工具&#xff0c;可以指定策略。Shell文件创建首先我们先创建文件scanners.shvim /usr/local/bin/auto_block_ip.sh我的目标是每10分钟自动扫描&#xff0c;再10分钟内一个IP访问50次以上就就…

LeetCode_哈希表

哈希表&#xff08;散列表&#xff09;一、哈希表二、有效的字母异位词1、有效的字母异位词(力扣242)2、赎金信(力扣383)3、字母异位词分组(力扣49)4、找到字符串中所有字母异位词(力扣438)三、两个数组的交集1、两个数组的交集(力扣349)2、两个数组的交集 II(力扣350)三、其他…

2.变量和常量

1.变量2.2 变量的基本使用2.3 变量的本质 2.4 变量命名规则与规范 2.5 变量拓展-数组 1.数组的基本使用 2.常量

Java并发核心基础解析

目录 一、背景 二、Java线程模型 三、Synchronized实现原理 3.1 锁的使用 3.2 解释执行 3.3 JIT执行 3.4 锁的状态 3.5 monitorenter 3.5.1 偏向锁 3.5.2 轻量级锁 3.5.3 重量级锁 3.6 monitorexit 3.6.1 偏向锁 3.6.2 轻量级锁 3.6.3 重量级 四、可见性的真相…

线程池111

线程池框图C语言线程池详解&#xff1a;从基础到实现通俗理解线程池想象你开了一家快递站&#xff0c;每天要处理很多包裹派送&#xff1a;​没有线程池​&#xff1a;每来一个包裹就雇一个新快递员&#xff0c;送完就解雇问题&#xff1a;频繁招聘解雇成本高&#xff08;线程创…

Qt-Advanced-Docking-System

直译一下 &#xff1a; 先进的停靠系统 github: mfreiholz/Qt-Advanced-Docking-System: Advanced Docking System for Qt 这是这个项目的起源 这个最后一次更新&#xff1a; githubuser0xFFFF/Qt-Advanced-Docking-System: Advanced Docking System for Qt 这是另一个人复刻…

湖南(源点咨询)市场调研 如何在行业研究中快速有效介入 中篇

我们接着起头篇来说迈克尔波特认为一个行业内存在着五种基本竞争力量&#xff0c;即潜在入侵者、替代产品、供方、需方以及行业内现有竞争者。如附图&#xff1a;即&#xff1a;同行业内现有竞争者的竞争能力、潜在竞争者进入的能力、替代品的替代能力、供应商的讨价还价能力、…

【无标题】消息队列(Message Queue)是一种**进程间通信(IPC)机制

消息队列&#xff08;Message Queue&#xff09;是一种进程间通信&#xff08;IPC&#xff09;机制&#xff0c;它允许进程通过在队列中添加和读取消息来交换数据。与管道&#xff08;命名/匿名&#xff09;相比&#xff0c;消息队列具有结构化消息、异步通信和消息持久化等特点…

mac中多版本JDK配置和切换

下载 从jdk官网下载即可&#xff0c;找到自己要用的版本。 官网&#xff1a;https://www.oracle.com/java/technologies/downloads/#jdk21-mac 我这里下载的jdk1.8和21。 根据自己芯片下载&#xff0c;一般都是m芯片。下载好后&#xff0c;点击&#xff0c;一直下一步就行&…