天天看點

HarmonyOS - 服務卡片進階(一)

作者:賈葉照

前言

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

基本概念

服務卡片(以下簡稱“卡片”)是FA的一種界面展示形式,将FA的重要資訊或操作前置到卡片,以達到服務直達,減少體驗層級的目的。

卡片常用于嵌入到其他應用(目前隻支援系統應用)中作為其界面的一部分顯示,并支援拉起頁面,發送消息等基礎的互動功能。卡片使用方負責顯示卡片。

  • 卡片提供方

    開發者僅需作為卡片提供方進行服務卡片内容的開發,控制卡片實際顯示的内容、控件布局以及控件點選事件

  • 卡片使用方

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

  • 卡片管理服務

    用于管理系統中所添加卡片的常駐代理服務,包括卡片對象的管理與使用,以及卡片周期性重新整理等。

說明

卡片使用方和提供方不要求常駐運作,在需要添加/删除/請求更新卡片時,卡片管理服務會拉起卡片提供方擷取卡片資訊。

服務卡片的運作機制

先上圖:

HarmonyOS - 服務卡片進階(一)

卡片管理服務包含以下子產品:

  • 周期性重新整理:在卡片添加後,根據卡片的重新整理政策啟動定時任務周期性觸發夾片的重新整理。
  • 卡片緩存管理:在卡片添加到卡片管理服務後,對卡片的視圖資訊進行緩存,以便下次擷取卡片時可以直接傳回緩存資料,降低延遲時間。
  • 卡片生命周期管理:對于卡片切換到背景或者被遮擋時,暫停卡片的重新整理;以及卡片的更新/解除安裝場景下對卡片資料的更新和清理。
  • 卡片使用方對象管理:對卡片使用方的RPC對象進行管理,用于使用方請求進行校驗以及對卡片更新後的回調處理。
  • 通信适配層:負責與卡片使用方和提供方進行RPC通信。

卡片提供方包含以下子產品:

  • 卡片服務:由卡片提供方開發者實作,開發者實作onCreateForm、onUpdateForm和onDeleteForm處理建立卡片、更新卡片以及删除卡片等請求,提供相應的卡片服務。
  • 卡片提供方執行個體管理子產品:由卡片提供方開發者實作,負責對卡片管理服務配置設定的卡片執行個體進行持久化管理。
  • 通信适配層:由HarmonyOS SDK提供,負責與卡片管理服務通信,用于将卡片的更新資料主動推送到卡片管理服務。

服務卡片開發簡介

關于服務卡片的接口說明,Java卡片與JS卡片選型,限制與限制可以去官網上檢視

服務卡片開發簡介

Java卡片開發

這次先來講解Java卡片開發,後期會專門用一篇來講解JS卡片開發。

  1. 使用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<Long, Integer> 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>
           
HarmonyOS - 服務卡片進階(一)

當需要卡片提供方更新資料時(如觸發了定時更新、定點更新或者卡片使用方主動請求更新),卡片提供方擷取最新資料,并調用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");
            }
        }
    }
           

定時更新效果:

HarmonyOS - 服務卡片進階(一)

總結

實際項目中需要通過網絡擷取資料,這裡隻是簡單的模拟資料。隻是簡單說明了服務卡片建立的回調方法實作,定點和定時資料更新的時機和回調方法的實作,下期會更新關于服務卡片資訊持久化、卡片控制事件。

更多原創内容請關注:中軟國際 HarmonyOS 技術團隊

入門到精通、技巧到案例,系統化分享HarmonyOS開發技術,歡迎投稿和訂閱,讓我們一起攜手前行共建鴻蒙生态。

想了解更多關于鴻蒙的内容,請通路:

51CTO OpenHarmony技術社群

https://ost.51cto.com/#bkwz

繼續閱讀