HarmonyOS元服务与卡片

news2024/9/19 9:58:46

元服务与卡片

文章目录

  • 一、元服务
    • 1.介绍
    • 2.常见元服务项目步骤
  • 二、卡片
    • 1.介绍
    • 2.卡片的创建
    • 3.卡片的数据的变更
    • 4.卡片的进程间通讯
      • 4.1使用工具包
      • 4.2使用步骤
    • 5.卡片路由postCardAction:快速拉起后台
      • 5.1格式
      • 5.2快速拉起指定页面--router
      • 5.3调用后台功能--call
      • 5.3卡片内的数据获取(适合轻量级,限制在5s内)--message

一、元服务

1.介绍

元服务就是手机中自带的小组件类似。
是一种有独立入口、免安装、可为用户提供一个或多个服务的新型应用程序形态。它基于 HarmonyOS API 开发,支持运行在 “1+8+N” 设备上,让用户在合适的场景、合适的设备上便捷使用。
特点: 
1.免下载安装:用户无需像传统应用那样经历下载、安装等繁琐过程,节省了设备存储空间和下载时间,能够快速使用服务。例如,用户在使用一些简单功能的应用服务时,无需等待下载安装,直接通过元服务即可快速获取相关功能。
2.即开即用、即用即走:使用非常便捷,用户在需要时可以快速打开使用,使用完毕后不需要专门去关闭或卸载,减少了操作步骤和使用负担。比如用户在查询某个信息时,通过元服务快速查询到结果后即可关闭,下次使用时再次快速打开。
3.多端部署:只需一次开发,就可以部署在各种 HarmonyOS 终端上,包括手机、平板、智能手表、智慧屏等,大大降低了开发者的开发成本和工作量,同时也为用户提供了跨设备的一致使用体验。
4.使用方式与入口:
用户可以通过负一屏、智慧搜索、小艺助手等入口唤起元服务。例如,在负一屏中搜索相关的元服务名称,或者通过语音指令让小艺助手打开相应的元服务。
元服务还可以以服务卡片的形式存在于用户的设备桌面,用户可以根据自己的需求添加、管理和使用服务卡片,方便快捷地获取服务信息和进行操作。
对开发者的优势:
5.开发相对简单,开发者可以快速加入鸿蒙生态。并且元服务代码 100% 可复用到原生应用开发,提高了开发效率和代码的复用性。
通过鸿蒙系统的服务分发能力,元服务可以获得更多的流量和曝光机会,有助于开发者的服务更好地推广和被用户使用。
总之,元服务是 HarmonyOS 生态中的一个重要组成部分,为用户提供了更加便捷、高效的服务体验,也为开发者提供了新的开发和推广机会。

2.常见元服务项目步骤

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

二、卡片

1.介绍

元服务与卡片开发之间的关联主要体现在:卡片作为元服务的展现形式之一,可以为用户提供与元服务交互的界面。通过卡片,用户可以方便地访问和控制后台的元服务,而开发者则可以利用元服务为卡片提供丰富的功能和数据。这种设计允许鸿蒙操作系统在不同设备上提供一致且高效的用户体验,同时也简化了跨设备服务的开发和维护。

总的来说,元服务和卡片开发是鸿蒙操作系统中支持分布式能力和提高用户体验的两个关键技术。通过元服务,鸿蒙能够在多种设备之间提供无缝的服务体验;而卡片开发则使得这些服务能够以一种简洁而直观的方式呈现给用户,从而促进了不同设备和场景下的信息流通和功能使用。

2.卡片的创建

元服务和普通项目都一致,项目的文件夹可以变更

在这里插入图片描述

3.卡片的数据的变更

使用的工具包,可以见首选项工具包:PreferencesUtil,主要用于存放卡片ID

思路:根据ID
1.在EntryFormAbility中获取卡片ID:
2.在特定位置触发,用于加载卡片显示的数据
3. 卡片接收方式: @LocalStorageProp(“title”) // 使用页面级别Ui接收

 1.在EntryFormAbility中获取卡片ID:
 
 private preference: PreferencesUtil = PreferencesUtil.getInstance()
  onAddForm(want: Want) { // 请求不能超出5秒,否则自动断开
    // 正常业务使用的情况 -- 进保存卡片ID,存在问题:有变更则所有的都变更 ---优化增加卡片name保存到首选项
    let formData = {
      "title": "加载中..."
    } as Record<string, string>;
    
    // 业务处理和返回无关
    // 获取卡片ID
    let id = want.parameters![formInfo.FormParam.IDENTITY_KEY]  
    // 获取卡片name // 可以根据name过滤非同一类的卡片,做到指定更新
    let name = want.parameters![formInfo.FormParam.NAME_KEY]  
    console.log('system===>卡片ID:' + id+'卡片name:'+name)
    // 首选项封装的工具,将ID,name保存至首选项
    this.preference.addFormId(this.context, JSON.stringify({"id":id,"name":name}))
      .then((res) => {
        console.log('system===>添加')
      })
      .catch(() => {
        console.error('system===>错误')
      })
    return formBindingData.createFormBindingData(formData);
  }
 2.在特定位置触发,用于加载卡片显示的数据。
 以根据卡片名称,指定更新为例:

// 封装方法
  getForm(formName: string) { // 传递的卡片的名称
  // 根据首选项,获取所有的卡片ID
    this.preference.getFormIds(getContext(this)).then((item) => { // 返回JSON数组
    // 所要变更的成的数据
      let formData = {
        "title": "卡片延时加载" + formName
      } as Record<string, string>;
      
      // 获取索要的卡片ID
      const arr = item.filter((formDataS) => {
        const obj: Record<string,string|number> = JSON.parse(formDataS) as Record<string,string|number>
        console.log('system===>'+JSON.parse(formDataS)+':'+obj.name)
        return obj.name == formName
      })
      if (arr.length > 0) {
        arr.forEach((son: string) => {
          const obj: Record<string,string|number> = JSON.parse(son) as Record<string,string|number>

         // 执行卡片ID,将数据变更
          formProvider.updateForm(obj.id as string, formBindingData.createFormBindingData(formData))
          // 执行固定函数
          formBindingData.createFormBindingData(formData);
        })
      }
    }).catch((err: BusinessError) => {
      console.error('system===>更新' + JSON.stringify(err))
    })
  }

3. 卡片接收数据方式:   @LocalStorageProp("title") // 使用页面级别Ui接收

  @LocalStorageProp("title") // 使用页面级别Ui接收
  readonly TITLE: string = '';
  build() {
    Row() {
      Column() {
        Text(this.TITLE)
          .fontSize($r('app.float.font_size'))
          .fontWeight(FontWeight.Medium)
          .fontColor($r('app.color.item_title_font'))
      }
    }
  }

4.卡片的进程间通讯

使用的原因:
原因是在App存在期间,卡片与App不是同一个进程,App中不能直接访问卡片保存在首选 项中的数据,即App读取不到添加到桌面的元卡片ID,所以导致更新ArkTS卡片数据失败。
当App关闭后,第二次打开时,就可以正常访问到卡片保存在首选项中的卡片ID数据了,所以再次点击更新卡片数据就能成功了。

卡片的加载数据与APP应用不是同一个进程,可能回导致数据刷新不到,此时需要进程间的通讯(发布和订阅)–进程间通信(IPC)的订阅-发布模式实现。
发布: 谁触发
订阅: 根据获取的ID指定更新

4.1使用工具包

import commonEventManager from '@ohos.commonEventManager'


// Publisher通讯事件类型
enum PublishEventType {
  APP_PUBLISH = "APP_PUBLISH",
  CARD_PUBLISH = "CARD_PUBLISH"
}


class IPCManagerClass {
  static publishCount:number = 1
  // 发布者
  static publish(eventType:PublishEventType,data:string){
    // commonEventManager作用:可用于进程间通讯
    commonEventManager.publish(eventType,{data},(err)=>{
      if(err){
        // 失败只发3次
        if(this.publishCount<=3){
          this.publish(eventType,data)
        }else{
          this.publishCount = 1
        }
      }else{
        this.publishCount = 1
      }
    })
  }
  // 订阅者
  static subscribe(eventType:PublishEventType,subscriber,callback:(event:string)=>void){
    commonEventManager.createSubscriber({ events: [eventType] }, (err, data) => {
      if (err) {
        return console.log('common-->', `创建订阅者error ${JSON.stringify(err)}`)
      }
      console.log('common-->', `创建订阅者success`)
      subscriber = data
      if (subscriber !== null) {
        //订阅事件
        commonEventManager.subscribe(subscriber, (err, data) => {
          if (err) {
            return console.error(`logData`, '订阅事件失败')
          }
          console.log('common-->',`接受订阅事件:${data.data}`)
          callback(data.data)
        })
      } else {
        console.error('common-->',`需要创建subscriber`);
      }
    })
  }
}

export {IPCManagerClass,PublishEventType}

4.2使用步骤

发布:谁触发的就是发布者(卡片被触发)
订阅:端侧订阅

发布:

`src/main/ets/entryformability/EntryFormAbility.ets``onAddForm` 事件中增加如下代码:
PreferencesUtil.getInstance().addFormId(this.context, formid).then(res => {
      console.log('hmlog-->', '保存卡片id成功');
      // 增加一个发布卡片ID(formid)的消息
      IPCManagerClass.publish(PublishEventType.APP_PUBLISH,formid)
    }).catch(err => {
      console.log('hmlog-->', '保存卡片id失败');
});

订阅:

`src/main/ets/pages/Index.ets` 中的 ` aboutToAppear` 事件的重构代码如下:

async aboutToAppear(): Promise<void> {
    console.log('hmlog-->','aboutToAppear....')
    IPCManagerClass.subscribe(PublishEventType.CARD_PUBLISH,undefined, async (formId)=>{
        console.log('hmlog-->',' aboutToAppear,IPCManagerClass,formId = '+formId);
        // this.cardIds.push(formId);
      // 将接收到的formId保存到当前进程的首选项中
        await PreferencesUtil.getInstance().addFormId(getContext(),formId);
        this.getCardIds();
    })
  }

  getCardIds(){
   PreferencesUtil.getInstance().getFormIds(getContext()).then(formIds=>{
     console.log('hmlog-->','cardids:'+JSON.stringify(formIds));
     this.cardIds.length = 0;
     this.cardIds.push(...formIds);
   }).catch((err:BusinessError)=>{
     console.error('hmlog-->','getCardIds Failed. Err:'+JSON.stringify(err));
   })
  }

5.卡片路由postCardAction:快速拉起后台

5.1格式

postCardAction(this, {
              action: 'router', // 三种方式: router:拉起后台 /call:拉起后台 /message 卡片内的数据获取,受限大
              abilityName: 'EntryAbility', // app的启动UiAbility
              // 参数
              params: {
                // 传参JSON格式
                message: '跳转B成功'
              }
            });


 // 接收参数的方式:APP的EntryAbility文件中: let params = JSON.parse(want.parameters!.params as string) as Record<string, string>;
const message = params.message;

5.2快速拉起指定页面–router

思路:
在EntryAbility 定义变量用于接收路径path 和 windowStage
当用于被隐藏第二次不会再次调用onWindowStageCreate和onCreate 则需要使用 使用 onNewWant 并在调用时,重新调用onWindowStageCreate

5.3调用后台功能–call

5.3卡片内的数据获取(适合轻量级,限制在5s内)–message

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

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

相关文章

idea连接docker 自动化部署

进入Linux服务器 vim /lib/systemd/system/docker.service将 ExecStart/usr/bin/dockerd -H fd:// --containerd/run/containerd/containerd.sock 替换为 ExecStart/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock新建文件 Dockerfile配置Dockerfile文…

rocky9虚拟机配置双网卡的详细过程

编辑虚拟机配置->添加->选择网络适配器->确认->打开虚拟机 1.ip add查看第二个网卡的名称&#xff0c;我这里是ens36 2.cd到网卡的配置文件目录 cd /etc/NetworkManager/system-connections/ ls3.复制一份网卡的配置文件并改名为ens36.nmconnection(根据自己的第…

工程车辆目标检测、程车检测算法、工程车辆类型检测算法

工程车检测算法主要用于智能交通系统、建筑工地管理、矿山开采、物流运输等领域&#xff0c;通过图像识别技术来检测和识别工程车&#xff0c;以提高安全管理、交通流量管理和资源调度的效率。以下是关于工程车检测算法的技术实现、应用场景及优势的详细介绍。 一、技术实现 工…

钉钉与MySQL对接集成获取部门列表2.0打通EXECUTE语句

钉钉与MySQL对接集成获取部门列表2.0打通EXECUTE语句 接入系统&#xff1a;钉钉 钉钉是阿里巴巴集团打造的企业级智能移动办公平台&#xff0c;是数字经济时代的企业组织协同办公和应用开发平台。钉钉将IM即时沟通、钉钉文档、钉闪会、钉盘、Teambition、OA审批、智能人事、钉工…

《深入理解 Java 线程池:高效管理线程的利器》

线程池 1. 什么是线程池&#xff1f; ​ 线程池内部维护了若干个线程&#xff0c;没有任务的时候&#xff0c;这些线程都处于等待空闲状态。如果有新的线程任务&#xff0c;就分配一个空闲线程执行。如果所有线程都处于忙碌状态&#xff0c;线程池会创建一个新线程进行处理或…

【sgCreateCallAPIFunctionParam】自定义小工具:敏捷开发→调用接口方法参数生成工具

<template><div :class"$options.name" class"sgDevTool"><sgHead /><div class"sg-container"><div class"sg-start"><div style"margin-bottom: 10px">参数列表[逗号模式]<el-too…

小微金融企业系统小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;贷款信息管理&#xff0c;贷款申请管理&#xff0c;贷款种类管理&#xff0c;代办项目管理&#xff0c;项目分类管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;代办项…

基于51单片机的物联网安防系统(Proteus+Python脚本+阿里云)

基于51单片机的物联网安防系统使用Proteus进行仿真&#xff0c;LCD12864进行数据显示&#xff0c;集成了温湿度传感器、烟雾、甲烷传感器&#xff0c;执行器件是风扇&#xff0c;采用L298进行驱动&#xff0c;按键实现用户交互&#xff0c;蜂鸣器报警&#xff0c;红外检测人员状…

如何将示波器输出的电压数据转换为频域数据,五句代码解决问题,详细分析五句代码

这四句代码是关于对电压数据&#xff08;voltage&#xff09;进行快速傅里叶变换&#xff08;FFT&#xff09;&#xff0c;并生成相应的频率向量&#xff0c;提取并计算频谱的幅度&#xff0c;同时只保留正频率部分。 五句代码如下图所示&#xff1a; % 计算采样频率dt mean(…

Python | Leetcode Python题解之第413题等差数列划分

题目&#xff1a; 题解&#xff1a; class Solution:def numberOfArithmeticSlices(self, nums: List[int]) -> int:n len(nums)if n 1:return 0d, t nums[0] - nums[1], 0ans 0# 因为等差数列的长度至少为 3&#xff0c;所以可以从 i2 开始枚举for i in range(2, n):i…

Rust GUI框架 tauri V2 项目创建

文章目录 Tauri 2.0创建应用文档移动应用开发 Android 前置要求移动应用开发 iOS 前置要求参考资料 Tauri 2.0 Tauri 是一个构建适用于所有主流桌面和移动平台的轻快二进制文件的框架。开发者们可以集成任何用于创建用户界面的可以被编译成 HTML、JavaScript 和 CSS 的前端框架…

电源电压输入输出保护电路

输入正负极接反芯片损坏 解决方案&#xff1a;添加防反接电路(蓝色虚线框中电路)。 Q1:VDS≥1.5*VINMAX&#xff1b; DZ1:VDZ110V&#xff0c;500mW&#xff1b; R3:20K&#xff1b; R4:20K。 输入尖峰电压损坏芯片 ➢ 解决方案一&#xff1a;输入添加瞬态尖峰电压吸收电路…

【中国留学网-注册_登录安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞…

如何兼容性地开发响应式站点——WEB开发系列40

CSS在不同浏览器的支持历史中&#xff0c;有过多次变革。尽管现代浏览器逐步趋向一致&#xff0c;但仍有一些较旧的浏览器广泛使用&#xff0c;特别是在某些地区或特定环境中。 一、浏览器生态&#xff1a;了解你的网站用户 在设计和开发站点之前&#xff0c;了解目标用户所使…

多旅行商问题:鹈鹕优化算法(Pelican Optimization Algorithm,POA)求解多仓库多旅行商问题MD-MTSP(提供Matlab代码)

一、鹈鹕优化算法 鹈鹕优化算法(Pelican Optimization Algorithm,POA)由Pavel Trojovsk和Mohammad Dehghani 于2022年提出&#xff0c;该算法模拟了鹈鹕在狩猎过程中的自然行为。 鹈鹕很大&#xff0c;喙很长&#xff0c;喉咙里有一个大袋子&#xff0c;用来捕捉和吞咽猎物。…

记录一下ElementUI 3 在浏览器导入, table表格显示问题

当时问题忘了截图, 现在通过文字记录一下问题 我直接在html了引入 vue3 和 ElementUI 3 , 使用了table组件, 但是表格的td 总是只显示一列, 问题是我的 el-table-column 标签 没有结束标签 , 在vue文件模块化里写不需要结束标签, 在浏览器里无法直接识别出来, 所以他是渲染了第…

鸿蒙开发之ArkUI 界面篇 十 边框border

border语法格式如下&#xff1a; 要实现如下效果&#xff1a; 代码如下&#xff1a; Entry Component struct IndexTest {State message: string IndexTest;build() {Column(){Text(border实现).fontSize(30) .border({width:4,color:Color.Red,style:BorderStyle.Solid,ra…

进程的重要函数

进程的重要函数: fork函数 了解fork函数 通过调用fork()函数&#xff0c;则会产生一个新的进程。调用fork()函数的进程叫做 父进程&#xff0c;产生的新进程则为子进程。 其编码过程: 1.函数功能: 函数头文件 #include <sys/types.h> #include <unistd.h> 函数…

【FFT】信号处理——快速傅里叶变换【通俗易懂】

快速傅里叶变换&#xff08;Fast Fourier Transform, FFT&#xff09;是一种用于将信号从时间域转换到频率域的算法。 傅里叶变换的核心思想是&#xff1a;任何周期性信号都可以分解成多个不同频率的正弦波或余弦波的叠加。 简单来说&#xff0c;FFT可以帮助我们理解一个信号…

使用 Internet 共享 (ICS) 方式分配ip

设备A使用dhcp的情况下&#xff0c;通过设备B分配ip并共享网络的方法。 启用网络共享&#xff08;ICS&#xff09;并配置 NAT Windows 自带的 Internet Connection Sharing (ICS) 功能可以简化 NAT 设置&#xff0c;允许共享一个网络连接给其他设备。 打开网络设置&#xff1…