美文网首页
Android 原生混合 Flutter 开发初体验之二

Android 原生混合 Flutter 开发初体验之二

作者: _Jun | 来源:发表于2023-01-30 17:22 被阅读0次

    前言

    上篇中,我和大家分享了我对于Android原生与Flutter模块混合构建的一些经验,在本篇中,我将和大家分享Android原生和Flutter模块通信方面的经验。

    所谓通信

    事先声明,我这里所说的通信,指的就是Android原生和Flutter模块之间的方法互调,数据传递。 Flutter官方提供了Channel也即平台通道帮助开发者实现:

    • Flutter原生平台发送消息。
    • 原生平台监听通道并接收消息。然后,处理逻辑并将数据整合好之后作为响应发送回Flutter

    Flutter官方提供了三种Channel用于跨平台通信

    Channel 功能
    MethodChannel 跨平台方法互调
    EventChannel 跨平台消息传递
    BasicMessageChannel 跨平台元数据传递

    你以为我要开始 1-2-3 开始给你介绍这三种Channel了吗?不!

    官方文档在编写自定义的特定平台代码一节中,以获取原生平台电池电量为例演示了如何使用MethodChannel进行跨平台的方法调用,不难发现在MethodChannel的使用中,有两处(每个平台)使用了硬编码字符串用于各平台间的标识、匹配。这还只是调用了一个原生平台的方法,实际生产中十个,百个方法都是有可能的!

    鄙人十分讨厌这种分散的无法管理的用于标识、匹配的硬编码字符串,因为团队中英文水平参差不齐,即便都很好,谁能保证自己不会手抖拼错呢,这就增加了一个可能的出错点。因此,官网也在后半篇介绍了一种更安全的跨平台通信的方式。

    Pigeon

    Pigeon是一个用于Flutter原生平台之间建立类型安全的通信的代码生成工具,更快更易用。

    Pigeon免去了在Flutter原生之间用硬编码字符串的方式匹配通道、消息的名称和数据类型,并要求Flutter原生声明相同的参数和数据类型,生成以结构化类型安全方式发送消息的代码。

    其实,观察Pigeon生成的代码可以发现,Pigeon其实也是借助BasicMessageChannel实现通信的,只不过它以脚本的方式生成了模板代码,正是在这个过程中避免了手写硬编码可能出现的问题。

    Pigeon的使用

    添加Pigeon依赖

    dart pub add pigeon
    

    然后

    dart pub get
    

    创建pigeon文件夹并新建一个platformApi.dart文件用于声明对应的方法

    这里platformApi.dart的文件命名可自定义

    pigeon/platformApi.dart

    import 'package:pigeon/pigeon.dart';
    
    // 这是声明 Flutter 调用原生方法
    // 如果是原生调用 Flutter 方法,请使用 @FlutterApi() 注解
    @HostApi()
    abstract class AndroidBatteryApi {
      int getAndroidBattery();
    }
    

    新建Pigeon脚本用于生成对应的通信代码

    复制下方代码创建一个run_pigeon.sh文件,将下方代码复制,针对你的项目修改成对应的文件名,文件路径

    $ flutter pub run pigeon \
    
      --input pigeon/platformApi.dart \
    
      --dart_out lib/api_generated.dart \
    
      --experimental_kotlin_out android/app/src/main/kotlin/com/randalldev/native_provider/Pigeon.kt \
    
      --experimental_kotlin_package "com.randalldev.native_provider"
    

    我这里只生成了Android平台的模板代码

    pigeon工具还有其他命令选项,比如iOS平台

      --objc_header_out ios/Runner/pigeon.h \
      --objc_source_out ios/Runner/pigeon.m \
      --experimental_swift_out ios/Runner/Pigeon.swift \
    

    执行脚本,会生成各端需要的原生代码

    Windows编译环境,ASTerminal工具内直接输入下方命令

    run_pigeon.sh
    

    MacOSLiunx编译环境,ASTerminal工具内需要输入下方命令

    ./run_pigeon.sh
    

    实现原生方法的逻辑

    pigeon脚本生成代码是接口类,我们需要实现接口,并实现其内部的方法

    打开android/app/src/main/kotlin/com/randalldev/native_provider/MainActivity.kt

    使用延迟加载的方式新建一个实例,这是一种更安全更方便的写法,根据需要的参数选择内部类的方式有时也可以,关注内部实现即可

        private val batteryApi by lazy {
            object : AndroidBatteryApi {
                override fun getAndroidBatteryApi(): Long {
                    TODO("Not yet implemented")
                }
            }
        }
    

    TODO部分就是我们需要实现的Android平台的逻辑

    针对需要异步操作才能获取返回值的情况

    这种情况通常出现在一些网络操作、文件操作的情况。

    声明异步的方法

    还是之前的platformApi.dart文件,增加一个异步方法的声明

      ···
      @async
      int getAsyncAndroidBattery();
      ···
    

    运行run_pigeon.sh脚本,生成新声明的方法,并在Android平台添加实现

        private val batteryApi by lazy { 
            ···
                override fun getAsyncAndroidBattery(callback: (Long) -> Unit) {
                    TODO("Not yet implemented")
                }
            ···
        }
    

    实现异步逻辑

        private val batteryApi by lazy { 
            ···
                override fun getAsyncAndroidBattery(callback: (Long) -> Unit) {
                    // 演示代码,实际没有这样的 api
                    system.getBattery(object : BatteryResultListener {
                            override fun onSucceed(battery: Integer) {
                                callback.invoke(battery)
                            }
    
                            override fun onFailed(msg: String?) {
                                callback.invoke(-1)
                            }
                        })
                }
            ···
        }
    

    总结

    Flutter提供了Channel用于实现与原生平台的通信,但是基于我个人的技术选择,我选择了使用官方提供的代码生成工具Pigeon去生成ChannelApi 的代码。

    使用Pigeon主要是以下这几个步骤

    • 添加依赖
    • 创建pigeon相关dart文件并声明需要的方法
    • 编写并运行pigeon脚本
    • 原生平台实现Pigeon生成的抽象方法,并返回对应的数据

    参考文章

    Writing custom platform-specific code

    [Flutter] 使用 Pigeon 实现跨平台方法调用

    Pigeon

    作者:Randall_Xia
    链接:https://juejin.cn/post/7192589048727207973

    相关文章

      网友评论

          本文标题:Android 原生混合 Flutter 开发初体验之二

          本文链接:https://www.haomeiwen.com/subject/bnnmhdtx.html