1# 卡片代理刷新 2 3卡片代理刷新是一种通过系统应用刷新卡片的机制。卡片提供方不在运行时,仍然可以通过开启了数据共享能力的系统应用完成卡片数据的更新。 4 5## 实现原理 6 7**图1** 代理刷新运行原理 8 9 10如图1,与[ArkTS卡片实现原理图](../application-models/arkts-ui-widget-working-principles.md#实现原理)相比,卡片代理刷新原理新增了数据管理服务和数据提供方。 11 12- 数据管理服务:该场景下主要提供了多应用间的数据共享的机制。 13- 数据提供方(仅支持系统应用):系统应用作为数据提供方,需要开启数据共享能力,同时需要自定义`key + subscriberId`作为共享数据的标识。 14 15> **说明:** 16> 17> 只有系统提供了作为数据提供方的应用,同时提供公开可获得的共享数据标识,才能正常使用该特性。 18 19卡片提供方处理流程(图中蓝色箭头): 20 211. 卡片提供方在卡片提供方的配置文件`form_config.json`中配置`dataProxyEnabled`字段为`true`,以开启卡片代理刷新功能。 22> **说明:** 23> 24> 卡片代理刷新开启后,[定时刷新](../application-models/arkts-ui-widget-update-by-time.md)和[下次刷新](../application-models/arkts-ui-widget-update-by-time.md)失效。 25 262. 卡片提供方在[onAddForm](../reference/apis/js-apis-app-form-formExtensionAbility.md#onaddform)回调中,把数据提供方定义的`key + subscriberId`返回给卡片管理服务。 27 283. 卡片管理服务解析卡片提供方的订阅信息,并向数据管理服务注册订阅实例。 29 30卡片代理刷新运行流程(图中红色箭头): 31 321. 数据提供方以`key + subscriberId`作为数据的标识,将数据存储到数据库。 332. 数据管理服务感知到数据库变化,将新的数据发布给当前注册的所有订阅实例。 343. 卡片管理服务从订阅实例中解析出数据,发送给卡片渲染服务。 354. 卡片渲染服务运行卡片页面代码widgets.abc,widgets.abc按新数据进行渲染,并将渲染后的数据发送至卡片使用方对应的[卡片组件](../reference/arkui-ts/ts-basic-components-formcomponent.md)。 36 37数据提供方提供的共享数据有两种类型: 38 39- 过程数据,不会一直存储,有老化期,所有应用都可以订阅。 40 41- 持久化数据,仅系统应用可以订阅。 42 43相应的卡片代理刷新配置有所不同,下面分别介绍具体开发方式。 44 45## 数据提供方开发步骤 46 47参考[数据管理](../database/share-data-by-silent-access.md)开发指南。 48 49## 卡片提供方开发步骤(过程数据) 50 51- 配置form_config.json文件中的`dataProxyEnabled`字段为`true`,以启用卡片代理刷新功能,当订阅的过程数据更新时,系统会自动更新卡片数据。 52 ```json 53 { 54 "forms": [ 55 { 56 "name": "widget", 57 "description": "This is a service widget.", 58 "src": "./ets/widget/pages/WidgetCard.ets", 59 "uiSyntax": "arkts", 60 "window": { 61 "designWidth": 720, 62 "autoDesignWidth": true 63 }, 64 "colorMode": "auto", 65 "isDefault": true, 66 "updateEnabled": true, 67 "scheduledUpdateTime": "10:30", 68 "defaultDimension": "2*2", 69 "supportDimensions": ["2*2"], 70 "dataProxyEnabled": true 71 } 72 ] 73 } 74 ``` 75 76- 在[onAddForm](../reference/apis/js-apis-app-form-formExtensionAbility.md#onaddform)回调中配置订阅信息[proxyData](../reference/apis/js-apis-app-form-formBindingData.md#proxydata10),并通过[formBinding](../reference/apis/js-apis-app-form-formBindingData.md#formbindingdata)返回给卡片管理服务。示例中将key设置为"detail",subscriberId设置为"11"。 77 > **说明:** 78 > 79 > key可以是uri也可以是简单字符串,subscriberId默认值为当前formId,实际取值都依赖于数据发布方的定义。 80 ```ts 81 import formBindingData from '@ohos.app.form.formBindingData'; 82 import Want from '@ohos.app.ability.Want'; 83 import FormExtensionAbility from '@ohos.app.form.FormExtensionAbility'; 84 85 export default class EntryFormAbility extends FormExtensionAbility { 86 onAddForm(want: Want) { 87 let formData: Record<string, Object> = {}; 88 let proxies: formBindingData.ProxyData[] = [ 89 { 90 "key": "detail", 91 "subscriberId": "11" 92 } 93 ] 94 let formBinding = formBindingData.createFormBindingData(formData); 95 formBinding["proxies"] = proxies; 96 return formBinding; 97 } 98 } 99 ``` 100 101- 在[卡片页面文件](arkts-ui-widget-creation.md)中,通过LocalStorage变量获取订阅到的数据,LocalStorage绑定了一个字符串,以key:value的键值对格式来刷新卡片订阅数据,其中key必须与卡片提供方订阅的key保持一致。示例中,通过'detail'获取订阅的数据,并在Text组件显示。 102 ```ts 103 let storage = new LocalStorage(); 104 @Entry(storage) 105 @Component 106 struct Index { 107 @LocalStorageProp('detail') detail: string = '加载中...'; 108 109 build() { 110 Row() { 111 Column() { 112 Text(this.detail) 113 .fontSize('12vp') 114 .textAlign(TextAlign.Center) 115 .width('100%') 116 .height('15%') 117 } 118 .width('100%') 119 } 120 .height('100%') 121 } 122 } 123 ``` 124 125## 卡片提供方开发步骤(持久化数据,仅对系统应用开放) 126- 配置form_config.json文件中的`dataProxyEnabled`字段为`true`,以启用卡片代理刷新功能。 127 ```json 128 { 129 "forms": [ 130 { 131 "name": "widget", 132 "description": "This is a service widget.", 133 "src": "./ets/widget/pages/WidgetCard.ets", 134 "uiSyntax": "arkts", 135 "window": { 136 "designWidth": 720, 137 "autoDesignWidth": true 138 }, 139 "colorMode": "auto", 140 "isDefault": true, 141 "updateEnabled": true, 142 "scheduledUpdateTime": "10:30", 143 "defaultDimension": "2*2", 144 "supportDimensions": ["2*2"], 145 "dataProxyEnabled": true 146 } 147 ] 148 } 149 ``` 150 151- 在[onAddForm](../reference/apis/js-apis-app-form-formExtensionAbility.md#onaddform)回调中添加订阅模板[addTemplate](../reference/apis/js-apis-data-dataShare.md#addtemplate10),通过模板谓词告诉数据库订阅的数据条件。然后配置订阅信息[proxyData](../reference/apis/js-apis-app-form-formBindingData.md#proxydata10),并通过[formBinding](../reference/apis/js-apis-app-form-formBindingData.md#formbindingdata)返回给卡片管理服务。示例中将谓词设置为`"list" : "select type from TBL00 limit 0,1"`,表示从TBL00数据库中获取type列的第一条数据,数据将会以`{"list":[{"type":"value0"}]}`格式返回到卡片页面代码widgets.abc中。当订阅的持久化数据更新时,系统会自动更新卡片数据。 152 153 > **说明:** 154 > 155 > - key的取值是uri,依赖于数据发布方定义。 156 > - subscriberId可自定义,addTemplate中的subscriberId参数与proxies.subscriberId保持一致即可。 157 ```ts 158 import formBindingData from '@ohos.app.form.formBindingData'; 159 import FormExtensionAbility from '@ohos.app.form.FormExtensionAbility'; 160 import dataShare from '@ohos.data.dataShare'; 161 import Want from '@ohos.app.ability.Want'; 162 163 let dataShareHelper: dataShare.DataShareHelper; 164 export default class EntryFormAbility extends FormExtensionAbility { 165 onAddForm(want: Want) { 166 let template: dataShare.Template = { 167 predicates: { 168 "list": "select type from TBL00 limit 0,1" 169 }, 170 scheduler: "" 171 } 172 let subscriberId: string = "111"; 173 dataShare.createDataShareHelper(this.context, "datashareproxy://com.example.myapplication", { 174 isProxy: true 175 }).then((data: dataShare.DataShareHelper) => { 176 dataShareHelper = data; 177 dataShareHelper.addTemplate("datashareproxy://com.example.myapplication/test", subscriberId, template); 178 }) 179 180 let formData: Record<string, Object> = {}; 181 let proxies: formBindingData.ProxyData[] = [ 182 { 183 "key": "datashareproxy://com.example.myapplication/test", 184 "subscriberId": subscriberId 185 } 186 ] 187 let formBinding = formBindingData.createFormBindingData(formData); 188 formBinding["proxies"] = proxies; 189 190 return formBinding; 191 } 192 } 193 ``` 194 195- 在[卡片页面文件](arkts-ui-widget-creation.md)中,通过LocalStorage变量获取订阅到的数据,LocalStorage绑定了一个字符串,以key:value的键值对格式来刷新卡片订阅数据,其中key必须与卡片提供方订阅的key保持一致。示例中,通过'list'获取订阅的数据,并把第一个元素的值显示在Text组件上。 196 ```ts 197 let storage = new LocalStorage(); 198 @Entry(storage) 199 @Component 200 struct WidgetCard { 201 readonly ACTION_TYPE: string = 'router'; 202 readonly ABILITY_NAME: string = 'EntryAbility'; 203 readonly MESSAGE: string = 'add detail'; 204 readonly FULL_WIDTH_PERCENT: string = '100%'; 205 readonly FULL_HEIGHT_PERCENT: string = '100%'; 206 @LocalStorageProp('list') list: Record<string, string>[] = [{"type": "a"}]; 207 208 build() { 209 Row() { 210 Column() { 211 Text((this.list[0]["type"])) 212 .fontSize($r('app.float.font_size')) 213 } 214 .width(this.FULL_WIDTH_PERCENT) 215 } 216 .height(this.FULL_HEIGHT_PERCENT) 217 .onClick(() => { 218 postCardAction(this, { 219 action: this.ACTION_TYPE, 220 abilityName: this.ABILITY_NAME, 221 params: { 222 message: this.MESSAGE 223 } 224 }) 225 }) 226 } 227 } 228 ``` 229 230## 相关实例 231 232针对卡片代理开发,有以下相关实例可供参考: 233 234- [应用主动添加数据代理卡片到桌面(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/OpenHarmony-4.0-Release/code/SuperFeature/Widget/RequestAddForm)