写点什么

鸿蒙 Flutter 实战:06- 使用 ArkTs 开发 Flutter 鸿蒙插件

作者:星释
  • 2024-11-06
    浙江
  • 本文字数:2851 字

    阅读完需:约 9 分钟

鸿蒙Flutter实战:06-使用ArkTs开发Flutter鸿蒙插件

使用 ArkTs 开发 Flutter 鸿蒙平台插件

本文讲述如何开发一个 Flutter 鸿蒙插件,如何实现 Flutter 与鸿蒙的混合开发,以及双端消息通信。

Flutter 侧,编写 MethodChannel

const MethodChannel _methodChannel = MethodChannel('xxx.com/app');

/// 获取token static Future<dynamic> getToken() { return _methodChannel.invokeMethod("getPrefs", 'token'); }
/// 设置token static Future<dynamic> setToken(String token) { return _methodChannel .invokeMethod("setPrefs", {'key': 'token', 'value': token}); }
复制代码


代码生命了一个 methodChannel, 并实现了 token 存错的调用方法。

ArkTs 侧,实现调用

编写 src/main/ets/entryability/EntryAbility.ets



import { FlutterAbility, FlutterEngine } from '@ohos/flutter_ohos';import { GeneratedPluginRegistrant } from '../plugins/GeneratedPluginRegistrant';import ForestPlugin from './ForestPlugin';import { BusinessError } from '@kit.BasicServicesKit';import { window } from '@kit.ArkUI';import { preferences } from '@kit.ArkData';
let dataPreferences: preferences.Preferences | null = null;
export default class EntryAbility extends FlutterAbility {
onWindowStageCreate(windowStage: window.WindowStage): void { super.onWindowStageCreate(windowStage); preferences.getPreferences(this.context, 'forestStore', (err: BusinessError, val: preferences.Preferences) => { if (err) { console.error("Failed to get preferences. code =" + err.code + ", message =" + err.message); return; } dataPreferences = val; console.info("Succeeded in getting preferences1."); }) }
configureFlutterEngine(flutterEngine: FlutterEngine) { super.configureFlutterEngine(flutterEngine) GeneratedPluginRegistrant.registerWith(flutterEngine) this.addPlugin(new ForestPlugin()); }}
export {dataPreferences};
复制代码


该文件使的原生页面在加载时,配置 Flutter 引擎,注册插件。 Flutter 初始化时,同时初始化了 首选项 dataPreferences,以备后用。


编写 src/main/ets/entryability/ForestPlugin.ets


import { Any, BasicMessageChannel, EventChannel, FlutterManager, FlutterPlugin, Log, MethodCall, MethodChannel, StandardMessageCodec} from '@ohos/flutter_ohos';import { FlutterPluginBinding } from '@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/FlutterPlugin';import { batteryInfo } from '@kit.BasicServicesKit';import { MethodCallHandler, MethodResult } from '@ohos/flutter_ohos/src/main/ets/plugin/common/MethodChannel';import { preferences } from '@kit.ArkData';import { BusinessError } from '@kit.BasicServicesKit';import {dataPreferences} from './EntryAbility';import router from '@ohos.router'import { webviewRouterParams } from '../pages/Webview';
const TAG = "[flutter][plugin][forest]";
export default class ForestPlugin implements FlutterPlugin { private channel?: MethodChannel; private basicChannel?: BasicMessageChannel<Any>; private api = new ForestApi(); private dataPreferences: preferences.Preferences | null = null;
onAttachedToEngine(binding: FlutterPluginBinding): void { this.channel = new MethodChannel(binding.getBinaryMessenger(), "xxx.com/app"); this.channel.setMethodCallHandler({ onMethodCall : (call: MethodCall, result: MethodResult) => { console.log(`${TAG}-->[${call.method}]: ${JSON.stringify(call.args)}`); switch (call.method) { case "getPrefs": this.api.getPrefs(String(call.args), result); break; case "setPrefs": let key = String(call.argument("key")); let value = String(call.argument("value")); this.api.setPrefs(key, value); default: result.notImplemented(); break; } } }) } //··· onDetachedFromEngine(binding: FlutterPluginBinding): void { Log.i(TAG, "onDetachedFromEngine"); this.channel?.setMethodCallHandler(null); }
getUniqueClassName(): string { return "ForestPlugin"; }
复制代码


以上代码实现了一个插件类,其核心实现了 FlutterPlugin 中的 onAttachedToEngine 方法,该方法在 Flutter 引擎加载成功后调用。


onMethodCall中接收来自 Flutter 的消息调用,分别实现了 'getPrefs' 和 'setPrefs' 两个回掉,其中 getPrefs有返回值,通过 result.success(val);(见下)异步返回,setPrefs没有返回值。


以下为 ForestApi的具体实现,使用了 HarmonyOS 中的首选项 API 设置和读取数据。


class ForestApi {  getPrefs(key: string, result: MethodResult) {    dataPreferences?.get(key, '', (err: BusinessError, val: preferences.ValueType) => {      if (err) {        console.error(`${TAG} Failed to get value of ${key}. code =` + err.code + ", message =" + err.message);        result.success('');      }      console.info(`${TAG} Succeeded in getting value of ${key}:${val}.`);      result.success(val);    })
}
setPrefs(key: string, value: string) { dataPreferences?.put(key, value, (err: BusinessError) => { if (err) { console.error(`${TAG} Failed to put value of ${key}. code =` + err.code + ", message =" + err.message); return; } console.info(`${TAG} Succeeded in putting value of ${key}.`); }) }
clearPrefs(key: string) { dataPreferences?.delete(key, (err: BusinessError) => { if (err) { console.error("Failed to delete the key 'startup'. code =" + err.code + ", message =" + err.message); return; } console.info(`Succeeded in deleting the key ${key}.`); }) }}
复制代码

注意事项

1.双端初始化 methodChannel 中的名称必须保持一致,如 xxx.com/app.2.arkTS 侧通过 result.success(val) 返回数据,该过程是异步的,故在 Dart 侧需要使用 await 或者回调函数取值。3.通信中默认只支持基础的数据类型,复杂类型的需要进行序列化或编解码。4.在 Dart 侧接收的数据为 dymanic 类型,需要进行数据类型转换。

参考资料

发布于: 刚刚阅读数: 4
用户头像

星释

关注

还未添加个人签名 2020-12-05 加入

还未添加个人简介

评论

发布
暂无评论
鸿蒙Flutter实战:06-使用ArkTs开发Flutter鸿蒙插件_flutter_星释_InfoQ写作社区