flutter开发多端平台应用的探索

简介: 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});

@override
Widget 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});

@override
State createState() => _PlatformVersionWidgetState();
}

class _PlatformVersionWidgetState extends State {
static const platform = MethodChannel('com.example.platform/version'); // 创建平台通道
String _platformVersion = 'Unknown';

Future _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;
});
}

@override
Widget 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.platformchannel

import io.flutter.embedding.android.FlutterActivity
import io.flutter.plugin.common.MethodChannel

class 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! FlutterViewController
let channel = FlutterMethodChannel(name: "com.example.platform/version", binaryMessenger: controller.binaryMessenger)

channel.setMethodCallHandler { (call, result) in
  if 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方法通过通道发送一个方法调用请求,这个请求包括:

• 通道名称。

• 方法名称。

• 可选参数。

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

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

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

  4. 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对象的回调机制将结果返回给调用者。

相关文章
|
7天前
flutter开发中Use ‘const’ with the constructor to improve performance. Try adding the ‘const’ keyword to the constructor invocation.报错如何解决-优雅草卓伊凡
flutter开发中Use ‘const’ with the constructor to improve performance. Try adding the ‘const’ keyword to the constructor invocation.报错如何解决-优雅草卓伊凡
|
7天前
|
Dart 前端开发
【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
105 75
【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
|
5天前
|
Dart 前端开发 容器
【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
|
10天前
|
缓存 前端开发 Android开发
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
|
7天前
|
缓存 前端开发 IDE
【06】flutter完成注册页面-密码登录-手机短信验证-找回密码相关页面-并且实现静态跳转打包demo做演示-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【06】flutter完成注册页面-密码登录-手机短信验证-找回密码相关页面-并且实现静态跳转打包demo做演示-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【06】flutter完成注册页面-密码登录-手机短信验证-找回密码相关页面-并且实现静态跳转打包demo做演示-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
|
Android开发
【错误记录】Android Studio 创建 Flutter 应用被卡住 ( 更新 Flutter 插件 | 命令行创建 | 断网 )
【错误记录】Android Studio 创建 Flutter 应用被卡住 ( 更新 Flutter 插件 | 命令行创建 | 断网 )
340 0
【错误记录】Android Studio 创建 Flutter 应用被卡住 ( 更新 Flutter 插件 | 命令行创建 | 断网 )
|
13天前
|
前端开发 Java 开发工具
【03】完整flutter的APP打包流程-以apk设置图标-包名-签名-APP名-打包流程为例—-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈 章节内容【03】
【03】完整flutter的APP打包流程-以apk设置图标-包名-签名-APP名-打包流程为例—-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈 章节内容【03】
【03】完整flutter的APP打包流程-以apk设置图标-包名-签名-APP名-打包流程为例—-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈 章节内容【03】
|
3月前
|
Android开发 iOS开发 容器
鸿蒙harmonyos next flutter混合开发之开发FFI plugin
鸿蒙harmonyos next flutter混合开发之开发FFI plugin
|
14天前
|
Dart 前端开发 Android开发
【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
|
15天前
|
Dart 前端开发 架构师
【01】vs-code如何配置flutter环境-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈-供大大的学习提升
【01】vs-code如何配置flutter环境-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈-供大大的学习提升

热门文章

最新文章

  • 1
    【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
  • 2
    【01】vs-code如何配置flutter环境-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈-供大大的学习提升
  • 3
    flutter开发-figma交互设计图可以转换为flutter源代码-如何将设计图转换为flutter源代码-优雅草央千澈
  • 4
    【03】完整flutter的APP打包流程-以apk设置图标-包名-签名-APP名-打包流程为例—-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈 章节内容【03】
  • 5
    【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
  • 6
    【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
  • 7
    【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
  • 8
    【06】flutter完成注册页面-密码登录-手机短信验证-找回密码相关页面-并且实现静态跳转打包demo做演示-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
  • 9
    flutter开发中Use ‘const’ with the constructor to improve performance. Try adding the ‘const’ keyword to the constructor invocation.报错如何解决-优雅草卓伊凡
  • 10
    程序员必下20本电子书:Java手册、Flutter最佳实践、AIoT开发手册... | 1024程序员节技术礼包之二