1# 通过router或call事件刷新卡片内容 2 3使用router事件,点击卡片可拉起对应应用的UIAbility至前台,并刷新卡片。使用call事件,点击卡片可拉起对应应用的UIAbility至后台,并刷新卡片。在卡片页面中可以通过[postCardAction](../reference/apis-arkui/js-apis-postCardAction.md#postcardaction)接口触发router事件或者call事件拉起UIAbility,然后由UIAbility刷新卡片内容,下面是这种刷新方式的简单示例。 4 5> **说明:** 6> 7> 本文主要介绍动态卡片的事件开发。对于静态卡片,请参见[FormLink](../reference/apis-arkui/arkui-ts/ts-container-formlink.md)。 8 9## 通过router事件刷新卡片内容 10 11- 在卡片页面代码文件中,通过注册Button的onClick点击事件回调并在回调中调用postCardAction接口,触发router事件拉起UIAbility至前台。 12 13 ```ts 14 let storageUpdateRouter = new LocalStorage(); 15 16 @Entry(storageUpdateRouter) 17 @Component 18 struct WidgetUpdateRouterCard { 19 @LocalStorageProp('routerDetail') routerDetail: ResourceStr = $r('app.string.init'); 20 21 build() { 22 Column() { 23 Column() { 24 Text(this.routerDetail) 25 .fontColor('#FFFFFF') 26 .opacity(0.9) 27 .fontSize(14) 28 .margin({ top: '8%', left: '10%', right: '10%' }) 29 .textOverflow({ overflow: TextOverflow.Ellipsis }) 30 .maxLines(2) 31 }.width('100%').height('50%') 32 .alignItems(HorizontalAlign.Start) 33 34 Row() { 35 Button() { 36 Text($r('app.string.JumpLabel')) 37 .fontColor('#45A6F4') 38 .fontSize(12) 39 } 40 .width(120) 41 .height(32) 42 .margin({ top: '30%', bottom: '10%' }) 43 .backgroundColor('#FFFFFF') 44 .borderRadius(16) 45 .onClick(() => { 46 postCardAction(this, { 47 action: 'router', 48 abilityName: 'WidgetEventRouterEntryAbility', // 只能跳转到当前应用下的UIAbility 49 params: { 50 routerDetail: 'RouterFromCard', 51 } 52 }); 53 }) 54 }.width('100%').height('40%') 55 .justifyContent(FlexAlign.Center) 56 } 57 .width('100%') 58 .height('100%') 59 .alignItems(HorizontalAlign.Start) 60 .backgroundImage($r('app.media.CardEvent')) 61 .backgroundImageSize(ImageSize.Cover) 62 } 63 } 64 ``` 65 66- 在UIAbility的onCreate或者onNewWant生命周期中可以通过入参want获取卡片的formID和传递过来的参数信息,然后调用[updateForm](../reference/apis-form-kit/js-apis-app-form-formProvider.md#updateform)接口刷新卡片。 67 68 ```ts 69 import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; 70 import { window } from '@kit.ArkUI'; 71 import { BusinessError } from '@kit.BasicServicesKit'; 72 import { formBindingData, formInfo, formProvider } from '@kit.FormKit'; 73 import { hilog } from '@kit.PerformanceAnalysisKit'; 74 75 const TAG: string = 'WidgetEventRouterEntryAbility'; 76 const DOMAIN_NUMBER: number = 0xFF00; 77 78 export default class WidgetEventRouterEntryAbility extends UIAbility { 79 onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { 80 this.handleFormRouterEvent(want, 'onCreate'); 81 } 82 83 handleFormRouterEvent(want: Want, source: string): void { 84 hilog.info(DOMAIN_NUMBER, TAG, `handleFormRouterEvent ${source}, Want: ${JSON.stringify(want)}`); 85 if (want.parameters && want.parameters[formInfo.FormParam.IDENTITY_KEY] !== undefined) { 86 let curFormId = want.parameters[formInfo.FormParam.IDENTITY_KEY].toString(); 87 // want.parameters.params 对应 postCardAction() 中 params 内容 88 let message: string = (JSON.parse(want.parameters?.params as string))?.routerDetail; 89 hilog.info(DOMAIN_NUMBER, TAG, `UpdateForm formId: ${curFormId}, message: ${message}`); 90 let formData: Record<string, string> = { 91 'routerDetail': message + ' ' + source + ' UIAbility', // 和卡片布局中对应 92 }; 93 let formMsg = formBindingData.createFormBindingData(formData); 94 formProvider.updateForm(curFormId, formMsg).then((data) => { 95 hilog.info(DOMAIN_NUMBER, TAG, 'updateForm success.', JSON.stringify(data)); 96 }).catch((error: BusinessError) => { 97 hilog.info(DOMAIN_NUMBER, TAG, 'updateForm failed.', JSON.stringify(error)); 98 }); 99 } 100 } 101 102 // 如果UIAbility已在后台运行,在收到Router事件后会触发onNewWant生命周期回调 103 onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): void { 104 hilog.info(DOMAIN_NUMBER, TAG, 'onNewWant Want:', JSON.stringify(want)); 105 this.handleFormRouterEvent(want, 'onNewWant'); 106 } 107 108 onWindowStageCreate(windowStage: window.WindowStage): void { 109 110 hilog.info(DOMAIN_NUMBER, TAG, '%{public}s', 'Ability onWindowStageCreate'); 111 112 windowStage.loadContent('pages/Index', (err, data) => { 113 if (err.code) { 114 hilog.error(DOMAIN_NUMBER, TAG, 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); 115 return; 116 } 117 hilog.info(DOMAIN_NUMBER, TAG, 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? ''); 118 }); 119 } 120 // ... 121 } 122 ``` 123## 通过call事件刷新卡片内容 124 125- 在卡片页面代码文件中,通过注册Button的onClick点击事件回调并在回调中调用postCardAction接口,触发call事件拉起UIAbility至后台。 126 127 ```ts 128 let storageUpdateCall = new LocalStorage(); 129 130 @Entry(storageUpdateCall) 131 @Component 132 struct WidgetUpdateCallCard { 133 @LocalStorageProp('formId') formId: string = '12400633174999288'; 134 @LocalStorageProp('calleeDetail') calleeDetail: ResourceStr = $r('app.string.init'); 135 136 build() { 137 Column() { 138 Column() { 139 Text(this.calleeDetail) 140 .fontColor('#FFFFFF') 141 .opacity(0.9) 142 .fontSize(14) 143 .margin({ top: '8%', left: '10%' }) 144 }.width('100%').height('50%') 145 .alignItems(HorizontalAlign.Start) 146 147 Row() { 148 Button() { 149 Text($r('app.string.CalleeJumpLabel')) 150 .fontColor('#45A6F4') 151 .fontSize(12) 152 } 153 .width(120) 154 .height(32) 155 .margin({ top: '30%', bottom: '10%' }) 156 .backgroundColor('#FFFFFF') 157 .borderRadius(16) 158 .onClick(() => { 159 postCardAction(this, { 160 action: 'call', 161 abilityName: 'WidgetCalleeEntryAbility', // 只能拉起当前应用下的UIAbility 162 params: { 163 method: 'funA', 164 formId: this.formId, 165 calleeDetail: 'CallFrom' 166 } 167 }); 168 }) 169 }.width('100%').height('40%') 170 .justifyContent(FlexAlign.Center) 171 } 172 .width('100%') 173 .height('100%') 174 .alignItems(HorizontalAlign.Start) 175 .backgroundImage($r('app.media.CardEvent')) 176 .backgroundImageSize(ImageSize.Cover) 177 } 178 } 179 ``` 180 181- 在UIAbility的onCreate生命周期中监听call事件所需的方法,然后在对应方法中调用[updateForm](../reference/apis-form-kit/js-apis-app-form-formProvider.md#updateform)接口刷新卡片。 182 183 ```ts 184 import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; 185 import { window } from '@kit.ArkUI'; 186 import { BusinessError } from '@kit.BasicServicesKit'; 187 import { formBindingData, formProvider } from '@kit.FormKit'; 188 import { rpc } from '@kit.IPCKit'; 189 import { hilog } from '@kit.PerformanceAnalysisKit'; 190 191 const TAG: string = 'WidgetCalleeEntryAbility'; 192 const DOMAIN_NUMBER: number = 0xFF00; 193 const MSG_SEND_METHOD: string = 'funA'; 194 const CONST_NUMBER_1: number = 1; 195 196 class MyParcelable implements rpc.Parcelable { 197 num: number; 198 str: string; 199 200 constructor(num: number, str: string) { 201 this.num = num; 202 this.str = str; 203 }; 204 205 marshalling(messageSequence: rpc.MessageSequence): boolean { 206 messageSequence.writeInt(this.num); 207 messageSequence.writeString(this.str); 208 return true; 209 }; 210 211 unmarshalling(messageSequence: rpc.MessageSequence): boolean { 212 this.num = messageSequence.readInt(); 213 this.str = messageSequence.readString(); 214 return true; 215 }; 216 } 217 218 // 在收到call事件后会触发callee监听的方法 219 let funACall = (data: rpc.MessageSequence): MyParcelable => { 220 // 获取call事件中传递的所有参数 221 let params: Record<string, string> = JSON.parse(data.readString()); 222 if (params.formId !== undefined) { 223 let curFormId: string = params.formId; 224 let message: string = params.calleeDetail; 225 hilog.info(DOMAIN_NUMBER, TAG, `UpdateForm formId: ${curFormId}, message: ${message}`); 226 let formData: Record<string, string> = { 227 'calleeDetail': message 228 }; 229 let formMsg: formBindingData.FormBindingData = formBindingData.createFormBindingData(formData); 230 formProvider.updateForm(curFormId, formMsg).then((data) => { 231 hilog.info(DOMAIN_NUMBER, TAG, `updateForm success. ${JSON.stringify(data)}`); 232 }).catch((error: BusinessError) => { 233 hilog.error(DOMAIN_NUMBER, TAG, `updateForm failed: ${JSON.stringify(error)}`); 234 }); 235 } 236 return new MyParcelable(CONST_NUMBER_1, 'aaa'); 237 }; 238 239 export default class WidgetCalleeEntryAbility extends UIAbility { 240 onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { 241 try { 242 // 监听call事件所需的方法 243 this.callee.on(MSG_SEND_METHOD, funACall); 244 } catch (error) { 245 hilog.error(DOMAIN_NUMBER, TAG, `${MSG_SEND_METHOD} register failed with error ${JSON.stringify(error)}`); 246 } 247 } 248 249 onWindowStageCreate(windowStage: window.WindowStage): void { 250 // Main window is created, set main page for this ability 251 hilog.info(DOMAIN_NUMBER, TAG, '%{public}s', 'Ability onWindowStageCreate'); 252 253 windowStage.loadContent('pages/Index', (err, data) => { 254 if (err.code) { 255 hilog.error(DOMAIN_NUMBER, TAG, 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); 256 return; 257 } 258 hilog.info(DOMAIN_NUMBER, TAG, 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? ''); 259 }); 260 } 261 } 262 ``` 263 要拉起UIAbility至后台,需要在`module.json5`配置文件中,配置`ohos.permission.KEEP_BACKGROUND_RUNNING`权限。 264 ```json 265 "requestPermissions":[ 266 { 267 "name": "ohos.permission.KEEP_BACKGROUND_RUNNING" 268 } 269 ] 270 ```