HarmonyOS4.0系统性深入开发08服务卡片架构
服务卡片概述
服务卡片(以下简称“卡片”)是一种界面展示形式,可以将应用的重要信息或操作前置到卡片,以达到服务直达、减少体验层级的目的。卡片常用于嵌入到其他应用(当前卡片使用方只支持系统应用,如桌面)中作为其界面显示的一部分,并支持拉起页面、发送消息等基础的交互功能。
服务卡片架构
图1 服务卡片架构
卡片的基本概念:
- 卡片使用方:如上图中的桌面,显示卡片内容的宿主应用,控制卡片在宿主中展示的位置。
- 应用图标:应用入口图标,点击后可拉起应用进程,图标内容不支持交互。
- 卡片:具备不同规格大小的界面展示,卡片的内容可以进行交互,如实现按钮进行界面的刷新、应用的跳转等。
- 卡片提供方:包含卡片的应用,提供卡片的显示内容、控件布局以及控件点击处理逻辑。
- FormExtensionAbility:卡片业务逻辑模块,提供卡片创建、销毁、刷新等生命周期回调。
- 卡片页面:卡片UI模块,包含页面控件、布局、事件等显示和交互信息。
卡片的常见使用步骤如下。
图2 卡片常见使用步骤
- 长按“桌面图标”,弹出操作菜单。
- 点击“服务卡片”选项,进入卡片预览界面。
- 点击“添加到桌面”按钮,即可在桌面上看到新添加的卡片。
服务卡片UI页面开发方式
在Stage模型下,服务卡片的UI页面支持通过ArkTS和JS两种语言进行开发:
- 基于声明式范式ArkTS UI开发的卡片,简称ArkTS卡片。
- 基于类Web范式JS UI开发的卡片,简称JS卡片。
ArkTS卡片与JS卡片具备不同的实现原理及特征,在场景能力上的差异如下表所示。
类别 | JS卡片 | ArkTS卡片 |
---|---|---|
开发范式 | 类Web范式 | 声明式范式 |
组件能力 | 支持 | 支持 |
布局能力 | 支持 | 支持 |
事件能力 | 支持 | 支持 |
自定义动效 | 不支持 | 支持 |
自定义绘制 | 不支持 | 支持 |
逻辑代码执行(不包含import能力) | 不支持 | 支持 |
相比于JS卡片,ArkTS卡片在能力和场景方面更加丰富,因此无论开发何种用途的卡片,都推荐使用ArkTS卡片,因为它可以提高开发效率并实现动态化。但如果只需要做静态页面展示的卡片,可以考虑使用JS卡片。
开发基于JS UI的卡片
以下内容介绍基于类Web范式的JS UI卡片开发指南。
运作机制
卡片框架的运作机制如图1所示。
图1 卡片框架运作机制(Stage模型)
卡片使用方包含以下模块:
- 卡片使用:包含卡片的创建、删除、请求更新等操作。
- 通信适配层:由OpenHarmony SDK提供,负责与卡片管理服务通信,用于将卡片的相关操作到卡片管理服务。
卡片管理服务包含以下模块:
- 周期性刷新:在卡片添加后,根据卡片的刷新策略启动定时任务周期性触发卡片的刷新。
- 卡片缓存管理:在卡片添加到卡片管理服务后,对卡片的视图信息进行缓存,以便下次获取卡片时可以直接返回缓存数据,降低时延。
- 卡片生命周期管理:对于卡片切换到后台或者被遮挡时,暂停卡片的刷新;以及卡片的升级/卸载场景下对卡片数据的更新和清理。
- 卡片使用方对象管理:对卡片使用方的RPC对象进行管理,用于使用方请求进行校验以及对卡片更新后的回调处理。
- 通信适配层:负责与卡片使用方和提供方进行RPC通信。
卡片提供方包含以下模块:
- 卡片服务:由卡片提供方开发者实现,开发者实现生命周期处理创建卡片、更新卡片以及删除卡片等请求,提供相应的卡片服务。
- 卡片提供方实例管理模块:由卡片提供方开发者实现,负责对卡片管理服务分配的卡片实例进行持久化管理。
- 通信适配层:由OpenHarmony SDK提供,负责与卡片管理服务通信,用于将卡片的更新数据主动推送到卡片管理服务。
说明
实际开发时只需要作为卡片提供方进行卡片内容的开发,卡片使用方和卡片管理服务由系统自动处理。
接口说明
FormExtensionAbility类拥有如下API接口,具体的API介绍详见接口文档。
接口名 | 描述 |
---|---|
onAddForm(want: Want): formBindingData.FormBindingData | 卡片提供方接收创建卡片的通知接口。 |
onCastToNormalForm(formId: string): void | 卡片提供方接收临时卡片转常态卡片的通知接口。 |
onUpdateForm(formId: string): void | 卡片提供方接收更新卡片的通知接口。 |
onChangeFormVisibility(newStatus: { [key: string]: number }): void | 卡片提供方接收修改可见性的通知接口。 |
onFormEvent(formId: string, message: string): void | 卡片提供方接收处理卡片事件的通知接口。 |
onRemoveForm(formId: string): void | 卡片提供方接收销毁卡片的通知接口。 |
onConfigurationUpdate(config: Configuration): void | 当系统配置更新时调用。 |
onShareForm?(formId: string): { [key: string]: any } | 卡片提供方接收卡片分享的通知接口。 |
formProvider类有如下API接口,具体的API介绍详见接口文档。
接口名 | 描述 |
---|---|
setFormNextRefreshTime(formId: string, minute: number, callback: AsyncCallback): void; | 设置指定卡片的下一次更新时间。 |
setFormNextRefreshTime(formId: string, minute: number): Promise; | 设置指定卡片的下一次更新时间,以promise方式返回。 |
updateForm(formId: string, formBindingData: FormBindingData, callback: AsyncCallback): void; | 更新指定的卡片。 |
updateForm(formId: string, formBindingData: FormBindingData): Promise; | 更新指定的卡片,以promise方式返回。 |
formBindingData类有如下API接口,具体的API介绍详见接口文档。
接口名 | 描述 |
---|---|
createFormBindingData(obj?: Object | string): FormBindingData | 创建一个FormBindingData对象。 |
开发步骤
Stage卡片开发,即基于Stage模型的卡片提供方开发,主要涉及如下关键步骤:
- 创建卡片FormExtensionAbility:卡片生命周期回调函数FormExtensionAbility开发。
- 配置卡片配置文件:配置应用配置文件module.json5和profile配置文件。
- 卡片信息的持久化:对卡片信息进行持久化管理。
- 卡片数据交互:通过updateForm更新卡片显示的信息。
- 开发卡片页面:使用HML+CSS+JSON开发JS卡片页面。
- 开发卡片事件:为卡片添加router事件和message事件。
创建卡片FormExtensionAbility
创建Stage模型的卡片,需实现FormExtensionAbility生命周期接口。先参考DevEco Studio服务卡片开发指南生成服务卡片模板。
-
在EntryFormAbility.ts中,导入相关模块。
import FormExtensionAbility from '@ohos.app.form.FormExtensionAbility'; import formBindingData from '@ohos.app.form.formBindingData'; import formInfo from '@ohos.app.form.formInfo'; import formProvider from '@ohos.app.form.formProvider'; import dataStorage from '@ohos.data.storage';
-
在EntryFormAbility.ts中,实现FormExtension生命周期接口。
export default class EntryFormAbility extends FormExtensionAbility {onAddForm(want) {console.info('[EntryFormAbility] onAddForm');// 使用方创建卡片时触发,提供方需要返回卡片数据绑定类let obj = {"title": "titleOnCreate","detail": "detailOnCreate"};let formData = formBindingData.createFormBindingData(obj);return formData;}onCastToNormalForm(formId) {// 使用方将临时卡片转换为常态卡片触发,提供方需要做相应的处理console.info('[EntryFormAbility] onCastToNormalForm');}onUpdateForm(formId) {// 若卡片支持定时更新/定点更新/卡片使用方主动请求更新功能,则提供方需要重写该方法以支持数据更新console.info('[EntryFormAbility] onUpdateForm');let obj = {"title": "titleOnUpdate","detail": "detailOnUpdate"};let formData = formBindingData.createFormBindingData(obj);formProvider.updateForm(formId, formData).catch((error) => {console.info('[EntryFormAbility] updateForm, error:' + JSON.stringify(error));});}onChangeFormVisibility(newStatus) {// 使用方发起可见或者不可见通知触发,提供方需要做相应的处理,仅系统应用生效console.info('[EntryFormAbility] onChangeFormVisibility');}onFormEvent(formId, message) {// 若卡片支持触发事件,则需要重写该方法并实现对事件的触发console.info('[EntryFormAbility] onFormEvent');}onRemoveForm(formId) {// 删除卡片实例数据console.info('[EntryFormAbility] onRemoveForm');}onConfigurationUpdate(config) {console.info('[EntryFormAbility] nConfigurationUpdate, config:' + JSON.stringify(config));}onAcquireFormState(want) {return formInfo.FormState.READY;} }
说明
FormExtensionAbility不能常驻后台,即在卡片生命周期回调函数中无法处理长时间的任务。
配置卡片配置文件
-
卡片需要在module.json5配置文件中的extensionAbilities标签下,配置ExtensionAbility相关信息。FormExtensionAbility需要填写metadata元信息标签,其中键名称为固定字符串"ohos.extension.form",资源为卡片的具体配置信息的索引。
配置示例如下:
{"module": {..."extensionAbilities": [{"name": "EntryFormAbility","srcEntrance": "./ets/entryformability/EntryFormAbility.ts","label": "$string:EntryFormAbility_label","description": "$string:EntryFormAbility_desc","type": "form","metadata": [{"name": "ohos.extension.form","resource": "$profile:form_config"}]}]} }
-
卡片的具体配置信息。在上述FormExtensionAbility的元信息("metadata"配置项)中,可以指定卡片具体配置信息的资源索引。例如当resource指定为$profile:form_config时,会使用开发视图的resources/base/profile/目录下的form_config.json作为卡片profile配置文件。内部字段结构说明如下表所示。
表1 卡片profile配置文件
属性名称 含义 数据类型 是否可缺省 name 表示卡片的类名,字符串最大长度为127字节。 字符串 否 description 表示卡片的描述。取值可以是描述性内容,也可以是对描述性内容的资源索引,以支持多语言。字符串最大长度为255字节。 字符串 可缺省,缺省为空。 src 表示卡片对应的UI代码的完整路径。 字符串 否 window 用于定义与显示窗口相关的配置。 对象 可缺省 isDefault 表示该卡片是否为默认卡片,每个UIAbility有且只有一个默认卡片。- true:默认卡片。- false:非默认卡片。 布尔值 否 colorMode 表示卡片的主题样式,取值范围如下:- auto:自适应。- dark:深色主题。- light:浅色主题。 字符串 可缺省,缺省值为“auto”。 supportDimensions 表示卡片支持的外观规格,取值范围:- 1 * 2:表示1行2列的二宫格。- 2 * 2:表示2行2列的四宫格。- 2 * 4:表示2行4列的八宫格。- 4 * 4:表示4行4列的十六宫格。 字符串数组 否 defaultDimension 表示卡片的默认外观规格,取值必须在该卡片supportDimensions配置的列表中。 字符串 否 updateEnabled 表示卡片是否支持周期性刷新,取值范围:- true:表示支持周期性刷新,可以在定时刷新(updateDuration)和定点刷新(scheduledUpdateTime)两种方式任选其一,优先选择定时刷新。- false:表示不支持周期性刷新。 布尔类型 否 scheduledUpdateTime 表示卡片的定点刷新的时刻,采用24小时制,精确到分钟。updateDuration参数优先级高于scheduledUpdateTime,两者同时配置时,以updateDuration配置的刷新时间为准。 字符串 可缺省,缺省值为“0:0”。 updateDuration 表示卡片定时刷新的更新周期,单位为30分钟,取值为自然数。当取值为0时,表示该参数不生效。当取值为正整数N时,表示刷新周期为30*N分钟。updateDuration参数优先级高于scheduledUpdateTime,两者同时配置时,以updateDuration配置的刷新时间为准。 数值 可缺省,缺省值为“0”。 formConfigAbility 表示卡片的配置跳转链接,采用URI格式。 字符串 可缺省,缺省值为空。 formVisibleNotify 标识是否允许卡片使用卡片可见性通知。 字符串 可缺省,缺省值为空。 metaData 表示卡片的自定义信息,包含customizeData数组标签。 对象 可缺省,缺省值为空。 配置示例如下:
{"forms": [{"name": "widget","description": "This is a service widget.","src": "./js/widget/pages/index/index","window": {"designWidth": 720,"autoDesignWidth": true},"colorMode": "auto","isDefault": true,"updateEnabled": true,"scheduledUpdateTime": "10:30","updateDuration": 1,"defaultDimension": "2*2","supportDimensions": ["2*2"]}] }
卡片信息的持久化
因大部分卡片提供方都不是常驻服务,只有在需要使用时才会被拉起获取卡片信息,且卡片管理服务支持对卡片进行多实例管理,卡片ID对应实例ID,因此若卡片提供方支持对卡片数据进行配置,则需要对卡片的业务数据按照卡片ID进行持久化管理,以便在后续获取、更新以及拉起时能获取到正确的卡片业务数据。
const DATA_STORAGE_PATH = "/data/storage/el2/base/haps/form_store";
async function storeFormInfo(formId: string, formName: string, tempFlag: boolean) {// 此处仅对卡片ID:formId,卡片名:formName和是否为临时卡片:tempFlag进行了持久化let formInfo = {"formName": formName,"tempFlag": tempFlag,"updateCount": 0};try {const storage = await dataStorage.getStorage(DATA_STORAGE_PATH);// put form infoawait storage.put(formId, JSON.stringify(formInfo));console.info(`[EntryFormAbility] storeFormInfo, put form info successfully, formId: ${formId}`);await storage.flush();} catch (err) {console.error(`[EntryFormAbility] failed to storeFormInfo, err: ${JSON.stringify(err)}`);}
}export default class EntryFormAbility extends FormExtension {...onAddForm(want) {console.info('[EntryFormAbility] onAddForm');let formId = want.parameters["ohos.extra.param.key.form_identity"];let formName = want.parameters["ohos.extra.param.key.form_name"];let tempFlag = want.parameters["ohos.extra.param.key.form_temporary"];// 将创建的卡片信息持久化,以便在下次获取/更新该卡片实例时进行使用// 此接口请根据实际情况实现,具体请参考:FormExtAbility Stage模型卡片实例storeFormInfo(formId, formName, tempFlag);let obj = {"title": "titleOnCreate","detail": "detailOnCreate"};let formData = formBindingData.createFormBindingData(obj);return formData;}
}
且需要适配onRemoveForm卡片删除通知接口,在其中实现卡片实例数据的删除。
const DATA_STORAGE_PATH = "/data/storage/el2/base/haps/form_store";
async function deleteFormInfo(formId: string) {try {const storage = await dataStorage.getStorage(DATA_STORAGE_PATH);// del form infoawait storage.delete(formId);console.info(`[EntryFormAbility] deleteFormInfo, del form info successfully, formId: ${formId}`);await storage.flush();} catch (err) {console.error(`[EntryFormAbility] failed to deleteFormInfo, err: ${JSON.stringify(err)}`);}
}...export default class EntryFormAbility extends FormExtension {...onRemoveForm(formId) {console.info('[EntryFormAbility] onRemoveForm');// 删除之前持久化的卡片实例数据// 此接口请根据实际情况实现,具体请参考:FormExtAbility Stage模型卡片实例deleteFormInfo(formId);}
}
具体的持久化方法可以参考应用数据持久化概述。
需要注意的是,卡片使用方在请求卡片时传递给提供方应用的Want数据中存在临时标记字段,表示此次请求的卡片是否为临时卡片:
- 常态卡片:卡片使用方会持久化的卡片;
- 临时卡片:卡片使用方不会持久化的卡片;
由于临时卡片的数据具有非持久化的特殊性,某些场景例如卡片服务框架死亡重启,此时临时卡片数据在卡片管理服务中已经删除,且对应的卡片ID不会通知到提供方,所以卡片提供方需要自己负责清理长时间未删除的临时卡片数据。同时对应的卡片使用方可能会将之前请求的临时卡片转换为常态卡片。如果转换成功,卡片提供方也需要对对应的临时卡片ID进行处理,把卡片提供方记录的临时卡片数据转换为常态卡片数据,防止提供方在清理长时间未删除的临时卡片时,把已经转换为常态卡片的临时卡片信息删除,导致卡片信息丢失。
卡片数据交互
当卡片应用需要更新数据时(如触发了定时更新或定点更新),卡片应用获取最新数据,并调用updateForm()接口主动触发卡片的更新。
onUpdateForm(formId) {// 若卡片支持定时更新/定点更新/卡片使用方主动请求更新功能,则提供方需要重写该方法以支持数据更新console.info('[EntryFormAbility] onUpdateForm');let obj = {"title": "titleOnUpdate","detail": "detailOnUpdate"};let formData = formBindingData.createFormBindingData(obj);// 调用updateForm接口去更新对应的卡片,仅更新入参中携带的数据信息,其他信息保持不变formProvider.updateForm(formId, formData).catch((error) => {console.info('[EntryFormAbility] updateForm, error:' + JSON.stringify(error));});
}
开发卡片页面
开发者可以使用类Web范式(HML+CSS+JSON)开发JS卡片页面。生成如下卡片页面,可以这样配置卡片页面文件:
说明
当前仅支持JS扩展的类Web开发范式来实现卡片的UI。
-
HML:使用类Web范式的组件描述卡片的页面信息。
<div class="container"><stack><div class="container-img"><image src="/common/widget.png" class="bg-img"></image></div><div class="container-inner"><text class="title">{{title}}</text><text class="detail_text" onclick="routerEvent">{{detail}}</text></div></stack> </div>
-
CSS:HML中类Web范式组件的样式信息。
.container {flex-direction: column;justify-content: center;align-items: center; }.bg-img {flex-shrink: 0;height: 100%; }.container-inner {flex-direction: column;justify-content: flex-end;align-items: flex-start;height: 100%;width: 100%;padding: 12px; }.title {font-size: 19px;font-weight: bold;color: white;text-overflow: ellipsis;max-lines: 1; }.detail_text {font-size: 16px;color: white;opacity: 0.66;text-overflow: ellipsis;max-lines: 1;margin-top: 6px; }
-
JSON:卡片页面中的数据和事件交互。
{"data": {"title": "TitleDefault","detail": "TextDefault"},"actions": {"routerEvent": {"action": "router","abilityName": "EntryAbility","params": {"message": "add detail"}}} }
开发卡片事件
卡片支持为组件设置交互事件(action),包括router事件和message事件,其中router事件用于UIAbility跳转,message事件用于卡片开发人员自定义点击事件。
关键步骤说明如下:
- 在HML中为组件设置onclick属性,其值对应到JSON文件的actions字段中。
- 设置router事件:
- action属性值为"router"。
- abilityName为跳转目标的UIAbility名(支持跳转FA模型的PageAbility组件和Stage模型的UIAbility组件),如目前DevEco Studio创建的Stage模型的UIAbility默认名为EntryAbility。
- params为传递给跳转目标UIAbility的自定义参数,可以按需填写。其值可以在目标UIAbility启动时的want中的parameters里获取。如Stage模型MainAbility的onCreate生命周期里的入参want的parameters字段下获取到配置的参数。
- 设置message事件:
- action属性值为"message"。
- params为message事件的用户自定义参数,可以按需填写。其值可以在卡片生命周期函数onFormEvent()中的message里获取。
示例如下。
-
HML文件
<div class="container"><stack><div class="container-img"><image src="/common/widget.png" class="bg-img"></image></div><div class="container-inner"><text class="title" onclick="routerEvent">{{title}}</text><text class="detail_text" onclick="messageEvent">{{detail}}</text></div></stack> </div>
-
CSS文件
.container {flex-direction: column;justify-content: center;align-items: center; }.bg-img {flex-shrink: 0;height: 100%; }.container-inner {flex-direction: column;justify-content: flex-end;align-items: flex-start;height: 100%;width: 100%;padding: 12px; }.title {font-size: 19px;font-weight: bold;color: white;text-overflow: ellipsis;max-lines: 1; }.detail_text {font-size: 16px;color: white;opacity: 0.66;text-overflow: ellipsis;max-lines: 1;margin-top: 6px; }
-
JSON文件
{"data": {"title": "TitleDefault","detail": "TextDefault"},"actions": {"routerEvent": {"action": "router","abilityName": "EntryAbility","params": {"info": "router info","message": "router message"}},"messageEvent": {"action": "message","params": {"detail": "message detail"}}} }
-
在UIAbility中接收router事件并获取参数
import UIAbility from '@ohos.app.ability.UIAbility'export default class EntryAbility extends UIAbility {onCreate(want, launchParam) {let params = JSON.parse(want.parameters.params);// 获取router事件中传递的info参数if (params.info === "router info") {// do something// console.info("router info:" + params.info)}// 获取router事件中传递的message参数if (params.message === "router message") {// do something// console.info("router message:" + params.message)}}... };
-
在FormExtensionAbility中接收message事件并获取参数
import FormExtension from '@ohos.app.form.FormExtensionAbility';export default class FormAbility extends FormExtension {...onFormEvent(formId, message) {// 获取message事件中传递的detail参数let msg = JSON.parse(message)if (msg.detail === "message detail") {// do something// console.info("message info:" + msg.detail)}}... };
相关文章:

HarmonyOS4.0系统性深入开发08服务卡片架构
服务卡片概述 服务卡片(以下简称“卡片”)是一种界面展示形式,可以将应用的重要信息或操作前置到卡片,以达到服务直达、减少体验层级的目的。卡片常用于嵌入到其他应用(当前卡片使用方只支持系统应用,如桌…...

002文章解读与程序——中国电机工程学报EI\CSCD\北大核心《计及源荷不确定性的综合能源生产单元运行调度与容量配置两阶段随机优化》已提供下载资源
👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆下载资源链接Ǵ…...

Typora快捷键设置详细教程
文章目录 一、快捷键设置步骤二、设置快捷键简单案例参考资料 一、快捷键设置步骤 在typora软件中,快捷键的设置步骤主要为: 打开【文件】–>【偏好设置】,找到【通用】–>【打开高级设置】,找到 conf.user.json 文件。 然…...

《异常检测——从经典算法到深度学习》25 基于深度隔离林的异常检测算法
《异常检测——从经典算法到深度学习》 0 概论1 基于隔离森林的异常检测算法 2 基于LOF的异常检测算法3 基于One-Class SVM的异常检测算法4 基于高斯概率密度异常检测算法5 Opprentice——异常检测经典算法最终篇6 基于重构概率的 VAE 异常检测7 基于条件VAE异常检测8 Donut: …...
第7章 1 异常处理
bug的由来及分类 p81 字符串形式表示的数字之间也可以比较大小 import re ageinput(年龄:) if age>18:print(age)列表的append操作每次只能添加一个元素: lst[] lst.append(A) lst.append(B) # lst.append(A,B) 错误python中的异常处理机制 p82 t…...

昇腾910平台安装驱动、固件、CANN toolkit、pytorch
本文使用的昇腾910平台操作系统是openEuler,之前没了解过,不过暂时感觉用起来和centOS差不多。系统架构是ARM,安装包基本都是带aarch64字样,注意和x86_64区别开,别下错了。 安装依赖 cmake 通过yum安装的cmake版本较…...
【数据挖掘】模型融合
模型融合是指将多个不同的机器学习模型组合起来,通过综合多个模型的预测结果来得到更准确的预测结果。模型融合可以提高模型的鲁棒性,减小模型的方差,提高模型的泛化能力。 常见的模型融合方法包括平均法、投票法和堆叠法。 平均法(Averagin…...

DM、Oracle、GaussDB、Kingbase8(人大金仓数据库)和HIVE给列增加注释
DM数据库给列增加注释 1、创建表 CREATE TABLE test222 ( id int NOT NULL PRIMARY KEY, name varchar(1000) DEFAULT NULL, email varchar(1000) DEFAULT NULL, phone varchar(1000) DEFAULT NULL ) 2、给列添加注释 comment on column TEST222.NAME is 这是一个列注释; 例如…...

C语言实例_stdlib.h库函数功能及其用法详解
一、前言 C语言作为一种高效、灵活的编程语言,标准库的使用对于开发人员来说是不可或缺的。其中,stdlib.h是C语言中一个重要的标准库头文件,提供了许多常用的函数和工具,以便开发人员能够更加便捷地进行内存管理、字符串处理、随…...
Error in onLoad hook: “URIError: URI malformed“ found in…报错处理以及完善uniapp针对对象传参
使用uniapp传参的过程中遇到这么一个问题,当我们需要传整个对象作为参数时,我会先将这个对象先编码,然后再解码,从而获取到怎么参数,平常实操的时候也没有遇到过问题,但是今天测试的时候,刚好一…...

c语言-位操作符练习题
文章目录 前言一、n&(n-1)的运用场景(n为整数)二、&1 和 >>的应用场景总结 前言 本篇文章介绍利用c语言的位操作符解决一些练习题,目的是掌握各个位操作符的使用和应用场景。 表1.1为c语言中的位操作符 操作符含义&按位与|按位或^按位异或~按位…...

园林机械部件自动化三维测量检测形位公差-CASAIM自动化三维检测工作站
随着园林机械的广泛应用,对其机械部件的精确测量需求也日益增加。传统的测量方法不仅效率低下,而且精度难以保证,因此,自动化三维测量技术成为了解决这一问题的有效途径。本文将重点介绍CASAIM自动化三维检测工作站在园林机械部件…...

o2o生活通全开源尊享版+多城市切换+企业付款+交友IM+平台快报
搭建教程 1.把 pigo2ov282.sql 文件里面的网址 test.souho.net 全部批量替换为你的自己的 2.使用 phpmyadmin 导入 pigo2ov282.sql 到你的数据库(直接访问/phpmyadmin 即可) 3.修改数据库文件/conf/db.php 里的数据库连接信息(请勿使用记事本…...

UE4开发BIM程序 的 流程
某机构BIM设计研究中心主任马晓龙,他对编程颇有研究。今天他会用通俗易懂的语言来讲解基于游戏引擎UE4的BIM技术可视化应用。对于想要自己开发程序的设计师一定要读一下! 1)关于UE4——UE4是什么? 可以简单的理解为,一…...

【AI大语言模型】ChatGPT在地学、GIS、气象、农业、生态、环境等领域中的应用
以ChatGPT、LLaMA、Gemini、DALLE、Midjourney、Stable Diffusion、星火大模型、文心一言、千问为代表AI大语言模型带来了新一波人工智能浪潮,可以面向科研选题、思维导图、数据清洗、统计分析、高级编程、代码调试、算法学习、论文检索、写作、翻译、润色、文献辅助…...
【面试题】写一个睡眠函数
题目要求 请你编写一个异步函数,它接收一个正整数参数 millis ,并休眠 millis 毫秒。要求此函数可以解析任何值。 示例 1: 输入:millis 100 输出:100 解释: 在 100ms 后此异步函数执行完时返回一个 Pro…...

4. 云原生之kubesphere基础服务搭建
文章目录 安装kubesphere插件服务暴露NodePort方式LoadBalancer方式安装 OpenELB部署eip资源配置网关启动网关创建路由测试网关路由ingress高级功能在服务中配置LoadBalancer 基础设施部署服务部署建议helm仓库添加helm仓库 运维相关部署gitlab部署nexus3部署harbor 研发相关 安…...

思福迪运维安全管理系统 任意文件读取漏洞
产品简介 思福迪运维安全管理系统是思福迪开发的一款运维安全管理堡垒机 漏洞概述 由于思福迪运维安全管理系统 GetCaCert路由存在任意文件读取漏洞,攻击者可通过该漏洞在服务器端读取任意文件敏感内容,可能导致攻击者后续获取到相关的服务器权限 资…...

OCR在审核应用落地
本文字数:6686字 预计阅读时间:35分钟 01 背景 1、业务背景 在传统视频审核场景中,审核人员需要对进审视频中的文字内容进行逐一审核,避免在文字上出现敏感词、违禁词或者广告等相关词汇。这种人工审核费时费力,并且由…...

借贷协议 Tonka Finance:铭文资产流动性的新破局者
“Tonka Finance 是铭文赛道中首个借贷协议,它正在为铭文资产赋予捕获流动性的能力,并为其构建全新的金融场景。” 在 2023 年的 1 月,比特币 Ordinals 协议被推出后,包括 BRC20,Ordinals 等在内的系列铭文资产在包括比…...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...

微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...
【Go】3、Go语言进阶与依赖管理
前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes࿰…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...
大数据学习(132)-HIve数据分析
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言Ǵ…...
Typeerror: cannot read properties of undefined (reading ‘XXX‘)
最近需要在离线机器上运行软件,所以得把软件用docker打包起来,大部分功能都没问题,出了一个奇怪的事情。同样的代码,在本机上用vscode可以运行起来,但是打包之后在docker里出现了问题。使用的是dialog组件,…...

CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)
漏洞概览 漏洞名称:Apache Flink REST API 任意文件读取漏洞CVE编号:CVE-2020-17519CVSS评分:7.5影响版本:Apache Flink 1.11.0、1.11.1、1.11.2修复版本:≥ 1.11.3 或 ≥ 1.12.0漏洞类型:路径遍历&#x…...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...

Unity中的transform.up
2025年6月8日,周日下午 在Unity中,transform.up是Transform组件的一个属性,表示游戏对象在世界空间中的“上”方向(Y轴正方向),且会随对象旋转动态变化。以下是关键点解析: 基本定义 transfor…...
Modbus RTU与Modbus TCP详解指南
目录 1. Modbus协议基础 1.1 什么是Modbus? 1.2 Modbus协议历史 1.3 Modbus协议族 1.4 Modbus通信模型 🎭 主从架构 🔄 请求响应模式 2. Modbus RTU详解 2.1 RTU是什么? 2.2 RTU物理层 🔌 连接方式 ⚡ 通信参数 2.3 RTU数据帧格式 📦 帧结构详解 🔍…...