HarmonyOS - 服務卡片進階之二
前言
繼 HarmonyOS - 服務卡片進階(一)之后,補充關于服務卡片信息持久化、卡片控制事件的內容。
服務卡片信息持久化
因大部分卡片提供方都不是常駐服務,只有在需要使用時才會被拉起獲取卡片信息。且卡片管理服務支持對卡片進行多實例管理,卡片ID對應實例ID,因此若卡片提供方支持對卡片數據進行配置,則需要提供方對卡片的業務數據按照卡片ID進行持久化管理,以便在后續獲取、更新以及拉起時能獲取到正確的卡片業務數據。同時,需要適配onDeleteForm(int formId)卡片刪除通知接口,在其中實現卡片實例數據的刪除。
和JS卡片相同,需要注意卡片使用方在請求卡片時傳遞給提供方應用的Intent數據中存在臨時標記字段,表示此次請求的卡片是否為臨時卡片,由于臨時卡片的數據具有非持久化的特殊性,某些場景比如卡片服務框架死亡重啟,此時臨時卡片數據在卡片管理服務中已經刪除,且對應的卡片ID不會通知到提供方,所以卡片提供方需要自己負責清理長時間未刪除的臨時卡片數據。同時對應的卡片使用方可能會將之前請求的臨時卡片轉換為常態卡片。如果轉換成功,卡片提供方也需要對對應的臨時卡片ID進行處理,把卡片提供方記錄的臨時卡片數據轉換為常態卡片數據,防止提供方在清理長時間未刪除的臨時卡片時,把已經轉換為常態卡片的臨時卡片信息刪除,導致卡片信息丟失。
//臨時標記字段,表示此次請求的卡片是否為臨時卡片
boolean tempFlag = intent.getBooleanParam(AbilitySlice.PARAM_FORM_TEMPORARY_KEY, false);
- 常態卡片:卡片使用方會持久化的卡片。
- 臨時卡片:卡片使用方不會持久化的卡片。
臨時卡片轉換為常態卡片觸發
protected void onCastTempForm(long formId) {
// 使用方將臨時卡片轉換為常態卡片觸發,提供方需要做相應的處理
super.onCastTempForm(formId);
//todo
}
將創建的卡片信息持久化,以便在下次獲取/更新該卡片實例時進行使用。
// 將卡片信息存入數據庫
saveFormInfo(formId, formName, dimension);
private void saveFormInfo(Long formId, String formName, int dimension) {
FormInfo form = new FormInfo(formId, formName, dimension);
DatabaseUtils.insertForm(this, form);
}
關于OrmDatabase對象型數據庫部分我們可以參考肖瑜博老師我們帶來的??HarmonyOS-十分鐘教會數據庫快速上手??這篇文章,里面詳細介紹了關于對象型數據庫的配置、創建數據庫、表、對應實體類的屬性以及ormContext的創建。
Java卡片控制事件
Java卡片當前通過IntentAgent能力支持對卡片控制設置事件,例如可以使用START_ABILITY、START_SERVICE這兩類能力,在點擊整張卡片時,跳轉到提供卡片的ability。(注:Intent中支持自定義參數的傳遞,支持的類型有int/long/String/List)。
// 獲取ComponentProvider,渲染卡片界面
@Override
protected ProviderFormInfo onCreateForm(Intent intent) {
HiLog.info(TAG, "onCreateForm");
// 卡片id
long formId = intent.getLongParam(AbilitySlice.PARAM_FORM_IDENTITY_KEY, INVALID_FORM_ID);
// 卡片名稱
String formName = intent.getStringParam(AbilitySlice.PARAM_FORM_NAME_KEY);
// 卡片規格
int dimension = intent.getIntParam(AbilitySlice.PARAM_FORM_DIMENSION_KEY, DEFAULT_DIMENSION_2X2);
HiLog.info(TAG, "onCreateForm: formId=" + formId + ",formName=" + formName + ",dimension=" + dimension);
// 將卡片信息存入數據庫
saveFormInfo(formId, formName, dimension);
// 開發者需要根據卡片的名稱以及外觀規格獲取對應的xml布局并構造卡片對象,此處ResourceTable.Layout_form_weather_widget_2_2
ProviderFormInfo formInfo = new ProviderFormInfo(ResourceTable.Layout_form_weather_widget_2_2, this);
//獲取此 ProviderFormInfo 對象中包含的ComponentProvider數據。
ComponentProvider componentProvider = formInfo.getComponentProvider();
//設置組件的文本內容
componentProvider.setText(ResourceTable.Id_weather_text, "天氣:多云");
componentProvider.setText(ResourceTable.Id_weather_temperature, "溫度:29度");
componentProvider.setText(ResourceTable.Id_weather_ph, "PH值:2.9");
// 針對title控件設置事件
componentProvider.setIntentAgent(ResourceTable.Id_weather_text, startAbilityIntentAgent());
//將ComponentProvider中指定的操作合并到此ProviderFormInfo對象中包含的 ComponentProvider 對象中
formInfo.mergeActions(componentProvider);
return formInfo;
}
以上我們可以通過componentProvider 的setIntentAgent方法給卡片上的組件設置點擊事件,第一個參數為組件的資源id,第二個參數為IntentAgent對象,示例代碼如下:
componentProvider.setIntentAgent(ResourceTable.Id_weather_text, startAbilityIntentAgent());
獲取IntentAgent對象,示例代碼如下:
private IntentAgent startAbilityIntentAgent() {
Intent intent = new Intent();
Operation operation = new Intent.OperationBuilder()
.withDeviceId("")
.withBundleName("com.example.weatherservicecard")
.withAbilityName("com.example.weatherservicecard.MainAbility")
.build();
intent.setOperation(operation);
List<Intent> intentList = new ArrayList<>();
intentList.add(intent);
IntentAgentInfo paramsInfo = new IntentAgentInfo(200, IntentAgentConstant.OperationType.START_ABILITY, IntentAgentConstant.Flags.UPDATE_PRESENT_FLAG, intentList, null);
IntentAgent intentAgent = IntentAgentHelper.getIntentAgent(this, paramsInfo);
return intentAgent;
}
通過以上方式,我們就可以給卡片的每個組件設置點擊事件,跳轉到不同的頁面了。
IntentAgentInfo方法參數解說:
public IntentAgentInfo(int requestCode, IntentAgentConstant.OperationType operationType, List < IntentAgentConstant.Flags > flags, List < Intent > intents, IntentParams extraInfo)。
參數說明
- requestCode:表示要設置的請求代碼。它是用戶定義的私有值。
- operationType:指示 IntentAgent 對象要執行的操作的類型。取值范圍詳見IntentAgentConstant.OperationType。
- flags: 指示用于處理 IntentAgent 的標志。取值范圍詳見IntentAgentConstant.Flags。
- intents: 指示用于創建 IntentAgent 對象的 Intent 對象的集合。集合中的意圖數量由IntentAgentConstant.OperationType確定。
- extraInfo:指示用于創建 IntentAgent 對象的額外信息。
總結
1.卡片信息持久化目的是在使用方刪除/定時定點更新卡片時,提供方能夠根據卡片的ID刪除/更新對應的業務數據,還有就是針對:
- 臨時卡片:卡片提供方需要自己負責清理長時間未刪除的臨時卡片數據。
- 臨時卡片轉換為常態卡片:防止提供方在清理長時間未刪除的臨時卡片時,把已經轉換為常態卡片的臨時卡片信息刪除,導致卡片信息丟失。
2.卡片控制事件目的是實際應用中可能需要針對卡片中的各個組件設置對應的點擊事件,跳轉不同的頁面。具體使用見以上說明。
關于原子化服務卡片信息分享暫時在這里告一段落了,以后若遇到服務卡片的其它應用場景會繼續補充,謝謝!