【Flutter】三个Channel(Android-java / Ios-swift)

Channel

实现与原生通信

【1】MethodChannel

flutter MethodChannel官方文档
通过MethodChannel来传递数据,调用方法

案例

分别调用Android和Ios原生的获取电量的方法

Flutter端

实例一个MethodChannel, 唯一标识name,定义方法名称getBatteryLevel
在这里插入图片描述
methodchannel.invokeMethod(name)来调用方法

  static const platform = MethodChannel('sample.flutter.dev/battery');static const method = 'getBatteryLevel';String _batteryLevel = 'Unknown battery level';Future<void> _getBatteryLevel() async {String batteryLevel;try {final result = await platform.invokeMethod<int>(method);batteryLevel = 'Battery level at $result';} on PlatformException catch (e) {batteryLevel = "Failed to get battery level: '${e.message}";}setState(() {_batteryLevel = batteryLevel;});}

界面操作

  Widget build(BuildContext context) {return Material(child: Column(mainAxisAlignment: MainAxisAlignment.spaceEvenly,children: [ElevatedButton(onPressed: _getBatteryLevel,child: const Text('Get Battery Level'),),Text(_batteryLevel),],),);}
Android端

在这里插入图片描述

    private static final String CHANNEL = "sample.flutter.dev/battery";private MethodChannel methodChannel;private static final String METHOD = "getBatteryLevel";@Overridepublic void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {super.configureFlutterEngine(flutterEngine);BinaryMessenger binaryMessenger = flutterEngine.getDartExecutor().getBinaryMessenger();methodChannel = new MethodChannel(binaryMessenger, CHANNEL);methodChannel.setMethodCallHandler((call, result) -> {});}

在这里插入图片描述

if (call.method.equals(METHOD)) {int batteryLevel = getBatteryLevel();if (batteryLevel != -1) {result.success(batteryLevel);} else {result.error("UNAVAILABLE", "Battery level not avaiable", null);}} else {result.notImplemented();}
private int getBatteryLevel() {int batteryLevel = -1;if (VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {BatteryManager batteryManager = (BatteryManager) getSystemService(BATTERY_SERVICE);batteryLevel = batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY);} else {IntentFilter intentFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);Intent intent = new ContextWrapper(getApplicationContext()).registerReceiver(null, intentFilter);batteryLevel = (intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) * 100) /intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);}return batteryLevel;}
Ios端

实例FlutterMethodChannel
在这里插入图片描述

override func application(_ application: UIApplication,didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {let method : String = "getBatteryLevel"let controller : FlutterViewController = window?.rootViewController as! FlutterViewControllerlet batteryChannel = FlutterMethodChannel(name: "sample.flutter.dev/battery", binaryMessenger: controller.binaryMessenger)batteryChannel.setMethodCallHandler({(call: FlutterMethodCall, result: @escaping FlutterResult) -> Void inguard call.method == method else {result(FlutterMethodNotImplemented)return}self.receiveBatteryLevel(result: result)})GeneratedPluginRegistrant.register(with: self)return super.application(application, didFinishLaunchingWithOptions: launchOptions)}

定义获取电量的方法

func receiveBatteryLevel(result: FlutterResult) -> Void {let device = UIDevice.currentdevice.isBatteryMonitoringEnabled = trueif device.batteryState == UIDevice.BatteryState.unknown {result(FlutterError(code: "UNAVAILABLE", message: "Battery level not available.", details: nil))} else {result(Int(device.batteryLevel * 100))}}
运行测试

在这里插入图片描述

【2】EventChannel

墙外的参考文章
区别MethodChannel,它是continuously
采用event streams

案例

在原生端(Android&Ios)会有个计时器,不停的传时间给Flutter端,Flutter端显示出来

Flutter端

实例一个EventChannel,唯一标识name
在这里插入图片描述

  late EventChannel eventChannel;void initState() {eventChannel = const EventChannel('timeHandlerEvent');super.initState();}

在Flutter注册监听
在这里插入图片描述

Stream<String> get streamTimeFromNative =>eventChannel.receiveBroadcastStream().map((event) => event.toString());Widget build(BuildContext context) {return Scaffold(body: Center(child: StreamBuilder<String>(stream: streamTimeFromNative,builder: (BuildContext context, AsyncSnapshot<String> snapshot) {if (snapshot.hasData) {return Text('${snapshot.data}',style: Theme.of(context).textTheme.headlineMedium,);} else {return const CircularProgressIndicator();}},),),);}
Ios端

实例一个FlutterEventChannel,加上唯一标识timeHandlerEvent
在这里插入图片描述

let controller : FlutterViewController = window?.rootViewController as! FlutterViewControllerlet eventChannel = FlutterEventChannel(name: "timeHandlerEvent", binaryMessenger: controller.binaryMessenger)

定义FlutterStreamHandler

class TimeHandler: NSObject, FlutterStreamHandler {func onCancel(withArguments arguments: Any?) -> FlutterError? {return nil}func onListen(withArguments arguments: Any?, eventSink: @escaping FlutterEventSink) -> FlutterError? {return nil}}

每间隔1秒发送一次当前时间

    class TimeHandler: NSObject, FlutterStreamHandler {var timer = Timer()private var eventSink: FlutterEventSink?func onCancel(withArguments arguments: Any?) -> FlutterError? {eventSink = nilreturn nil}func onListen(withArguments arguments: Any?, eventSink: @escaping FlutterEventSink) -> FlutterError? {self.eventSink = eventSinkself.timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true, block: {_ in let dateFormat = DateFormatter()dateFormat.dateFormat = "HH:mm:ss"let time = dateFormat.string(from: Date())eventSink(time)})return nil}}

注册监听

eventChannel.setStreamHandler(TimeHandler())

在这里插入图片描述

Android端

new 一个EventChannel对象
在这里插入图片描述
在channel注册一个stream Handler
在这里插入图片描述
在这里插入图片描述

        EventChannel.StreamHandler streamHandler = new EventChannel.StreamHandler() {@Overridepublic void onListen(Object arguments, EventChannel.EventSink events) {}@Overridepublic void onCancel(Object arguments) {}};eventChannel.setStreamHandler(streamHandler);

不断将当前时间返回
在这里插入图片描述

EventChannel.StreamHandler streamHandler = new EventChannel.StreamHandler() {private final Handler handler = new Handler(Looper.getMainLooper());private EventChannel.EventSink eventSink = null;@Overridepublic void onListen(Object arguments, EventChannel.EventSink events) {eventSink = events;Runnable runnable = new Runnable() {@Overridepublic void run() {Locale locale = new Locale("zh", "CN");SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss", locale);String time = dateFormat.format(new Date());events.success(time);handler.postDelayed(this, 1000);}};handler.postDelayed(runnable, 1000);}@Overridepublic void onCancel(Object arguments) {eventSink = null;}};eventChannel.setStreamHandler(streamHandler);
运行测试

在建立好EventChannel之后,运行项目。
在这里插入图片描述
获取到当前的时间,并且不停的

【3】BasicMessageChannel

参考文章
约定一种数据格式,来互相传递数据

案例

传递Map数据到Android/Ios端,再解析并返回数据到Flutter端

Flutter端

构建BasicMessageChannel, 唯一标识name,约定数据格式StandardMessageCodec

static const messageChannel =BasicMessageChannel('basic_message_channel', StandardMessageCodec());

发送数据

Map<String, dynamic> message = {"name": "apple","time": "2024-04-09 12:30:00"};
messageChannel.send(arguments)

接收数据

Map reply = await messageChannel.send(arguments) as Map;

在这里插入图片描述

Android 端

接收数据

messageChannel.setMessageHandler((message, reply) -> {});

发送数据

reply.reply(resultMap);

在这里插入图片描述

package com.example.basic_message_channel_example;import android.os.Bundle;import androidx.annotation.NonNull;
import androidx.annotation.Nullable;import java.sql.Timestamp;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;import io.flutter.embedding.android.FlutterActivity;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.plugin.common.BasicMessageChannel;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.StandardMessageCodec;public class MainActivity extends FlutterActivity {@Overridepublic void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {super.configureFlutterEngine(flutterEngine);BinaryMessenger binaryMessenger = Objects.requireNonNull(getFlutterEngine()).getDartExecutor().getBinaryMessenger();BasicMessageChannel<Object> messageChannel = new BasicMessageChannel<Object>(binaryMessenger, "basic_message_channel", StandardMessageCodec.INSTANCE);messageChannel.setMessageHandler((message, reply) -> {Map<Object, Object> arguments = (Map<Object, Object>) message;assert message != null;String name = (String) arguments.get("name");assert name != null;if (name.equals("apple")) {Map<String, Object> resultMap = new HashMap<>();String timeStr = (String) arguments.get("time");Timestamp timestamp = Timestamp.valueOf(timeStr);resultMap.put("message", "i eat the " + name + " at " + timestamp.toString());resultMap.put("code", 200);reply.reply(resultMap);} else {Map<String, Object> resultMap = new HashMap<>();resultMap.put("message", "i dislike " + name);resultMap.put("code", 500);reply.reply(resultMap);}});}
}
Ios 端

构建通道

let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
let basicMessageChannel = FlutterBasicMessageChannel(name: channelName, binaryMessenger: controller.binaryMessenger)

接收数据

      basicMessageChannel.setMessageHandler { message, reply in}

返回数据

reply(result)

在这里插入图片描述

import UIKit
import Flutter@available(iOS 15.0, *)
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {override func application(_ application: UIApplication,didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {let channelName : String = "basic_message_channel"let controller : FlutterViewController = window?.rootViewController as! FlutterViewControllerlet basicMessageChannel = FlutterBasicMessageChannel(name: channelName, binaryMessenger: controller.binaryMessenger)basicMessageChannel.setMessageHandler { message, reply inif let data = message as? Dictionary<String, Any> {let name: String = data["name"] as? String ?? ""if name == "apple" {let timeStr: String = data["time"] as? String ?? ""var message: String = "I eat the "message.append(name)message.append(" at ")message.append(timeStr)let result = ["code": 200, "message": message]reply(result)} else {var message = "I dislike "message.append(name)let result = ["code": 500, "message": message]reply(result)}}}GeneratedPluginRegistrant.register(with: self)return super.application(application, didFinishLaunchingWithOptions: launchOptions)}
}
运行测试

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

总结

MethodChannel 定义方法名调用
EventChannel 持续监听数据传递
BasicMessageChannel 约定一种数据格式,传递数据

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/804255.shtml

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

相关文章

JavaScript ECMAScript标准的与时俱进:从ES6至ES14的革新之路与关键技术特性剖析

ECMAScript&#xff08;通常缩写为ES&#xff09;是一种标准化的脚本语言规范&#xff0c;由ECMA International&#xff08;前身为European Computer Manufacturers Association&#xff0c;欧洲计算机制造商协会&#xff09;制定。自1997年发布首个版本以来&#xff0c;ECMAS…

设计模式之创建型模式---建造者模式

文章目录 建造者模式概述经典的建造者模式建造者模式的变种总结 建造者模式概述 建造者模式是一种广泛使用的设计模式&#xff0c;在三方开源库和各种SDK中经常见到。建造者设计模式在四人帮的经典著作《设计模式&#xff1a;可复用面向对象软件基础》中被提及&#xff0c;它的…

搭建前后端的链接(java)

搭建前后端的链接(java) 一.前提 1.1 javaEE 搭建前后端的链接首先需要用到javaEE&#xff0c;也就是java企业版&#xff0c;也就是java后端(后端javaSE) 利用javaEE和前端交互&#xff0c;javaSE和数据库交互&#xff0c;javaSE和javaEE之间再进行交互就实现了前后端的交互…

语音识别(录音与语音播报)

语音识别&#xff08;录音与语音播报&#xff09; 简介 语音识别人工智能技术的应用领域非常广泛&#xff0c;常见的应用系统有&#xff1a;语音输入系统&#xff0c;相对于键盘输入方法&#xff0c;它更符合人的日常习惯&#xff0c;也更自然、更高效&#xff1b;语音控制系…

JVM—垃圾收集器

JVM—垃圾收集器 什么是垃圾 没有被引用的对象就是垃圾。 怎么找到垃圾 引用计数法 当对象引用消失&#xff0c;对象就称为垃圾。 对象消失一个引用&#xff0c;计数减去一&#xff0c;当引用都消失了&#xff0c;计数就会变为0.此时这个对象就会变成垃圾。 在堆内存中主…

C++设计模式:抽象工厂模式(七)

1、定义与动机 抽象工厂定义&#xff1a;提供一个接口&#xff0c;让该接口负责创建一系列“相关或者相互依赖的对象”&#xff0c;无需指定它们具体的类动机&#xff1a; 在软件系统中&#xff0c;经常面临着“一系列相互依赖的对象”的创建工作&#xff1b;同时&#xff0c;…

人工智能——深度学习

4. 深度学习 4.1. 概念 深度学习是一种机器学习的分支&#xff0c;旨在通过构建和训练多层神经网络模型来实现数据的高级特征表达和复杂模式识别。与传统机器学习算法相比&#xff0c;深度学习具有以下特点&#xff1a; 多层表示学习&#xff1a;深度学习使用深层神经网络&a…

麒麟KOS删除鼠标右键新建菜单里不需要的选项

原文链接&#xff1a;麒麟KOS删除鼠标右键新建菜单里不需要的选项 Hello&#xff0c;大家好啊&#xff01;在日常使用麒麟KOS操作系统时&#xff0c;我们可能会发现鼠标右键新建菜单里包含了一些不常用或者不需要的选项。这不仅影响我们的使用效率&#xff0c;也让菜单显得杂乱…

新能源电力行业设备点巡检系统的应用

新能源电力行业正日益成为全球能源结构的重要支柱&#xff0c;其设备点巡检系统作为确保电力设施安全、高效运行的关键环节&#xff0c;正受到业界的广泛关注和应用。 设备点巡检系统是一种集数据采集、实时监控、智能分析于一体的现代化管理工具。在新能源电力行业中&#xff…

Java常见算法_常见的查找算法和排序算法——简介及代码演示

在本文中我将介绍Java中的常见算法&#xff0c;查找算法包括基本查找、二分查找、插值查找和分块查找。排序算法包括冒泡排序、选择排序、插入排序和快速排序 查找算法&#xff1a; 1.基本查找&#xff1a; 代码&#xff1a; public class BasicSearchDemo {public static …

SpringMVC:搭建第一个web项目并配置视图解析器

&#x1f449;需求&#xff1a;用spring mvc框架搭建web项目&#xff0c;通过配置视图解析器达到jsp页面不得直接访问&#xff0c;实现基本的输出“hello world”功能。&#x1f469;‍&#x1f4bb;&#x1f469;‍&#x1f4bb;&#x1f469;‍&#x1f4bb; 1 创建web项目 1…

如何解决Python包管理问题:ERROR: Could not find a version that satisfies the requirement

如何解决Python包管理问题&#xff1a;“ERROR: Could not find a version that satisfies the requirement” 文章目录 如何解决Python包管理问题&#xff1a;“ERROR: Could not find a version that satisfies the requirement”错误描述问题分析解决方案检查包名确保网络连…

【JVM】面试题汇总

JVM1. 什么是JVM&#xff1f;2. 了解过字节码文件的组成吗&#xff1f;3. 什么是运行时数据区4. 哪些区域会出现内存溢出5. JVM在JDK6-8之间在内存区域上有什么不同 6. 类的生命周期 7. 什么是类加载器&#xff1f;类加载器有哪几种 8. 什么是双亲委派机制&#xff1f;有什么好…

“国字号”荣誉、全国试点,侨乡群众身边的“放心”公证处

日前&#xff0c;我市五邑公证处获评“全国公共法律服务工作先进集体”称号。 走进公证处&#xff0c;首先映入眼帘的是一间宽敞明亮的大厅&#xff0c;办证点内还设置多个独立办证室&#xff0c;工作人员热情地为前来办理业务的市民提供专业、人性化的公证服务。江门市五邑公证…

Windows上面搭建Flutter Android运行环境

Flutter Android环境搭建 电脑上面安装配置JDK电脑上下载安装Android Studio电脑上面下载配置Flutter Sdk &#xff08;避坑点一&#xff09;下载SDK配置对应的环境变量 到path 电脑上配置Flutter国内镜像运行 flutter doctor命令检测环境是否配置成功创建运行Flutter项目&…

ARM单片机的GPIO口在控制不同LED、按键时的设置

个人备忘&#xff0c;不喜勿喷。 GPIO口在驱动共阴极、共阳极LED灯时需要不同的初始化设置 对于这一类的led灯&#xff1a; 最好选择推挽、上拉、高速输出&#xff0c;同时IO口初始化时需要拉高。 上面这种需要下拉输入&#xff1b; 上图这种需要上拉输入&#xff0c;这样才…

vue点击上传图片并实现图片预览功能,并实现多张图片放到一个数组中进行后端请求(使用原生input)

一、将 File 对象转成 BASE64 字符串 &#xff08;FileReader&#xff09; <template><div><!-- 用来显示封面的图片 --><!-- <img src"/assets/images/cover.jpg" alt"" class"cover-img" ref"imgRef" />…

html基础(2)(链接、图像、表格、列表、id、块)

1、链接 <a href"https://www.example.com" target"_blank" title"Example Link">Click here</a> 在上示例中&#xff0c;定义了一个链接&#xff0c;在网页中显示为Click here&#xff0c;鼠标悬停指示为Example Link&#xff0c…

Java(多线程)

一、基本概念 进程&#xff1a;一个具有一定独立功能的程序关于某个数据集合的一次运行活动。它是操作系统动态执行的基本单元&#xff0c;在传统的操作系统中&#xff0c;进程既是基本的分配单元&#xff0c;也是基本的执行单元。线程&#xff1a;操作系统中能够进行运算的最…

java Web课程管理系统用eclipse定制开发mysql数据库BS模式java编程jdbc

一、源码特点 JSP 课程管理系统是一套完善的web设计系统&#xff0c;对理解JSP java 编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,eclipse开发&#xff0c;数据库为Mysql5.0&#xff0c;使用ja…