zh_native_channel 0.0.3 copy "zh_native_channel: ^0.0.3" to clipboard
zh_native_channel: ^0.0.3 copied to clipboard

Reusable platform channel message framework for Flutter.

zh_native_channel #

zh_native_channel 是一个面向 Flutter 的跨端 MethodChannel 消息框架。它把一次平台调用抽象成“消息对象 + 处理器”,让 Dart、iOS、Android、Web 之间用同一套 channel name、序列化规则和注册入口通信。

配套的 zh_native_channel_generator 负责扫描 Dart 消息定义和平台 handler 标记,生成 Dart 注册代码、Swift/Kotlin/TypeScript 消息模型和平台注册代码。运行时能力由本库提供,代码生成能力由 generator 提供。

这个库能做什么 #

  • 在 Dart 侧通过 ZHNativeChannel.instance.invoke(msg) 发送业务消息到平台侧。
  • 在平台侧通过 MethodChannelMsgManager 接收 MethodChannel 调用、解析消息、查找 handler,并返回消息对象。
  • 支持平台侧主动调用 Dart,并把返回值解析为对应的 ChannelBaseMsg
  • 通过 @ChannelMsg 标记 Dart 消息类型,通过 @ChannelHandlerFor 标记 Dart handler。
  • 通过原生注释 // PlatformChannelHandler("MessageName") 标记 Swift/Kotlin/Web handler。
  • 通过配置文件生成 Dart/iOS/Android/Web 的注册代码和平台消息模型。

当前生成器支持的字段类型包括 StringintdoublenumboolMap<String, dynamic>List<...>。复杂自定义 model 的递归嵌套生成还不是当前版本的完整能力。

使用它的好处 #

直接写 MethodChannel 时,Flutter 和原生两边通常要重复维护 method name、Map 字段、注册表和类型转换。zh_native_channel 把这些约定集中到消息类和 handler 上,再由生成器产出重复代码,带来的好处是:

  • 降低手写 MethodChannel 字符串和 Map 字段不一致的风险。
  • 新增一个业务通道时,只需要新增消息类和对应 handler。
  • Dart、Swift、Kotlin、Web 使用同一套消息命名和注册入口。
  • 生成文件集中管理,业务代码更聚焦在 handler 逻辑。

快速上手 #

在 Flutter 项目中添加运行时库和生成器:

dependencies:
  zh_native_channel:
    path: ../

dev_dependencies:
  build_runner: ^2.10.4
  zh_native_channel_generator: ^0.0.1

创建消息类:

import 'package:zh_native_channel/zh_native_channel.dart';

@ChannelMsg()
class PingMsg extends ChannelBaseMsg {
  final String text;

  PingMsg({required this.text});

  static PingMsg fromMap(Map<String, dynamic> map) {
    return PingMsg(text: map['text'] as String? ?? '');
  }

  @override
  Map<String, dynamic> toMap() {
    return {'text': text};
  }
}

创建 Dart handler。如果当前消息由 Dart 处理,可以使用 @ChannelHandlerFor 注册:

@ChannelHandlerFor('PingMsg')
class PingHandler extends ChannelBaseHandler {
  @override
  Future<ChannelBaseMsg> handle(ChannelBaseMsg msg) async {
    final ping = msg as PingMsg;
    return PingMsg(text: 'dart:${ping.text}');
  }
}

创建原生 handler。iOS 示例:

import zh_native_channel

// PlatformChannelHandler("PingMsg")
final class PingMsgHandler: ChannelBaseHandler {
  func handle(
    _ message: ChannelBaseMsg,
    completion: @escaping (Result<ChannelBaseMsg, Error>) -> Void
  ) {
    guard let ping = message as? PingMsg else {
      completion(.failure(ChannelMsgError.typeMismatch(expected: "PingMsg")))
      return
    }
    completion(.success(PingMsg(text: "ios:\(ping.text)")))
  }
}

Android 示例:

import com.example.zh_native_channel.ChannelBaseHandler
import com.example.zh_native_channel.ChannelBaseMsg

// PlatformChannelHandler("PingMsg")
class PingMsgHandler : ChannelBaseHandler {
    override fun handle(message: ChannelBaseMsg): ChannelBaseMsg {
        val ping = message as PingMsg
        return PingMsg(text = "android:${ping.text}")
    }
}

生成代码后,在 Dart 侧使用生成入口:

initializeGeneratedChannels();
final channel = ZHNativeChannel.instance;
final response = await channel.invoke(PingMsg(text: 'hello'));

iOS/Android 启动阶段需要调用生成的平台注册入口,把消息和 handler 注册进原生 manager:

GeneratedChannelRegistrations.registerAll()
GeneratedChannelRegistrations.registerAll()

完整示例见 example/README.md

脚本命令 #

生成器会在项目 Makefile 中维护一段命令块。默认入口是:

ZH_NATIVE_CHANNEL_GENERATOR ?= dart run zh_native_channel_generator:generate_native_channel
ZH_NATIVE_CHANNEL_CONFIG ?= zh_native_channel_config.json

常用命令:

make gen

完整生成流程。它会依次执行 clean-generatedbuild-runner-buildcreate-platformcode-all,适合新增或修改消息后重新生成所有产物。

make clean-generated

按配置删除生成产物,不删除手写 handler。底层执行 --clean-generated-only

make build-runner-sync-config

只根据 zh_native_channel_config.json 同步 build.yaml,不执行 build_runner。底层执行 --sync-build-config-only

make build-runner-build

先同步 build.yaml,再执行 dart run build_runner build,生成 Dart 侧注册文件,例如 ChannelGeneratedRegister.g.dart

make create-platformcode-all

根据配置文件中声明的平台生成平台代码。配置里有 iOS 和 Android,就生成 Swift 和 Kotlin;如果只配置某个平台,就只生成那个平台。

make create-platformcode-ios
make create-platformcode-android
make create-platformcode-web

只生成指定平台。执行单个平台命令时,对应的 platforms.<platform> 配置必须存在。

也可以直接调用生成器:

dart run zh_native_channel_generator:generate_native_channel zh_native_channel_config.json --platform all

仓库 example 里还有一个测试脚本:

./tool/run_generation_tests.sh

它会清理示例生成产物、执行 flutter pub get、同步 build 配置、运行 build_runner、重新生成 iOS/Android 平台代码,并执行 flutter analyzeflutter test

zh_native_channel_config.json #

配置文件描述“扫描哪里”和“生成到哪里”。默认文件名是 zh_native_channel_config.json,也可以在命令里传入其他 JSON 文件路径。

example 当前配置如下:

{
  "dart": {
    "defaultOutputDirectory": "lib/base/zHNativeChannel",
    "messageScanPath": [
      "lib/base/zHNativeChannel/msgs"
    ],
    "handlerScanPath": [
      "lib/base/zHNativeChannel/handlers"
    ],
    "generatedChannelRegisterOutputPath": "lib/base/zHNativeChannel/ChannelGeneratedRegister.g.dart"
  },
  "platforms": {
    "ios": {
      "defaultOutputDirectory": "ios/Runner/zHNativeChannel",
      "scanHandlerPath": [
        "ios/Runner/zHNativeChannel/handler_ios"
      ],
      "msgsOutputPath": "ios/Runner/zHNativeChannel/msgs",
      "generatedChannelRegistrationsOutputPath": "ios/Runner/zHNativeChannel",
      "xcodeProjectPath": "ios/Runner.xcodeproj/project.pbxproj"
    },
    "android": {
      "defaultOutputDirectory": "android/app/src/main/kotlin/com/example/zh_native_channel_example/zHNativeChannel",
      "scanHandlerPath": [
        "android/app/src/main/kotlin/com/example/zh_native_channel_example/zHNativeChannel/handlers"
      ],
      "msgsOutputPath": "android/app/src/main/kotlin/com/example/zh_native_channel_example/zHNativeChannel/msgs",
      "generatedChannelRegistrationsOutputPath": "android/app/src/main/kotlin/com/example/zh_native_channel_example/zHNativeChannel",
      "packageName": "com.example.zh_native_channel_example.zHNativeChannel"
    }
  }
}

字段说明:

  • dart.defaultOutputDirectory:Dart 生成代码默认目录,默认是 lib/base/zHNativeChannel
  • dart.messageScanPath:扫描 Dart @ChannelMsg 消息类的位置。原生生成脚本用它生成 Swift/Kotlin/TypeScript 的 msg 类型,同步 build.yaml 时也会加入 build_runner 扫描范围。
  • dart.handlerScanPath:扫描 Dart @ChannelHandlerFor handler 的位置,用于生成 Dart 侧 handler 注册代码。
  • dart.generatedChannelRegisterOutputPath:Dart 侧注册文件输出路径,例如 ChannelGeneratedRegister.g.dart
  • platforms.<platform>.defaultOutputDirectory:某个平台生成代码的默认根目录。
  • platforms.<platform>.scanHandlerPath:扫描原生 handler 的目录。没有配置时会扫描配置文件所在项目,项目较大时建议显式配置。
  • platforms.<platform>.msgsOutputPath:平台 msg 文件输出目录,例如 iOS 的 PingMsg.g.swift、Android 的 PingMsg.g.kt
  • platforms.<platform>.generatedChannelRegistrationsOutputPath:平台总注册文件输出目录,例如 GeneratedChannelRegistrations.g.swiftGeneratedChannelRegistrations.g.kt
  • platforms.android.packageName:Android 生成 Kotlin 文件使用的 package,真实业务工程建议显式配置。
  • platforms.ios.xcodeProjectPath:iOS Xcode 工程文件路径,用于把生成的 Swift 文件加入 Runner target;不配置时会尝试从输出目录向上查找。
  • platforms.web.globalName:Web 端挂到 globalThis 上的全局对象名,默认是 ZHNativeChannel

所有字段都可以使用默认值,但业务项目建议至少明确配置扫描目录、平台输出目录和 Android packageName

0
likes
0
points
193
downloads

Publisher

unverified uploader

Weekly Downloads

Reusable platform channel message framework for Flutter.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

flutter, flutter_web_plugins

More

Packages that depend on zh_native_channel

Packages that implement zh_native_channel