写点什么

前端技术:一文带你掌握 Flutter 插件开发新姿势

2021 年 5 月 05 日

前端技术:一文带你掌握Flutter插件开发新姿势

概述


随着开发技术的发展,几乎所有主流的开发语言都有自己的包管理工具。Node 开发有 npm、Android 开发有 Gradle,Flutter 也有自己的 Dart Packages 仓库。插件的开发和复用能够提高开发效率,降低工程的耦合度,像网络请求(http)、用户授权(permission_handler)等客户端开发常用的功能模块,我们只需要引入对应插件就可以为项目快速集成相关能力,从而专注于具体业务功能的实现。


除了使用仓库中的流行组件以外,在 Flutter 项目开发过程中面对通用业务逻辑拆分、或者需要对原生能力封装等场景时,开发者仍然需要开发新的组件。本文以一个具体的 native_image_view 插件为例,将从 Flutter 组件的创建、开发、测试和发布等多个方面进行介绍,力图完整的展示整个 Flutter 组件的开发和发布流程。


Flutter 与 Native 通信


在 Flutter 插件开发过程中,几乎都会需要进行 Flutter 与 Native 端的数据交互,因此在进行插件开发之前,我们先简单了解下 Platform Channel 机制


Flutter 与 Native 的通信是通过 Platform Channel 实现的,它是一种 C/S 模型,其中 Flutter 作为 Client,iOS 和 Android 平台作为 Host,Flutter 通过该机制向 Native 发送消息,Native 在收到消息后调用平台自身的 API 进行实现,然后将处理结果再返回给 Flutter 页面。



Flutter 中的 Platform Channel 机制提供了三种交互方式:


  • BasicMessageChannel :用于传递字符串和半结构化信息;

  • MethodChannel :用于传递方法调用和处理回调;

  • EventChannel:用于数据流的监听与发送。


这三种 channel 虽然用途不同,但都包含了三个重要的成员变量:


(1)String name


表示 channel 的名字,在一个项目中可能会有很多的 channel,每个 channel 都应该使用唯一的命名标识,否则可能会被覆盖。推荐的命名方式是组织名称加插件的名称,例如:com.tencent.game/native_image_view,如果一个插件中包含了多个 channel 可再根据功能模块进一步进行区分。


(2)BinaryMessager messager


作为 Native 与 Flutter 通信的载体,能够将 codec 转换后的二进制数据在 Native 与 Flutter 之间进行传递。每个 channel 在初始化时都要生成或提供对应的 messager,如果 channel 注册了对应的 handler,则 messager 会维护一个 name 与 handler 的映射关系。


Native 平台在收到对方发来的消息后,meesager 会将消息内容分发给对应的 handler 进行处理,在处理完成后还可以通过回调方法 result 将处理结果返回给 Flutter。



(3)MessageCodec/MethodCodec codec


用于 Native 与 Flutter 通信过程中的编解码,在发送方能够将 Flutter(或 Native)的基础类型编码为二进制进行数据传输,在接收方 Native(或 Flutter)将二进制转换为 handler 能够识别的基础类型。


注:本文实现的 native_image_share 插件仅用到了最为常用的 MethodChannel 通信,Flutter 通过 MethodChannel 将远程图片地址或本地图片文件名传递给原生侧,iOS 和 Android 平台获取到图片后转换为二进制并通过 result 返回。更多关于 MessageChannel 和 EventChannel 的示例可以文末提供参考扩展阅读。


插件创建


Flutter 组件根据是否包含原生代码可分为两种:


  • Flutter Package(包):仅包含 dart 代码,一般是对 flutter 特定功能的封装实现,例如用于网络请求的 http 包。

  • Flutter Plugin(插件):除了 dart 代码之外,还包含了 Android 和 iOS 平台的代码实现,常用于将客户端原生的能力进行封装,然后提供给 flutter 项目使用。例如用于判断键盘可见状态的 flutter_keyboard_visibility 插件,就是分别在 iOS 和 Android 端监听了键盘的打开和关闭事件,然后将对应事件通过 Platform Channel 传递给 Flutter 项目。



Flutter 插件可以通过 Android Studio 创建(需要在 Android Studio 中先安装 Dart 和 Flutter 插件),或者使用命令行创建。


1. 创建 Dart 包


使用--template=package 声明创建的是只包含 dart 代码的 package。


flutter create --template=package hello
复制代码



lib 目录用于存放 package 的代码实现,Flutter 脚手架会自动生成一个与 package 同名的 dart 文件。

pubspec.yaml 文件想必做过 Flutter 开发的同学都非常熟悉,我们开发 package 所依赖的 package 或者 plugin 都需要在该文件中声明。


2. 创建 Flutter 插件


  • 使用--template=plugin 声明创建的是同时包含了 iOS 和 Android 代码的 plugin;

  • 使用--org 选项指定组织,一般采用反向域名表示法;

  • 使用-i 选项指定 iOS 平台开发语言,objc 或者 swift;

  • 使用-a 选项指定 Android 平台开发语言,java 或者 kotlin。

flutter create --template=plugin --org com.tencent.game -i objc -a java native_image_view
复制代码



相比 Package,我们可以看到 Plugin 多出了一些目录,android 目录用于 Android 平台的代码实现,ios 目录用于 iOS 平台的代码实现,example 目录用于该组件的调试。


注:Flutter 脚手架在创建 Plugin 时默认实现了一个获取系统版本号的示例,该示例的原理是分别在 iOS 和 Android 平台获取到系统版本号,然后通过 MethodChannel 调用返回给 Flutter 平台显示。


插件开发


Plugin 和 Package 的开发和发布流程基本一致,相比之下 Plugin 还涉及到 iOS 和 Android 的开发,实现起来要更加复杂一些。


在 Flutter 嵌入原生项目的场景中,比较常见的一个问题是:Flutter 和原生项目中都使用了同一张图片时,两侧会分别进行存储,即该图片会被存储两次。不同于 Weex、Hippy 等基于 JS 的跨平台框架是依赖于原生进行图片的获取和显示,Flutter 是自行进行图片的管理并直接通过 Skia 引擎直接进行绘制的。


针对这一问题,本文将开发一个 Flutter 插件(native_image_view),把 Flutter 图片的下载和缓存工作交给 Native 实现,Flutter 端则仅负责图片的绘制。此外,我们还可以定义一个特殊协议,用于处理本地图片的调用,同时解决 Flutter 无法复用原生项目本地图片的问题。



注:本文开发的插件仅用于介绍插件的开发和发布流程,不建议在生成环境中直接使用,关于图片二次缓存问题还可以参考扩展阅读中关于 Texture(外接纹理)的文章。


头图:Unsplash

作者:赵哲

原文:https://mp.weixin.qq.com/s/mRXDKvyj_3pDjxM_axTDmQ

原文:前端技术:一文带你掌握 Flutter 插件开发新姿势

来源:云加社区 - 微信公众号 [ID:QcloudCommunity]

转载:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

2021 年 5 月 05 日 07:071

评论

发布
暂无评论
发现更多内容

将原则纳入到架构的生命中

soolaugust

架构 思考 设计

云图说 | 云上资源管控有神器!关于IAM,你想知道的都在这里!

华为云开发者社区

服务 权限管理 iam

Shell脚本命令常用技巧

MySQL从删库到跑路

shell脚本编写

图文回顾丨北京「解构云原生:企业数字化转型新支点」沙龙

RancherLabs

k8s rancher

好久不见!这份Spring全家桶、Docker、Redis架构大礼包免费赠送

Java架构之路

Java 程序员 架构 面试 编程语言

EMAS远程日志 - 移动端问题排查利器

应用研发平台EMAS

阿里云 运维 日志 监控告警 应用

从源码的角度搞懂 Java 动态代理!

Java架构师迁哥

一文为你详解Unique SQL原理和应用

华为云开发者社区

数据库 sql unique

第13周作业

饭桶

建信金科大咖访谈:金融衍生品定价与建行实践

金科优源汇

金融科技 金融创新

为了SpringBoot提交Tomcat执行,我总结了这么多

小Q

tomcat 学习 面试 微服务 springboot

面试被问高并发一脸懵?那是你没看过我整理得高并发回答模板

小Q

Java 学习 面试 高并发 性能调优

太赞了!滴滴开源了一套分布式ID的生成系统...

Java架构师迁哥

面向全场景模块化设计 京东智联云的服务器部署有多灵活?

京东科技开发者

服务器 云主机

耗时一个月整理的97道大厂Java核心面试题出炉,精心整理,无偿分享

Java架构之路

Java 程序员 架构 面试 编程语言

Java进阶文档:彻底搞懂JVM+Linux+MySQL+Netty+Tomcat+并发编程

Java架构之路

Java 程序员 架构 面试 编程语言

第十三周学习总结

饭桶

传统巨头抢占区块链场景高地 医疗、汽车、金融成为热门赛道

CECBC区块链专委会

区块链 金融

我和阿里P7差的不是薪资?而是Redis+微服务+Nginx+MySQL+Tomcat

Java架构之路

Java 程序员 架构 面试 编程语言

住建部等六部门:广泛运用区块链等技术,建设智慧物业管理服务平台

CECBC区块链专委会

物业生活

浅谈JDK并发包下面的分治思想及分治思想在高并发场景的运用

AI乔治

Java 架构 jdk 分布式 多线程与高并发

搭建网站/APP最全准备攻略

前嗅大数据

小程序 建站 APP发布

Java中多线程安全问题实例分析

叫练

Java 多线程 什么是多线程 多线程与高并发

附PPT丨AI和云原生时代的数据库进化之路

dbaplus社群

数据库 云原生

即构实时音视频多中心调度设计

ZEGO即构

如何在数智化时代少走弯路? 这里有100个案例可以借鉴

京东科技开发者

DevOps 云原生

云南区块链电子发票全面推广啦!

CECBC区块链专委会

区块链 纳税人

80%Java开发者面试都问的SpringBoot你竟不会?看完这些笔记足以

Java架构之路

Java 程序员 架构 面试 编程语言

倾斜摄影实景三维在智慧工厂 Web 3D GIS 数字孪生应用

一只数据鲸鱼

GIS 数字化 数据可视化 3D渲染 数字工厂

VACUUM无法从表中删除死元组的三个原因

PostgreSQLChina

数据库 postgresql

一口气说出四种幂等性解决方案,面试官露出了姨母笑~

不才陈某

Java 分布式 接口

前端技术:一文带你掌握Flutter插件开发新姿势-InfoQ