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

news/2024/10/22 18:40:42

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

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

Flutter侧,编写 MethodChannel

const MethodChannel _methodChannel = MethodChannel('xxx.com/app');/// 获取tokenstatic Future<dynamic> getToken() {return _methodChannel.invokeMethod("getPrefs", 'token');}/// 设置tokenstatic 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 类型,需要进行数据类型转换。

参考资料

  • 撰写双端平台代码(插件编写实现)
  • 用户首选项API

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/74746.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

高等数学 7.7常系数齐次线性微分方程

在二阶齐次线性微分方程 \[y + P(x)y + Q(x)y = 0 \tag{1} \]中,如果 \(y, y\) 的系数 \(P(x), Q(x)\) 均为常数,即 \((1)\) 式成为 \[y + py + qy = 0 \tag{2} \]其中 \(p, q\) 是常数,那么称 \((2)\) 为二阶常系数齐次线性微分方程。如果 \(p, q\) 不全为常数,就称 \((1)…

线性代数--线性方程组

线性方程组有解的判定 {x1+x2+x3=1x1−x2−x3=−32x1+9x2+10x3=11系数矩阵:A=(1111−1−12910)增广矩阵:A=(11111−1−1−3291011) n是未知量的个数,m是方程的个数怎么判断秩是否相等步骤:通过方程,写出增广系数矩阵 只做初等行变换,化为阶梯型 看系数矩阵的秩和增广系数…

Python 应用可观测重磅上线:解决 LLM 应用落地的“最后一公里”问题

本文将从阿里云 Python 探针的接入步骤、产品能力、兼容性等方面展开介绍。并提供一个简单的 LLM 应用例子,方便测试。作者:彦鸿 背景 随着 LLM(大语言模型)技术的不断成熟和应用场景的不断拓展,越来越多的企业开始将 LLM 技术纳入自己的产品和服务中。LLM 在自然语言处理…

计算机视觉领域的实际应用有什么

计算机视觉在多个行业和应用场景中有着广泛的实际应用,主要包括医疗图像分析、自动驾驶、物体检测、人脸识别、增强现实(AR)和虚拟现实(VR)、工业自动化、农业监测等。医疗图像分析用于诊断疾病和制定治疗方案,提高医疗服务的质量和效率。其中,自动驾驶是一个相对成熟的…

【八叉树】从上千万个物体中【**瞬间**】就近选取坐标

众里寻他千百度,蓦然回首,那人却在灯火阑珊处前情提要 在某些情况下,我们在场景中创建了数百万个物体,这些物体没有直接的网格或碰撞体(例如,通过GPU绘制的物体),因此无法通过常规的射线检测与碰撞体进行交互。我们仅掌握这些物体的坐标或顶点位置。在这种情况下,我们…

Python 数据分析与可视化有什么区别

在当今的数据驱动时代,Python已成为数据分析和数据可视化的重要工具。尽管这两个领域经常在数据科学项目中相互交织,但它们在功能和目的上存在本质区别。本文旨在详细探讨Python在数据分析和数据可视化方面的差异,包括它们的定义、使用的主要库、应用场景以及在实际项目中的…

python第六章课后习题

点击查看代码print("学号:2023310143028")点击查看代码def prim(graph, start): num_nodes = len(graph) visited = [False] * num_nodes min_heap = [(0, start, -1)] mst_cost = 0 mst_edges = [] while min_heap: weight, u, parent = heapq.heappop(min…

go1.18版本下 beego/bee安装无法生成exe问题已解决

转自: https://www.cnblogs.com/leijiangsheng/p/17392795.html 我原来的项目是教育学习APP使用gin框架,很多东西都是自己原来实现的。最近开发小程序,需要重新独立后台,又重新找了下go框架研究了下,beego确实是个好框架,至少项目能用到的都考虑进去了。 然后发现我本地装…