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