赞
踩
点击上方蓝字关注我,知识会给你力量
在鸿蒙中开发Flutter项目,一个最大的问题,就是「不太会写鸿蒙代码」,这对于一个Flutter开发者来说,虽然不是一件很麻烦的事,但由于现在鸿蒙的版本和文档还略有一些混乱,所以要写好还是有一些麻烦的,所以,秉着能用工具解决的问题就不要自己写的原则,我们参考Native的Flutter Channel的实现,也就是pigeon的方式,不熟悉的同学可以参考我之前的文章。
这套东西在鸿蒙中也有的适配,可以一键生成ets代码,方便我们进行多端复用,项目地址如下。
https://gitee.com/openharmony-sig/flutter_packages/tree/master/packages/pigeon
在鸿蒙中使用也非常简单,指定引用即可,代码如下所示。
- yaml
- pigeon:
- git:
- url: "https://gitee.com/openharmony-sig/flutter_packages.git"
- path: "packages/pigeon"
pub get之后,参考我们之前的实现,创建一个接口协议文件,这里就用之前的来示例。
- dart
- import 'package:pigeon/pigeon.dart';
-
- @HostApi()
- abstract class NativeNetApi {
- @async
- String getNativeNetBridge(String path, Map<String, Object> params);
-
- @async
- String postNativeNetBridge(String path, Map<String, Object> params);
-
- void doActionUrlCall(String actionUrl);
- }
接下来执行命令:
- shell
- flutter pub run pigeon --input lib/native_api.dart --arkts_out lib/native_channel.ets --dart_out lib/native_channel.dart
执行完成后,就会在指定目录下生成我们需要的Channel文件,dart代码我就不贴了,和之前文章中的一样,我们来看下鸿蒙的代码。
- arkts
- import StandardMessageCodec from '@ohos/flutter_ohos/src/main/ets/plugin/common/StandardMessageCodec';
- import BasicMessageChannel, { Reply } from '@ohos/flutter_ohos/src/main/ets/plugin/common/BasicMessageChannel';
- import { BinaryMessenger,TaskQueue } from '@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryMessenger';
- import MessageCodec from '@ohos/flutter_ohos/src/main/ets/plugin/common/MessageCodec';
- import { ByteBuffer } from '@ohos/flutter_ohos/src/main/ets/util/ByteBuffer';
-
-
- /** Error class for passing custom error details to Flutter via a thrown PlatformException. */
- export class FlutterError implements Error {
-
- /** The error code. */
- public code: string;
-
- /** The error name. */
- public name: string;
-
- /** The error message. */
- public message: string;
- /** The error stack. */
- public stack?: string;
-
- constructor(code: string, name: string, message: string, stack: string)
- {
- this.code = code;
- this.name = name;
- this.message = message;
- this.stack = stack;
- }
- }
-
- function wrapError(error: Error): Array<Object> {
- let errorList: Array<Object> = new Array<Object>(3);
- if (error instanceof FlutterError) {
- let err: FlutterError = error as FlutterError;
- errorList[0] = err.code;
- errorList[1] = err.name;
- errorList[2] = err.message;
- } else {
- errorList[0] = error.toString();
- errorList[1] = error.name;
- errorList[2] = "Cause: " + error.message + ", Stacktrace: " + error.stack;
- }
- return errorList;
- }
-
- export interface Result<T> {
- success( result: T ): void;
-
- error( error: Error): void;
- }
- /* Generated abstract class from Pigeon that represents a handler of messages from Flutter.*/
- export abstract class NativeNetApi {
-
- abstract getNativeNetBridge(path: string , params: Map<string, Object> , result: Result<string>): void;
-
- abstract postNativeNetBridge(path: string , params: Map<string, Object> , result: Result<string>): void;
-
- abstract doActionUrlCall(actionUrl: string ): void;
- /** The codec used by NativeNetApi. */
- static getCodec(): MessageCodec<Object>{
- return new StandardMessageCodec();
- }
- /*Sets up an instance of `NativeNetApi` to handle messages through the `binaryMessenger`.*/
- static setup(binaryMessenger: BinaryMessenger, api: NativeNetApi | null): void {
- {
- let channel: BasicMessageChannel<Object> =
- new BasicMessageChannel(
- binaryMessenger, "dev.flutter.pigeon.test1.NativeNetApi.getNativeNetBridge", NativeNetApi.getCodec());
- if (api != null) {
- channel.setMessageHandler({
- onMessage(message: Object ,reply: Reply<Object> ) {
- let args: Array<Object> = message as Array<Object>;
- class ResultImp implements Result<string>{
- success(result: string): void {
- let res: Array<Object> = [];
- res.push(result);
- reply.reply(res);
- }
-
- error(error: Error): void {
- let wrappedError: Array<Object> = wrapError(error);
- reply.reply(wrappedError);
- }
- }
- let resultCallback: Result<string> = new ResultImp();
-
- api!.getNativeNetBridge(args[0] as string, args[1] as Map<string, Object>, resultCallback);
- } });
- } else {
- channel.setMessageHandler(null);
- }
- }
- {
- let channel: BasicMessageChannel<Object> =
- new BasicMessageChannel(
- binaryMessenger, "dev.flutter.pigeon.test1.NativeNetApi.postNativeNetBridge", NativeNetApi.getCodec());
- if (api != null) {
- channel.setMessageHandler({
- onMessage(message: Object ,reply: Reply<Object> ) {
- let args: Array<Object> = message as Array<Object>;
- class ResultImp implements Result<string>{
- success(result: string): void {
- let res: Array<Object> = [];
- res.push(result);
- reply.reply(res);
- }
-
- error(error: Error): void {
- let wrappedError: Array<Object> = wrapError(error);
- reply.reply(wrappedError);
- }
- }
- let resultCallback: Result<string> = new ResultImp();
-
- api!.postNativeNetBridge(args[0] as string, args[1] as Map<string, Object>, resultCallback);
- } });
- } else {
- channel.setMessageHandler(null);
- }
- }
- {
- let channel: BasicMessageChannel<Object> =
- new BasicMessageChannel(
- binaryMessenger, "dev.flutter.pigeon.test1.NativeNetApi.doActionUrlCall", NativeNetApi.getCodec());
- if (api != null) {
- channel.setMessageHandler({
- onMessage(message: Object ,reply: Reply<Object> ) {
- let args: Array<Object> = message as Array<Object>;
- let res: Array<Object> = [];
- try {
- api!.doActionUrlCall(args[0] as string);
- res.push(null);
- }
- catch (error) {
- let wrappedError: Array<Object> = wrapError(error);
- res = wrappedError;
- }
- reply.reply(res);
- } });
- } else {
- channel.setMessageHandler(null);
- }
- }
- }
- }

整体代码和Java的代码很类似,阅读基本没什么障碍,使用方式也和Native保持一致,通过调用setup方法,传入接口的实现即可,这里就不赘述了。
这样一来,我们的通信协议就打通了,Flutter的代码基本可以无损迁移,在鸿蒙侧,只需要根据协议实现对应的Channel接口即可,这样就完成了Android、iOS、鸿蒙的UI多端统一,Flutter & 鸿蒙,真香。
向大家推荐下我的网站 https://www.yuque.com/xuyisheng 点击原文一键直达
专注 Android-Kotlin-Flutter 欢迎大家访问
往期推荐
本文原创公众号:群英传,授权转载请联系微信(Tomcat_xu),授权后,请在原创发表24小时后转载。
< END >
作者:徐宜生
更文不易,点个“三连”支持一下
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。