卡片代理刷新

卡片代理刷新是一种通过系统应用刷新卡片的机制。卡片提供方不在运行时,仍然可以通过开启了数据共享能力的系统应用完成卡片数据的更新。

实现原理

图1 代理刷新运行原理 UpdateWidgetByProxyPrinciple

如图1,与ArkTS卡片实现原理图相比,卡片代理刷新原理新增了数据管理服务和数据提供方。

  • 数据管理服务:该场景下主要提供了多应用间的数据共享的机制。
  • 数据提供方(仅支持系统应用):系统应用作为数据提供方,需要开启数据共享能力,同时需要自定义key + subscriberId作为共享数据的标识。

说明:

只有系统提供了作为数据提供方的应用,同时提供公开可获得的共享数据标识,才能正常使用该特性。

卡片提供方处理流程(图中蓝色箭头):

  1. 卡片提供方在卡片提供方的配置文件form_config.json中配置dataProxyEnabled字段为true,以开启卡片代理刷新功能。

说明:

卡片代理刷新开启后,定时刷新下次刷新失效。

  1. 卡片提供方在onAddForm回调中,把数据提供方定义的key + subscriberId返回给卡片管理服务。

  2. 卡片管理服务解析卡片提供方的订阅信息,并向数据管理服务注册订阅实例。

卡片代理刷新运行流程(图中红色箭头):

  1. 数据提供方以key + subscriberId作为数据的标识,将数据存储到数据库。
  2. 数据管理服务感知到数据库变化,将新的数据发布给当前注册的所有订阅实例。
  3. 卡片管理服务从订阅实例中解析出数据,发送给卡片渲染服务。
  4. 卡片渲染服务运行卡片页面代码widgets.abc,widgets.abc按新数据进行渲染,并将渲染后的数据发送至卡片使用方对应的卡片组件

数据提供方提供的共享数据有两种类型:

  • 过程数据,不会一直存储,有老化期,所有应用都可以订阅。

  • 持久化数据,仅系统应用可以订阅。

相应的卡片代理刷新配置有所不同,下面分别介绍具体开发方式。

数据提供方开发步骤

参考数据管理开发指南。

卡片提供方开发步骤(过程数据)

  • 配置form_config.json文件中的dataProxyEnabled字段为true,以启用卡片代理刷新功能,当订阅的过程数据更新时,系统会自动更新卡片数据。

    {
      "forms": [
        {
          "name": "WidgetProcessData",
          "description": "$string:ProcessDataEntryAbility_desc",
          "src": "./ets/widgetprocessdata/pages/WidgetProcessDataCard.ets",
          "uiSyntax": "arkts",
          "window": {
            "designWidth": 720,
            "autoDesignWidth": true
          },
          "colorMode": "auto",
          "isDefault": true,
          "updateEnabled": true,
          "scheduledUpdateTime": "10:30",
          "defaultDimension": "2*2",
          "supportDimensions": [
            "2*2"
          ],
          "dataProxyEnabled": true
        }
      ]
    }
    
  • onAddForm回调中配置订阅信息proxyData,并通过formBinding返回给卡片管理服务。示例中将key设置为"datashareproxy://com.samples.widgetupdatebyproxy/weather",subscriberId设置为"11"。

    说明:

    key可以是uri也可以是简单字符串,subscriberId默认值为当前formId,实际取值都依赖于数据发布方的定义。

    import formBindingData from '@ohos.app.form.formBindingData';
    import FormExtensionAbility from '@ohos.app.form.FormExtensionAbility';
    import hilog from '@ohos.hilog';
    import type Want from '@ohos.app.ability.Want';
    
    const TAG: string = 'ProcessDataFormAbility';
    const DOMAIN_NUMBER: number = 0xFF00;
    
    export default class ProcessDataFormAbility extends FormExtensionAbility {
      onAddForm(want: Want): formBindingData.FormBindingData {
        let formData: Record<string, Object> = {};
        let proxies: formBindingData.ProxyData[] = [
          {
            key: 'datashareproxy://com.samples.widgetupdatebyproxy/weather',
            subscriberId: '11'
          }
        ];
        let formBinding = formBindingData.createFormBindingData(formData);
        formBinding.proxies = proxies;
        hilog.info(DOMAIN_NUMBER, TAG, 'onAddForm');
        return formBinding;
      }
    }
    
  • 卡片页面文件中,通过LocalStorage变量获取订阅到的数据,LocalStorage绑定了一个字符串,以key:value的键值对格式来刷新卡片订阅数据,其中key必须与卡片提供方订阅的key保持一致。示例中,通过'city'获取订阅的数据,并在Text组件显示。

    let storageProcess = new LocalStorage();
    
    @Entry(storageProcess)
    @Component
    struct WidgetProcessDataCard {
      @LocalStorageProp('datashareproxy://com.samples.widgetupdatebyproxy/weather') city: ResourceStr = $r('app.string.loading');
    
      build() {
        Column() {
          Column() {
            Text(this.city)
              .fontColor('#FFFFFF')
              .opacity(0.9)
              .fontSize(14)
              .margin({ top: '8%', left: '10%' })
          }.width('100%')
          .alignItems(HorizontalAlign.Start)
        }.width('100%').height('100%')
        .backgroundImage($r('app.media.CardEvent'))
        .backgroundImageSize(ImageSize.Cover)
      }
    }
    

卡片提供方开发步骤(持久化数据,仅对系统应用开放)

  • 配置form_config.json文件中的dataProxyEnabled字段为true,以启用卡片代理刷新功能。

    {
      "forms": [
        {
          "name": "WidgetPersistentData",
          "description": "This is a service widget update by proxy using persistent data.",
          "src": "./ets/widgetpersistentdata/pages/WidgetPersistentDataCard.ets",
          "uiSyntax": "arkts",
          "window": {
            "designWidth": 720,
            "autoDesignWidth": true
          },
          "colorMode": "auto",
          "isDefault": true,
          "updateEnabled": true,
          "scheduledUpdateTime": "10:30",
          "updateDuration": 1,
          "defaultDimension": "2*2",
          "supportDimensions": [
            "2*2"
          ],
          "dataProxyEnabled": true
        }
    ]
    }
    
  • onAddForm回调中添加订阅模板addTemplate,通过模板谓词告诉数据库订阅的数据条件。然后配置订阅信息proxyData,并通过formBinding返回给卡片管理服务。示例中将谓词设置为"list" : "select type from TBL00 limit 0,1",表示从TBL00数据库中获取type列的第一条数据,数据将会以{"list":[{"type":"value0"}]}格式返回到卡片页面代码widgets.abc中。当订阅的持久化数据更新时,系统会自动更新卡片数据。

    说明:

    • key的取值是uri,依赖于数据发布方定义。
    • subscriberId可自定义,addTemplate中的subscriberId参数与proxies.subscriberId保持一致即可。
    import dataShare from '@ohos.data.dataShare';
    import type formBindingData from '@ohos.app.form.formBindingData';
    import FormExtensionAbility from '@ohos.app.form.FormExtensionAbility';
    import type Want from '@ohos.app.ability.Want';
    
    export default class PersistentDataFormAbility extends FormExtensionAbility {
      onAddForm(want: Want): formBindingData.FormBindingData {
        let dataShareHelper;
        let subscriberId = '111';
        let template = {
          predicates: {
            'list': `select type from TBL00 where cityId = ${subscriberId}`
          },
          scheduler: ''
        };
        dataShare.createDataShareHelper(this.context, 'datashareproxy://com.samples.widgetupdatebyproxy', {
          isProxy: true
        }).then((data) => {
          dataShareHelper = data;
          dataShareHelper.addTemplate('datashareproxy://com.samples.widgetupdatebyproxy/test', subscriberId, template);
        });
        let formData = {};
        let proxies = [
          {
            key: 'datashareproxy://com.samples.widgetupdatebyproxy/test',
            subscriberId: subscriberId
          }
        ];
    
        let formBinding = {
          data: JSON.stringify(formData),
          proxies: proxies
        };
        return formBinding;
      }
    }
    
  • 卡片页面文件中,通过LocalStorage变量获取订阅到的数据,LocalStorage绑定了一个字符串,以key:value的键值对格式来刷新卡片订阅数据,其中key必须与卡片提供方订阅的key保持一致。示例中,通过'list'获取订阅的数据,并把第一个元素的值显示在Text组件上。

    let storagePersis = new LocalStorage();
    
    @Entry(storagePersis)
    @Component
    struct WidgetPersistentDataCard {
      readonly FULL_WIDTH_PERCENT: string = '100%';
      readonly FULL_HEIGHT_PERCENT: string = '100%';
      @LocalStorageProp('list') list: Record<string, string>[] = [{ 'type': 'a' }];
    
      build() {
        Column() {
          Column() {
            Text((this.list[0]['type']))
              .fontColor('#FFFFFF')
              .opacity(0.9)
              .fontSize(14)
              .margin({ top: '8%', left: '10%' })
          }.width('100%')
          .alignItems(HorizontalAlign.Start)
        }.width(this.FULL_WIDTH_PERCENT).height(this.FULL_HEIGHT_PERCENT)
        .backgroundImage($r('app.media.CardEvent'))
        .backgroundImageSize(ImageSize.Cover)
      }
    }
    

相关实例

针对卡片代理开发,有以下相关实例可供参考: