flutter开发多端平台应用的探索 下 (跨模块、跨语言通信之平台通道)

2024-09-07 10:04

本文主要是介绍flutter开发多端平台应用的探索 下 (跨模块、跨语言通信之平台通道),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前文

Flutter 是一个跨平台的开发框架,它允许开发者使用相同的代码库来构建 iOS、Android、Web 和桌面应用程序。

上文flutter开发多端平台应用的探索 上(基本操作)-CSDN博客列举了一些特定平台的case(桌面端菜单,鼠标快捷键)的使用方法,有些是flutter提供了对应能力,只需要学习如何调API,有些事三方库支持,本文要探讨的平台通道是更为强大的工具,很多三方插件底层也是使用了平台通道的能力,我们也可以用平台通道来完成各种各样需要做的操作。

平台通道

介绍以及使用

Flutter官方框架目前对一些特定的功能(比如桌面端的菜单、多窗口管理等)支持有限,很多功能是通过第三方库来实现的。这些第三方库大多使用了Flutter的平台通道(Platform Channels)机制,与原生平台代码交互来提供相应的功能。

在开发中,很多flutter开发受限的操作我们也可以使用平台通道机制,类似Android开发的JNI,JSI。


编写平台通道的基本步骤:

1. 在Flutter中创建一个平台通道

        使用MethodChannel类创建一个通道,并指定一个唯一的通道名称。

2. 在Dart中定义需要调用的原生方法

        使用invokeMethod函数调用通道上的方法。

3. 在原生代码中接收来自Flutter的消息

        在相应的原生平台代码中实现相应的通道和方法处理逻辑。

如下是一个获取运行平台的系统版本的例子

flutter侧

import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; // 导入平台通道的包void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({super.key});@overrideWidget build(BuildContext context) {return MaterialApp(home: Scaffold(appBar: AppBar(title: const Text('Platform Channel Demo')),body: const Center(child: PlatformVersionWidget()),),);}
}class PlatformVersionWidget extends StatefulWidget {const PlatformVersionWidget({super.key});@overrideState<PlatformVersionWidget> createState() => _PlatformVersionWidgetState();
}class _PlatformVersionWidgetState extends State<PlatformVersionWidget> {static const platform = MethodChannel('com.example.platform/version'); // 创建平台通道String _platformVersion = 'Unknown';Future<void> _getPlatformVersion() async {String version;try {version = await platform.invokeMethod('getPlatformVersion'); // 调用原生方法} on PlatformException catch (e) {version = "Failed to get platform version: '${e.message}'.";}setState(() {_platformVersion = version;});}@overrideWidget build(BuildContext context) {return Column(mainAxisAlignment: MainAxisAlignment.center,children: [Text('Platform Version: $_platformVersion'),ElevatedButton(onPressed: _getPlatformVersion,child: const Text('Get Platform Version'),),],);}
}

原生平台侧

android/app/src/main/kotlin/example/MainActivity.kt添加以下代码:

package com.example.platformchannelimport io.flutter.embedding.android.FlutterActivity
import io.flutter.plugin.common.MethodChannelclass MainActivity: FlutterActivity() {private val CHANNEL = "com.example.platform/version"override fun configureFlutterEngine(flutterEngine: io.flutter.embedding.engine.FlutterEngine) {super.configureFlutterEngine(flutterEngine)MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler {call, result ->if (call.method == "getPlatformVersion") {val version = "Android ${android.os.Build.VERSION.RELEASE}"result.success(version)} else {result.notImplemented()}}}
}

ios/Runner/AppDelegate.swift添加以下代码:

import UIKit
import Flutter@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {override func application(_ application: UIApplication,didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {let controller = window?.rootViewController as! FlutterViewControllerlet channel = FlutterMethodChannel(name: "com.example.platform/version", binaryMessenger: controller.binaryMessenger)channel.setMethodCallHandler { (call, result) inif call.method == "getPlatformVersion" {result("iOS " + UIDevice.current.systemVersion)} else {result(FlutterMethodNotImplemented)}}return super.application(application, didFinishLaunchingWithOptions: launchOptions)}
}

原理探究

lutter平台通道的底层原理是基于消息传递机制实现的,它允许Flutter代码与各个原生平台代码之间进行双向通信。这个机制的核心在于Flutter引擎提供的二进制消息传递和解码协议

平台通道的基础架构由以下几个部分组成:

Flutter Engine:Flutter引擎负责运行Dart代码,并提供渲染、事件处理和平台通道等功能。Flutter引擎使用二进制消息在Flutter应用和平台端之间传递数据。

Dart 端的 MethodChannel:在Dart中,通过MethodChannel类创建一个通道。MethodChannel 允许Flutter应用向原生平台发送方法调用并接收响应。

原生平台端的 MethodChannel 实现:在原生平台代码中,开发者需要实现一个与Dart端相同通道名称的处理器,来接收来自Flutter的消息,并将结果返回给Flutter。

平台通道的消息传递基于异步二进制消息流,整个过程大致可以分为以下几步:

1. 通道创建:在Dart代码中,开发者创建一个MethodChannel对象,指定一个唯一的通道名称(如com.example.platform/version)。

2. 方法调用:Dart代码使用invokeMethod方法通过通道发送一个方法调用请求,这个请求包括:

• 通道名称。

• 方法名称。

• 可选参数。

3. Flutter引擎序列化消息:Flutter引擎将Dart端的方法调用和参数序列化为二进制消息格式,并将其发送到原生平台。

4. 原生平台接收消息:原生平台代码中的相应通道接收到消息后,将其反序列化为平台特定的数据结构。然后,调用相应的方法并传入参数。

5. 方法执行和返回结果:原生平台执行对应的方法,并将结果或错误返回给Flutter引擎。

6. Flutter引擎反序列化结果:Flutter引擎接收到原生平台的响应后,将其反序列化为Dart对象,并将其传递给Dart代码中的invokeMethod调用者。

平台通道中的消息传递是基于二进制数据的,所有的数据在传输之前都需要序列化为二进制格式。Flutter引擎使用以下格式进行序列化:

• 标准消息编解码器:支持传输各种常见的Dart对象类型,如int、double、bool、String、List、Map等。

• JSON消息编解码器:将Dart对象序列化为JSON字符串,但不支持某些复杂类型。

• 二进制消息编解码器:直接传输二进制数据。

开发者可以自定义自己的编解码器,以支持自定义的数据结构和序列化格式。

Flutter平台通道支持两种异步模式:

1. 单一消息响应模式:即一个方法调用对应一个响应(通常通过invokeMethod发起)。

2. 数据流模式:使用EventChannel来处理持续的数据流,这种模式适合用于监听事件(如传感器数据、位置更新等)。

补充说明:消息通信机制

当invokeMethod在Dart中被调用时,Flutter引擎将方法名和参数使用编码器序列化为二进制格式,然后,这个二进制消息通过Flutter引擎的C++代码传递给Java层,使用BinaryMessenger来发送和接收信息,使用JNI调用相应的Java方法。在Java端,Flutter的Java层实现了一个MethodChannel来接收和处理这些消息。它使用MethodChannel.setMethodCallHandler来设置一个消息处理器,处理传入的消息,并调用对应的Java方法。处理完消息后,Java代码会将结果编码回一个二进制格式,通过JNI回传给Flutter引擎。Flutter引擎将接收到的结果解码为Dart对象,并通过Future对象的回调机制将结果返回给调用者。

谨上

这篇关于flutter开发多端平台应用的探索 下 (跨模块、跨语言通信之平台通道)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1144756

相关文章

基于 Cursor 开发 Spring Boot 项目详细攻略

《基于Cursor开发SpringBoot项目详细攻略》Cursor是集成GPT4、Claude3.5等LLM的VSCode类AI编程工具,支持SpringBoot项目开发全流程,涵盖环境配... 目录cursor是什么?基于 Cursor 开发 Spring Boot 项目完整指南1. 环境准备2. 创建

PHP应用中处理限流和API节流的最佳实践

《PHP应用中处理限流和API节流的最佳实践》限流和API节流对于确保Web应用程序的可靠性、安全性和可扩展性至关重要,本文将详细介绍PHP应用中处理限流和API节流的最佳实践,下面就来和小编一起学习... 目录限流的重要性在 php 中实施限流的最佳实践使用集中式存储进行状态管理(如 Redis)采用滑动

Python中logging模块用法示例总结

《Python中logging模块用法示例总结》在Python中logging模块是一个强大的日志记录工具,它允许用户将程序运行期间产生的日志信息输出到控制台或者写入到文件中,:本文主要介绍Pyt... 目录前言一. 基本使用1. 五种日志等级2.  设置报告等级3. 自定义格式4. C语言风格的格式化方法

SpringBoot 多环境开发实战(从配置、管理与控制)

《SpringBoot多环境开发实战(从配置、管理与控制)》本文详解SpringBoot多环境配置,涵盖单文件YAML、多文件模式、MavenProfile分组及激活策略,通过优先级控制灵活切换环境... 目录一、多环境开发基础(单文件 YAML 版)(一)配置原理与优势(二)实操示例二、多环境开发多文件版

使用docker搭建嵌入式Linux开发环境

《使用docker搭建嵌入式Linux开发环境》本文主要介绍了使用docker搭建嵌入式Linux开发环境,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录1、前言2、安装docker3、编写容器管理脚本4、创建容器1、前言在日常开发全志、rk等不同

深入浅出Spring中的@Autowired自动注入的工作原理及实践应用

《深入浅出Spring中的@Autowired自动注入的工作原理及实践应用》在Spring框架的学习旅程中,@Autowired无疑是一个高频出现却又让初学者头疼的注解,它看似简单,却蕴含着Sprin... 目录深入浅出Spring中的@Autowired:自动注入的奥秘什么是依赖注入?@Autowired

Python 基于http.server模块实现简单http服务的代码举例

《Python基于http.server模块实现简单http服务的代码举例》Pythonhttp.server模块通过继承BaseHTTPRequestHandler处理HTTP请求,使用Threa... 目录测试环境代码实现相关介绍模块简介类及相关函数简介参考链接测试环境win11专业版python

GO语言短变量声明的实现示例

《GO语言短变量声明的实现示例》在Go语言中,短变量声明是一种简洁的变量声明方式,使用:=运算符,可以自动推断变量类型,下面就来具体介绍一下如何使用,感兴趣的可以了解一下... 目录基本语法功能特点与var的区别适用场景注意事项基本语法variableName := value功能特点1、自动类型推

GO语言中函数命名返回值的使用

《GO语言中函数命名返回值的使用》在Go语言中,函数可以为其返回值指定名称,这被称为命名返回值或命名返回参数,这种特性可以使代码更清晰,特别是在返回多个值时,感兴趣的可以了解一下... 目录基本语法函数命名返回特点代码示例命名特点基本语法func functionName(parameters) (nam

Python实战之SEO优化自动化工具开发指南

《Python实战之SEO优化自动化工具开发指南》在数字化营销时代,搜索引擎优化(SEO)已成为网站获取流量的重要手段,本文将带您使用Python开发一套完整的SEO自动化工具,需要的可以了解下... 目录前言项目概述技术栈选择核心模块实现1. 关键词研究模块2. 网站技术seo检测模块3. 内容优化分析模