专栏名称: 51CTO官微
51CTO官方公众号——聚焦最新最前沿最有料的IT技术资讯、IT行业精华内容、产品交流心得。本订阅号为大家提供各种技术资讯和干货,还会不定期举办有奖活动,敬请关注。
目录
相关文章推荐
程序员的那些事  ·  Rust ... ·  3 天前  
程序员的那些事  ·  国企也中招!官网被挂上“码农的钱你也敢吞,* ... ·  3 天前  
程序员小灰  ·  DeepSeek让我的朋友一夜暴富! ·  5 天前  
程序员小灰  ·  DeepSeek + IDEA!辅助编程太强了! ·  4 天前  
51好读  ›  专栏  ›  51CTO官微

用Java开发HarmonyOS服务卡片

51CTO官微  · 公众号  · 程序员  · 2022-04-26 11:52

正文

点击蓝字 关注我们

了解与IT有关的人和事


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




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


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


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


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


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


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


服务卡片的运作机制


先上图:


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


  • 周期性刷新: 在卡片添加后,根据卡片的刷新策略启动定时任务周期性触发卡片的刷新。

  • 卡片缓存管理: 在卡片添加到卡片管理服务后,对卡片的视图信息进行缓存,以便下次获取卡片时可以直接返回缓存数据,降低时延。

  • 卡片生命周期管理: 对于卡片切换到后台或者被遮挡时,暂停卡片的刷新;以及卡片的升级/卸载场景下对卡片数据的更新和清理。

  • 卡片使用方对象管理: 对卡片使用方的 RPC 对象进行管理,用于使用方请求进行校验以及对卡片更新后的回调处理。

  • 通信适配层: 负责与卡片使用方和提供方进行 RPC 通信。


卡片提供方包含以下模块:


  • 卡片服务: 由卡片提供方开发者实现,开发者实现 onCreateForm、onUpdateForm 和 onDeleteForm 处理创建卡片、更新卡片以及删除卡片等请求,提供相应的卡片服务。

  • 卡片提供方实例管理模块: 由卡片提供方开发者实现,负责对卡片管理服务分配的卡片实例进行持久化管理。

  • 通信适配层: 由 HarmonyOS SDK 提供,负责与卡片管理服务通信,用于将卡片的更新数据主动推送到卡片管理服务。


服务卡片开发简介


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


https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ability-service-widget-provider-intro-0000001150722105

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 卡片时,需要配置该标签。


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



<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>



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


示例如下:


 protected void onUpdateForm(long formId{
        HiLog.info(TAG, "onUpdateForm");
        super.onUpdateForm(formId);
        refeshData();
    }

    /**
     * update forms
     */

    private void refeshData






请到「今天看啥」查看全文