3

HarmonyOS - 服务卡片进阶(一)

 2 years ago
source link: https://os.51cto.com/article/707284.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
HarmonyOS - 服务卡片进阶(一)-51CTO.COM
HarmonyOS - 服务卡片进阶(一)
作者:贾叶照 2022-04-24 15:26:38
服务卡片(以下简称“卡片”)是FA的一种界面展示形式,将FA的重要信息或操作前置到卡片,以达到服务直达,减少体验层级的目的。

b4c258695eb65f4e10296555865aa4593cef87.png

​想了解更多内容,请访问:​

​51CTO OpenHarmony技术社区​

​https://ost.51cto.com​

看本文章之前需要先熟悉一下原子化服务特征和流程 ​​HarmonyOS-5分钟教会你原子化服务​

服务卡片(以下简称“卡片”)是FA的一种界面展示形式,将FA的重要信息或操作前置到卡片,以达到服务直达,减少体验层级的目的。

卡片常用于嵌入到其他应用(当前只支持系统应用)中作为其界面的一部分显示,并支持拉起页面,发送消息等基础的交互功能。卡片使用方负责显示卡片。

  • 卡片提供方

开发者仅需作为卡片提供方进行服务卡片内容的开发,控制卡片实际显示的内容、控件布局以及控件点击事件

  • 卡片使用方

显示卡片内容的宿主应用,控制卡片在宿主中展示的位置。

  • 卡片管理服务

用于管理系统中所添加卡片的常驻代理服务,包括卡片对象的管理与使用,以及卡片周期性刷新等。

卡片使用方和提供方不要求常驻运行,在需要添加/删除/请求更新卡片时,卡片管理服务会拉起卡片提供方获取卡片信息。

服务卡片的运作机制

c8ac72a1115f259003e469f58b8aa4ec678bfe.png

卡片管理服务包含以下模块:

  • 周期性刷新:在卡片添加后,根据卡片的刷新策略启动定时任务周期性触发卡片的刷新。
  • 卡片缓存管理:在卡片添加到卡片管理服务后,对卡片的视图信息进行缓存,以便下次获取卡片时可以直接返回缓存数据,降低时延。
  • 卡片生命周期管理:对于卡片切换到后台或者被遮挡时,暂停卡片的刷新;以及卡片的升级/卸载场景下对卡片数据的更新和清理。
  • 卡片使用方对象管理:对卡片使用方的RPC对象进行管理,用于使用方请求进行校验以及对卡片更新后的回调处理。
  • 通信适配层:负责与卡片使用方和提供方进行RPC通信。
  • 卡片提供方包含以下模块:
  • 卡片服务:由卡片提供方开发者实现,开发者实现onCreateForm、onUpdateForm和onDeleteForm处理创建卡片、更新卡片以及删除卡片等请求,提供相应的卡片服务。
  • 卡片提供方实例管理模块:由卡片提供方开发者实现,负责对卡片管理服务分配的卡片实例进行持久化管理。
  • 通信适配层:由HarmonyOS SDK提供,负责与卡片管理服务通信,用于将卡片的更新数据主动推送到卡片管理服务。

服务卡片开发简介

关于服务卡片的接口说明,Java卡片与JS卡片选型,约束与限制可以去官网上查看:

​服务卡片开发简介​

Java卡片开发

这次先来讲解Java卡片开发,后期会专门用一篇来讲解JS卡片开发。

使用DevEco Studio创建卡片工程(前面文章已经说明,这里不再累述)。

我们先看看配置文件config.json:

  "forms": [
          {
            "landscapeLayouts": [
              "$layout:form_weather_widget_2_2"
            ],
            "isDefault": true,
            "scheduledUpdateTime": "10:30",
            "defaultDimension": "2*2",
            "name": "widget",
            "description": "This is a service widget",
            "colorMode": "auto",
            "type": "Java",
            "supportDimensions": [
              "2*2"
            ],
            "portraitLayouts": [
              "$layout:form_weather_widget_2_2"
            ],
            "updateEnabled": true,
            "updateDuration": 1
          }
        ],

“type”: 默认值是JS,我们需要更改为“Java”代表是一个Java卡片。

“scheduledUpdateTime”: 表示卡片的定点刷新的时刻,采用24小时制,精确到分钟。但是我在设置时间点的时候并没有更新,具体原因待考察。

 "scheduledUpdateTime": "10:30",

“updateEnabled”: 表示卡片是否支持周期性刷新,取值范围:

  • true:表示支持周期性刷。
  • false:表示不支持周期性刷新。

“updateDuration”:表示卡片定时刷新的更新周期,单位为30分钟,取值为自然数。

当取值为0时,表示该参数不生效。

当取值为正整数N时,表示刷新周期为30*N分钟。

 "updateEnabled": true,
 "updateDuration": 1

设置卡片定时刷新,每30分钟更新一次。

“supportDimensions”: 表示卡片支持的外观规格,取值范围:

  • 1*2:表示1行2列的二宫格。
  • 2*2:表示2行2列的四宫格。
  • 2*4:表示2行4列的八宫格。
  • 4*4:表示4行4列的十六宫格。

“portraitLayouts”:表示卡片外观规格对应的竖向布局文件,与supportDimensions中的规格一一对应。

仅当卡片类型为Java卡片时,需要配置该标签。

“landscapeLayouts”:表示卡片外观规格对应的横向布局文件,与supportDimensions中的规格一一对应。

仅当卡片类型为Java卡片时,需要配置该标签。

2. MainAbility中覆写卡片相关回调函数。

  • onCreateForm(Intent intent)。
  • onUpdateForm(long formId)。
  • onDeleteForm(long formId)。
  • onCastTempForm(long formId)。
  • onEventNotify(Map formEvents)。
  • onAcquireFormState(Intent intent)。

当卡片使用方请求获取卡片时,卡片提供方会被拉起并调用onCreateForm(Intent intent)回调,intent中会带有卡片ID,卡片名称,临时卡片标记和卡片外观规格信息,代码如下:

 protected ProviderFormInfo onCreateForm(Intent intent) {
        HiLog.info(TAG, "onCreateForm");
        // 卡片id
        long formId = intent.getLongParam(AbilitySlice.PARAM_FORM_IDENTITY_KEY, INVALID_FORM_ID);
        // 卡片名称
        String formName = intent.getStringParam(AbilitySlice.PARAM_FORM_NAME_KEY);
        // 卡片规格
        int dimension = intent.getIntParam(AbilitySlice.PARAM_FORM_DIMENSION_KEY, DEFAULT_DIMENSION_2X2);
        HiLog.info(TAG, "onCreateForm: formId=" + formId + ",formName=" + formName + ",dimension=" + dimension);
        // 将卡片信息存入数据库
        saveFormInfo(formId, formName, dimension);
        // 开发者需要根据卡片的名称以及外观规格获取对应的xml布局并构造卡片对象,此处ResourceTable.Layout_form_weather_widget_2_2
        ProviderFormInfo formInfo = new ProviderFormInfo(ResourceTable.Layout_form_weather_widget_2_2, this);
        //获取此 ProviderFormInfo 对象中包含的ComponentProvider数据。
        ComponentProvider componentProvider = formInfo.getComponentProvider();
        //设置组件的文本内容
        componentProvider.setText(ResourceTable.Id_weather_text,  "天气:多云");
        componentProvider.setText(ResourceTable.Id_weather_temperature,  "温度:29度");
        componentProvider.setText(ResourceTable.Id_weather_ph,  "PH值:2.9");
        //将ComponentProvider中指定的操作合并到此ProviderFormInfo对象中包含的 ComponentProvider 对象中
        formInfo.mergeActions(componentProvider);
        return formInfo;
    }

布局:form_weather_widget_2_2.xml。

<?xml version="1.0" encoding="utf-8"?>
<DependentLayout
    xmlns:ohos="http://schemas.huawei.com/res/ohos"
    ohos:height="match_parent"
    ohos:width="match_parent"
    ohos:background_element="#FFFFFFFF"
    ohos:remote="true">
    <Image
        ohos:height="match_parent"
        ohos:width="126vp"
        ohos:horizontal_center="true"
        ohos:image_src="$media:weather"
        ohos:scale_mode="zoom_start"
        ohos:top_margin="17vp"/>
    <DirectionalLayout
        ohos:height="match_content"
        ohos:width="match_content"
        ohos:align_parent_bottom="true"
        ohos:bottom_margin="12vp"
        ohos:horizontal_center="true"
        ohos:orientation="vertical">
        <Text
            ohos:id="$+id:weather_text"
            ohos:height="match_content"
            ohos:width="match_parent"
            ohos:text="天气:晴"
            ohos:text_color="#E5000000"
            ohos:text_size="12fp"
            ohos:text_weight="400"
            ohos:top_margin="2vp"
            ohos:truncation_mode="ellipsis_at_end"/>
        <Text
            ohos:id="$+id:weather_temperature"
            ohos:height="match_content"
            ohos:width="match_parent"
            ohos:text="温度:25度"
            ohos:text_color="#99000000"
            ohos:text_size="12fp"
            ohos:text_weight="400"
            ohos:top_margin="2vp"
            ohos:truncation_mode="ellipsis_at_end"/>
        <Text
            ohos:id="$+id:weather_ph"
            ohos:height="match_content"
            ohos:width="match_parent"
            ohos:text="PH值:2.5"
            ohos:text_color="#99000000"
            ohos:text_size="12fp"
            ohos:text_weight="400"
            ohos:top_margin="2vp"
            ohos:truncation_mode="ellipsis_at_end"/>
    </DirectionalLayout>
</DependentLayout>

6254e84498fdbfe328a0981a58e68eed095319.png

当需要卡片提供方更新数据时(如触发了定时更新、定点更新或者卡片使用方主动请求更新),卡片提供方获取最新数据,并调用updateForm接口更新卡片。示例如下:

 protected void onUpdateForm(long formId) {
        HiLog.info(TAG, "onUpdateForm");
        super.onUpdateForm(formId);
        refeshData();
    }
    /**
     * update forms
     */
    private void refeshData() {
        // 获取卡片集合
        List<FormInfo> formList = DatabaseUtils.queryForms(this, null);
        for (FormInfo formInfo : formList) {
            ProviderFormInfo refesh = new ProviderFormInfo(ResourceTable.Layout_form_weather_widget_2_2, this);
            ComponentProvider componentProvider = refesh.getComponentProvider();
            //这里更新的值,实际使用中可根据自己项目要求设置,比如:随机获取一个值
            componentProvider.setText(ResourceTable.Id_weather_text,  "天气:多云转晴");
            componentProvider.setText(ResourceTable.Id_weather_temperature,  "温度:30度");
            componentProvider.setText(ResourceTable.Id_weather_ph,  "PH值:3.0");
            try {
               //卡片提供方主动更新卡片
                updateForm(formInfo.getFormId(), componentProvider);
            } catch (FormException e) {
                HiLog.error(TAG, "FormException");
            }
        }
    }

定时更新效果:

45577b854ad647480bb47407439cd1e1d9166b.png

实际项目中需要通过网络获取数据,这里只是简单的模拟数据。只是简单说明了服务卡片创建的回调方法实现,定点和定时数据更新的时机和回调方法的实现,下期会更新关于服务卡片信息持久化、卡片控制事件。

​想了解更多内容,请访问:​

​51CTO OpenHarmony技术社区​

​https://ost.51cto.com​

71eea7105a1cf9982d2996c42d853b97bd50ef.jpg


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK