HarmonyOS服務(wù)卡片開發(fā)知識總結(jié)
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)
前言
服務(wù)卡片的征文活動也已經(jīng)接近尾聲,在這段時間里,論壇里有許多優(yōu)秀的服務(wù)卡片作品和相關(guān)的文章涌現(xiàn)。我拜讀了專欄中幾乎所有的服務(wù)卡片的開發(fā)分享文章,從每一篇文章中提取并汲取精華,整合到本文中。一些較為顯然的介紹性的內(nèi)容在本文中將會被省略(如卡片有多少種尺寸之類),但是一些即使在很多文章都已經(jīng)說明過的,而我又認(rèn)為比較重要的內(nèi)容,我仍然會再次記錄下來(例如卡片的框架)。另外,作為學(xué)習(xí)筆記,我會記錄下一些我在學(xué)習(xí)種遇到的新的名詞的概念,這些概念可能是大家已經(jīng)熟知的,這部分大家可以直接忽略;文章的內(nèi)容整合自論壇種的眾多文章,所以大家可能會在本文中看到自己文章的影子。
服務(wù)卡片的框架
服務(wù)卡片整體框架主要包含三部分:卡片使用方、卡片管理服務(wù)和卡片提供方。其概念分別如下:
● 卡片使用方:顯示卡片內(nèi)容的宿主應(yīng)用,控制卡片在宿主中展示的位置,如桌面、服務(wù)中心、搜索等。
● 卡片管理服務(wù):用于管理系統(tǒng)中所添加卡片的常駐代理服務(wù),包括卡片對象的管理與使用,以及卡片周期性刷新等。
● 卡片提供方:提供卡片顯示內(nèi)容的HarmonyOS應(yīng)用或原子化服務(wù),控制卡片的顯示內(nèi)容、控件布局以及控件點擊事件。
卡片的運行框架有如下示意圖:

簡明版示意圖

詳細(xì)版示意圖
卡片的常用功能
Java卡片與JS卡片功能的對比圖

MainAbility的自動生成函數(shù)解析
在新建服務(wù)卡片的時候,在MainAbility類中將會生成一些回調(diào)方法,具體方法及其回調(diào)條件如下圖,在后面的具體的卡片操作中,也會再次聲明所調(diào)用的回調(diào)方法。

在onCreatForm(Intent)方法中,卡片提供方被拉起后intent會攜帶卡片相關(guān)信息,具體如下:

服務(wù)卡片生命周期回調(diào)函數(shù)時序如下:

配置卡片編輯功能
有些服務(wù)卡片需要具備可編輯能力,如天氣App需要編輯所在城市。具體實現(xiàn)方法如下:在config.json中,對某一個form的配置增加formConfigAbility的屬性配置,可實現(xiàn)編輯功能。formConfigAbility的值是一個url格式的Ability名稱。若不配置formConfigAbility,則不顯示編輯菜單。示例代碼如下:(摘抄自[一文看懂HarmonyOS服務(wù)卡片運行原理和開發(fā)方法])(https://harmonyos.oss-cn-beijing.aliyuncs.com/images/202106/830a107135e5fa06fa1714ebaa9fa523833da2.jpg?x-oss-process=image/resize,w_1080,h_478)

卡片的定點/定時刷新:將回調(diào)updateForm()方法
運作機制示意圖如下:

注意:定時刷新和定點刷新都配置的情況下,定時刷新優(yōu)先。
JS卡片的定點更新步驟:
1.關(guān)閉定時更新:updateDuration”修改為0,以關(guān)閉定時刷新(config.json文件中)
2.設(shè)定“scheduledUpdateTime”的時刻
3.在具體的xxxxlmpl中重寫updateFormData()方法
4.把需要刷新的數(shù)據(jù)存入一個ZSONObject實例中
5.將這個實例封裝在一個FormBindingData的實例bindingData中
6.調(diào)用MainAbility的方法updateForm(),并將bindingData作為第二個實參。
JS卡片重寫updateFormData()方法的代碼如下:

JAVA卡片的定點更新步驟:
1.前三步與JS卡片相同
2.構(gòu)造一個ComponentProvider的實例,用于表示一個Java卡片實例,傳入的第一個實參是根據(jù)卡片尺寸得到的布局文件。然后,調(diào)用方法setText()修改卡片的標(biāo)題;最后,調(diào)用MainAbility的方法updateForm(),并將componentProvider作為第二個實參。
JAVA卡片重寫updateFormData()方法的代碼如下:

卡片的定時刷新
卡片的定時刷新的最小單位時間是三十分鐘,這就帶來了兩個問題:
1.創(chuàng)建卡片后的最初的三十分鐘是不會進(jìn)行卡片刷新的,所以需要進(jìn)行手動的刷新。
2.如果是編寫刷新間隔小于三十分的卡片(如時鐘卡片每一秒刷新一次),那么需要自己重新創(chuàng)建一個timer實例來設(shè)定刷新時間。
添加手動刷新:用onCreateForm()調(diào)用onUpdateForm(formId)即可,代碼摘抄自亮子力的嗶哩嗶哩卡片
- @Override
- protected ProviderFormInfo onCreateForm(Intent intent) {
- ... ...
- //初始化時先在線更新一下卡片
- onUpdateForm(formId);
- return formController.bindFormData();
- }
重新編寫刷新時間的代碼為代碼摘抄自Codelabs 之 時鐘FA卡片開發(fā)樣例
- private void startTimer() {
- Timer timer = new Timer();
- timer.schedule(
- new TimerTask() {
- @Override
- public void run() {
- updateForms();
- }
- },
- 0,
- SEND_PERIOD);
- }
- private void updateForms() {
- // 從數(shù)據(jù)庫中獲取卡片信息
- HiLog.info(LABEL, "從數(shù)據(jù)庫中獲取卡片");
- OrmPredicates ormPredicates = new OrmPredicates(Form.class);
- List<Form> formList = connect.query(ormPredicates);
- int layoutId=0;
- // 更新時分秒
- if (formList.size() <= 0) {
- return;
- }
- HiLog.info(LABEL, "遍歷卡片列表,逐個更新");
- for (Form form : formList) {
- // 遍歷卡片列表更新卡片
- ComponentProvider componentProvider = ComponentProviderUtils.getComponentProvider(form, this);
- try {
- Long updateFormId = form.getFormId();
- HiLog.info(LABEL, "updateForm,更新卡片[:"+updateFormId+"] 的數(shù)據(jù),并非數(shù)據(jù)庫操作" );
- //更新卡片數(shù)據(jù)
- boolean isSucc=updateForm(updateFormId, componentProvider);
- HiLog.info(LABEL, "更新卡片數(shù)據(jù)完成,"+isSucc);
- } catch (FormException e) {
- // 刪除不存在的卡片
- DatabaseUtils.deleteFormData(form.getFormId(), connect);
- HiLog.error(LABEL, "更新卡片異常,刪除數(shù)據(jù)庫中不存在的卡片");
- }
- }
- }
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)