提交 45a63f1a 编写于 作者: X xsz233

Merge remote-tracking branch 'upstream/master'

要显示的变更太多。

To preserve performance only 1000 of 1000+ files are displayed.
...@@ -135,7 +135,7 @@ zh-cn/application-dev/IDL/ @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingz ...@@ -135,7 +135,7 @@ zh-cn/application-dev/IDL/ @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingz
zh-cn/application-dev/device-usage-statistics/ @chenmingJay @ningningW @tangtiantian2021 @nan-xiansen @iceice1001 zh-cn/application-dev/device-usage-statistics/ @chenmingJay @ningningW @tangtiantian2021 @nan-xiansen @iceice1001
zh-cn/application-dev/ui/ @HelloCrease @huaweimaxuchu @tomatodevboy @niulihua zh-cn/application-dev/ui/ @HelloCrease @huaweimaxuchu @tomatodevboy @niulihua
zh-cn/application-dev/notification/ @RayShih @jayleehw @li-weifeng2 @currydavids zh-cn/application-dev/notification/ @RayShih @jayleehw @li-weifeng2 @currydavids
zh-cn/application-dev/windowmanager/ @ge-yafang @zhangqiang183 @zhouyaoying @zxg-gitee zh-cn/application-dev/windowmanager/ @ge-yafang @zhangqiang183 @zhouyaoying @zxg-gitee @nobuggers
zh-cn/application-dev/webgl/ @zengyawen @zhangqiang183 @wind_zj @zxg-gitee zh-cn/application-dev/webgl/ @zengyawen @zhangqiang183 @wind_zj @zxg-gitee
zh-cn/application-dev/media/audio-overview.md @zengyawen @liuyuehua1 @saga2020 @currydavids zh-cn/application-dev/media/audio-overview.md @zengyawen @liuyuehua1 @saga2020 @currydavids
zh-cn/application-dev/media/audio-playback.md @zengyawen @liuyuehua1 @saga2020 @currydavids zh-cn/application-dev/media/audio-playback.md @zengyawen @liuyuehua1 @saga2020 @currydavids
...@@ -186,8 +186,12 @@ zh-cn/application-dev/dfx/errormanager-guidelines.md @littlejerry1 @ccllee @chen ...@@ -186,8 +186,12 @@ zh-cn/application-dev/dfx/errormanager-guidelines.md @littlejerry1 @ccllee @chen
zh-cn/application-dev/dfx/errormanager-guidelines.md @littlejerry1 @ccllee @chengxingzhen @RayShih zh-cn/application-dev/dfx/errormanager-guidelines.md @littlejerry1 @ccllee @chengxingzhen @RayShih
zh-cn/application-dev/key-features/multi-device-app-dev/ @lingminghw @crazyracing0726 zh-cn/application-dev/key-features/multi-device-app-dev/ @lingminghw @crazyracing0726
zh-cn/application-dev/database/ @ge-yafang @feng-aiwen @gong-a-shi @logic42 zh-cn/application-dev/database/ @ge-yafang @feng-aiwen @gong-a-shi @logic42
zh-cn/application-dev/napi/native-window-guidelines.md @ge-yafang @zhangqiang183 @zhouyaoying @zxg-gitee zh-cn/application-dev/napi/native-window-guidelines.md @ge-yafang @zhangqiang183 @zhouyaoying @zxg-gitee @nobuggers
zh-cn/application-dev/napi/mindspore-lite-guidelines.md @ge-yafang @grbuzhidao @jianghui58 @auraxu zh-cn/application-dev/napi/mindspore-lite-guidelines.md @ge-yafang @principal87 @jianghui58
zh-cn/application-dev/napi/mindspore-lite-offline-model-guidelines.md @ge-yafang @principal87 @jianghui58
zh-cn/application-dev/reference/apis/js-apis-mindSporeLite.md @ge-yafang @principal87 @jianghui58
zh-cn/application-dev/ai/mindspore-lite-js-guidelines.md @ge-yafang @principal87 @jianghui58
zh-cn/application-dev/napi/neural-network-runtime-guidelines.md @ge-yafang @principal87 @win10wei
zh-cn/application-dev/napi/rawfile_guidelines.md @ningningW zh-cn/application-dev/napi/rawfile_guidelines.md @ningningW
zh-cn/application-dev/background-agent-scheduled-reminder/ @RayShih zh-cn/application-dev/background-agent-scheduled-reminder/ @RayShih
zh-cn/application-dev/background-task-management/ @ningningW @wangwenli_wolf @tangtiantian2021 @nan-xiansen zh-cn/application-dev/background-task-management/ @ningningW @wangwenli_wolf @tangtiantian2021 @nan-xiansen
...@@ -274,9 +278,9 @@ zh-cn/application-dev/reference/apis/js-apis-application-shellCmdResult.md @litt ...@@ -274,9 +278,9 @@ zh-cn/application-dev/reference/apis/js-apis-application-shellCmdResult.md @litt
zh-cn/application-dev/reference/apis/js-apis-application-StartOptions.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen zh-cn/application-dev/reference/apis/js-apis-application-StartOptions.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen
zh-cn/application-dev/reference/apis/js-apis-application-staticSubscriberExtensionAbility.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen zh-cn/application-dev/reference/apis/js-apis-application-staticSubscriberExtensionAbility.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen
zh-cn/application-dev/reference/apis/js-apis-application-Want.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen zh-cn/application-dev/reference/apis/js-apis-application-Want.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen
zh-cn/application-dev/reference/apis/js-apis-application-WindowExtensionAbility.md @zhangqiang183 @ge-yafang @zhouyaoying @zxg-gitee zh-cn/application-dev/reference/apis/js-apis-application-WindowExtensionAbility.md @zhangqiang183 @ge-yafang @zhouyaoying @zxg-gitee @nobuggers
zh-cn/application-dev/application-models/windowextensionability.md @zhangqiang183 @ge-yafang @zhouyaoying @zxg-gitee zh-cn/application-dev/application-models/windowextensionability.md @zhangqiang183 @ge-yafang @zhouyaoying @zxg-gitee @nobuggers
zh-cn/application-dev/reference/apis/js-apis-inner-application-windowExtensionContext.md @ge-yafang @zhouyaoying @zxg-gitee zh-cn/application-dev/reference/apis/js-apis-inner-application-windowExtensionContext.md @ge-yafang @zhouyaoying @zxg-gitee @nobuggers
zh-cn/application-dev/reference/apis/js-apis-appmanager.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen zh-cn/application-dev/reference/apis/js-apis-appmanager.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen
zh-cn/application-dev/reference/apis/js-apis-arraylist.md @gongjunsong @ge-yafang @flyingwolf @BlackStone zh-cn/application-dev/reference/apis/js-apis-arraylist.md @gongjunsong @ge-yafang @flyingwolf @BlackStone
zh-cn/application-dev/reference/apis/js-apis-audio.md @liuyuehua1 @zengyawen @magekkkk @currydavids zh-cn/application-dev/reference/apis/js-apis-audio.md @liuyuehua1 @zengyawen @magekkkk @currydavids
...@@ -321,6 +325,8 @@ zh-cn/application-dev/reference/apis/js-apis-data-DataShareResultSet.md @feng-ai ...@@ -321,6 +325,8 @@ zh-cn/application-dev/reference/apis/js-apis-data-DataShareResultSet.md @feng-ai
zh-cn/application-dev/reference/apis/js-apis-data-distributedobject.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 zh-cn/application-dev/reference/apis/js-apis-data-distributedobject.md @feng-aiwen @ge-yafang @gong-a-shi @logic42
zh-cn/application-dev/reference/apis/js-apis-data-preferences.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 zh-cn/application-dev/reference/apis/js-apis-data-preferences.md @feng-aiwen @ge-yafang @gong-a-shi @logic42
zh-cn/application-dev/reference/apis/js-apis-data-rdb.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 zh-cn/application-dev/reference/apis/js-apis-data-rdb.md @feng-aiwen @ge-yafang @gong-a-shi @logic42
zh-cn/application-dev/reference/apis/js-apis-data-udmf.md @feng-aiwen @ge-yafang @gong-a-shi @logic42
zh-cn/application-dev/reference/apis/js-apis-data-cloudData.md @feng-aiwen @ge-yafang @gong-a-shi @logic42
zh-cn/application-dev/reference/apis/js-apis-data-relationStore.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 zh-cn/application-dev/reference/apis/js-apis-data-relationStore.md @feng-aiwen @ge-yafang @gong-a-shi @logic42
zh-cn/application-dev/reference/apis/js-apis-data-resultset.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 zh-cn/application-dev/reference/apis/js-apis-data-resultset.md @feng-aiwen @ge-yafang @gong-a-shi @logic42
zh-cn/application-dev/reference/apis/js-apis-data-storage.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 zh-cn/application-dev/reference/apis/js-apis-data-storage.md @feng-aiwen @ge-yafang @gong-a-shi @logic42
...@@ -331,7 +337,7 @@ zh-cn/application-dev/reference/apis/js-apis-deque.md @gongjunsong @ge-yafang @f ...@@ -331,7 +337,7 @@ zh-cn/application-dev/reference/apis/js-apis-deque.md @gongjunsong @ge-yafang @f
zh-cn/application-dev/reference/apis/js-apis-device-info.md @mupceet @zengyawen @handyohos @nan-xiansen zh-cn/application-dev/reference/apis/js-apis-device-info.md @mupceet @zengyawen @handyohos @nan-xiansen
zh-cn/application-dev/reference/apis/js-apis-device-manager.md @intermilano @RayShih @william-ligang @liuhonggang123 zh-cn/application-dev/reference/apis/js-apis-device-manager.md @intermilano @RayShih @william-ligang @liuhonggang123
zh-cn/application-dev/reference/apis/js-apis-deviceUsageStatistics.md @shuaytao @RayShih @wangzhen107 @inter515 zh-cn/application-dev/reference/apis/js-apis-deviceUsageStatistics.md @shuaytao @RayShih @wangzhen107 @inter515
zh-cn/application-dev/reference/apis/js-apis-display.md @zhangqiang183 @ge-yafang @zhouyaoying @zxg-gitee zh-cn/application-dev/reference/apis/js-apis-display.md @zhangqiang183 @ge-yafang @zhouyaoying @zxg-gitee @nobuggers
zh-cn/application-dev/reference/apis/js-apis-distributed-account.md @nianCode @zengyawen @JiDong-CS @murphy1984 zh-cn/application-dev/reference/apis/js-apis-distributed-account.md @nianCode @zengyawen @JiDong-CS @murphy1984
zh-cn/application-dev/reference/apis/js-apis-distributed-data.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 zh-cn/application-dev/reference/apis/js-apis-distributed-data.md @feng-aiwen @ge-yafang @gong-a-shi @logic42
zh-cn/application-dev/reference/apis/js-apis-distributedMissionManager.md @chenmingJay @ningningW @nan-xiansen @iceice1001 zh-cn/application-dev/reference/apis/js-apis-distributedMissionManager.md @chenmingJay @ningningW @nan-xiansen @iceice1001
...@@ -415,9 +421,8 @@ zh-cn/application-dev/reference/apis/js-apis-resource-manager.md @Buda-Liu @ning ...@@ -415,9 +421,8 @@ zh-cn/application-dev/reference/apis/js-apis-resource-manager.md @Buda-Liu @ning
zh-cn/application-dev/reference/apis/js-apis-router.md @huaweimaxuchu @HelloCrease @niulihua @tomatodevboy zh-cn/application-dev/reference/apis/js-apis-router.md @huaweimaxuchu @HelloCrease @niulihua @tomatodevboy
zh-cn/application-dev/reference/apis/js-apis-rpc.md @xuepianpian @RayShih @zhaopeng_gitee @vagrant_world zh-cn/application-dev/reference/apis/js-apis-rpc.md @xuepianpian @RayShih @zhaopeng_gitee @vagrant_world
zh-cn/application-dev/reference/apis/js-apis-runninglock.md @aqxyjay @zengyawen @aqxyjay @alien0208 zh-cn/application-dev/reference/apis/js-apis-runninglock.md @aqxyjay @zengyawen @aqxyjay @alien0208
zh-cn/application-dev/reference/apis/js-apis-screen.md @zhangqiang183 @ge-yafang @zhouyaoying @zxg-gitee @nobuggers
zh-cn/application-dev/reference/apis/js-apis-screen.md @zhangqiang183 @ge-yafang @zhouyaoying @zxg-gitee zh-cn/application-dev/reference/apis/js-apis-screenshot.md @zhangqiang183 @ge-yafang @zhouyaoying @zxg-gitee @nobuggers
zh-cn/application-dev/reference/apis/js-apis-screenshot.md @zhangqiang183 @ge-yafang @zhouyaoying @zxg-gitee
zh-cn/application-dev/reference/apis/js-apis-securityLabel.md @panqinxu @zengyawen @bubble_mao @jinhaihw zh-cn/application-dev/reference/apis/js-apis-securityLabel.md @panqinxu @zengyawen @bubble_mao @jinhaihw
zh-cn/application-dev/reference/apis/js-apis-sensor.md @hellohyh001 @ningningW @butterls @star-wind-snow-and-rain zh-cn/application-dev/reference/apis/js-apis-sensor.md @hellohyh001 @ningningW @butterls @star-wind-snow-and-rain
zh-cn/application-dev/reference/apis/js-apis-service-extension-ability.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen zh-cn/application-dev/reference/apis/js-apis-service-extension-ability.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen
...@@ -458,6 +463,8 @@ zh-cn/application-dev/reference/apis/js-apis-testRunner.md @inter515 @littlejerr ...@@ -458,6 +463,8 @@ zh-cn/application-dev/reference/apis/js-apis-testRunner.md @inter515 @littlejerr
zh-cn/application-dev/reference/apis/js-apis-thermal.md @aqxyjay @zengyawen @aqxyjay @alien0208 zh-cn/application-dev/reference/apis/js-apis-thermal.md @aqxyjay @zengyawen @aqxyjay @alien0208
zh-cn/application-dev/reference/apis/js-apis-timer.md @gongjunsong @ge-yafang @flyingwolf @BlackStone zh-cn/application-dev/reference/apis/js-apis-timer.md @gongjunsong @ge-yafang @flyingwolf @BlackStone
zh-cn/application-dev/reference/apis/js-apis-touchevent.md @mayunteng_1 @ningningW @cococoler @alien0208 zh-cn/application-dev/reference/apis/js-apis-touchevent.md @mayunteng_1 @ningningW @cococoler @alien0208
zh-cn/application-dev/reference/apis/js-apis-shortKey.md @mayunteng_1 @ningningW @cococoler @alien0208
zh-cn/application-dev/reference/apis/js-apis-devicestatus-cooperate.md @mayunteng_1 @ningningW @cococoler @alien0208
zh-cn/application-dev/reference/apis/js-apis-treemap.md @gongjunsong @ge-yafang @flyingwolf @BlackStone zh-cn/application-dev/reference/apis/js-apis-treemap.md @gongjunsong @ge-yafang @flyingwolf @BlackStone
zh-cn/application-dev/reference/apis/js-apis-treeset.md @gongjunsong @ge-yafang @flyingwolf @BlackStone zh-cn/application-dev/reference/apis/js-apis-treeset.md @gongjunsong @ge-yafang @flyingwolf @BlackStone
zh-cn/application-dev/reference/apis/js-apis-uitest.md @inter515 @ningningW @inter515 @jiyong zh-cn/application-dev/reference/apis/js-apis-uitest.md @inter515 @ningningW @inter515 @jiyong
...@@ -473,17 +480,19 @@ zh-cn/application-dev/reference/apis/js-apis-vector.md @gongjunsong @ge-yafang @ ...@@ -473,17 +480,19 @@ zh-cn/application-dev/reference/apis/js-apis-vector.md @gongjunsong @ge-yafang @
zh-cn/application-dev/reference/apis/js-apis-vibrator.md @hellohyh001 @ningningW @butterls @star-wind-snow-and-rain zh-cn/application-dev/reference/apis/js-apis-vibrator.md @hellohyh001 @ningningW @butterls @star-wind-snow-and-rain
zh-cn/application-dev/reference/apis/js-apis-volumemanager.md @panqinxu @zengyawen @bubble_mao @jinhaihw zh-cn/application-dev/reference/apis/js-apis-volumemanager.md @panqinxu @zengyawen @bubble_mao @jinhaihw
zh-cn/application-dev/reference/apis/js-apis-wallpaper.md @feng-aiwen @ningningW @wangzhangjun @murphy1984 zh-cn/application-dev/reference/apis/js-apis-wallpaper.md @feng-aiwen @ningningW @wangzhangjun @murphy1984
zh-cn/application-dev/reference/apis/js-apis-screen-lock.md @feng-aiwen @ningningW @wangzhangjun @murphy1984
zh-cn/application-dev/reference/apis/js-apis-wantAgent.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen zh-cn/application-dev/reference/apis/js-apis-wantAgent.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen
zh-cn/application-dev/reference/apis/js-apis-webgl.md @zhangqiang183 @ge-yafang @wind_zj @zxg-gitee zh-cn/application-dev/reference/apis/js-apis-webgl.md @zhangqiang183 @ge-yafang @wind_zj @zxg-gitee
zh-cn/application-dev/reference/apis/js-apis-webgl2.md @zhangqiang183 @ge-yafang @wind_zj @zxg-gitee zh-cn/application-dev/reference/apis/js-apis-webgl2.md @zhangqiang183 @ge-yafang @wind_zj @zxg-gitee
zh-cn/application-dev/reference/apis/js-apis-webSocket.md @zhang-hai-feng @zengyawen @jyh926 @gaoxi785 zh-cn/application-dev/reference/apis/js-apis-webSocket.md @zhang-hai-feng @zengyawen @jyh926 @gaoxi785
zh-cn/application-dev/reference/apis/js-apis-wifi.md @cheng_guohong @RayShih @cheng_guohong @quanli125 zh-cn/application-dev/reference/apis/js-apis-wifi.md @cheng_guohong @RayShih @cheng_guohong @quanli125
zh-cn/application-dev/reference/apis/js-apis-wifiext.md @cheng_guohong @RayShih @cheng_guohong @quanli125 zh-cn/application-dev/reference/apis/js-apis-wifiext.md @cheng_guohong @RayShih @cheng_guohong @quanli125
zh-cn/application-dev/reference/apis/js-apis-window.md @zhangqiang183 @ge-yafang @zhouyaoying @zxg-gitee zh-cn/application-dev/reference/apis/js-apis-window.md @zhangqiang183 @ge-yafang @zhouyaoying @zxg-gitee @nobuggers
zh-cn/application-dev/reference/apis/js-apis-windowAnimationManager.md @zhangqiang183 @ge-yafang @wind_zj @zxg-gitee zh-cn/application-dev/reference/apis/js-apis-windowAnimationManager.md @zhangqiang183 @ge-yafang @wind_zj @zxg-gitee
zh-cn/application-dev/reference/apis/js-apis-worker.md @gongjunsong @ge-yafang @flyingwolf @BlackStone zh-cn/application-dev/reference/apis/js-apis-worker.md @gongjunsong @ge-yafang @flyingwolf @BlackStone
zh-cn/application-dev/reference/apis/js-apis-taskpool.md @gongjunsong @ge-yafang @flyingwolf @BlackStone zh-cn/application-dev/reference/apis/js-apis-taskpool.md @gongjunsong @ge-yafang @flyingwolf @BlackStone
zh-cn/application-dev/reference/apis/js-apis-workScheduler.md @chenmingJay @ningningW @nan-xiansen @iceice1001 zh-cn/application-dev/reference/apis/js-apis-workScheduler.md @chenmingJay @ningningW @nan-xiansen @iceice1001
zh-cn/application-dev/reference/apis/js-apis-inner-application-WorkSchedulerExtensionContext.md @chenmingJay @ningningW @nan-xiansen @iceice1001
zh-cn/application-dev/reference/apis/js-apis-WorkSchedulerExtensionAbility.md @chenmingJay @ningningW @nan-xiansen @iceice1001 zh-cn/application-dev/reference/apis/js-apis-WorkSchedulerExtensionAbility.md @chenmingJay @ningningW @nan-xiansen @iceice1001
zh-cn/application-dev/reference/apis/js-apis-xml.md @gongjunsong @ge-yafang @flyingwolf @BlackStone zh-cn/application-dev/reference/apis/js-apis-xml.md @gongjunsong @ge-yafang @flyingwolf @BlackStone
zh-cn/application-dev/reference/apis/js-apis-zlib.md @shuaytao @RayShih @wangzhen107 @inter515 zh-cn/application-dev/reference/apis/js-apis-zlib.md @shuaytao @RayShih @wangzhen107 @inter515
...@@ -529,6 +538,7 @@ zh-cn/application-dev/reference/apis/js-apis-curve.md @huaweimaxuchu @HelloCreas ...@@ -529,6 +538,7 @@ zh-cn/application-dev/reference/apis/js-apis-curve.md @huaweimaxuchu @HelloCreas
zh-cn/application-dev/reference/apis/js-apis-defaultAppManager.md @shuaytao @RayShih @wangzhen107 @inter515 zh-cn/application-dev/reference/apis/js-apis-defaultAppManager.md @shuaytao @RayShih @wangzhen107 @inter515
zh-cn/application-dev/reference/apis/js-apis-distributedBundle.md @shuaytao @RayShih @wangzhen107 @inter515 zh-cn/application-dev/reference/apis/js-apis-distributedBundle.md @shuaytao @RayShih @wangzhen107 @inter515
zh-cn/application-dev/reference/apis/js-apis-distributedKVStore.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 zh-cn/application-dev/reference/apis/js-apis-distributedKVStore.md @feng-aiwen @ge-yafang @gong-a-shi @logic42
zh-cn/application-dev/reference/apis/js-apis-enterprise-applicationManager.md @liuzuming @ningningW @yangqing3
zh-cn/application-dev/reference/apis/js-apis-enterprise-accountManager.md @liuzuming @ningningW @yangqing3 zh-cn/application-dev/reference/apis/js-apis-enterprise-accountManager.md @liuzuming @ningningW @yangqing3
zh-cn/application-dev/reference/apis/js-apis-enterprise-adminManager.md @liuzuming @ningningW @yangqing3 zh-cn/application-dev/reference/apis/js-apis-enterprise-adminManager.md @liuzuming @ningningW @yangqing3
zh-cn/application-dev/reference/apis/js-apis-enterprise-bundleManager.md @liuzuming @ningningW @yangqing3 zh-cn/application-dev/reference/apis/js-apis-enterprise-bundleManager.md @liuzuming @ningningW @yangqing3
...@@ -551,8 +561,10 @@ zh-cn/application-dev/reference/apis/js-apis-net-sharing.md @zhang-hai-feng @zen ...@@ -551,8 +561,10 @@ zh-cn/application-dev/reference/apis/js-apis-net-sharing.md @zhang-hai-feng @zen
zh-cn/application-dev/reference/apis/js-apis-nfctech.md @cheng_guohong @RayShih @cheng_guohong @quanli125 zh-cn/application-dev/reference/apis/js-apis-nfctech.md @cheng_guohong @RayShih @cheng_guohong @quanli125
zh-cn/application-dev/reference/apis/js-apis-promptAction.md @huaweimaxuchu @HelloCrease @niulihua @tomatodevboy zh-cn/application-dev/reference/apis/js-apis-promptAction.md @huaweimaxuchu @HelloCrease @niulihua @tomatodevboy
zh-cn/application-dev/reference/apis/js-apis-reminderAgentManager.md @chenmingJay @ningningW @nan-xiansen @iceice1001 zh-cn/application-dev/reference/apis/js-apis-reminderAgentManager.md @chenmingJay @ningningW @nan-xiansen @iceice1001
zh-cn/application-dev/reference/apis/js-apis-resourceschedule-deviceStandby.md @chenmingJay @ningningW @nan-xiansen @iceice1001
zh-cn/application-dev/reference/apis/js-apis-resourceschedule-backgroundTaskManager.md @chenmingJay @ningningW @nan-xiansen @iceice1001 zh-cn/application-dev/reference/apis/js-apis-resourceschedule-backgroundTaskManager.md @chenmingJay @ningningW @nan-xiansen @iceice1001
zh-cn/application-dev/reference/apis/js-apis-resourceschedule-deviceUsageStatistics.md @chenmingJay @ningningW @nan-xiansen @iceice1001 zh-cn/application-dev/reference/apis/js-apis-resourceschedule-deviceUsageStatistics.md @chenmingJay @ningningW @nan-xiansen @iceice1001
zh-cn/application-dev/reference/apis/js-apis-resourceschedule-deviceStandby.md @chenmingJay @ningningW @nan-xiansen @iceice1001
zh-cn/application-dev/reference/apis/js-apis-resourceschedule-workScheduler.md @chenmingJay @ningningW @nan-xiansen @iceice1001 zh-cn/application-dev/reference/apis/js-apis-resourceschedule-workScheduler.md @chenmingJay @ningningW @nan-xiansen @iceice1001
zh-cn/application-dev/reference/apis/js-apis-stationary.md @mayunteng_1 @ningningW @cococoler @alien0208 zh-cn/application-dev/reference/apis/js-apis-stationary.md @mayunteng_1 @ningningW @cococoler @alien0208
zh-cn/application-dev/reference/apis/js-apis-system-capability.md taiyipei taiyipei BlackStone zh-cn/application-dev/reference/apis/js-apis-system-capability.md taiyipei taiyipei BlackStone
...@@ -607,6 +619,7 @@ zh-cn/application-dev/reference/errorcodes/errorcode-request.md @ningningW ...@@ -607,6 +619,7 @@ zh-cn/application-dev/reference/errorcodes/errorcode-request.md @ningningW
zh-cn/application-dev/reference/errorcodes/errorcode-resource-manager.md @ningningW zh-cn/application-dev/reference/errorcodes/errorcode-resource-manager.md @ningningW
zh-cn/application-dev/reference/errorcodes/errorcode-router.md @HelloCrease zh-cn/application-dev/reference/errorcodes/errorcode-router.md @HelloCrease
zh-cn/application-dev/reference/errorcodes/errorcode-rpc.md @RayShih zh-cn/application-dev/reference/errorcodes/errorcode-rpc.md @RayShih
zh-cn/application-dev/reference/errorcodes/errorcode-screenlock.md @ningningW
zh-cn/application-dev/reference/errorcodes/errorcode-runninglock.md @zengyawen zh-cn/application-dev/reference/errorcodes/errorcode-runninglock.md @zengyawen
zh-cn/application-dev/reference/errorcodes/errorcode-sensor.md @ningningW zh-cn/application-dev/reference/errorcodes/errorcode-sensor.md @ningningW
zh-cn/application-dev/reference/errorcodes/errorcode-system-parameterV9.md @zengyawen zh-cn/application-dev/reference/errorcodes/errorcode-system-parameterV9.md @zengyawen
......
...@@ -162,7 +162,7 @@ Go to the local installation path, choose **toolchains > 3.x.x.x** (the folder n ...@@ -162,7 +162,7 @@ Go to the local installation path, choose **toolchains > 3.x.x.x** (the folder n
If the executable file does not exist, download the SDK package from the mirror as instructed in the [Release Notes](../../release-notes). The following uses [3.2 Beta3](../../release-notes/OpenHarmony-v3.2-beta3.md) as an example. If the executable file does not exist, download the SDK package from the mirror as instructed in the [Release Notes](../../release-notes). The following uses [3.2 Beta3](../../release-notes/OpenHarmony-v3.2-beta3.md) as an example.
For details about how to replace the SDK package, see [Full SDK Compilation Guide](../quick-start/full-sdk-compile-guide.md). For details about how to replace the SDK package, see [Full SDK Compilation Guide](../faqs/full-sdk-compile-guide.md).
After obtaining the executable file, perform subsequent development steps based on your scenario. After obtaining the executable file, perform subsequent development steps based on your scenario.
......
...@@ -17,18 +17,43 @@ ...@@ -17,18 +17,43 @@
- ExtensionAbility Component - ExtensionAbility Component
- [ExtensionAbility Component Overview](extensionability-overview.md) - [ExtensionAbility Component Overview](extensionability-overview.md)
- [ServiceExtensionAbility](serviceextensionability.md) - [ServiceExtensionAbility](serviceextensionability.md)
- [FormExtensionAbility (Widget)](widget-development-stage.md)
- [AccessibilityExtensionAbility](accessibilityextensionability.md) - [AccessibilityExtensionAbility](accessibilityextensionability.md)
- [EnterpriseAdminExtensionAbility](enterprise-extensionAbility.md) - [EnterpriseAdminExtensionAbility](enterprise-extensionAbility.md)
- [InputMethodExtensionAbility](inputmethodextentionability.md) - [InputMethodExtensionAbility](inputmethodextentionability.md)
- [WindowExtensionAbility](windowextensionability.md) - [WindowExtensionAbility (for System Applications Only)](windowextensionability.md)
- Service Widget Development in Stage Model
- [Service Widget Overview](service-widget-overview.md)
- Developing an ArkTS Widget
- [ArkTS Widget Working Principles](arkts-ui-widget-working-principles.md)
- [ArkTS Widget Related Modules](arkts-ui-widget-modules.md)
- ArkTS Widget Development
- [Creating an ArkTS Widget](arkts-ui-widget-creation.md)
- [Configuring Widget Configuration Files](arkts-ui-widget-configuration.md)
- [Widget Lifecycle Management](arkts-ui-widget-lifecycle.md)
- Widget Page Development
- [Widget Page Capability Overview](arkts-ui-widget-page-overview.md)
- [Using Animations in the Widget](arkts-ui-widget-page-animation.md)
- [Applying Custom Drawing in the Widget](arkts-ui-widget-page-custom-drawing.md)
- Widget Event Development
- [Widget Event Capability Overview](arkts-ui-widget-event-overview.md)
- [Redirecting to a UIAbility Through the router Event](arkts-ui-widget-event-router.md)
- [Launching a UIAbility in the Background Through the call Event](arkts-ui-widget-event-call.md)
- [Updating Widget Content Through the message Event](arkts-ui-widget-event-formextensionability.md)
- [Updating Widget Content Through the router or call Event](arkts-ui-widget-event-uiability.md)
- Widget Data Interaction
- [Widget Data Interaction Overview](arkts-ui-widget-interaction-overview.md)
- [Configuring a Widget to Update Periodically](arkts-ui-widget-update-by-time.md)
- [Updating Local and Online Images in the Widget](arkts-ui-widget-image-update.md)
- [Updating Widget Content by State](arkts-ui-widget-update-by-status.md)
- [Updating Widget Content by Widget Host (for System Applications Only)](arkts-ui-widget-content-update.md)
- [Developing a JS Widget](js-ui-widget-development.md)
- [AbilityStage Component Container](abilitystage.md) - [AbilityStage Component Container](abilitystage.md)
- [Context](application-context-stage.md) - [Context](application-context-stage.md)
- Want - Want
- [Want Overview](want-overview.md) - [Want Overview](want-overview.md)
- [Matching Rules of Explicit Want and Implicit Want](explicit-implicit-want-mappings.md) - [Matching Rules of Explicit Want and Implicit Want](explicit-implicit-want-mappings.md)
- [Common action and entities Values](actions-entities.md) - [Common action and entities Values](actions-entities.md)
- [Using Explicit Want to Start an Ability](ability-startup-with-explicit-want.md) - [Using Explicit Want to Start an Application Component](ability-startup-with-explicit-want.md)
- [Using Implicit Want to Open a Website](ability-startup-with-implicit-want.md) - [Using Implicit Want to Open a Website](ability-startup-with-implicit-want.md)
- [Using Want to Share Data Between Applications](data-share-via-want.md) - [Using Want to Share Data Between Applications](data-share-via-want.md)
- [Component Startup Rules](component-startup-rules.md) - [Component Startup Rules](component-startup-rules.md)
...@@ -37,8 +62,8 @@ ...@@ -37,8 +62,8 @@
- [Cross-Device Migration (for System Applications Only)](hop-cross-device-migration.md) - [Cross-Device Migration (for System Applications Only)](hop-cross-device-migration.md)
- [Multi-device Collaboration (for System Applications Only)](hop-multi-device-collaboration.md) - [Multi-device Collaboration (for System Applications Only)](hop-multi-device-collaboration.md)
- [Subscribing to System Environment Variable Changes](subscribe-system-environment-variable-changes.md) - [Subscribing to System Environment Variable Changes](subscribe-system-environment-variable-changes.md)
- IPC - Process Model
- [Process Model](process-model-stage.md) - [Process Model Overview](process-model-stage.md)
- Common Events - Common Events
- [Introduction to Common Events](common-event-overview.md) - [Introduction to Common Events](common-event-overview.md)
- Common Event Subscription - Common Event Subscription
...@@ -47,14 +72,15 @@ ...@@ -47,14 +72,15 @@
- [Subscribing to Common Events in Static Mode (for System Applications Only)](common-event-static-subscription.md) - [Subscribing to Common Events in Static Mode (for System Applications Only)](common-event-static-subscription.md)
- [Unsubscribing from Common Events](common-event-unsubscription.md) - [Unsubscribing from Common Events](common-event-unsubscription.md)
- [Publishing Common Events](common-event-publish.md) - [Publishing Common Events](common-event-publish.md)
- [Removing Sticky Common Events (for System Applications Only)](common-event-remove-sticky.md)
- [Background Services](background-services.md) - [Background Services](background-services.md)
- Inter-Thread Communication - Thread Model
- [Thread Model](thread-model-stage.md) - [Thread Model Overview](thread-model-stage.md)
- [Using Emitter for Inter-Thread Communication](itc-with-emitter.md) - [Using Emitter for Inter-Thread Communication](itc-with-emitter.md)
- [Using Worker for Inter-Thread Communication](itc-with-worker.md) - [Using Worker for Inter-Thread Communication](itc-with-worker.md)
- Mission Management - Mission Management
- [Mission Management Scenarios](mission-management-overview.md) - [Mission Management Scenarios](mission-management-overview.md)
- [Mission Management and Launch Type](mission-management-launch-type.md) - [Mission and Launch Type](mission-management-launch-type.md)
- [Page Stack and MissionList](page-mission-stack.md) - [Page Stack and MissionList](page-mission-stack.md)
- [Setting the Icon and Name of a Mission Snapshot](mission-set-icon-name-for-task-snapshot.md) - [Setting the Icon and Name of a Mission Snapshot](mission-set-icon-name-for-task-snapshot.md)
- [Application Configuration File](config-file-stage.md) - [Application Configuration File](config-file-stage.md)
...@@ -94,12 +120,12 @@ ...@@ -94,12 +120,12 @@
- [Context](application-context-fa.md) - [Context](application-context-fa.md)
- [Want](want-fa.md) - [Want](want-fa.md)
- [Component Startup Rules](component-startup-rules-fa.md) - [Component Startup Rules](component-startup-rules-fa.md)
- IPC - Process Model
- [Process Model](process-model-fa.md) - [Process Model Overview](process-model-fa.md)
- [Common Events](common-event-fa.md) - [Common Events](common-event-fa.md)
- [Background Services](rpc.md) - [Background Services](rpc.md)
- Inter-Thread Communication - Thread Model
- [Thread Model](thread-model-fa.md) - [Thread Model Overview](thread-model-fa.md)
- [Inter-Thread Communication](itc-fa-overview.md) - [Inter-Thread Communication](itc-fa-overview.md)
- [Mission Management](mission-management-fa.md) - [Mission Management](mission-management-fa.md)
- [Application Configuration File](config-file-fa.md) - [Application Configuration File](config-file-fa.md)
......
# Using Explicit Want to Start an Ability # Using Explicit Want to Start an Application Component
When a user touches a button in an application, the application often needs to start a UIAbility component to complete a specific task. If the **abilityName** and **bundleName** parameters are specified when starting a UIAbility, then the explicit Want is used. When a user touches a button in an application, the application often needs to start a UIAbility component to complete a specific task. If the **abilityName** and **bundleName** parameters are specified when starting a UIAbility, then the explicit Want is used.
......
...@@ -5,21 +5,21 @@ This section uses the operation of using a browser to open a website as an examp ...@@ -5,21 +5,21 @@ This section uses the operation of using a browser to open a website as an examp
```json ```json
{ {
"module": { "module": {
// ... ...
"abilities": [ "abilities": [
{ {
// ... ...
"skills": [ "skills": [
{ {
"entities": [ "entities": [
"entity.system.home", "entity.system.home",
"entity.system.browsable" "entity.system.browsable"
// ... ...
], ],
"actions": [ "actions": [
"action.system.home", "action.system.home",
"ohos.want.action.viewData" "ohos.want.action.viewData"
// ... ...
], ],
"uris": [ "uris": [
{ {
...@@ -31,9 +31,9 @@ This section uses the operation of using a browser to open a website as an examp ...@@ -31,9 +31,9 @@ This section uses the operation of using a browser to open a website as an examp
}, },
{ {
"scheme": "http", "scheme": "http",
// ... ...
} }
// ... ...
] ]
} }
] ]
...@@ -59,19 +59,18 @@ function implicitStartAbility() { ...@@ -59,19 +59,18 @@ function implicitStartAbility() {
'uri': 'https://www.test.com:8080/query/student' 'uri': 'https://www.test.com:8080/query/student'
} }
context.startAbility(wantInfo).then(() => { context.startAbility(wantInfo).then(() => {
// ... ...
}).catch((err) => { }).catch((err) => {
// ... ...
}) })
} }
``` ```
The matching process is as follows: The matching process is as follows:
1. If **action** in the passed **want** parameter is specified and is included in **actions** under **skills** of the ability to match, the matching is successful. 1. If **action** in the passed **want** parameter is specified and is included in **actions** under **skills** of the application component to match, the matching is successful.
2. If **entities** in the passed **want** parameter is specified and is included in **entities** under **skills** of the ability to match, the matching is successful. 2. If **entities** in the passed **want** parameter is specified and is included in **entities** under **skills** of the application component to match, the matching is successful.
3. If **uri** in the passed **want** parameter is included in **uris** under **skills** of the ability to match, which is concatenated into https://www.test.com:8080/query* (where * is a wildcard), the matching is successful. 3. If **uri** in the passed **want** parameter is included in **uris** under **skills** of the application component to match, which is concatenated into https://www.test.com:8080/query* (where * is a wildcard), the matching is successful.
4. If **type** in the passed **want** parameter is specified and is included in **type** under **skills** of the ability to match, the matching is successful.
If there are multiple matching applications, the system displays a dialog box for you to select one of them. The following figure shows an example. If there are multiple matching applications, the system displays a dialog box for you to select one of them. The following figure shows an example.
......
...@@ -12,7 +12,7 @@ AbilityStage is not automatically generated in the default project of DevEco Stu ...@@ -12,7 +12,7 @@ AbilityStage is not automatically generated in the default project of DevEco Stu
1. In the **ets** directory of the **Module** project, right-click and choose **New > Directory** to create a directory named **myabilitystage**. 1. In the **ets** directory of the **Module** project, right-click and choose **New > Directory** to create a directory named **myabilitystage**.
2. In the **myabilitystage** directory, right-click and choose **New > ts File** to create a file named **MyAbilityStage.ts**. 2. In the **myabilitystage** directory, right-click and choose **New > TypeScript File** to create a file named **MyAbilityStage.ts**.
3. Open the **MyAbilityStage.ts** file, and import the dependency package of AbilityStage. Customize a class that inherits from AbilityStage, and add the required lifecycle callbacks. The following code snippet adds the **onCreate()** lifecycle callback. 3. Open the **MyAbilityStage.ts** file, and import the dependency package of AbilityStage. Customize a class that inherits from AbilityStage, and add the required lifecycle callbacks. The following code snippet adds the **onCreate()** lifecycle callback.
...@@ -20,29 +20,28 @@ AbilityStage is not automatically generated in the default project of DevEco Stu ...@@ -20,29 +20,28 @@ AbilityStage is not automatically generated in the default project of DevEco Stu
import AbilityStage from '@ohos.app.ability.AbilityStage'; import AbilityStage from '@ohos.app.ability.AbilityStage';
export default class MyAbilityStage extends AbilityStage { export default class MyAbilityStage extends AbilityStage {
onCreate() { onCreate() {
// When the HAP of the application is loaded for the first time, initialize the module. // When the HAP of the application is loaded for the first time, initialize the module.
} }
onAcceptWant(want) { onAcceptWant(want) {
// Triggered only for the ability with the specified launch type. // Triggered only for the UIAbility with the specified launch type.
return "MyAbilityStage"; return "MyAbilityStage";
} }
} }
``` ```
4. Set **srcEntry** in the [module.json5 file](../quick-start/module-configuration-file.md) to the code path of the module. 4. In the [module.json5 file](../quick-start/module-configuration-file.md), set **srcEntry** to specify the code path of the module as the entry for loading the HAP.
```json ```json
{ {
"module": { "module": {
"name": "entry", "name": "entry",
"type": "entry", "type": "entry",
"srcEntry": "./ets/myabilitystage/MyAbilityStage.ts", "srcEntry": "./ets/myabilitystage/MyAbilityStage.ts",
// ... ...
} }
} }
``` ```
[AbilityStage](../reference/apis/js-apis-app-ability-abilityStage.md) has the lifecycle callback [onCreate()](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageoncreate) and the event callbacks [onAcceptWant()](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonacceptwant), [onConfigurationUpdated()](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonconfigurationupdate), and [onMemoryLevel()](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonmemorylevel). [AbilityStage](../reference/apis/js-apis-app-ability-abilityStage.md) has the lifecycle callback [onCreate()](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageoncreate) and the event callbacks [onAcceptWant()](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonacceptwant), [onConfigurationUpdated()](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonconfigurationupdate), and [onMemoryLevel()](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonmemorylevel).
...@@ -53,7 +52,6 @@ AbilityStage is not automatically generated in the default project of DevEco Stu ...@@ -53,7 +52,6 @@ AbilityStage is not automatically generated in the default project of DevEco Stu
- **onConfigurationUpdated()** event callback: triggered when the global system configuration changes. The global system configuration, such as the system language and theme, are defined in the [Configuration](../reference/apis/js-apis-app-ability-configuration.md) class before project configuration. - **onConfigurationUpdated()** event callback: triggered when the global system configuration changes. The global system configuration, such as the system language and theme, are defined in the [Configuration](../reference/apis/js-apis-app-ability-configuration.md) class before project configuration.
- **onMemoryLevel()** event callback: triggered when the system adjusts the memory. - **onMemoryLevel()** event callback: triggered when the system adjusts the memory.
When an application is switched to the background, it is cached in the background. This adversely affects the overall system performance. When system resources are insufficient, the system reclaims memory from applications in multiple ways. For example, the system may stop applications to release memory for executing key tasks. To further maintain the balance of the system memory and prevent the system from stopping application processes, you can subscribe to the system memory changes in the **onMemoryLevel()** lifecycle callback of AbilityStage to release unnecessary resources. When an application is switched to the background, it is cached in the background. This adversely affects the overall system performance. When system resources are insufficient, the system reclaims memory from applications in multiple ways. For example, the system may stop applications to release memory for executing key tasks. To further maintain the balance of the system memory and prevent the system from stopping application processes, you can subscribe to the system memory changes in the **onMemoryLevel()** lifecycle callback of AbilityStage to release unnecessary resources.
...@@ -62,8 +60,8 @@ When an application is switched to the background, it is cached in the backgroun ...@@ -62,8 +60,8 @@ When an application is switched to the background, it is cached in the backgroun
import AbilityStage from '@ohos.app.ability.AbilityStage'; import AbilityStage from '@ohos.app.ability.AbilityStage';
export default class MyAbilityStage extends AbilityStage { export default class MyAbilityStage extends AbilityStage {
onMemoryLevel(level) { onMemoryLevel(level) {
// Release unnecessary memory based on the change of available system memory. // Release unnecessary memory based on the change of available system memory.
} }
} }
``` ```
...@@ -12,14 +12,31 @@ The **AccessibilityExtensionAbility** module provides accessibility extension ca ...@@ -12,14 +12,31 @@ The **AccessibilityExtensionAbility** module provides accessibility extension ca
This document is organized as follows: This document is organized as follows:
- [Creating an AccessibilityExtAbility File](#creating-an-accessibility-extension-service) - [AccessibilityExtensionAbility Overview](#accessibilityextensionability-overview)
- [Creating an Accessibility Extension Service](#creating-an-accessibility-extension-service)
- [Processing an Accessibility Event](#processing-an-accessibility-event) - [Processing an Accessibility Event](#processing-an-accessibility-event)
- [Declaring Capabilities of Accessibility Extension Services](#declaring-capabilities-of-accessibility-extension-services) - [Declaring Capabilities of Accessibility Extension Services](#declaring-capabilities-of-accessibility-extension-services)
- [Enabling a Custom Accessibility Extension Service](#enabling-a-custom-accessibility-extension-service) - [Enabling a Custom Accessibility Extension Service](#enabling-a-custom-accessibility-extension-service)
## AccessibilityExtensionAbility Overview
Accessibility is about giving equal access to everyone so that they can access and use information equally and conveniently under any circumstances. It helps narrow the digital divide between people of different classes, regions, ages, and health status in terms of information understanding, information exchange, and information utilization, so that they can participate in social life more conveniently and enjoy the benefits of technological advances.
AccessibilityExtensionAbility is an accessibility extension service framework. It allows you to develop your own extension services and provides a standard mechanism for exchanging information between applications and extension services. You can make use of the provided capabilities and APIs to develop accessibility features for users with disabilities or physical limitations. For example, you can develop a screen reader for users with vision impairments.
Below shows the AccessibilityExtensionAbility framework.
![AccessibilityFramework](figures/AccessibilityFramework.png)
1. Accessibility app: extension service application developed based on the AccessibilityExtensionAbility framework, for example, a screen reader application.
2. Target app: application assisted by the accessibility app.
3. AccessibilityAbilityManagerService (AAMS): main service of the AccessibilityExtensionAbility framework, which is used to manage the lifecycle of accessibility apps and provide a bridge for information exchange between accessibility apps and target apps.
4. AccessibilityAbility (AAkit): ability that is used by the accessibility app to build an extension service ability operating environment and that provides interfaces for the accessibility app to query and operate the target app, including performing click/long press operations.
5. AccessibilitySystemAbilityClient (ASACkit): used by the target app to send accessibility events, such as content change events, to AAMS, and respond to the instructions (such as performing click/long press operations) sent by the accessibility app through AAMS.
## Creating an Accessibility Extension Service ## Creating an Accessibility Extension Service
You can create an accessibility extension service by creating a project from scratch or adding the service to an existing project. You can create an accessibility extension service by creating a project from scratch or adding the service to an existing project. Only one accessibility extension service can be created for a project.
### Creating a Project ### Creating a Project
...@@ -37,15 +54,15 @@ import AccessibilityExtensionAbility from '@ohos.application.AccessibilityExtens ...@@ -37,15 +54,15 @@ import AccessibilityExtensionAbility from '@ohos.application.AccessibilityExtens
class AccessibilityExtAbility extends AccessibilityExtensionAbility { class AccessibilityExtAbility extends AccessibilityExtensionAbility {
onConnect() { onConnect() {
console.log('AccessibilityExtAbility onConnect'); console.info('AccessibilityExtAbility onConnect');
} }
onDisconnect() { onDisconnect() {
console.log('AccessibilityExtAbility onDisconnect'); console.info('AccessibilityExtAbility onDisconnect');
} }
onAccessibilityEvent(accessibilityEvent) { onAccessibilityEvent(accessibilityEvent) {
console.log('AccessibilityExtAbility onAccessibilityEvent: ' + JSON.stringify(accessibilityEvent)); console.info('AccessibilityExtAbility onAccessibilityEvent: ' + JSON.stringify(accessibilityEvent));
} }
} }
...@@ -66,9 +83,9 @@ You can process the service logic for accessibility events in the **onAccessibil ...@@ -66,9 +83,9 @@ You can process the service logic for accessibility events in the **onAccessibil
```typescript ```typescript
onAccessibilityEvent(accessibilityEvent) { onAccessibilityEvent(accessibilityEvent) {
console.log('AccessibilityExtAbility onAccessibilityEvent: ' + JSON.stringify(accessibilityEvent)); console.info('AccessibilityExtAbility onAccessibilityEvent: ' + JSON.stringify(accessibilityEvent));
if (accessibilityEvent.eventType === 'pageStateUpdate') { if (accessibilityEvent.eventType === 'pageStateUpdate') {
console.log('AccessibilityExtAbility onAccessibilityEvent: pageStateUpdate'); console.info('AccessibilityExtAbility onAccessibilityEvent: pageStateUpdate');
// TODO: Develop custom logic. // TODO: Develop custom logic.
} }
} }
...@@ -79,13 +96,13 @@ You can also process physical key events in the accessibility extension service. ...@@ -79,13 +96,13 @@ You can also process physical key events in the accessibility extension service.
## Declaring Capabilities of Accessibility Extension Services ## Declaring Capabilities of Accessibility Extension Services
After developing the custom logic for an accessibility extension service, you must add the configuration information of the service to the corresponding module-level **module.json5** file in the project directory. In the file, the **srcEntrance** tag indicates the path to the accessibility extension service. Make sure the value of the **type** tag is fixed at **accessibility**. Otherwise, the connection to the service will fail. After developing the custom logic for an accessibility extension service, you must add the configuration information of the service to the corresponding module-level **module.json5** file in the project directory. In the file, the **srcEntry** tag indicates the path to the accessibility extension service. Make sure the value of the **type** tag is fixed at **accessibility**. Otherwise, the connection to the service will fail.
```json ```json
"extensionAbilities": [ "extensionAbilities": [
{ {
"name": "AccessibilityExtAbility", "name": "AccessibilityExtAbility",
"srcEntrance": "./ets/AccessibilityExtAbility/AccessibilityExtAbility.ts", "srcEntry": "./ets/AccessibilityExtAbility/AccessibilityExtAbility.ts",
"label": "$string:MainAbility_label", "label": "$string:MainAbility_label",
"description": "$string:MainAbility_desc", "description": "$string:MainAbility_desc",
"type": "accessibility", "type": "accessibility",
...@@ -116,3 +133,4 @@ To enable or disable an accessibility extension service, run the following comma ...@@ -116,3 +133,4 @@ To enable or disable an accessibility extension service, run the following comma
In the preceding commands, **AccessibilityExtAbility** indicates the name of the accessibility extension service, **com.example.demo** indicates the bundle name, and **rg** indicates the capabilities (**r** is short for retrieve). In the preceding commands, **AccessibilityExtAbility** indicates the name of the accessibility extension service, **com.example.demo** indicates the bundle name, and **rg** indicates the capabilities (**r** is short for retrieve).
If the service is enabled or disabled successfully, the message "enable ability successfully" or "disable ability successfully" is displayed. If the service is enabled or disabled successfully, the message "enable ability successfully" or "disable ability successfully" is displayed.
# Common action and entities Values # Common action and entities Values
**action**: Action to take, such as viewing, sharing, and application details, by the caller. In implicit Want, you can define this field and use it together with **uri** or **parameters** to specify the operation to be performed on the data, for example, viewing URI data. For example, if the URI is a website and the action is **ohos.want.action.viewData**, the ability that supports website viewing is matched. Declaring the **action** field in Want indicates that the invoked application should support the declared operation. The **actions** field under **skills** in the configuration file indicates the operations supported by the application. The **action** field specifies the common operation (such as viewing, sharing, and application details) to be performed by the caller. In implicit [Want](../reference/apis/js-apis-app-ability-want.md), you can define this field and use it together with **uri** or **parameters** to specify the operation to be performed on the data, for example, viewing URI data. For example, if the URI is a website and the action is **ohos.want.action.viewData**, the application component that supports website viewing is matched. Declaring the **action** field in [Want](../reference/apis/js-apis-app-ability-want.md) indicates that the invoked application is expected to support the declared operation. The **actions** field under **skills** in the configuration file indicates the operations supported by the application.
The following **action** values are available:
**Common action Values**
- **ACTION_HOME**: action of starting the application entry component. It must be used together with **ENTITY_HOME**. The application icon on the home screen is an explicit entry component. Users can touch the icon to start the entry component. Multiple entry components can be configured for an application. - **ACTION_HOME**: action of starting the application entry component. It must be used together with **ENTITY_HOME**. The application icon on the home screen is an explicit entry component. Users can touch the icon to start the entry component. Multiple entry components can be configured for an application.
...@@ -14,14 +13,13 @@ ...@@ -14,14 +13,13 @@
- **ACTION_VIEW_MULTIPLE_DATA**: action of launching the UI for sending multiple data records. - **ACTION_VIEW_MULTIPLE_DATA**: action of launching the UI for sending multiple data records.
**entities**: Category information (such as browser and video player) of the target ability. It is a supplement to **action** in implicit Want. You can define this field to filter application categories, for example, browser. Declaring the **entities** field in Want indicates that the invoked application should belong to the declared category. The **entities** field under **skills** in the configuration file indicates the categories supported by the application. The **entities** field specify the category information (such as browser and video player) of the target application component. It is a supplement to **action** in implicit Want. You can define this field to filter application categories, for example, browser. Declaring the **entities** field in Want indicates that the invoked application should belong to the declared category. The **entities** field under **skills** in the configuration file indicates the categories supported by the application.
**Common entities Values** The following **entities** values are available:
- **ENTITY_DEFAULT**: default category, which is meaningless. - **ENTITY_DEFAULT**: default category, which is meaningless.
- **ENTITY_HOME**: abilities with an icon displayed on the home screen. - **ENTITY_HOME**: application components with an icon displayed on the home screen.
- **ENTITY_BROWSABLE**: browser type. - **ENTITY_BROWSABLE**: browser type.
...@@ -22,7 +22,7 @@ OpenHarmony has reconstructed the [deviceConfig](../quick-start/deviceconfig-str ...@@ -22,7 +22,7 @@ OpenHarmony has reconstructed the [deviceConfig](../quick-start/deviceconfig-str
| deviceConfig in the FA Model| Description| Stage Model| Difference| | deviceConfig in the FA Model| Description| Stage Model| Difference|
| -------- | -------- | -------- | -------- | | -------- | -------- | -------- | -------- |
| deviceConfig| Device information.| / | This tag is no longer available in the stage model. In the stage model, device information is configured under the **app** tag.| | deviceConfig| Device information.| / | This tag is no longer available in the stage model. In the stage model, device information is configured under the **app** tag.|
| process | Name of the process running the application or ability. If the **process** attribute is configured in the **deviceConfig** tag, all abilities of the application run in this process. You can set the **process** attribute for a specific ability in the **abilities** attribute, so that the ability can run in the particular process.| / | The stage model does not support the configuration of process names.| | process | Name of the process running the application or UIAbility. If the **process** attribute is configured in the **deviceConfig** tag, all UIAbilities of the application run in this process. You can set the **process** attribute for a specific UIAbility in the **abilities** attribute, so that the UIAbility can run in the particular process.| / | The stage model does not support the configuration of process names.|
| keepAlive | Whether the application is always running. This attribute applies only to system applications and does not take effect for third-party applications.| / | The stage model does not support changing of the model control mode for system applications.| | keepAlive | Whether the application is always running. This attribute applies only to system applications and does not take effect for third-party applications.| / | The stage model does not support changing of the model control mode for system applications.|
| supportBackup | Whether the application supports data backup and restore.| / | This configuration is not supported in the stage model.| | supportBackup | Whether the application supports data backup and restore.| / | This configuration is not supported in the stage model.|
| compressNativeLibs | Whether the **libs** libraries are packaged in the HAP file after being compressed.| / | This configuration is not supported in the stage model.| | compressNativeLibs | Whether the **libs** libraries are packaged in the HAP file after being compressed.| / | This configuration is not supported in the stage model.|
......
...@@ -22,7 +22,7 @@ When developing an application, you may need to configure certain tags to identi ...@@ -22,7 +22,7 @@ When developing an application, you may need to configure certain tags to identi
"actions": ["action.system.home"] "actions": ["action.system.home"]
} }
] ]
// ... ...
} }
``` ```
......
# Application- or Component-Level Configuration (Stage Model) # Application- or Component-Level Configuration (Stage Model)
When developing an application, you may need to configure certain tags to identify the application, such as the bundle name and application icon. This topic describes key tags that need to be configured during application development.
When developing an application, you may need to configure certain tags to identify the application, such as the bundle name and application icon. This topic describes key tags that need to be configured during application development. Icons and labels are usually configured together. There is the application icon, application label, entry icon, and entry label, which correspond to the **icon** and **label** fields in the [app.json5 file](../quick-start/app-configuration-file.md) and [module.json5 file](../quick-start/module-configuration-file.md). The application icon and label are used in **Settings**. For example, they are displayed in the application list in **Settings**. The entry icon is displayed on the device's home screen after the application is installed. The entry icon maps to a [UIAbility](uiability-overview.md) component. Therefore, an application can have multiple entry icons and labels. When you touch one of them, the corresponding UIAbility page is displayed. Icons and labels are usually configured together. There is the application icon, application label, entry icon, and entry label, which correspond to the **icon** and **label** fields in the [app.json5 file](../quick-start/app-configuration-file.md) and [module.json5 file](../quick-start/module-configuration-file.md).
The application icon and label are used in **Settings**. For example, they are displayed in the application list in **Settings**. The entry icon is displayed on the device's home screen after the application is installed. The entry icon maps to a [UIAbility](uiability-overview.md) component. Therefore, an application can have multiple entry icons and entry labels. When you touch one of them, the corresponding UIAbility page is displayed.
**Figure 1** Icons and labels **Figure 1** Icons and labels
![application-component-configuration-stage](figures/application-component-configuration-stage.png) ![application-component-configuration-stage](figures/application-component-configuration-stage.png)
...@@ -22,13 +24,13 @@ When developing an application, you may need to configure certain tags to identi ...@@ -22,13 +24,13 @@ When developing an application, you may need to configure certain tags to identi
The application label is specified by the **label** field in the [app.json5 file](../quick-start/app-configuration-file.md) in the **AppScope** module of the project. The **label** field specifies the application name displayed to users. It must be set to the index of a string resource. The application label is specified by the **label** field in the [app.json5 file](../quick-start/app-configuration-file.md) in the **AppScope** module of the project. The **label** field specifies the application name displayed to users. It must be set to the index of a string resource.
```json ```json
{ {
"app": { "app": {
"icon": "$media:app_icon", "icon": "$media:app_icon",
"label": "$string:app_name" "label": "$string:app_name"
// ... ...
}
} }
}
``` ```
- **Configuring the entry icon and label** - **Configuring the entry icon and label**
...@@ -40,7 +42,7 @@ When developing an application, you may need to configure certain tags to identi ...@@ -40,7 +42,7 @@ When developing an application, you may need to configure certain tags to identi
```json ```json
{ {
"module": { "module": {
// ... ...
"abilities": [ "abilities": [
{ {
// The information starting with $ is the resource value. // The information starting with $ is the resource value.
...@@ -61,6 +63,35 @@ When developing an application, you may need to configure certain tags to identi ...@@ -61,6 +63,35 @@ When developing an application, you may need to configure certain tags to identi
} }
} }
``` ```
OpenHarmony strictly controls applications without icons to prevent malicious applications from deliberately configuring no icon to block uninstall attempts.
To hide an application icon from the home screen, you must configure the **AllowAppDesktopIconHide** privilege. For details, see [Application Privilege Configuration Guide](../../device-dev/subsystems/subsys-app-privilege-config-guide.md). The rules for displaying the entry icon and entry label are as follows:
1. The HAP file contains UIAbility configuration.
* An entry icon is set in the **abilities** field of the **module.json5** file.
* The application does not have the privilege to hide its icon from the home screen.
* The system uses the icon configured for the UIAbility as the entry icon and displays it on the home screen. Touching this icon will direct the user to the home page of the UIAbility.
* The system uses the label configured for the UIAbility as the entry label and displays it on the home screen. If no label is configured, the system uses the label specified in the **app.json5** file as the entry label and displays it on the home screen.
* The application has the privilege to hide its icon from the home screen.
* The application information is not returned when the home screen queries the information, and the entry icon and label of the application are not displayed on the home screen.
* No entry icon is set in the **abilities** field of the **module.json5** file.
* The application does not have the privilege to hide its icon from the home screen.
* The system uses the icon specified in the **app.json5** file as the entry icon and displays it on the home screen. Touching this icon will direct the user to the application details page, as shown below.
* The system uses the label specified in the **app.json5** file as the entry label and displays it on the home screen.
* The application has the privilege to hide its icon from the home screen.
* The application information is not returned when the home screen queries the information, and the entry icon and label of the application are not displayed on the home screen.
2. The HAP file does not contain UIAbility configuration.
* The application does not have the privilege to hide its icon from the home screen.
* The system uses the icon specified in the **app.json5** file as the entry icon and displays it on the home screen. Touching this icon will direct the user to the application details page, as shown below.
* The system uses the label specified in the **app.json5** file as the entry label and displays it on the home screen.
* The application has the privilege to hide its icon from the home screen.
* The application information is not returned when the home screen queries the information, and the entry icon and label of the application are not displayed on the home screen.
**Figure 2** Application details page
![Application details page](figures/application_details.jpg)
- **Configuring application version declaration** - **Configuring application version declaration**
To declare the application version, configure the **versionCode** and **versionName** fields in the [app.json5 file](../quick-start/app-configuration-file.md) in the **AppScope** directory of the project. **versionCode** specifies the version number of the application. The value is a 32-bit non-negative integer. It is used only to determine whether a version is later than another version. A larger value indicates a later version. **versionName** provides the text description of the version number. To declare the application version, configure the **versionCode** and **versionName** fields in the [app.json5 file](../quick-start/app-configuration-file.md) in the **AppScope** directory of the project. **versionCode** specifies the version number of the application. The value is a 32-bit non-negative integer. It is used only to determine whether a version is later than another version. A larger value indicates a later version. **versionName** provides the text description of the version number.
......
# Context (Stage Model) # Context (Stage Model)
## Overview ## Overview
[Context](../reference/apis/js-apis-inner-application-context.md) is the context of an object in an application. It provides basic information about the application, for example, **resourceManager**, **applicationInfo**, **dir** (application development path), and **area** (encrypted area). It also provides basic methods such as **createBundleContext()** and **getApplicationContext()**. The UIAbility component and ExtensionAbility derived class components have their own **Context** classes, for example, the base class **Context**, **ApplicationContext**, **AbilityStageContext**, **UIAbilityContext**, **ExtensionContext**, and **ServiceExtensionContext**. [Context](../reference/apis/js-apis-inner-application-context.md) is the context of an object in an application. It provides basic information about the application, for example, **resourceManager**, **applicationInfo**, **dir** (application development path), and **area** (encrypted level). It also provides basic methods such as **createBundleContext()** and **getApplicationContext()**. The UIAbility component and ExtensionAbility derived class components have their own **Context** classes, for example, the base class **Context**, **ApplicationContext**, **AbilityStageContext**, **UIAbilityContext**, **ExtensionContext**, and **ServiceExtensionContext**.
- The figure below illustrates the inheritance relationship of contexts. - The figure below illustrates the inheritance relationship of contexts.
![context-inheritance](figures/context-inheritance.png) ![context-inheritance](figures/context-inheritance.png)
- The figure below illustrates the holding relationship of contexts. - The figure below illustrates the holding relationship of contexts.
![context-holding](figures/context-holding.png) ![context-holding](figures/context-holding.png)
- The following describes the information provided by different contexts. The following describes the information provided by different contexts.
- [UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md): Each UIAbility has the **Context** attribute, which provides APIs to operate an application component, obtain the application component configuration, and more. - [UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md): Each UIAbility has the **Context** attribute, which provides APIs to operate an application component, obtain the application component configuration, and more.
```ts ```ts
...@@ -21,7 +18,7 @@ ...@@ -21,7 +18,7 @@
export default class EntryAbility extends UIAbility { export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) { onCreate(want, launchParam) {
let uiAbilityContext = this.context; let uiAbilityContext = this.context;
// ... ...
} }
} }
``` ```
...@@ -36,7 +33,7 @@ ...@@ -36,7 +33,7 @@
export default class MyService extends ServiceExtensionAbility { export default class MyService extends ServiceExtensionAbility {
onCreate(want) { onCreate(want) {
let serviceExtensionContext = this.context; let serviceExtensionContext = this.context;
// ... ...
} }
} }
``` ```
...@@ -47,7 +44,7 @@ ...@@ -47,7 +44,7 @@
export default class MyAbilityStage extends AbilityStage { export default class MyAbilityStage extends AbilityStage {
onCreate() { onCreate() {
let abilityStageContext = this.context; let abilityStageContext = this.context;
// ... ...
} }
} }
``` ```
...@@ -58,7 +55,7 @@ ...@@ -58,7 +55,7 @@
export default class EntryAbility extends UIAbility { export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) { onCreate(want, launchParam) {
let applicationContext = this.context.getApplicationContext(); let applicationContext = this.context.getApplicationContext();
// ... ...
} }
} }
``` ```
...@@ -71,7 +68,7 @@ This topic describes how to use the context in the following scenarios: ...@@ -71,7 +68,7 @@ This topic describes how to use the context in the following scenarios:
- [Obtaining the Application Development Path](#obtaining-the-application-development-path) - [Obtaining the Application Development Path](#obtaining-the-application-development-path)
- [Obtaining and Modifying Encryption Areas](#obtaining-and-modifying-encryption-areas) - [Obtaining and Modifying Encryption Levels](#obtaining-and-modifying-encryption-levels)
- [Creating Context of Another Application or Module](#creating-context-of-another-application-or-module) - [Creating Context of Another Application or Module](#creating-context-of-another-application-or-module)
- [Subscribing to UIAbility Lifecycle Changes in a Process](#subscribing-to-uiability-lifecycle-changes-in-a-process) - [Subscribing to UIAbility Lifecycle Changes in a Process](#subscribing-to-uiability-lifecycle-changes-in-a-process)
...@@ -85,12 +82,12 @@ The following table describes the application development paths obtained from co ...@@ -85,12 +82,12 @@ The following table describes the application development paths obtained from co
| Name| Type| Readable| Writable| Description| | Name| Type| Readable| Writable| Description|
| -------- | -------- | -------- | -------- | -------- | | -------- | -------- | -------- | -------- | -------- |
| bundleCodeDir | string | Yes | No | Path for storing the application's installation package, that is, installation directory of the application on the internal storage. | | bundleCodeDir | string | Yes | No | Path for storing the application's installation package, that is, installation directory of the application on the internal storage. |
| cacheDir | string | Yes| No| Path for storing the application's cache files, that is, cache directory of the application on the internal storage.<br>It is the content of **Storage** of an application under **Settings > Apps & services > Apps**.| | cacheDir | string | Yes| No| Path for storing the cache files, that is, cache directory of the application on the internal storage.<br>It is the content of **Storage** of an application under **Settings > Apps & services > Apps**.|
| filesDir | string | Yes | No | Path for storing the application's common files, that is, file directory of the application on the internal storage.<br>Files in this directory may be synchronized to other directories during application migration or backup.| | filesDir | string | Yes | No | Path for storing the common files, that is, file directory of the application on the internal storage.<br>Files in this directory may be synchronized to other directories during application migration or backup.|
| preferencesDir | string | Yes | Yes | Path for storing the application's preference files, that is, preferences directory of the application. | | preferencesDir | string | Yes | Yes | Path for storing the preference files, that is, preferences directory of the application. |
| tempDir | string | Yes | No | Path for storing the application's temporary files.<br>Files in this directory are deleted after the application is uninstalled.| | tempDir | string | Yes | No | Path for storing the temporary files.<br>Files in this directory are deleted after the application is uninstalled.|
| databaseDir | string | Yes | No | Path for storing the application's database, that is, storage directory of the local database. | | databaseDir | string | Yes | No | Path for storing the application's database, that is, storage directory of the local database. |
| distributedFilesDir | string | Yes| No| Path for storing the application's distributed files.| | distributedFilesDir | string | Yes| No| Path for storing the distributed files.|
The capability of obtaining the application development path is provided by the base class **Context**. This capability is also provided by **ApplicationContext**, **AbilityStageContext**, **UIAbilityContext**, and **ExtensionContext**. However, the paths obtained from different contexts may differ, as shown below. The capability of obtaining the application development path is provided by the base class **Context**. This capability is also provided by **ApplicationContext**, **AbilityStageContext**, **UIAbilityContext**, and **ExtensionContext**. However, the paths obtained from different contexts may differ, as shown below.
...@@ -135,7 +132,7 @@ export default class EntryAbility extends UIAbility { ...@@ -135,7 +132,7 @@ export default class EntryAbility extends UIAbility {
let bundleCodeDir = this.context.bundleCodeDir; let bundleCodeDir = this.context.bundleCodeDir;
let distributedFilesDir = this.context.distributedFilesDir; let distributedFilesDir = this.context.distributedFilesDir;
let preferencesDir = this.context.preferencesDir; let preferencesDir = this.context.preferencesDir;
// ... ...
} }
} }
``` ```
...@@ -144,19 +141,19 @@ export default class EntryAbility extends UIAbility { ...@@ -144,19 +141,19 @@ export default class EntryAbility extends UIAbility {
> >
> The sample code obtains the sandbox path of the application development path. The absolute path can be obtained by running the **find / -name <fileName>** command in the hdc shell after file creation or modification. > The sample code obtains the sandbox path of the application development path. The absolute path can be obtained by running the **find / -name <fileName>** command in the hdc shell after file creation or modification.
### Obtaining and Modifying Encryption Areas ### Obtaining and Modifying Encryption Levels
Encrypting application files enhances data security by preventing files from unauthorized access. Different application files require different levels of protection. For private files, such as alarms and wallpapers, the application must place them in the device-level encryption area (EL1) to ensure that they can be accessed before the user enters the password. For sensitive files, such as personal privacy data, the application must place them in the user-level encryption area (EL2). Encrypting application files enhances data security by preventing files from unauthorized access. Different application files require different levels of protection. For private files, such as alarms and wallpapers, the application must place them in a directory with the device-level encryption (EL1) to ensure that they can be accessed before the user enters the password. For sensitive files, such as personal privacy data, the application must place them in a directory with the user-level encryption (EL2).
In practice, you need to select a proper encrypted area based on scenario-specific requirements to protect application data security. The proper use of EL1 and the EL2 can efficiently improve the security. In practice, you need to select a proper encryption level based on scenario-specific requirements to protect application data security. The proper use of EL1 and the EL2 can efficiently improve the security.
> **NOTE** > **NOTE**
> >
> - AreaMode.EL1: device-level encryption area, which is accessible after the device is powered on. > - AreaMode.EL1: device-level encryption. Directories with this encryption level are accessible after the device is powered on.
> >
> - AreaMode.EL2: user-level encryption area, which is accessible only after the device is powered on and the password is entered (for the first time). > - AreaMode.EL2: user-level encryption. Directories with this encryption level are accessible only after the device is powered on and the password is entered (for the first time).
You can obtain and set the encryption area by reading and writing the [area attribute in Context](../reference/apis/js-apis-inner-application-context.md). You can obtain and set the encryption level by reading and writing the [area attribute in Context](../reference/apis/js-apis-inner-application-context.md).
```ts ```ts
import UIAbility from '@ohos.app.ability.UIAbility'; import UIAbility from '@ohos.app.ability.UIAbility';
...@@ -202,7 +199,7 @@ The base class **Context** provides [createBundleContext(bundleName:string)](../ ...@@ -202,7 +199,7 @@ The base class **Context** provides [createBundleContext(bundleName:string)](../
let bundleName2 = 'com.example.application'; let bundleName2 = 'com.example.application';
let context2 = this.context.createBundleContext(bundleName2); let context2 = this.context.createBundleContext(bundleName2);
let label2 = context2.applicationInfo.label; let label2 = context2.applicationInfo.label;
// ... ...
} }
} }
``` ```
...@@ -224,7 +221,7 @@ The base class **Context** provides [createBundleContext(bundleName:string)](../ ...@@ -224,7 +221,7 @@ The base class **Context** provides [createBundleContext(bundleName:string)](../
let bundleName2 = 'com.example.application'; let bundleName2 = 'com.example.application';
let moduleName2 = 'module1'; let moduleName2 = 'module1';
let context2 = this.context.createModuleContext(bundleName2, moduleName2); let context2 = this.context.createModuleContext(bundleName2, moduleName2);
// ... ...
} }
} }
``` ```
...@@ -238,7 +235,7 @@ The base class **Context** provides [createBundleContext(bundleName:string)](../ ...@@ -238,7 +235,7 @@ The base class **Context** provides [createBundleContext(bundleName:string)](../
onCreate(want, launchParam) { onCreate(want, launchParam) {
let moduleName2 = 'module1'; let moduleName2 = 'module1';
let context2 = this.context.createModuleContext(moduleName2); let context2 = this.context.createModuleContext(moduleName2);
// ... ...
} }
} }
``` ```
...@@ -248,7 +245,7 @@ The base class **Context** provides [createBundleContext(bundleName:string)](../ ...@@ -248,7 +245,7 @@ The base class **Context** provides [createBundleContext(bundleName:string)](../
In the DFX statistics scenario of an application, if you need to collect statistics on the stay duration and access frequency of a page, you can subscribe to UIAbility lifecycle changes in a process. In the DFX statistics scenario of an application, if you need to collect statistics on the stay duration and access frequency of a page, you can subscribe to UIAbility lifecycle changes in a process.
[ApplicationContext](../reference/apis/js-apis-inner-application-applicationContext) provides APIs for subscribing to UIAbility lifecycle changes in a process. When the UIAbility lifecycle changes in a process, for example, being created or destroyed, becoming visible or invisible, or gaining or losing focus, the corresponding callback is triggered. Each time the callback is registered, a listener lifecycle ID is returned, with the value incremented by 1 each time. When the number of listeners exceeds the upper limit (2^63-1), **-1** is returned. The following uses [UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md) as an example. [ApplicationContext](../reference/apis/js-apis-inner-application-applicationContext.md) provides APIs for subscribing to UIAbility lifecycle changes in a process. When the UIAbility lifecycle changes in a process, for example, being created or destroyed, becoming visible or invisible, or gaining or losing focus, the corresponding callback is triggered. Each time the callback is registered, a listener lifecycle ID is returned, with the value incremented by 1 each time. When the number of listeners exceeds the upper limit (2^63-1), **-1** is returned. The following uses [UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md) as an example.
```ts ```ts
...@@ -266,53 +263,53 @@ export default class EntryAbility extends UIAbility { ...@@ -266,53 +263,53 @@ export default class EntryAbility extends UIAbility {
let abilityLifecycleCallback = { let abilityLifecycleCallback = {
// Called when a UIAbility is created. // Called when a UIAbility is created.
onAbilityCreate(uiAbility) { onAbilityCreate(uiAbility) {
console.log(TAG, `onAbilityCreate uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`); console.info(TAG, `onAbilityCreate uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
}, },
// Called when a window is created. // Called when a window is created.
onWindowStageCreate(uiAbility, windowStage: window.WindowStage) { onWindowStageCreate(uiAbility, windowStage: window.WindowStage) {
console.log(TAG, `onWindowStageCreate uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`); console.info(TAG, `onWindowStageCreate uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
console.log(TAG, `onWindowStageCreate windowStage: ${JSON.stringify(windowStage)}`); console.info(TAG, `onWindowStageCreate windowStage: ${JSON.stringify(windowStage)}`);
}, },
// Called when the window becomes active. // Called when the window becomes active.
onWindowStageActive(uiAbility, windowStage: window.WindowStage) { onWindowStageActive(uiAbility, windowStage: window.WindowStage) {
console.log(TAG, `onWindowStageActive uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`); console.info(TAG, `onWindowStageActive uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
console.log(TAG, `onWindowStageActive windowStage: ${JSON.stringify(windowStage)}`); console.info(TAG, `onWindowStageActive windowStage: ${JSON.stringify(windowStage)}`);
}, },
// Called when the window becomes inactive. // Called when the window becomes inactive.
onWindowStageInactive(uiAbility, windowStage: window.WindowStage) { onWindowStageInactive(uiAbility, windowStage: window.WindowStage) {
console.log(TAG, `onWindowStageInactive uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`); console.info(TAG, `onWindowStageInactive uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
console.log(TAG, `onWindowStageInactive windowStage: ${JSON.stringify(windowStage)}`); console.info(TAG, `onWindowStageInactive windowStage: ${JSON.stringify(windowStage)}`);
}, },
// Called when the window is destroyed. // Called when the window is destroyed.
onWindowStageDestroy(uiAbility, windowStage: window.WindowStage) { onWindowStageDestroy(uiAbility, windowStage: window.WindowStage) {
console.log(TAG, `onWindowStageDestroy uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`); console.info(TAG, `onWindowStageDestroy uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
console.log(TAG, `onWindowStageDestroy windowStage: ${JSON.stringify(windowStage)}`); console.info(TAG, `onWindowStageDestroy windowStage: ${JSON.stringify(windowStage)}`);
}, },
// Called when the UIAbility is destroyed. // Called when the UIAbility is destroyed.
onAbilityDestroy(uiAbility) { onAbilityDestroy(uiAbility) {
console.log(TAG, `onAbilityDestroy uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`); console.info(TAG, `onAbilityDestroy uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
}, },
// Called when the UIAbility is switched from the background to the foreground. // Called when the UIAbility is switched from the background to the foreground.
onAbilityForeground(uiAbility) { onAbilityForeground(uiAbility) {
console.log(TAG, `onAbilityForeground uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`); console.info(TAG, `onAbilityForeground uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
}, },
// Called when the UIAbility is switched from the foreground to the background. // Called when the UIAbility is switched from the foreground to the background.
onAbilityBackground(uiAbility) { onAbilityBackground(uiAbility) {
console.log(TAG, `onAbilityBackground uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`); console.info(TAG, `onAbilityBackground uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
}, },
// Called when UIAbility is continued on another device. // Called when UIAbility is continued on another device.
onAbilityContinue(uiAbility) { onAbilityContinue(uiAbility) {
console.log(TAG, `onAbilityContinue uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`); console.info(TAG, `onAbilityContinue uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
} }
} }
// Obtain the application context. // Obtain the application context.
let applicationContext = this.context.getApplicationContext(); let applicationContext = this.context.getApplicationContext();
// Register the application lifecycle callback. // Register the application lifecycle callback.
this.lifecycleId = applicationContext.on('abilityLifecycle', abilityLifecycleCallback); this.lifecycleId = applicationContext.on('abilityLifecycle', abilityLifecycleCallback);
console.log(TAG, `register callback number: ${this.lifecycleId}`); console.info(TAG, `register callback number: ${this.lifecycleId}`);
} }
// ... ...
onDestroy() { onDestroy() {
// Obtain the application context. // Obtain the application context.
......
...@@ -12,10 +12,9 @@ Along its evolution, OpenHarmony has provided two application models: ...@@ -12,10 +12,9 @@ Along its evolution, OpenHarmony has provided two application models:
The stage model is designed based on the following considerations, which make it become the recommended model: The stage model is designed based on the following considerations, which make it become the recommended model:
1. **Designed for complex applications** 1. **Designed for complex applications**
- In the stage model, multiple application components share an ArkTS engine (VM running the programming language ArkTS) instance, making it easy for application components to share objects and status while requiring less memory. - In the stage model, multiple application components share an ArkTS engine (VM running the programming language ArkTS) instance, making it easy for application components to share objects and status while requiring less memory.
- The object-oriented development mode makes the code of complex applications easy to read, maintain, and scale. - The object-oriented development mode makes the code of complex applications easy to read, maintain, and scale.
2. **Native support for [cross-device migration](hop-cross-device-migration.md) and [multi-device collaboration](hop-multi-device-collaboration.md) at the application component level** 2. **Native support for [cross-device migration](hop-cross-device-migration.md) and [multi-device collaboration](hop-multi-device-collaboration.md) at the application component level**
The stage model decouples application components from User Interfaces (UIs). The stage model decouples application components from User Interfaces (UIs).
...@@ -38,7 +37,7 @@ The stage model is designed based on the following considerations, which make it ...@@ -38,7 +37,7 @@ The stage model is designed based on the following considerations, which make it
The stage model redefines the boundary of application capabilities to well balance application capabilities and system management costs. The stage model redefines the boundary of application capabilities to well balance application capabilities and system management costs.
- Diverse application components (such as widgets and input methods) for specific scenarios. - Diverse application components (such as service widgets and input methods) for specific scenarios.
- Standardized background process management. To deliver a better user experience, the stage model manages background application processes in a more orderly manner. Applications cannot reside in the background randomly, and their background behavior is strictly managed to minimize malicious behavior. - Standardized background process management. To deliver a better user experience, the stage model manages background application processes in a more orderly manner. Applications cannot reside in the background randomly, and their background behavior is strictly managed to minimize malicious behavior.
...@@ -52,8 +51,8 @@ The table below describes their differences in detail. ...@@ -52,8 +51,8 @@ The table below describes their differences in detail.
| Item| FA model| Stage model| | Item| FA model| Stage model|
| -------- | -------- | -------- | | -------- | -------- | -------- |
| **Application component**| 1. Component classification<br>![fa-model-component](figures/fa-model-component.png)<br/>- PageAbility: has the UI and supports user interaction For details, see [PageAbility Component Overview](pageability-overview.md).<br>- ServiceAbility: provides background services and has no UI. For details, see [ServiceAbility Component Overview](serviceability-overview.md).<br>- DataAbility: provides the data sharing capability and has no UI. For details, see [DataAbility Component Overview](dataability-overview.md).<br>2. Development mode<br>Application components are specified by exporting anonymous objects and fixed entry files. You cannot perform derivation. It is inconvenient for capability expansion. | 1. Component classification<br>![stage-model-component](figures/stage-model-component.png)<br/> - UIAbility: has the UI and supports user interaction. For details, see [UIAbility Component Overview](uiability-overview.md).<br>- ExtensionAbility: provides extension capabilities (such as widget and input methods) for specific scenarios. For details, see [ExtensionAbility Component Overview](extensionability-overview.md).<br>2. Development mode<br>The object-oriented mode is used to provide open application components as classes. You can derive application components for capability expansion. | | **Application component**| 1. Component classification<br>![fa-model-component](figures/fa-model-component.png)<br>- PageAbility: has the UI and supports user interaction For details, see [PageAbility Component Overview](pageability-overview.md).<br>- ServiceAbility: provides background services and has no UI. For details, see [ServiceAbility Component Overview](serviceability-overview.md).<br>- DataAbility: provides the data sharing capability and has no UI. For details, see [DataAbility Component Overview](dataability-overview.md).<br>2. Development mode<br>Application components are specified by exporting anonymous objects and fixed entry files. You cannot perform derivation. It is inconvenient for capability expansion.| 1. Component classification<br>![stage-model-component](figures/stage-model-component.png)<br>- UIAbility: has the UI and supports user interaction. For details, see [UIAbility Component Overview](uiability-overview.md).<br>- ExtensionAbility: provides extension capabilities (such as widget and input methods) for specific scenarios. For details, see [ExtensionAbility Component Overview](extensionability-overview.md).<br>2. Development mode<br>The object-oriented mode is used to provide open application components as classes. You can derive application components for capability expansion.|
| **Process model**| There are two types of processes:<br>1. Main process<br>2. Rendering process<br>For details, see [Process Model (FA Model)](process-model-fa.md).| There are three types of processes:<br>1. Main process<br>2. ExtensionAbility process<br>3. Rendering process<br>For details, see [Process Model (Stage Model)](process-model-stage.md).| | **Process model**| There are two types of processes:<br>1. Main process<br>2. Rendering process<br>For details, see [Process Model Overview (FA Model)](process-model-fa.md). | There are three types of processes:<br>1. Main process<br>2. ExtensionAbility process<br>3. Rendering process<br>For details, see [Process Model Overview (Stage Model)](process-model-stage.md). |
| **Thread model**| 1. ArkTS engine instance creation<br>A process can run multiple application component instances, and each application component instance runs in an independent ArkTS engine instance.<br>2. Thread model<br>Each ArkTS engine instance is created on an independent thread (non-main thread). The main thread does not have an ArkTS engine instance.<br>3. Intra-process object sharing: not supported.<br>For details, see [Thread Model (FA Model)](thread-model-fa.md).| 1. ArkTS engine instance creation<br>A process can run multiple application component instances, and all application component instances share one ArkTS engine instance.<br>2. Thread model<br>The ArkTS engine instance is created on the main thread.<br>3. Intra-process object sharing: supported.<br>For details, see [Thread Model (Stage Model)](thread-model-stage.md).| | **Thread model**| 1. ArkTS engine instance creation<br>A process can run multiple application component instances, and each application component instance runs in an independent ArkTS engine instance.<br>2. Thread model<br>Each ArkTS engine instance is created on an independent thread (non-main thread). The main thread does not have an ArkTS engine instance.<br>3. Intra-process object sharing: not supported.<br>For details, see [Thread Model Overview (FA Model)](thread-model-fa.md). | 1. ArkTS engine instance creation<br>A process can run multiple application component instances, and all application component instances share one ArkTS engine instance.<br>2. Thread model<br>The ArkTS engine instance is created on the main thread.<br>3. Intra-process object sharing: supported.<br>For details, see [Thread Model Overview (Stage Model)](thread-model-stage.md). |
| **Mission management model**| - A mission is created for each PageAbility component instance.<br>- Missions are stored persistently until the number of missions exceeds the maximum (customized based on the product configuration) or users delete missions.<br>- PageAbility components do not form a stack structure.<br>For details, see [Mission Management Scenarios](mission-management-overview.md).| - A mission is created for each UIAbility component instance.<br>- Missions are stored persistently until the number of missions exceeds the maximum (customized based on the product configuration) or users delete missions.<br>- UIAbility components do not form a stack structure.<br>For details, see [Mission Management Scenarios](mission-management-overview.md).| | **Mission management model**| - A mission is created for each PageAbility component instance.<br>- Missions are stored persistently until the number of missions exceeds the maximum (customized based on the product configuration) or users delete missions.<br>- PageAbility components do not form a stack structure.<br>For details, see [Mission Management Scenarios](mission-management-overview.md).| - A mission is created for each UIAbility component instance.<br>- Missions are stored persistently until the number of missions exceeds the maximum (customized based on the product configuration) or users delete missions.<br>- UIAbility components do not form a stack structure.<br>For details, see [Mission Management Scenarios](mission-management-overview.md).|
| **Application configuration file**| The **config.json** file is used to describe the application, HAP, and application component information.<br>For details, see [Application Configuration File Overview (FA Model)](../quick-start/application-configuration-file-overview-fa.md).| The **app.json5** file is used to describe the application information, and the **module.json5** file is used to describe the HAP and application component information.<br>For details, see [Application Configuration File Overview (Stage Model)](../quick-start/application-configuration-file-overview-stage.md).| | **Application configuration file**| The **config.json** file is used to describe the application, HAP, and application component information.<br>For details, see [Application Configuration File Overview (FA Model)](../quick-start/application-configuration-file-overview-fa.md).| The **app.json5** file is used to describe the application information, and the **module.json5** file is used to describe the HAP and application component information.<br>For details, see [Application Configuration File Overview (Stage Model)](../quick-start/application-configuration-file-overview-stage.md).|
# Configuring Widget Configuration Files
Widget-related configuration includes **FormExtensionAbility** configuration and widget configuration.
1. Configure FormExtensionAbility information under **extensionAbilities** in the [module.json5 file](../quick-start/module-configuration-file.md). For a FormExtensionAbility, you must specify **metadata**. Specifically, set **name** to **ohos.extension.form** (fixed), and set **resource** to the index of the widget configuration information.
Example configuration:
```json
{
"module": {
...
"extensionAbilities": [
{
"name": "EntryFormAbility",
"srcEntry": "./ets/entryformability/EntryFormAbility.ts",
"label": "$string:EntryFormAbility_label",
"description": "$string:EntryFormAbility_desc",
"type": "form",
"metadata": [
{
"name": "ohos.extension.form",
"resource": "$profile:form_config"
}
]
}
]
}
}
```
2. Configure the widget configuration information. In the **metadata** configuration item of FormExtensionAbility, you can specify the resource index of specific configuration information of the widget. For example, if resource is set to **$profile:form_config**, **form_config.json** in the **resources/base/profile/** directory of the development view is used as the profile configuration file of the widget. The following table describes the internal field structure.
**Table 1** form_config.json file
| Field| Description| Data Type| Default Value Allowed|
| -------- | -------- | -------- | -------- |
| name | Class name of the widget. The value is a string with a maximum of 127 bytes.| String| No|
| description | Description of the widget. The value can be a string or a resource index to descriptions in multiple languages. The value is a string with a maximum of 255 bytes.| String| Yes (initial value: left empty)|
| src | Full path of the UI code corresponding to the widget. For an ArkTS widget, the full path must contain the widget file name extension, for example, **./ets/widget/pages/WidgetCard.ets**. For a JS widget, the full path does not need to contain the widget file name extension, for example, **./js/widget/pages/WidgetCard**.| String| No|
| uiSyntax | Type of the widget.<br>- **arkts**: ArkTS widget<br>- **hml**: JS widget| String| Yes (initial value: **hml**)|
| window | Window-related configurations.| Object| Yes|
| isDefault | Whether the widget is a default one. Each UIAbility has only one default widget.<br>- **true**: The widget is the default one.<br>- **false**: The widget is not the default one.| Boolean| No|
| colorMode | Color mode of the widget.<br>- **auto**: auto-adaptive color mode<br>- **dark**: dark color mode<br>- **light**: light color mode| String| Yes (initial value: **auto**)|
| supportDimensions | Grid styles supported by the widget.<br>- **1 * 2**: indicates a grid with one row and two columns.<br>- **2 * 2**: indicates a grid with two rows and two columns.<br>- **2 * 4**: indicates a grid with two rows and four columns.<br>- **4 * 4**: indicates a grid with four rows and four columns.| String array| No|
| defaultDimension | Default grid style of the widget. The value must be available in the **supportDimensions** array of the widget.| String| No|
| updateEnabled | Whether the widget can be updated periodically.<br>- **true**: The widget can be updated at a specified interval (**updateDuration**) or at the scheduled time (**scheduledUpdateTime**). **updateDuration** takes precedence over **scheduledUpdateTime**.<br>- **false**: The widget cannot be updated periodically.| Boolean| No|
| scheduledUpdateTime | Scheduled time to update the widget. The value is in 24-hour format and accurate to minute.<br>**NOTE**<br>**updateDuration** takes precedence over **scheduledUpdateTime**. If both are specified, the value specified by **updateDuration** is used.| String| Yes (initial value: The widget cannot be updated periodically.)|
| updateDuration | Interval to update the widget. The value is a natural number, in the unit of 30 minutes.<br>If the value is **0**, this field does not take effect.<br>If the value is a positive integer *N*, the interval is calculated by multiplying *N* and 30 minutes.<br>**NOTE**<br>**updateDuration** takes precedence over **scheduledUpdateTime**. If both are specified, the value specified by **updateDuration** is used.| Number| Yes (initial value: **0**)|
| formConfigAbility | Link to a specific page of the application. The value is a URI.| String| Yes (initial value: left empty)|
| formVisibleNotify | Whether the widget is allowed to use the widget visibility notification.| String| Yes (initial value: left empty)|
| metadata | Metadata of the widget. This field contains the array of the **customizeData** field.| Object| Yes (initial value: left empty)|
Example configuration:
```json
{
"forms": [
{
"name": "widget",
"description": "This is a service widget.",
"src": "./ets/widget/pages/WidgetCard.ets",
"uiSyntax": "arkts",
"window": {
"designWidth": 720,
"autoDesignWidth": true
},
"colorMode": "auto",
"isDefault": true,
"updateEnabled": true,
"scheduledUpdateTime": "10:30",
"updateDuration": 1,
"defaultDimension": "2*2",
"supportDimensions": [
"2*2"
]
}
]
}
```
# Updating Widget Content by Widget Host (for System Applications Only)
Widgets that are updated periodically are subject to the scheduled time or interval settings. To offer more flexible updates, the widget host can provide a button to proactively trigger a widget update. Specifically, the widget host calls the [requestForm](../reference/apis/js-apis-app-form-formHost.md#requestform) API to request a widget update. The system then calls the [onUpdateForm](../reference/apis/js-apis-app-form-formExtensionAbility.md#onupdateform) lifecycle callback in the FormExtensionAbility of the widget provider. In the callback, the [updateForm](../reference/apis/js-apis-app-form-formProvider.md#updateform) API can be used to update the widget content. For details about the **onUpdateForm** lifecycle callback, see [Updating Widget Content Through FormExtensionAbility](arkts-ui-widget-event-formextensionability.md).
```ts
import formHost from '@ohos.app.form.formHost';
@Entry()
@Component
struct WidgetCard {
formId = ...; // Widget ID
build() {
Button (`Update Widget`)
.type(ButtonType.Capsule)
.width('50%')
.height(50)
.onClick(() => {
console.info('FormAbility update form click');
// formId is the ID of the widget to be updated.
formHost.requestForm(this.formId.toString()).then(() => {
console.info('Succeeded in requestForming.');
});
})
...
}
}
```
# Creating an ArkTS Widget
To create an ArkTS widget in an existing application project, perform the following steps:
1. Create a widget.
![WidgetProjectCreate1](figures/WidgetProjectCreate1.png)
2. Select a widget template based on the actual service scenario.
![WidgetProjectCreate2](figures/WidgetProjectCreate2.png)
3. Set **Language** to **ArkTS** and click **Finish**.
![WidgetProjectCreate3](figures/WidgetProjectCreate3.png)
After an ArkTS widget is created, the following widget-related files are added to the project directory: **EntryFormAbility.ts** (widget lifecycle management file), **WidgetCard.ets** (widget page file), and **form_config.json** (widget configuration file).
![WidgetProjectView](figures/WidgetProjectView.png)
# Launching a UIAbility in the Background Through the call Event
There may be cases you want to provide in a widget access to features available in your application when it is running in the foreground, for example, the play, pause, and stop buttons in a music application widget. This is where the **call** capability of the **postCardAction** API comes in handy. This capability, when used in a widget, can start the specified UIAbility of the widget provider in the background. It also allows the widget to call the specified method of the application and transfer data so that the application, while in the background, can behave accordingly in response to touching of the buttons on the widget.
Generally, buttons are used to trigger the **call** event. Below is an example.
- In this example, two buttons are laid out on the widget page. When one button is clicked, the **postCardAction** API is called to send a **call** event to the target UIAbility. Note that the **method** parameter in the API indicates the method to call in the target UIAbility. It is mandatory and of the string type.
```ts
@Entry
@Component
struct WidgetCard {
build() {
Column() {
Button ('Feature A')
.margin('20%')
.onClick(() => {
console.info('call EntryAbility funA');
postCardAction(this, {
'action': 'call',
'abilityName': 'EntryAbility', // Only the UIAbility of the current application is allowed.
'params': {
'method': 'funA' // Set the name of the method to call in the EntryAbility.
}
});
})
Button ('Feature B')
.margin('20%')
.onClick(() => {
console.info('call EntryAbility funB');
postCardAction(this, {
'action': 'call',
'abilityName': 'EntryAbility', // Only the UIAbility of the current application is allowed.
'params': {
'method': 'funB', // Set the name of the method to call in the EntryAbility.
'num': 1 // Set other parameters to be transferred.
}
});
})
}
.width('100%')
.height('100%')
}
}
```
- The UIAbility receives the **call** event and obtains the transferred parameters. It then executes the target method specified by the **method** parameter. Other data can be obtained in readString mode. Listen for the method required by the **call** event in the **onCreate** callback of the UIAbility.
```ts
import UIAbility from '@ohos.app.ability.UIAbility';
function FunACall(data) {
// Obtain all parameters transferred in the call event.
console.info('FunACall param:' + JSON.stringify(data.readString()));
return null;
}
function FunBCall(data) {
console.info('FunACall param:' + JSON.stringify(data.readString()));
return null;
}
export default class CameraAbility extends UIAbility {
// If the UIAbility is started for the first time, the onCreate lifecycle callback is triggered after the call event is received.
onCreate(want, launchParam) {
try {
// Listen for the method required by the call event.
this.callee.on('funA', FunACall);
this.callee.on('funB', FunBCall);
} catch (error) {
console.error(`Failed to register callee on. Cause: ${JSON.stringify(err)}`);
}
}
// Deregister the listener when the process exits.
onDestroy() {
try {
this.callee.off('funA');
this.callee.off('funB');
} catch (err) {
console.error(`Failed to register callee off. Cause: ${JSON.stringify(err)}`);
}
}
};
```
# Updating Widget Content Through the message Event
On the widget page, the **postCardAction** API can be used to trigger a message event to start a FormExtensionAbility, which then updates the widget content. The following is an example of this widget update mode.
- On the widget page, register the **onClick** event callback of the button and call the **postCardAction** API in the callback to trigger the event to the FormExtensionAbility.
```ts
let storage = new LocalStorage();
@Entry(storage)
@Component
struct WidgetCard {
@LocalStorageProp('title') title: string = 'init';
@LocalStorageProp('detail') detail: string = 'init';
build() {
Column() {
Button ('Update')
.onClick(() => {
postCardAction(this, {
'action': 'message',
'params': {
'msgTest': 'messageEvent'
}
});
})
Text(`${this.title}`)
Text(`${this.detail}`)
}
.width('100%')
.height('100%')
}
}
```
- Call the [updateForm](../reference/apis/js-apis-app-form-formProvider.md#updateform) API to update the widget in the **onFormEvent** callback of the FormExtensionAbility.
```ts
import formBindingData from '@ohos.app.form.formBindingData';
import FormExtensionAbility from '@ohos.app.form.FormExtensionAbility';
import formProvider from '@ohos.app.form.formProvider';
export default class EntryFormAbility extends FormExtensionAbility {
onFormEvent(formId, message) {
// Called when a specified message event defined by the form provider is triggered.
console.info(`FormAbility onEvent, formId = ${formId}, message: ${JSON.stringify(message)}`);
let formData = {
'title':'Title Update Success.', // Matches the widget layout.
'detail':'Detail Update Success.', // Matches the widget layout.
};
let formInfo = formBindingData.createFormBindingData(formData)
formProvider.updateForm(formId, formInfo).then((data) => {
console.info('FormAbility updateForm success.' + JSON.stringify(data));
}).catch((error) => {
console.error('FormAbility updateForm failed: ' + JSON.stringify(error));
})
}
...
}
```
The figure below shows the effect.
![WidgetUpdatePage](figures/WidgetUpdatePage.png)
# Widget Event Capability Overview
The ArkTS widget provides the **postCardAction()** API for interaction between the widget internal and the provider application. Currently, this API supports the router, message, and call events and can be called only in the widget.
![WidgetPostCardAction](figures/WidgetPostCardAction.png)
**Definition**: postCardAction(component: Object, action: Object): void
**Parameters**
| Name| Type| Mandatory| Description|
| -------- | -------- | -------- | -------- |
| component | Object | Yes| Instance of the current custom component. Generally, **this** is transferred.|
| action | Object | Yes| Action description. For details, see the following table.|
**Description of the action parameter**
| Key | Value | Description|
| -------- | -------- | -------- |
| "action" | string | Action type.<br>- **"router"**: redirection to the specified UIAbility of the widget provider.<br>- **"message"**: custom message. If this type of action is triggered, the [onFormEvent()](../reference/apis/js-apis-app-form-formExtensionAbility.md#onformevent) lifecycle callback of the provider FormExtensionAbility is called.<br>- **"call"**: launch of the widget provider in the background. If this type of action is triggered, the specified UIAbility of the widget provider is started in the background, but not displayed in the foreground. This action type requires that the widget provider should have the [ohos.permission.KEEP_BACKGROUND_RUNNING](../security/permission-list.md#ohospermissionkeep_background_running) permission.|
| "bundleName" | string | Name of the target bundle when **action** is **"router"** or **"call"**. This parameter is optional.|
| "moduleName" | string | Name of the target module when **action** is **"router"** or **"call"**. This parameter is optional.|
| "abilityName" | string | Name of the target UIAbility when **action** is **"router"** or **"call"**. This parameter is mandatory.|
| "params" | Object | Additional parameters carried in the current action. The value is a key-value pair in JSON format. For the **"call"** action type, the **method** parameter must be set and its value type must be string. This parameter is mandatory.|
Sample code of the **postCardAction()** API:
```typescript
Button ('Jump')
.width('40%')
.height('20%')
.onClick(() => {
postCardAction(this, {
'action': 'router',
'bundleName': 'com.example.myapplication',
'abilityName': 'EntryAbility',
'params': {
'message': 'testForRouter' // Customize the message to send.
}
});
})
Button ('Start in Background')
.width('40%')
.height('20%')
.onClick(() => {
postCardAction(this, {
'action': 'call',
'bundleName': 'com.example.myapplication',
'abilityName': 'EntryAbility',
'params': {
'method': 'fun', // Set the name of the method to call. It is mandatory.
'message': 'testForcall' // Customize the message to send.
}
});
})
```
Read on to learn the typical widget development scenarios that can be implemented through widget events.
# Redirecting to a UIAbility Through the router Event
The **router** capability of the **postCardAction** API can be used in a widget to quickly start a specific UIAbility of the widget provider. By leveraging this capability, an application can provide in the widget multiple buttons, each of which targets a different target UIAbility. For example, a camera widget can provide the buttons that redirect the user to the UIAbility for taking a photo and the UIAbility for recording a video.
![WidgerCameraCard](figures/WidgerCameraCard.png)
Generally, a button is used to start a page.
- Design two buttons on the widget page. When one of the buttons is clicked, **postCardAction** is called to send a router event to the specified UIAbility, with the content to be transferred defined in the event.
```ts
@Entry
@Component
struct WidgetCard {
build() {
Column() {
Button ('Function A')
.margin('20%')
.onClick(() => {
console.info('Jump to EntryAbility funA');
postCardAction(this, {
'action': 'router',
'abilityName': 'EntryAbility', // Only the UIAbility of the current application is allowed.
'params': {
'targetPage': 'funA' // Process the information in the EntryAbility.
}
});
})
Button ('Function B')
.margin('20%')
.onClick(() => {
console.info('Jump to EntryAbility funB');
postCardAction(this, {
'action': 'router',
'abilityName': 'EntryAbility', // Only the UIAbility of the current application is allowed.
'params': {
'targetPage': 'funB' // Process the information in the EntryAbility.
}
});
})
}
.width('100%')
.height('100%')
}
}
```
- The UIAbility receives the router event and obtains parameters. It then starts the page specified in the received message.
```ts
import UIAbility from '@ohos.app.ability.UIAbility';
import window from '@ohos.window';
let selectPage = "";
let currentWindowStage = null;
export default class CameraAbility extends UIAbility {
// If the UIAbility is started for the first time, the onCreate lifecycle callback is triggered after the router event is received.
onCreate(want, launchParam) {
// Obtain the targetPage parameter passed in the router event.
console.info("onCreate want:" + JSON.stringify(want));
if (want.parameters.params !== undefined) {
let params = JSON.parse(want.parameters.params);
console.info("onCreate router targetPage:" + params.targetPage);
selectPage = params.targetPage;
}
}
// If the UIAbility is running in the background, the onNewWant lifecycle callback is triggered after the router event is received.
onNewWant(want, launchParam) {
console.info("onNewWant want:" + JSON.stringify(want));
if (want.parameters.params !== undefined) {
let params = JSON.parse(want.parameters.params);
console.info("onNewWant router targetPage:" + params.targetPage);
selectPage = params.targetPage;
}
if (currentWindowStage != null) {
this.onWindowStageCreate(currentWindowStage);
}
}
onWindowStageCreate(windowStage: window.WindowStage) {
let targetPage;
// Start the page specified by targetPage.
switch (selectPage) {
case 'funA':
targetPage = 'pages/FunA';
break;
case 'funB':
targetPage = 'pages/FunB';
break;
default:
targetPage = 'pages/Index';
}
if (currentWindowStage === null) {
currentWindowStage = windowStage;
}
windowStage.loadContent(targetPage, (err, data) => {
if (err && err.code) {
console.info('Failed to load the content. Cause: %{public}s', JSON.stringify(err));
return;
}
});
}
};
```
# Updating Widget Content Through the router or call Event
On the widget page, the **postCardAction** API can be used to trigger a router or call event to start a UIAbility, which then updates the widget content. The following is an example of this widget update mode.
## Updating Widget Content Through the router Event
- On the widget page, register the **onClick** event callback of the button and call the **postCardAction** API in the callback to trigger the **router** event to the FormExtensionAbility.
```ts
let storage = new LocalStorage();
@Entry(storage)
@Component
struct WidgetCard {
@LocalStorageProp('detail') detail: string = 'init';
build() {
Column() {
Button ('Jump')
.margin('20%')
.onClick(() => {
console.info('postCardAction to EntryAbility');
postCardAction(this, {
'action': 'router',
'abilityName': 'EntryAbility', // Only the UIAbility of the current application is allowed.
'params': {
'detail': 'RouterFromCard'
}
});
})
Text(`${this.detail}`).margin('20%')
}
.width('100%')
.height('100%')
}
}
```
- In the **onCreate()** or **onNewWant()** lifecycle callback of the UIAbility, use the input parameter **want** to obtain the ID (**formID**) and other information of the widget, and then call the [updateForm](../reference/apis/js-apis-app-form-formProvider.md#updateform) API to update the widget.
```ts
import UIAbility from '@ohos.app.ability.UIAbility';
import formBindingData from '@ohos.app.form.formBindingData';
import formProvider from '@ohos.app.form.formProvider';
import formInfo from '@ohos.app.form.formInfo';
export default class EntryAbility extends UIAbility {
// If the UIAbility is started for the first time, the onCreate lifecycle callback is triggered after the router event is received.
onCreate(want, launchParam) {
console.info('Want:' + JSON.stringify(want));
if (want.parameters[formInfo.FormParam.IDENTITY_KEY] !== undefined) {
let curFormId = want.parameters[formInfo.FormParam.IDENTITY_KEY];
let message = JSON.parse(want.parameters.params).detail;
console.info(`UpdateForm formId: ${curFormId}, message: ${message}`);
let formData = {
"detail": message +': onCreate UIAbility.', // Matches the widget layout.
};
let formMsg = formBindingData.createFormBindingData(formData)
formProvider.updateForm(curFormId, formMsg).then((data) => {
console.info('updateForm success.' + JSON.stringify(data));
}).catch((error) => {
console.error('updateForm failed:' + JSON.stringify(error));
})
}
}
// If the UIAbility is running in the background, the onNewWant lifecycle callback is triggered after the router event is received.
onNewWant(want, launchParam) {
console.info('onNewWant Want:' + JSON.stringify(want));
if (want.parameters[formInfo.FormParam.IDENTITY_KEY] !== undefined) {
let curFormId = want.parameters[formInfo.FormParam.IDENTITY_KEY];
let message = JSON.parse(want.parameters.params).detail;
console.info(`UpdateForm formId: ${curFormId}, message: ${message}`);
let formData = {
"detail": message +': onNewWant UIAbility.', // Matches the widget layout.
};
let formMsg = formBindingData.createFormBindingData(formData)
formProvider.updateForm(curFormId, formMsg).then((data) => {
console.info('updateForm success.' + JSON.stringify(data));
}).catch((error) => {
console.error('updateForm failed:' + JSON.stringify(error));
})
}
}
...
}
```
## Updating Widget Content Through the call Event
- When using the **call** event of the **postCardAction** API, the value of **formId** must be updated in the **onAddForm** callback of the FormExtensionAbility.
```ts
import formBindingData from '@ohos.app.form.formBindingData';
import FormExtensionAbility from '@ohos.app.form.FormExtensionAbility';
export default class EntryFormAbility extends FormExtensionAbility {
onAddForm(want) {
let formId = want.parameters["ohos.extra.param.key.form_identity"];
let dataObj1 = {
"formId": formId
};
let obj1 = formBindingData.createFormBindingData(dataObj1);
return obj1;
}
...
};
```
- On the widget page, register the **onClick** event callback of the button and call the **postCardAction** API in the callback to trigger the event to the UIAbility.
```ts
let storage = new LocalStorage();
@Entry(storage)
@Component
struct WidgetCard {
@LocalStorageProp('detail') detail: string = 'init';
@LocalStorageProp('formId') formId: string = '0';
build() {
Column() {
Button ('Start in Background')
.margin('20%')
.onClick(() => {
console.info('postCardAction to EntryAbility');
postCardAction(this, {
'action': 'call',
'abilityName': 'EntryAbility', // Only the UIAbility of the current application is allowed.
'params': {
'method': 'funA',
'formId': this.formId,
'detail': 'CallFromCard'
}
});
})
Text(`${this.detail}`).margin('20%')
}
.width('100%')
.height('100%')
}
}
```
- Listen for the method required by the **call** event in the **onCreate** callback of the UIAbility, and then call the [updateForm](../reference/apis/js-apis-app-form-formProvider.md#updateform) API in the corresponding method to update the widget.
```ts
import UIAbility from '@ohos.app.ability.UIAbility';
import formBindingData from '@ohos.app.form.formBindingData';
import formProvider from '@ohos.app.form.formProvider';
import formInfo from '@ohos.app.form.formInfo';
const MSG_SEND_METHOD: string = 'funA';
// After the call event is received, the method listened for by the callee is triggered.
function FunACall(data) {
// Obtain all parameters transferred in the call event.
let params = JSON.parse(data.readString())
if (params.formId !== undefined) {
let curFormId = params.formId;
let message = params.detail;
console.info(`UpdateForm formId: ${curFormId}, message: ${message}`);
let formData = {
"detail": message
};
let formMsg = formBindingData.createFormBindingData(formData)
formProvider.updateForm(curFormId, formMsg).then((data) => {
console.info('updateForm success.' + JSON.stringify(data));
}).catch((error) => {
console.error('updateForm failed:' + JSON.stringify(error));
})
}
return null;
}
export default class EntryAbility extends UIAbility {
// If the UIAbility is started for the first time, the onCreate lifecycle callback is triggered after the call event is received.
onCreate(want, launchParam) {
console.info('Want:' + JSON.stringify(want));
try {
// Listen for the method required by the call event.
this.callee.on(MSG_SEND_METHOD, FunACall);
} catch (error) {
console.info(`${MSG_SEND_METHOD} register failed with error ${JSON.stringify(error)}`)
}
}
...
}
```
# Updating Local and Online Images in the Widget
Typically, a widget includes local images or online images downloaded from the network. To obtain local and online images, use the FormExtensionAbility. The following exemplifies how to show local and online images on a widget.
1. For the widget to download online images, declare the **ohos.permission.INTERNET** permission for the widget. For details, see [Declaring Permissions in the Configuration File](../security/accesstoken-guidelines.md).
2. Update local files in the **onAddForm** lifecycle callback of the EntryFormAbility.
```ts
import formBindingData from '@ohos.app.form.formBindingData';
import formProvider from '@ohos.app.form.formProvider';
import FormExtensionAbility from '@ohos.app.form.FormExtensionAbility';
import request from '@ohos.request';
import fs from '@ohos.file.fs';
export default class EntryFormAbility extends FormExtensionAbility {
...
// When the widget is added, a local image is opened and transferred to the widget page for display.
onAddForm(want) {
// Assume that the local image head.PNG is in the tmp directory of the current widget.
let tempDir = this.context.getApplicationContext().tempDir;
// Open the local image and obtain the FD after the image is opened.
let file;
try {
file = fs.openSync(tempDir + '/' + 'head.PNG');
} catch (e) {
console.error(`openSync failed: ${JSON.stringify(e)}`);
}
let formData = {
'text': 'Image: Bear',
'imgName': 'imgBear',
'formImages': {
'imgBear': file.fd
},
'loaded': true
}
// Encapsulate the FD in formData and return it to the widget page.
return formBindingData.createFormBindingData(formData);
}
...
}
```
3. Update online images in the **onFormEvent** lifecycle callback of the EntryFormAbility.
```ts
import formBindingData from '@ohos.app.form.formBindingData';
import formProvider from '@ohos.app.form.formProvider';
import FormExtensionAbility from '@ohos.app.form.FormExtensionAbility';
import request from '@ohos.request';
import fs from '@ohos.file.fs';
export default class EntryFormAbility extends FormExtensionAbility {
// When the message event is triggered on the widget page, an online image is downloaded and transferred to the widget page for display.
onFormEvent(formId, message) {
let formInfo = formBindingData.createFormBindingData({
'text': 'Updating...'
})
formProvider.updateForm(formId, formInfo)
// Note: After being started with the triggering of the lifecycle callback, the FormExtensionAbility can run in the background for only 5 seconds.
// When possible, limit the size of the image to download. If an image cannot be downloaded within 5 seconds, it will not be updated to the widget page.
let netFile = 'https://xxxx/xxxx.png'; // Specify the URL of the image to download.
let tempDir = this.context.getApplicationContext().tempDir;
let fileName = 'file' + Date.now();
let tmpFile = tempDir + '/' + fileName;
request.downloadFile(this.context, {
url: netFile, filePath: tmpFile, enableMetered: true, enableRoaming: true
}).then((task) => {
task.on('complete', function callback() {
console.info('ArkTSCard download complete:' + tmpFile);
let file;
try {
file = fs.openSync(tmpFile);
} catch (e) {
console.error(`openSync failed: ${JSON.stringify(e)}`);
}
let fileInfo = {};
fileInfo[fileName] = file.fd;
let formData = {
'text': 'Image:' + fileName,
'imgName': fileName,
'formImages': fileInfo,
'loaded': true
};
let formInfo = formBindingData.createFormBindingData(formData)
formProvider.updateForm(formId, formInfo).then((data) => {
console.info('FormAbility updateForm success.' + JSON.stringify(data));
}).catch((error) => {
console.error('FormAbility updateForm failed: ' + JSON.stringify(error));
})
})
task.on('fail', function callBack(err) {
console.info('ArkTSCard download task failed. Cause:' + err);
let formInfo = formBindingData.createFormBindingData({
'text':'Update failed.'
})
formProvider.updateForm(formId, formInfo)
});
}).catch((err) => {
console.error('Failed to request the download. Cause: ' + JSON.stringify(err));
});
}
...
};
```
4. On the widget page, use the **\<Image>** component to display the widget content transferred from the EntryFormAbility.
```ts
let storage = new LocalStorage();
@Entry(storage)
@Component
struct WidgetCard {
@LocalStorageProp('text') text: string = 'Loading...';
@LocalStorageProp('loaded') loaded: boolean = false;
@LocalStorageProp('imgName') imgName: string = 'name';
build() {
Column() {
Text(this.text)
.fontSize('12vp')
.textAlign(TextAlign.Center)
.width('100%')
.height('15%')
Row() {
if (this.loaded) {
Image('memory://' + this.imgName)
.width('50%')
.height('50%')
.margin('5%')
} else {
Image('common/start.PNG')
.width('50%')
.height('50%')
.margin('5%')
}
}.alignItems(VerticalAlign.Center)
.justifyContent(FlexAlign.Center)
Button ('Update')
.height('15%')
.onClick(() => {
postCardAction(this, {
'action': 'message',
'params': {
'info': 'refreshImage'
}
});
})
}
.width('100%').height('100%')
.alignItems(HorizontalAlign.Center)
.padding('5%')
}
}
```
> **NOTE**
> - The **\<Image>** component displays images in the remote memory based on the **memory://** identifier in the input parameter (**memory://fileName**). The value of **fileName** must be consistent with the key in the object (**'formImages': {key: fd}**) passed by the EntryFormAbility.
>
> - The **\<Image>** component determines whether to update the image by comparing the values of **imgName** consecutively passed by the EntryFormAbility. It updates the image only when the values are different.
# Widget Data Interaction
The ArkTS widget framework provides the **updateForm()** and **requestForm()** APIs to proactively trigger widget updates.
![WidgetLocalStorageProp](figures/WidgetLocalStorageProp.png)
| API| System Capability| Constraints|
| -------- | -------- | -------- |
| updateForm | No| 1. Invoked by the provider.<br>2. Allows only the widget provider to update its own widgets. It cannot be used to update widgets by other providers.|
| requestForm | Yes| 1. Invoked by the host.<br>2. Allows only the widget host to update the widgets added to it. It cannot be used to update widgets added to other hosts.|
The following describes the typical use cases of widget updates:
- [Configuring a Widget to Update Periodically](arkts-ui-widget-update-by-time.md)
- [Updating Local and Online Images](arkts-ui-widget-image-update.md)
- [Updating Widget Content by State](arkts-ui-widget-update-by-status.md)
- [Updating Widget Content by Widget Host (for System Applications Only)](arkts-ui-widget-content-update.md)
# Widget Lifecycle Management
When creating an ArkTS widget, you need to implement the [FormExtensionAbility](../reference/apis/js-apis-app-form-formExtensionAbility.md) lifecycle APIs.
1. Import related modules to **EntryFormAbility.ts**.
```ts
import formInfo from '@ohos.app.form.formInfo';
import formBindingData from '@ohos.app.form.formBindingData';
import FormExtensionAbility from '@ohos.app.form.FormExtensionAbility';
import formProvider from '@ohos.app.form.formProvider';
```
2. In **EntryFormAbility.ts**, implement the [FormExtensionAbility](../reference/apis/js-apis-app-form-formExtensionAbility.md) lifecycle APIs, including **onAddForm**, whose **want** parameter can be used to obtain the widget information through [FormParam](../reference/apis/js-apis-app-form-formInfo.md#formparam).
```typescript
import formInfo from '@ohos.app.form.formInfo';
import formBindingData from '@ohos.app.form.formBindingData';
import FormExtensionAbility from '@ohos.app.form.FormExtensionAbility';
import formProvider from '@ohos.app.form.formProvider';
export default class EntryFormAbility extends FormExtensionAbility {
onAddForm(want) {
console.info('[EntryFormAbility] onAddForm');
// Obtain the unique widget ID formId from the want parameter.
let formId: string = want.parameters[formInfo.FormParam.IDENTITY_KEY];
// Called when the widget is created. The widget provider should return the widget data binding class.
let obj = {
'title': 'titleOnAddForm',
'detail': 'detailOnAddForm'
};
let formData = formBindingData.createFormBindingData(obj);
return formData;
}
onCastToNormalForm(formId) {
// Called when the form provider is notified that a temporary form is successfully
// converted to a normal form.
// Called when the widget host converts the temporary widget into a normal one. The widget provider should do something to respond to the conversion.
console.info(`[EntryFormAbility] onCastToNormalForm, formId: ${formId}`);
}
onUpdateForm(formId) {
// Override this method to support scheduled updates, periodic updates, or updates requested by the widget host.
console.info('[EntryFormAbility] onUpdateForm');
let obj = {
'title': 'titleOnUpdateForm',
'detail': 'detailOnUpdateForm'
};
let formData = formBindingData.createFormBindingData(obj);
formProvider.updateForm(formId, formData).catch((err) => {
if (err) {
// Print errors.
console.error(`[EntryFormAbility] Failed to updateForm. Code: ${err.code}, message: ${err.message}`);
return;
}
});
}
onChangeFormVisibility(newStatus) {
// Called when the form provider receives form events from the system.
// The callback is performed only when formVisibleNotify is set to true and the application is a system application.
console.info('[EntryFormAbility] onChangeFormVisibility');
}
onFormEvent(formId, message) {
// Called when a specified message event defined by the form provider is triggered.
// If the widget supports event triggering, override this method and implement the trigger.
console.info('[EntryFormAbility] onFormEvent');
}
onRemoveForm(formId) {
// Called to notify the form provider that a specified form has been destroyed.
// Called when the corresponding widget is deleted. The input parameter is the ID of the deleted card.
console.info('[EntryFormAbility] onRemoveForm');
}
onConfigurationUpdate(config) {
// Called when the system configuration is updated.
console.info('[EntryFormAbility] configurationUpdate:' + JSON.stringify(config));
}
onAcquireFormState(want) {
// Called to return a {@link FormState} object.
// Called when the widget provider receives the status query result of a widget. By default, the initial state of the widget is returned.
return formInfo.FormState.READY;
}
}
```
> **NOTE**
>
> The FormExtensionAbility cannot reside in the background. It persists for 5 seconds after the lifecycle callback is completed and exist if no new lifecycle callback is invoked during this time frame. This means that continuous tasks cannot be processed in the widget lifecycle callbacks. For the service logic that may take more than 5 seconds to complete, it is recommended that you [start the application](arkts-ui-widget-event-uiability.md) for processing. After the processing is complete, use [updateForm()](../reference/apis/js-apis-app-form-formProvider.md#updateform) to notify the widget of the update.
# ArkTS Widget Related Modules
**Figure 1** ArkTS widget related modules
![WidgetModules](figures/WidgetModules.png)
- [FormExtensionAbility](../reference/apis/js-apis-app-form-formExtensionAbility.md): provides lifecycle callbacks invoked when a widget is created, destroyed, or updated.
- [FormExtensionContext](../reference/apis/js-apis-inner-application-formExtensionContext.md): provides context for FormExtensionAbilities. You can use the APIs of this module to start FormExtensionAbilities.
- [formProvider](../reference/apis/js-apis-app-form-formProvider.md): provides APIs related to the widget provider. You can use the APIs to update a widget, set the next update time for a widget, obtain widget information, and request a widget release.
- [formInfo](../reference/apis/js-apis-app-form-formInfo.md): provides types and enums related to the widget information and state.
- [formBindingData](../reference/apis/js-apis-app-form-formBindingData.md): provides APIs for widget data binding. You can use the APIs to create a **FormBindingData** object and obtain related information.
- [Page layout (Card.ets)](arkts-ui-widget-page-overview.md): provides APIs for a declarative paradigm UI.
- [Capabilities exclusive to ArkTS widgets](arkts-ui-widget-event-overview.md): include the **postCardAction** API used for interaction between the widget internal and the provider application and can be called only in the widget.
- [ArkTS widget capability list](arkts-ui-widget-page-overview.md#page-capabilities-supported-by-arkts-widgets): contain the APIs, components, events, attributes, and lifecycle callbacks that can be used in ArkTS widgets.
- [Widget configuration](arkts-ui-widget-configuration.md): includes FormExtensionAbility configuration and widget configuration.
- Configure the FormExtensionAbility information under **extensionAbilities** in the [module.json5 file](../quick-start/module-configuration-file.md).
- Configure the widget configuration information (**WidgetCard.ets**) in the [form_config.json](arkts-ui-widget-configuration.md) file in **resources/base/profile**.
# Using Animations in the Widget
To make your ArkTS widget more engaging, you can apply animations to it, including [explicit animation](../reference/arkui-ts/ts-explicit-animation.md), [attribute animation](../reference/arkui-ts/ts-animatorproperty.md), and [component transition](../reference/arkui-ts/ts-transition-animation-component.md). Just note the following restrictions when using the animations in ArkTS widgets.
**Table 1** Restrictions on animation parameters
| Name| Description| Description|
| -------- | -------- | -------- |
| duration | Animation playback duration| The maximum value is 1 second. If a larger value is set, the animation is still played for 1 second.|
| tempo | Animation playback speed.| Do not set this parameter in the widget. Use the default value 1.|
| delay | Animation delay duration.| Do not set this parameter in the widget. Use the default value 0.|
| iterations | Number of times that the animation is played.| Do not set this parameter in the widget. Use the default value 1.|
The following sample code implements the animation effect of button rotation:
![WidgetAnimation](figures/WidgetAnimation.gif)
```ts
@Entry
@Component
struct AttrAnimationExample {
@State rotateAngle: number = 0;
build() {
Column() {
Button('change rotate angle')
.onClick(() => {
this.rotateAngle = 90;
})
.margin(50)
.rotate({ angle: this.rotateAngle })
.animation({
curve: Curve.EaseOut,
playMode: PlayMode.AlternateReverse
})
}.width('100%').margin({ top: 20 })
}
}
```
# Applying Custom Drawing in the Widget
You can apply custom drawing in your ArkTS widget to create a more vibrant experience. Use the [Canvas](../reference/arkui-ts/ts-components-canvas-canvas.md) component to create a canvas on the widget, and then use the [CanvasRenderingContext2D](../reference/arkui-ts/ts-canvasrenderingcontext2d.md) object to draw custom graphics on the canvas. The following code snippet draws a smiling face in the center of a canvas.
```ts
@Entry
@Component
struct Card {
private canvasWidth: number = 0;
private canvasHeight: number = 0;
// Initialize CanvasRenderingContext2D and RenderingContextSettings.
private settings: RenderingContextSettings = new RenderingContextSettings(true);
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);
build() {
Column() {
Row() {
Canvas(this.context)
.margin('5%')
.width('90%')
.height('90%')
.onReady(() => {
console.info('[ArkTSCard] onReady for canvas draw content');
// Obtain the actual width and height of the canvas in the onReady callback.
this.canvasWidth = this.context.width;
this.canvasHeight = this.context.height;
// Draw the background of the canvas.
this.context.fillStyle = 'rgba(203, 154, 126, 1.00)';
this.context.fillRect(0, 0, this.canvasWidth, this.canvasHeight);
// Draw a red circle in the center of the canvas.
this.context.beginPath();
let radius = this.context.width / 3;
let circleX = this.context.width / 2;
let circleY = this.context.height / 2;
this.context.moveTo(circleX - radius, circleY);
this.context.arc(circleX, circleY, radius, 2 * Math.PI, 0, true);
this.context.closePath();
this.context.fillStyle = 'red';
this.context.fill();
// Draw the left eye of the smiling face.
let leftR = radius / 4;
let leftX = circleX - (radius / 2);
let leftY = circleY - (radius / 3.5);
this.context.beginPath();
this.context.arc(leftX, leftY, leftR, 0, Math.PI, true);
this.context.strokeStyle = '#ffff00';
this.context.lineWidth = 10;
this.context.stroke();
// Draw the right eye of the smiling face.
let rightR = radius / 4;
let rightX = circleX + (radius / 2);
let rightY = circleY - (radius / 3.5);
this.context.beginPath();
this.context.arc(rightX, rightY, rightR, 0, Math.PI, true);
this.context.strokeStyle = '#ffff00';
this.context.lineWidth = 10;
this.context.stroke();
// Draw the mouth of the smiling face.
let mouthR = radius / 2.5;
let mouthX = circleX;
let mouthY = circleY + (radius / 3);
this.context.beginPath();
this.context.arc(mouthX, mouthY, mouthR, Math.PI, 0, true);
this.context.strokeStyle = '#ffff00';
this.context.lineWidth = 10;
this.context.stroke();
})
}
}.height('100%').width('100%')
}
}
```
The figure below shows the effect.
![WidgetCanvasDemo](figures/WidgetCanvasDemo.png)
\ No newline at end of file
# Widget Page Capability Overview
You can leverage the ArkUI declarative paradigm to develop ArkTS widget pages. The following widget pages are automatically generated by a DevEco Studio template. You can adjust the pages based on the real-world service scenarios.
![WidgetPreviewPage](figures/WidgetPreviewPage.png)
ArkTS widgets have full capabilities of JS widgets, with added animation and custom drawing capabilities plus partial support for components, events, animations, data management, and state management capabilities of the [declarative paradigm](../reference/arkui-ts/ts-components-summary.md). For details, see [Page Capabilities Supported by ArkTS Widgets](#page-capabilities-supported-by-arkts-widgets).
## Page Capabilities Supported by ArkTS Widgets
For details about the page capabilities supported by ArkTS widgets, see [Learning ArkTS](../quick-start/arkts-create-custom-components.md) and [ArkTS-based Declarative Development Paradigm](../reference/arkui-ts/ts-components-summary.md).
Only the APIs marked with "supported in ArkTS widgets" can be used for ArkTS widgets. Pay special attention to the capability differences with applications.
For example, the following description indicates that the @Component decorator can be used in ArkTS widgets.
![WidgetSupportApi](figures/WidgetSupportApi.png)
# Updating Widget Content by State
There are cases where multiple copies of the same widget are added to the home screen to accommodate different needs. In these cases, the widget content needs to be dynamically updated based on the state. This topic exemplifies how this is implemented. In the following example, two weather widgets are added to the home screen: one for displaying the weather of London, and the other Beijing, both configured to be updated at 07:00 every morning. The widget provider detects the target city, and then displays the city-specific weather information on the widgets.
- Widget configuration file: Configure the widget to be updated at 07:00 every morning.
```json
{
"forms": [
{
"name": "widget",
"description": "This is a service widget.",
"src": "./ets/widget/pages/WidgetCard.ets",
"uiSyntax": "arkts",
"window": {
"designWidth": 720,
"autoDesignWidth": true
},
"colorMode": "auto",
"isDefault": true,
"updateEnabled": true,"scheduledUpdateTime": "07:00",
"updateDuration": 0,
"defaultDimension": "2*2",
"supportDimensions": ["2*2"]
}
]
}
```
- Widget page: A widget has different states and needs to be updated by state. When the state changes, **postCardAction** is called to notify the EntryFormAbility.
```ts
let storage = new LocalStorage();
@Entry(storage)
@Component
struct WidgetCard {
@LocalStorageProp('textA') textA: string = 'To be updated...';
@LocalStorageProp('textB') textB: string ='To be updated...';
@State selectA: boolean = false;
@State selectB: boolean = false;
build() {
Column() {
Row() {
Checkbox({ name: 'checkbox1', group: 'checkboxGroup' })
.select(false)
.onChange((value: boolean) => {
this.selectA = value;
postCardAction(this, {
'action': 'message',
'params': {
'selectA': JSON.stringify(value)
}
});
})
Text ('State A')
}
Row() {
Checkbox({ name: 'checkbox2', group: 'checkboxGroup' })
.select(false)
.onChange((value: boolean) => {
this.selectB = value;
postCardAction(this, {
'action': 'message',
'params': {
'selectB': JSON.stringify(value)
}
});
})
Text ('State B')
}
Row() {// Content that is updated only in state A
Text ('State A:')
Text(this.textA)
}
Row() { // Content that is updated only in state B
Text ('State B:')
Text(this.textB)
}
}.padding('10%')
}
}
```
- EntryFormAbility: The widget state data is stored in the local database. When the update event callback is triggered, the current widget state is obtained through **formId**, and then content is updated based on the state obtained.
```ts
import formInfo from '@ohos.app.form.formInfo'
import formProvider from '@ohos.app.form.formProvider';
import formBindingData from '@ohos.app.form.formBindingData';
import FormExtensionAbility from '@ohos.app.form.FormExtensionAbility';
import dataStorage from '@ohos.data.storage'
export default class EntryFormAbility extends FormExtensionAbility {
onAddForm(want) {
let formId = want.parameters[formInfo.FormParam.IDENTITY_KEY];
let isTempCard: boolean = want.parameters[formInfo.FormParam.TEMPORARY_KEY];
if (isTempCard === false) {// If the widget is a normal one, the widget information is persisted.
console.info('Not temp card, init db for:' + formId);
let storeDB = dataStorage.getStorageSync(this.context.filesDir + 'myStore')
storeDB.putSync('A' + formId, 'false');
storeDB.putSync('B' + formId, 'false');
storeDB.flushSync();
}
let formData = {};
return formBindingData.createFormBindingData(formData);
}
onRemoveForm(formId) {
console.info('onRemoveForm, formId:' + formId);
let storeDB = dataStorage.getStorageSync(this.context.filesDir + 'myStore')
storeDB.deleteSync('A' + formId);
storeDB.deleteSync('B' + formId);
}
// If the widget is a temporary one, it is recommended that the widget information be persisted when the widget is converted to a normal one.
onCastToNormalForm(formId) {
console.info('onCastToNormalForm, formId:' + formId);
let storeDB = dataStorage.getStorageSync(this.context.filesDir + 'myStore')
storeDB.putSync('A' + formId, 'false');
storeDB.putSync('B' + formId, 'false');
storeDB.flushSync();
}
onUpdateForm(formId) {
let storeDB = dataStorage.getStorageSync(this.context.filesDir + 'myStore')
let stateA = storeDB.getSync('A' + formId, 'false').toString()
let stateB = storeDB.getSync('B' + formId, 'false').toString()
// Update textA in state A.
if (stateA === 'true') {
let formInfo = formBindingData.createFormBindingData({
'textA': 'AAA'
})
formProvider.updateForm(formId, formInfo)
}
// Update textB in state B.
if (stateB === 'true') {
let formInfo = formBindingData.createFormBindingData({
'textB': 'BBB'
})
formProvider.updateForm(formId, formInfo)
}
}
onFormEvent(formId, message) {
// Store the widget state.
console.info('onFormEvent formId:' + formId + 'msg:' + message);
let storeDB = dataStorage.getStorageSync(this.context.filesDir + 'myStore')
let msg = JSON.parse(message)
if (msg.selectA != undefined) {
console.info('onFormEvent selectA info:' + msg.selectA);
storeDB.putSync('A' + formId, msg.selectA);
}
if (msg.selectB != undefined) {
console.info('onFormEvent selectB info:' + msg.selectB);
storeDB.putSync('B' + formId, msg.selectB);
}
storeDB.flushSync();
}
};
```
> **NOTE**
>
> When the local database is used for widget information persistence, it is recommended that [TEMPORARY_KEY](../reference/apis/js-apis-app-form-formInfo.md#formparam) be used to determine whether the currently added widget is a normal one in the [onAddForm](../reference/apis/js-apis-app-form-formExtensionAbility.md#onaddform) lifecycle callback. If the widget is a normal one, the widget information is directly persisted. If the widget is a temporary one, the widget information is persisted when the widget is converted to a normal one ([onCastToNormalForm](../reference/apis/js-apis-app-form-formExtensionAbility.md#oncasttonormalform)). In addition, the persistent widget information needs to be deleted when the widget is destroyed ([onRemoveForm](../reference/apis/js-apis-app-form-formExtensionAbility.md#onremoveform)), preventing the database size from continuously increasing due to repeated widget addition and deletion.
# Configuring a Widget to Update Periodically
Before configuring a widget to update periodically, enable the periodic update feature by setting the **updateEnabled** field to **true** in the **form_config.json** file.
The widget framework provides the following modes of updating widgets periodically:
- Set the update interval: The widget will be updated at the specified interval by calling [onUpdateForm](../reference/apis/js-apis-app-form-formExtensionAbility.md#onupdateform). You can specify the interval by setting the [updateDuration](arkts-ui-widget-configuration.md) field in the **form_config.json** file. For example, you can configure the widget to update once an hour.
> **NOTE**
>
> **updateDuration** takes precedence over **scheduledUpdateTime**. If both are specified, the value specified by **updateDuration** is used.
```json
{
"forms": [
{
"name": "widget",
"description": "This is a service widget.",
"src": "./ets/widget/pages/WidgetCard.ets",
"uiSyntax": "arkts",
"window": {
"designWidth": 720,
"autoDesignWidth": true
},
"colorMode": "auto",
"isDefault": true,
"updateEnabled": true, // Enable the periodic update feature.
"scheduledUpdateTime": "10:30",
"updateDuration": 2, // Set the interval to update the widget. The value is a natural number, in the unit of 30 minutes.
"defaultDimension": "2*2",
"supportDimensions": ["2*2"]
}
]
}
```
- Set the scheduled update time: The widget will be updated at the scheduled time every day. You can specify the time by setting the [scheduledUpdateTime](arkts-ui-widget-configuration.md) field in the **form_config.json** file. For example, you can configure the widget to update at 10:30 a.m. every day.
> **NOTE**
>
> **updateDuration** takes precedence over **scheduledUpdateTime**. For the **scheduledUpdateTime** settings to take effect, set **updateDuration** to **0**.
```json
{
"forms": [
{
"name": "widget",
"description": "This is a service widget.",
"src": "./ets/widget/pages/WidgetCard.ets",
"uiSyntax": "arkts",
"window": {
"designWidth": 720,
"autoDesignWidth": true
},
"colorMode": "auto",
"isDefault": true,
"updateEnabled": true, // Enable the periodic update feature.
"scheduledUpdateTime": "10:30", // Set the scheduled time to update the widget.
"updateDuration": 0,
"defaultDimension": "2*2",
"supportDimensions": ["2*2"]
}
]
}
```
- Set the next update time: The widget will be updated next time at the specified time. You can specify the time by calling the [setFormNextRefreshTime()](../reference/apis/js-apis-app-form-formProvider.md#setformnextrefreshtime) API. The minimum update interval is 5 minutes. For example, you can configure the widget to update within 5 minutes after the API is called.
```ts
import formProvider from '@ohos.app.form.formProvider';
let formId = '123456789'; // Use the actual widget ID in real-world scenarios.
try {
// Configure the widget to update in 5 minutes.
formProvider.setFormNextRefreshTime(formId, 5, (err, data) => {
if (err) {
console.error(`Failed to setFormNextRefreshTime. Code: ${err.code}, message: ${err.message}`);
return;
} else {
console.info('Succeeded in setFormNextRefreshTimeing.');
}
});
} catch (err) {
console.error(`Failed to setFormNextRefreshTime. Code: ${err.code}, message: ${err.message}`);
}
```
When periodic update is triggered, the system calls the [onUpdateForm()](../reference/apis/js-apis-app-form-formExtensionAbility.md#onupdateform) lifecycle callback of the FormExtensionAbility. In the callback, [updateForm()](../reference/apis/js-apis-app-form-formProvider.md#updateform) can be used to update the widget by the provider. For details about how to use **onUpdateForm()**, see [Updating Widget Content Through FormExtensionAbility](arkts-ui-widget-event-formextensionability.md).
> **NOTE**
> 1. Each widget can be updated at the specified interval for a maximum of 50 times every day, including updates triggered by setting [updateDuration](arkts-ui-widget-configuration.md) or calling [setFormNextRefreshTime()](../reference/apis/js-apis-app-form-formProvider.md#setformnextrefreshtime). When the limit is reached, the widget cannot be updated in this mode again. The number of update times is reset at 00:00 every day.
>
> 2. The same timer is used for timing updates at the specified interval. Therefore, the first scheduled update of widgets may have a maximum deviation of 30 minutes. For example, the first widget A (updated every half an hour) is added at 03:20. The timer starts and triggers an update every half an hour. The second widget B (updated every half an hour) is added at 03:40. When the timer event is triggered at 03:50, widget A is updated, and widget B will be updated at 04:20 next time.
>
> 3. Updates at the specified interval and updates at the scheduled time are triggered only when the screen is on. When the screen is off, the update action is merely recorded. When the screen is on, the update action is performed.
# ArkTS Widget Working Principles
## Implementation Principles
**Figure 1** ArkTS widget implementation principles
![WidgetPrinciple](figures/WidgetPrinciple.png)
- Widget host: an application that displays the widget content and controls the widget location. Only the system application can function as a widget host.
- Widget provider: an application that provides the widget content to display and controls how widget components are laid out and how they interact with users.
- Widget Manager: a resident agent that manages widgets in the system. It provides the [formProvider](../reference/apis/js-apis-app-form-formProvider.md) and [formHost](../reference/apis/js-apis-app-form-formHost.md) APIs as well as widget management, usage, and periodic updates.
- Widget rendering service: a service that manages widget rendering instances. Widget rendering instances are bound to the [widget components](../reference/arkui-ts/ts-basic-components-formcomponent.md) on the widget host on a one-to-one basis. The widget rendering service runs the widget page code **widgets.abc** for rendering, and sends the rendered data to the corresponding widget component on the widget host.
**Figure 2** Working principles of the ArkTS widget rendering service
![WidgetRender](figures/WidgetRender.png)
Unlike JS widgets, ArkTS widgets support logic code running. To avoid potential ArkTS widget issues from affecting the use of applications, the widget page code **widgets.abc** is executed by the widget rendering service, which is managed by the Widget Manager. Each widget component of a widget host corresponds to a rendering instance in the widget rendering service. Rendering instances of an application provider run in the same virtual machine operating environment, and rendering instances of different application providers run in different virtual machine operating environments. In this way, the resources and state data are isolated between widgets of different application providers. During development, pay attention to the use of the [globalThis](uiability-data-sync-with-ui.md#using-globalthis-between-uiability-and-page) object. Use one **globalThis** object for widgets by the same application provider, and different **globalThis** objects for widgets by different application providers.
## Advantages of ArkTS Widgets
As a quick entry to applications, ArkTS widgets have the following advantages over JS widgets:
- Improved development experience and efficiency, thanks to the unified development paradigm
ArkTS widgets share the same declarative UI development framework as application pages. This means that the page layouts can be directly reused in widgets, improving development experience and efficiency.
**Figure 3** Comparison of widget project structures
![WidgetProject](figures/WidgetProject.png)
- More widget features
- Animation: The ArkTS widget supports the [attribute animation](../reference/arkui-ts/ts-animatorproperty.md) and [explicit animation](../reference/arkui-ts/ts-explicit-animation.md) capabilities, which can be leveraged to deliver a more engaging experience.
- Custom drawing: The ArkTS widget allows you to draw graphics with the [Canvas](../reference/arkui-ts/ts-components-canvas-canvas.md) component to present information more vividly.
- Logic code execution: The capability to run logic code in widgets means that service logic can be self-closed in widgets, expanding the service application scenarios of widgets.
## Constraints on ArkTS Widgets
Compared with JS widgets, ArkTS widgets provide more capabilities, but they are also more prone to malicious behavior. The ArkTS widget is displayed in the widget host, which is usually the home screen. To ensure user experience and power consumption, the ArkTS widget capability is restricted as follows:
- The .so file cannot be loaded.
- The native programming language cannot be used for development.
- Only [partial](arkts-ui-widget-page-overview.md) components, events, animations, data management, state management, and API capabilities of the declarative paradigm are supported.
- The event processing of the widget is independent of that of the widget host. It is recommended that you do not use the left and right sliding components when the widget host supports left and right swipes to prevent gesture conflicts.
The following features are coming to ArkTS widgets in later versions:
- Breakpoint debugging
- import statements
- Instant preview
...@@ -7,8 +7,7 @@ OpenHarmony provides Common Event Service (CES) for applications to subscribe to ...@@ -7,8 +7,7 @@ OpenHarmony provides Common Event Service (CES) for applications to subscribe to
Common events are classified into system common events and custom common events. Common events are classified into system common events and custom common events.
- System common events: defined in CES. Only system applications and system services can publish system common events, such as HAP installation, update, and uninstall. For details about the supported system common events, see [Support](../reference/apis/js-apis-commonEventManager.md#support). - System common events: defined in CES. Currently, only system applications and system services can publish system common events, such as HAP installation, update, and uninstall. For details about the supported system common events, see [System Common Events](../reference/apis/commonEventManager-definitions.md).
- Custom common events: customized by applications to implement cross-process event communication. - Custom common events: customized by applications to implement cross-process event communication.
...@@ -16,9 +15,7 @@ Common events are also classified into unordered, ordered, and sticky common eve ...@@ -16,9 +15,7 @@ Common events are also classified into unordered, ordered, and sticky common eve
- Unordered common events: common events that CES forwards regardless of whether subscribers receive the events and when they subscribe to the events. - Unordered common events: common events that CES forwards regardless of whether subscribers receive the events and when they subscribe to the events.
- Ordered common events: common events that CES forwards based on the subscriber priority. CES preferentially forwards an ordered common event to the subscriber with higher priority, waits until the subscriber receives the event, and then forwards the events to the subscriber with lower priority. Subscribers with the same priority receive common events in a random order.
- Ordered common events: common events that CES forwards based on the subscriber priority. CES forwards common events to the subscriber with lower priority only after receiving a reply from the previous subscriber with higher priority. Subscribers with the same priority receive common events in a random order.
- Sticky common events: common events that can be sent to a subscriber before or after they initiate a subscription. Only system applications and system services can send sticky common events, which remain in the system after being sent. The sends must first request the **ohos.permission.COMMONEVENT_STICKY** permission. For details about the configuration, see [Permission Application Guide](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file). - Sticky common events: common events that can be sent to a subscriber before or after they initiate a subscription. Only system applications and system services can send sticky common events, which remain in the system after being sent. The sends must first request the **ohos.permission.COMMONEVENT_STICKY** permission. For details about the configuration, see [Permission Application Guide](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file).
......
# Removing Sticky Common Events (for System Applications Only)
## When to Use
Subscribers can receive sticky common events that have been sent. If the events are no longer forwarded, the event publisher needs to remove them. OpenHarmony provides an API for removing sticky common events.
## Available APIs
For details, see [Common Event](../reference/apis/js-apis-commonEventManager.md)
| Name| Description|
| -------- | -------- |
| removeStickyCommonEvent(event: string, callback: AsyncCallback\<void>): void | Removes a sticky common event.|
## How to Develop
1. Request the **ohos.permission.COMMONEVENT_STICKY** permission. For details, see [Declaring Permissions in the Configuration File](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file).
2. Import the module.
```ts
import commonEventManager from '@ohos.commonEventManager';
```
3. Call the [removeStickyCommonEvent()](../reference/apis/js-apis-commonEventManager.md#commoneventmanagerremovestickycommonevent10) API to remove the target sticky common event.
> **NOTE**
>
> The sticky common event to be removed must have been released by the application. For details about how to release sticky common events, see [Publishing Common Events](common-event-publish.md).
```ts
commonEventManager.removeStickyCommonEvent("sticky_event", (err) => { // sticky_event indicates the name of the target sticky common event.
if (err) {
console.error(`Failed to remove sticky common event. Code is ${err.code}, message is ${err.message}`);
return;
}
console.info(`Succeeded in removeing sticky event.`);
});
```
...@@ -2,45 +2,51 @@ ...@@ -2,45 +2,51 @@
## When to Use ## When to Use
A static subscriber is started once it receives a target event published by the system or application. At the same time, the **onReceiveEvent** callback is triggered, in which you can implement the service logic. For example, if an application needs to execute some initialization tasks during device power-on, the application can subscribe to the power-on event in static mode. After receiving the power-on event, the application is started to execute the initialization tasks. Subscribing to a common event in static mode is achieved by configuring a declaration file and implementing a class that inherits from **StaticSubscriberExtensionAbility**. Note that this subscribing mode has negative impact on system power consumption. Therefore, exercise caution when using this mode. A static subscriber is started once it receives a target event published by the system or application. At the same time, the [onReceiveEvent()](../reference/apis/js-apis-application-staticSubscriberExtensionAbility.md#staticsubscriberextensionabilityonreceiveevent) callback is triggered.
You can implement the service logic in the [onReceiveEvent()](../reference/apis/js-apis-application-staticSubscriberExtensionAbility.md#staticsubscriberextensionabilityonreceiveevent) callback. For example, if an application needs to execute some initialization tasks during device power-on, the application can subscribe to the power-on event in static mode. After receiving the power-on event, the application is started to execute the initialization tasks.
Subscribing to a common event in static mode is achieved by configuring a declaration file and implementing a class that inherits from [StaticSubscriberExtensionAbility](../reference/apis/js-apis-application-staticSubscriberExtensionAbility.md).
> **NOTE**
>
> The static subscription mode has negative impact on system power consumption. Therefore, exercise caution when using this mode.
## How to Develop ## How to Develop
1. Declaring a Static Subscriber 1. Declaring a static subscriber.
To declare a static subscriber, create an ExtensionAbility, which is derived from the **StaticSubscriberExtensionAbility** class, in the project. The sample code is as follows: To declare a static subscriber, create an ExtensionAbility, which is derived from the **StaticSubscriberExtensionAbility** class, in the project.
You can implement service logic in the **onReceiveEvent()** callback.
```ts ```ts
import StaticSubscriberExtensionAbility from '@ohos.application.StaticSubscriberExtensionAbility' import StaticSubscriberExtensionAbility from '@ohos.application.StaticSubscriberExtensionAbility'
export default class StaticSubscriber extends StaticSubscriberExtensionAbility { export default class StaticSubscriber extends StaticSubscriberExtensionAbility {
onReceiveEvent(event) { onReceiveEvent(event) {
console.log('onReceiveEvent, event:' + event.event); console.info('onReceiveEvent, event: ' + event.event);
} }
} }
``` ```
You can implement service logic in the **onReceiveEvent** callback. 2. Configure static subscriber settings.
After writing the static subscriber code, configure the subscriber in the [module.json5](../quick-start/module-configuration-file.md) file.
2. Project Configuration for a Static Subscriber
After writing the static subscriber code, configure the subscriber in the **module.json5** file. The configuration format is as follows:
```ts ```ts
{ {
"module": { "module": {
...... ...
"extensionAbilities": [ "extensionAbilities": [
{ {
"name": "StaticSubscriber", "name": "StaticSubscriber",
"srcEntrance": "./ets/StaticSubscriber/StaticSubscriber.ts", "srcEntry": "./ets/staticsubscriber/StaticSubscriber.ts",
"description": "$string:StaticSubscriber_desc", "description": "$string:StaticSubscriber_desc",
"icon": "$media:icon", "icon": "$media:icon",
"label": "$string:StaticSubscriber_label", "label": "$string:StaticSubscriber_label",
"type": "staticSubscriber", "type": "staticSubscriber",
"visible": true, "exported": true,
"metadata": [ "metadata": [
{ {
"name": "ohos.extension.staticSubscriber", "name": "ohos.extension.staticSubscriber",
...@@ -49,14 +55,14 @@ A static subscriber is started once it receives a target event published by the ...@@ -49,14 +55,14 @@ A static subscriber is started once it receives a target event published by the
] ]
} }
] ]
...... ...
} }
} }
``` ```
Pay attention to the following fields in the JSON file: Some fields in the file are described as follows:
- **srcEntrance**: entry file path of the ExtensionAbility, that is, the file path of the static subscriber declared in Step 2. - **srcEntry **: entry file path of the ExtensionAbility, that is, the file path of the static subscriber declared in Step 2.
- **type**: ExtensionAbility type. For a static subscriber, set this field to **staticSubscriber**. - **type**: ExtensionAbility type. For a static subscriber, set this field to **staticSubscriber**.
...@@ -64,42 +70,46 @@ A static subscriber is started once it receives a target event published by the ...@@ -64,42 +70,46 @@ A static subscriber is started once it receives a target event published by the
- **name**: name of the ExtensionAbility. For a static subscriber, declare the name as **ohos.extension.staticSubscriber** for successful identification. - **name**: name of the ExtensionAbility. For a static subscriber, declare the name as **ohos.extension.staticSubscriber** for successful identification.
- **resource**: path that stores the ExtensionAbility configuration, which is customizable. In this example, the path is **resources/base/profile/subscribe.json**. - **resource**: path that stores the ExtensionAbility configuration, which is customizable. In this example, the path is **resources/base/profile/subscribe.json**.
A level-2 configuration file pointed to by **metadata** must be in the following format:
```ts 3. Configure the level-2 configuration file to which the metadata points.
{
"commonEvents": [
{
"name": "xxx",
"permission": "xxx",
"events":[
"xxx"
]
}
]
}
```
If the level-2 configuration file is not declared in this format, the file cannot be identified. The fields are described as follows: ```json
{
"commonEvents": [
{
"name": "xxx",
"permission": "xxx",
"events":[
"xxx"
]
}
]
}
```
- **name**: name of the ExtensionAbility, which must be the same as the name of **extensionAbility** declared in **module.json5**. If the level-2 configuration file is not declared in this format, the file cannot be identified. Some fields in the file are described as follows:
- **permission**: permission required for the publisher. If a publisher without the required permission attempts to publish an event, the event is regarded as invalid and will not be published. - **name**: name of the ExtensionAbility, which must be the same as the name of **extensionAbility** declared in **module.json5**.
- **permission**: permission required for the publisher. If a publisher without the required permission attempts to publish an event, the event is regarded as invalid and will not be published.
- **events**: list of target events to subscribe to.
- **events**: list of target events to subscribe to. 4. Modify the [preset configuration file](https://gitee.com/openharmony/vendor_hihope/blob/master/rk3568/preinstall-config/install_list_permissions.json) of the device, that is, the **/system/etc/app/install_list_permission.json** file on the device. When the device is started, this file is read. During application installation, the common event type specified by **allowCommonEvent** in the file is authorized. The **install_list_permission.json** file contains the following fields:
3. Device System Configuration - **bundleName**: bundle name of the application.
- **app_signature**: fingerprint information of the application. For details, see [Application Privilege Configuration Guide](../../device-dev/subsystems/subsys-app-privilege-config-guide.md#configuration-in-install_list_capabilityjson).
- **allowCommonEvent**: type of common event that can be started by static broadcast.
In the device system configuration file **/system/etc/app/install_list_capability.json**, add the bundle name of the static subscriber. > **NOTE**
>
> The **install_list_permissions.json** file is available only for preinstalled applications.
```json ```json
{ [
"install_list": [ {
{ "bundleName": "com.example.myapplication",
"bundleName": "ohos.extension.staticSubscriber", "app_signature": ["****"],
"allowCommonEvent": ["usual.event.A", "usual.event.B"], "allowCommonEvent": ["usual.event.A", "usual.event.B"]
} }
] ]
}
``` ```
# Common Event Subscription Overview # Common Event Subscription Overview
The common event service provides two subscription modes: dynamic and static. The biggest difference between these two modes is that dynamic subscription requires the application to be running, while static subscription does not. The common event service provides two subscription modes: dynamic and static. The biggest difference between these two modes is that dynamic subscription requires the application to be running, while static subscription does not.
- In dynamic subscription mode, a subscriber subscribes to common events by calling an API during the running period. For details, see [Subscribing to Common Events in Dynamic Mode](common-event-subscription.md). - In dynamic subscription mode, a subscriber subscribes to common events by calling an API during the running period. For details, see [Subscribing to Common Events in Dynamic Mode](common-event-subscription.md).
- In static subscription mode, a subscriber subscribes to common events by configuring a declaration file and implementing a class that inherits from StaticSubscriberExtensionAbility. For details, see [Subscribing to Common Events in Static Mode](common-event-static-subscription.md). - In static subscription mode, a subscriber subscribes to common events by configuring a declaration file and implementing a class that inherits from **StaticSubscriberExtensionAbility**. For details, see [Subscribing to Common Events in Static Mode](common-event-static-subscription.md).
...@@ -32,7 +32,7 @@ For details about the APIs, see [API Reference](../reference/apis/js-apis-common ...@@ -32,7 +32,7 @@ For details about the APIs, see [API Reference](../reference/apis/js-apis-common
let subscriber = null; let subscriber = null;
// Subscriber information. // Subscriber information.
let subscribeInfo = { let subscribeInfo = {
events: ["usual.event.SCREEN_OFF"], // Subscribe to the common event screen-off. events: ["usual.event.SCREEN_OFF"], // Subscribe to the common event screen-off.
} }
``` ```
...@@ -41,13 +41,13 @@ For details about the APIs, see [API Reference](../reference/apis/js-apis-common ...@@ -41,13 +41,13 @@ For details about the APIs, see [API Reference](../reference/apis/js-apis-common
```ts ```ts
// Callback for subscriber creation. // Callback for subscriber creation.
commonEventManager.createSubscriber(subscribeInfo, (err, data) => { commonEventManager.createSubscriber(subscribeInfo, (err, data) => {
if (err) { if (err) {
console.error(`[CommonEvent] CreateSubscriberCallBack err=${JSON.stringify(err)}`); console.error(`Failed to create subscriber. Code is ${err.code}, message is ${err.message}`);
} else { return;
console.info(`[CommonEvent] CreateSubscriber success`); }
subscriber = data; console.info('Succeeded in creating subscriber.');
// Callback for common event subscription. subscriber = data;
} // Callback for common event subscription.
}) })
``` ```
...@@ -56,14 +56,13 @@ For details about the APIs, see [API Reference](../reference/apis/js-apis-common ...@@ -56,14 +56,13 @@ For details about the APIs, see [API Reference](../reference/apis/js-apis-common
```ts ```ts
// Callback for common event subscription. // Callback for common event subscription.
if (subscriber !== null) { if (subscriber !== null) {
commonEventManager.subscribe(subscriber, (err, data) => { commonEventManager.subscribe(subscriber, (err, data) => {
if (err) { if (err) {
console.error(`[CommonEvent] SubscribeCallBack err=${JSON.stringify(err)}`); console.error(`Failed to subscribe common event. Code is ${err.code}, message is ${err.message}`);
} else { return;
console.info(`[CommonEvent] SubscribeCallBack data=${JSON.stringify(data)}`); }
} })
})
} else { } else {
console.error(`[CommonEvent] Need create subscriber`); console.error(`Need create subscriber`);
} }
``` ```
...@@ -23,8 +23,8 @@ In view of this, OpenHarmony formulates a set of component startup rules, as fol ...@@ -23,8 +23,8 @@ In view of this, OpenHarmony formulates a set of component startup rules, as fol
- **Before starting a component of another application, verify the visible field of the target component.** - **Before starting a component of another application, verify the visible field of the target component.**
- If the **visible** field of the target component is **false**, verify the **ohos.permission.START_INVISIBLE_ABILITY** permission. - If the **exported** field of the target component is **false**, verify the **ohos.permission.START_INVISIBLE_ABILITY** permission.
- For details, see [Component Visible Configuration](../quick-start/module-configuration-file.md#abilities). - For details, see [Component exported Configuration](../quick-start/module-configuration-file.md#abilities).
- **Before starting a component of a background application, verify the BACKGROUND permission.** - **Before starting a component of a background application, verify the BACKGROUND permission.**
- An application is considered as a foreground application only when the application process gains focus or its UIAbility component is running in the foreground. - An application is considered as a foreground application only when the application process gains focus or its UIAbility component is running in the foreground.
...@@ -37,8 +37,8 @@ In view of this, OpenHarmony formulates a set of component startup rules, as fol ...@@ -37,8 +37,8 @@ In view of this, OpenHarmony formulates a set of component startup rules, as fol
> **NOTE** > **NOTE**
> >
> - Component startup control has been implemented since OpenHarmony v3.2 Release. > - Component startup control has been implemented since OpenHarmony v3.2 Release.
> >
> - The new component startup rules are more strict than the original ones. You must be familiar with the new startup rules to prevent service exceptions. > - The new component startup rules are more strict than the original ones. You must be familiar with the new startup rules to prevent service exceptions.
## Intra-Device Component Startup Rules ## Intra-Device Component Startup Rules
......
...@@ -48,9 +48,9 @@ function implicitStartAbility() { ...@@ -48,9 +48,9 @@ function implicitStartAbility() {
} }
} }
context.startAbility(wantInfo).then(() => { context.startAbility(wantInfo).then(() => {
// ... ...
}).catch((err) => { }).catch((err) => {
// ... ...
}) })
} }
``` ```
...@@ -66,8 +66,7 @@ In the preceding code, under the custom field **parameters**, the following **ab ...@@ -66,8 +66,7 @@ In the preceding code, under the custom field **parameters**, the following **ab
- **ability.picker.fileSizes**: file size, in bytes. - **ability.picker.fileSizes**: file size, in bytes.
- **ability.picker.fileNames** and **ability.picker.fileSizes** are arrays and have a one-to-one mapping. - **ability.picker.fileNames** and **ability.picker.fileSizes** are arrays and have a one-to-one mapping.
The following figure shows an example. The following figure shows an example.
![](figures/ability-startup-with-implicit-want2.png) ![](figures/ability-startup-with-implicit-want2.png)
## Shared Party ## Shared Party
...@@ -77,17 +76,17 @@ To enable the shared party to identify the shared content, configure **skills** ...@@ -77,17 +76,17 @@ To enable the shared party to identify the shared content, configure **skills**
```json ```json
{ {
"module": { "module": {
// ... ...
"abilities": [ "abilities": [
{ {
// ... ...
"skills": [ "skills": [
{ {
// ... ...
"actions": [ "actions": [
"action.system.home", "action.system.home",
"ohos.want.action.sendData" "ohos.want.action.sendData"
// ... ...
], ],
"uris": [ "uris": [
{ {
...@@ -102,7 +101,7 @@ To enable the shared party to identify the shared content, configure **skills** ...@@ -102,7 +101,7 @@ To enable the shared party to identify the shared content, configure **skills**
} }
``` ```
After the user selects an application, the Want nested in the **ability.want.params.INTENT** field is passed to that application. The UIAbility of the shared party, after being started, can call [onCreate()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityoncreate) or [onNewWant()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityonnewwant) to obtain the passed Want. After the user selects an application, the Want nested in the **ability.want.params.INTENT** field is passed to that application. After the UIAbility of the application starts, the application obtains **want** information from [**onCreate()**](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityoncreate) or [**onNewWant()**](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityonnewwant).
The following is an example of the Want obtained. You can use the FD of the shared file to perform required operations. The following is an example of the Want obtained. You can use the FD of the shared file to perform required operations.
......
# DataShareExtensionAbility (for System Applications Only)
DataShareExtensionAbility provides the data sharing capability. System applications can implement a DataShareExtensionAbility or access an existing DataShareExtensionAbility in the system. Third-party applications can only access an existing DataShareExtensionAbility. For details, see [DataShare Development](../database/database-datashare-guidelines.md).
...@@ -60,15 +60,15 @@ To implement EnterpriseAdminExtensionAbility, you need to activate the device ad ...@@ -60,15 +60,15 @@ To implement EnterpriseAdminExtensionAbility, you need to activate the device ad
}; };
``` ```
4. Register **ServiceExtensionAbility** in the [**module.json5**](../quick-start/module-configuration-file.md) file corresponding to the project module. Set **type** to **enterpriseAdmin** and **srcEntrance** to the path of the ExtensionAbility code. 4. Register **ServiceExtensionAbility** in the [**module.json5**](../quick-start/module-configuration-file.md) file corresponding to the project module. Set **type** to **enterpriseAdmin** and **srcEntry** to the path of the ExtensionAbility code.
```ts ```ts
"extensionAbilities": [ "extensionAbilities": [
{ {
"name": "ohos.samples.enterprise_admin_ext_ability", "name": "ohos.samples.enterprise_admin_ext_ability",
"type": "enterpriseAdmin", "type": "enterpriseAdmin",
"visible": true, "exported": true,
"srcEntrance": "./ets/enterpriseextability/EnterpriseAdminAbility.ts" "srcEntry": "./ets/enterpriseextability/EnterpriseAdminAbility.ts"
} }
] ]
``` ```
......
# Matching Rules of Explicit Want and Implicit Want # Matching Rules of Explicit Want and Implicit Want
Both explicit Want and implicit Want can be used to match an ability to start based on certain rules. These rules determine how the parameters set in Want match the configuration file declared by the target ability. Both explicit [Want](../reference/apis/js-apis-app-ability-want.md) and implicit [Want](../reference/apis/js-apis-app-ability-want.md) can be used to match an application component to start based on certain rules. These rules determine how the parameters set in [want](../reference/apis/js-apis-app-ability-want.md) match the configuration file declared by the target application component.
## Matching Rules of Explicit Want ## Matching Rules of Explicit Want
The table below describes the matching rules of explicit Want. The table below describes the matching rules of explicit [Want](../reference/apis/js-apis-app-ability-want.md).
| Name| Type| Matching Item| Mandatory| Rule Description| | Name| Type| Matching Item| Mandatory| Rule Description|
| -------- | -------- | -------- | -------- | -------- | | -------- | -------- | -------- | -------- | -------- |
| deviceId | string | Yes| No| If this field is unspecified, only abilities on the local device are matched.| | deviceId | string | Yes| No| If this field is unspecified, only application components on the local device are matched.|
| bundleName | string | Yes| Yes| If **abilityName** is specified but **bundleName** is unspecified, the matching fails.| | bundleName | string | Yes| Yes| If **abilityName** is specified but **bundleName** is unspecified, the matching fails.|
| moduleName | string | Yes| No| If this field is unspecified and multiple modules with the same ability name exist in the application, the first ability is matched by default.| | moduleName | string | Yes| No| If this field is unspecified and multiple modules with the same ability name exist in the application, the first application component is matched by default.|
| abilityName | string | Yes| Yes| To use explicit Want, this field must be specified.| | abilityName | string | Yes| Yes| To use explicit Want, this field must be specified.|
| uri | string | No| No| This field is not used for matching. It is passed to the target ability as a parameter.| | uri | string | No| No| This field is not used for matching. It is passed to the target application component as a parameter.|
| type | string | No| No| This field is not used for matching. It is passed to the target ability as a parameter.| | type | string | No| No| This field is not used for matching. It is passed to the target application component as a parameter.|
| action | string | No| No| This field is not used for matching. It is passed to the target ability as a parameter.| | action | string | No| No| This field is not used for matching. It is passed to the target application component as a parameter.|
| entities | Array&lt;string&gt; | No| No| This field is not used for matching. It is passed to the target ability as a parameter.| | entities | Array&lt;string&gt; | No| No| This field is not used for matching. It is passed to the target application component as a parameter.|
| flags | number | No| No| This field is not used for matching and is directly transferred to the system for processing. It is generally used to set runtime information, such as URI data authorization.| | flags | number | No| No| This field is not used for matching and is directly transferred to the system for processing. It is generally used to set runtime information, such as URI data authorization.|
| parameters | {[key:&nbsp;string]:&nbsp;any} | No| No| This field is not used for matching. It is passed to the target ability as a parameter.| | parameters | {[key:&nbsp;string]:&nbsp;any} | No| No| This field is not used for matching. It is passed to the target application component as a parameter.|
## Matching Rules for Implicit Want ## Matching Rules for Implicit Want
The table below describes the matching rules of implicit Want. The table below describes the matching rules of implicit [Want](../reference/apis/js-apis-app-ability-want.md).
| Name | Type | Matching Item| Mandatory| Rule Description | | Name | Type | Matching Item| Mandatory| Rule Description |
| ----------- | ------------------------------ | ------ | ---- | ------------------------------------------------------------ | | ----------- | ------------------------------ | ------ | ---- | ------------------------------------------------------------ |
...@@ -35,30 +35,32 @@ The table below describes the matching rules of implicit Want. ...@@ -35,30 +35,32 @@ The table below describes the matching rules of implicit Want.
| action | string | Yes | No | | | action | string | Yes | No | |
| entities | Array&lt;string&gt; | Yes | No | | | entities | Array&lt;string&gt; | Yes | No | |
| flags | number | No | No | This field is not used for matching and is directly transferred to the system for processing. It is generally used to set runtime information, such as URI data authorization.| | flags | number | No | No | This field is not used for matching and is directly transferred to the system for processing. It is generally used to set runtime information, such as URI data authorization.|
| parameters | {[key:&nbsp;string]:&nbsp;any} | No | No | This field is not used for matching. It is passed to the target ability as a parameter. | | parameters | {[key:&nbsp;string]:&nbsp;any} | No | No | This field is not used for matching. It is passed to the target application component as a parameter. |
Get familiar with the following about implicit Want: Get familiar with the following about implicit Want:
- The **want** parameter passed by the caller indicates the operation to be performed by the caller. It also provides data and application type restrictions. - The **want** parameter passed by the caller indicates the operation to be performed by the caller. It also provides data and application type restrictions.
- The **skills** field declares the capabilities of the target ability. For details, see [the skills tag](../quick-start/module-configuration-file.md#skills) in the [module.json5 file](../quick-start/module-configuration-file.md). - The **skills** field declares the capabilities of the target application component. For details, see [the skills tag](../quick-start/module-configuration-file.md#skills) in the [module.json5 file](../quick-start/module-configuration-file.md).
The system matches the **want** parameter (including the **action**, **entities**, **uri**, and **type** attributes) passed by the caller against the **skills** configuration (including the **actions**, **entities**, **uris**, and **type** attributes) of the abilities one by one. When all the four attributes are matched, a dialog box is displayed for users to select a matched application. The system matches the **want** parameter (including the **action**, **entities**, **uri**, and **type** attributes) passed by the caller against the **skills** configuration (including the **actions**, **entities**, **uris**, and **type** attributes) of the application components one by one. When all the four attributes are matched, a dialog box is displayed for users to select a matched application.
### Matching Rules of action in the want Parameter ### Matching Rules of action in the want Parameter
The system matches the **action** attribute in the **want** parameter passed by the caller against **actions** under **skills** of the abilities. The system matches the **action** attribute in the **want** parameter passed by the caller against **actions** under **skills** of the application components.
- If **action** in the passed **want** parameter is specified but **actions** under **skills** of an ability is unspecified, the matching fails. - If **action** in the passed **want** parameter is unspecified and **actions** under **skills** of an application component is unspecified, the matching fails.
- If **action** in the passed **want** parameter is unspecified but **actions** under **skills** of an ability is specified, the matching is successful. - If **action** in the passed **want** parameter is specified but **actions** under **skills** of an application component is unspecified, the matching fails.
- If **action** in the passed **want** parameter is specified, and **actions** under **skills** of an ability is specified and contains **action** in the passed **want** parameter, the matching is successful. - If **action** in the passed **want** parameter is unspecified but **actions** under **skills** of an application component is specified, the matching is successful.
- If **action** in the passed **want** parameter is specified, and **actions** under **skills** of an ability is specified but does not contain **action** in the passed **want** parameter, the matching fails. - If **action** in the passed **want** parameter is specified, and **actions** under **skills** of an application component is specified and contains **action** in the passed **want** parameter, the matching is successful.
- If **action** in the passed **want** parameter is specified, and **actions** under **skills** of an application component is specified but does not contain **action** in the passed **want** parameter, the matching fails.
**Figure 1** Matching rules of action in the want parameter **Figure 1** Matching rules of action in the want parameter
...@@ -67,55 +69,56 @@ The system matches the **action** attribute in the **want** parameter passed by ...@@ -67,55 +69,56 @@ The system matches the **action** attribute in the **want** parameter passed by
### Matching Rules of entities in the want Parameter ### Matching Rules of entities in the want Parameter
The system matches the **entities** attribute in the **want** parameter passed by the caller against **entities** under **skills** of the abilities. The system matches the **entities** attribute in the **want** parameter passed by the caller against **entities** under **skills** of the application components.
- If **entities** in the passed **want** parameter is unspecified but **entities** under **skills** of an ability is specified, the matching is successful. - If **entities** in the passed **want** parameter is unspecified but **entities** under **skills** of an application component is specified, the matching is successful.
- If **entities** in the passed **want** parameter is unspecified but **entities** under **skills** of an ability is unspecified, the matching is successful. - If **entities** in the passed **want** parameter is unspecified but **entities** under **skills** of an application component is unspecified, the matching is successful.
- If **entities** in the passed **want** parameter is specified but **entities** under **skills** of an ability is unspecified, the matching fails. - If **entities** in the passed **want** parameter is specified but **entities** under **skills** of an application component is unspecified, the matching fails.
- If **entities** in the passed **want** parameter is specified, and **entities** under **skills** of an ability is specified and contains **entities** in the passed **want** parameter, the matching is successful. - If **entities** in the passed **want** parameter is specified, and **entities** under **skills** of an application component is specified and contains **entities** in the passed **want** parameter, the matching is successful.
- If **entities** in the passed **want** parameter is specified, and **entities** under **skills** of an ability is specified but does not contain **entities** in the passed **want** parameter, the matching fails. - If **entities** in the passed **want** parameter is specified, and **entities** under **skills** of an application component is specified but does not contain **entities** in the passed **want** parameter, the matching fails.
**Figure 2** Matching rule of entities in the want parameter **Figure 2** Matching rules of entities in the want parameter
![want-entities](figures/want-entities.png) ![want-entities](figures/want-entities.png)
### Matching Rules of uri and type in the want Parameter ### Matching Rules of uri and type in the want Parameter
When the **uri** and **type** parameters are specified in the **want** parameter to initiate a component startup request, the system traverses the list of installed components and matches the **uris** array under **skills** of the abilities one by one. If one of the **uris** arrays under **skills** matches the **uri** and **type** in the passed **want**, the matching is successful. When the **uri** and **type** parameters are specified in the **want** parameter to initiate an application component startup request, the system traverses the list of installed components and matches the **uris** array under **skills** of the application components one by one. If one of the **uris** arrays under **skills** matches the **uri** and **type** in the passed **want**, the matching is successful.
There are four combinations of **uri** and **type** settings. The matching rules are as follows: There are four combinations of **uri** and **type** settings. The matching rules are as follows:
- Neither **uri** or **type** is specified in the **want** parameter. - Neither **uri** or **type** is specified in the **want** parameter.
- If the **uris** array under **skills** of an ability is unspecified, the matching is successful. - If the **uris** array under **skills** of an application component is unspecified, the matching is successful.
- If the **uris** array under **skills** of an ability contains an URI element whose **scheme** and **type** are unspecified, the matching is successful. - If the **uris** array under **skills** of an application component contains an URI element whose **scheme** and **type** are unspecified, the matching is successful.
- In other cases, the matching fails. - In other cases, the matching fails.
- Only **uri** is specified in the **want** parameter. - Only **uri** is specified in the **want** parameter.
- If the **uris** array under **skills** of an ability is unspecified, the matching fails. - If the **uris** array under **skills** of an application component is unspecified, the matching fails.
- If the **uris** array under **skills** of an ability contains an element whose [uri is matched](#matching-rules-of-uri) and **type** is unspecified, the matching is successful. Otherwise, the matching fails. - If the **uris** array under **skills** of an application component contains an element whose [uri is matched](#matching-rules-of-uri) and **type** is unspecified, the matching is successful. Otherwise, the matching fails.
- Only **type** is specified in the **want** parameter. - Only **type** is specified in the **want** parameter.
- If the **uris** array under **skills** of an ability is unspecified, the matching fails. - If the **uris** array under **skills** of an application component is unspecified, the matching fails.
- If the **uris** array under **skills** of an ability contains an URI element whose **scheme** is unspecified and [type is matched](#matching-rules-of-type), the matching is successful. Otherwise, the matching fails. - If the **uris** array under **skills** of an application component contains an URI element whose **scheme** is unspecified and [type is matched](#matching-rules-of-type), the matching is successful. Otherwise, the matching fails.
- Both **uri** and **type** are specified in the **want** parameter, as shown in Figure 3. - Both **uri** and **type** are specified in the **want** parameter, as shown below.
- If the **uris** array under **skills** of an ability is unspecified, the matching fails. - If the **uris** array under **skills** of an application component is unspecified, the matching fails.
- If the **uris** array under **skills** of an ability contains an element whose [uri is matched](#matching-rules-of-uri) and [type is matched](#matching-rules-of-type), the matching is successful. Otherwise, the matching fails. - If the **uris** array under **skills** of an application component contains an element whose [uri is matched](#matching-rules-of-uri) and [type is matched](#matching-rules-of-type), the matching is successful. Otherwise, the matching fails.
Leftmost URI matching: When only **scheme**, a combination of **scheme** and **host**, or a combination of **scheme**, **host**, and **port** is configured in the **uris** array under **skills** of the ability, Leftmost URI matching: When only **scheme**, a combination of **scheme** and **host**, or a combination of **scheme**, **host**, and **port** is configured in the **uris** array under **skills** of the application component, the matching is successful only if the leftmost URI in the passed **want** parameter matches **scheme**, the combination of **scheme** and **host**, or the combination of **scheme**, **host**, and **port**.
the matching is successful only if the leftmost URI in the passed **want** parameter matches **scheme**, the combination of **scheme** and **host**, or the combination of **scheme**, **host**, and **port**.
**Figure 3** Matching rules when uri and type are specified in the want parameter **Figure 3** Matching rules when uri and type are specified in the want parameter
![want-uri-type1](figures/want-uri-type1.png) ![want-uri-type1](figures/want-uri-type1.png)
To simplify the description:
To simplify the description, **uri** and **type** passed in the **want** parameter are called **w_uri** and **w_type**, respectively; the **uris** array under **skills** of an ability to match is called **s_uris**; each element in the array is called **s_uri**. Matching is performed from top to bottom. - **uri** in the **want** parameter passed in by the caller is called **w_uri**; each element in the **uris** array under **skills** of the application component to match is called **s_uri**.
- **type** in the **want** parameter passed in by the caller is called **w_type**; the type in the **uris** array under **skills** of the application component to match is called **s_type**.
**Figure 4** Matching rules of uri and type in the want parameter **Figure 4** Matching rules of uri and type in the want parameter
...@@ -124,7 +127,7 @@ To simplify the description, **uri** and **type** passed in the **want** paramet ...@@ -124,7 +127,7 @@ To simplify the description, **uri** and **type** passed in the **want** paramet
### Matching Rules of uri ### Matching Rules of uri
To simplify the description, **uri** in the passed **want** parameter is called **w_uri**; **uri** under **skills** of an ability to match is called **s_uri**. The matching rules are as follows: The rules are as follows:
- If **scheme** of **s_uri** is unspecified and **w_uri** is unspecified, the matching is successful. Otherwise, the matching fails. - If **scheme** of **s_uri** is unspecified and **w_uri** is unspecified, the matching is successful. Otherwise, the matching fails.
...@@ -142,18 +145,15 @@ To simplify the description, **uri** in the passed **want** parameter is called ...@@ -142,18 +145,15 @@ To simplify the description, **uri** in the passed **want** parameter is called
> **NOTE** > **NOTE**
> >
> The **scheme**, **host**, **port**, **path**, **pathStartWith**, and **pathRegex** attributes of **uris** under **skills** of an ability are concatenated. If **path**, **pathStartWith**, and **pathRegex** are declared in sequence, **uris** can be concatenated into the following expressions: > The **scheme**, **host**, **port**, **path**, **pathStartWith**, and **pathRegex** attributes of **uris** under **skills** of an application component are concatenated. If **path**, **pathStartWith**, and **pathRegex** are declared in sequence, **uris** can be concatenated into the following expressions:
>
> - **Full path expression**: `scheme://host:port/path`
>
> - **Prefix expression**: `scheme://host:port/pathStartWith`
>
> - **Regular expression**: `scheme://host:port/pathRegex`
> >
> - **Prefix URI expression**: When only **scheme**, a combination of **scheme** and **host**, or a combination of **scheme**, **host**, and **port** is configured in the configuration file, the matching is successful if a URI prefixed with the configuration file is passed in. > - **Prefix URI expression**: When only **scheme**, a combination of **scheme** and **host**, or a combination of **scheme**, **host**, and **port** is configured in the configuration file, the matching is successful if a URI prefixed with the configuration file is passed in.
> * `scheme://` > * `scheme://`
> * `scheme://host` > * `scheme://host`
> * `scheme://host:port` > * `scheme://host:port`
> - **Full path expression**: `scheme://host:port/path`
> - **Prefix expression**: `scheme://host:port/pathStartWith`
> - **Regular expression**: `scheme://host:port/pathRegex`
### Matching Rules of type ### Matching Rules of type
...@@ -162,7 +162,7 @@ To simplify the description, **uri** in the passed **want** parameter is called ...@@ -162,7 +162,7 @@ To simplify the description, **uri** in the passed **want** parameter is called
> >
> The matching rules of **type** described in this section are based on the fact that **type** in the **want** parameter is specified. If **type** is unspecified, follow the [matching rules of uri and type in the want parameter](#matching-rules-of-uri-and-type-in-the-want-parameter). > The matching rules of **type** described in this section are based on the fact that **type** in the **want** parameter is specified. If **type** is unspecified, follow the [matching rules of uri and type in the want parameter](#matching-rules-of-uri-and-type-in-the-want-parameter).
To simplify the description, **uri** in the passed **want** parameter is called **w_type**, and **type** of **uris** under **skills** of an ability to match is called **s_type**. The matching rules are as follows: The matching rules are as follows:
- If **s_type** is unspecified, the matching fails. - If **s_type** is unspecified, the matching fails.
......
...@@ -11,21 +11,22 @@ An [ExtensionAbilityType](../reference/apis/js-apis-bundleManager.md#extensionab ...@@ -11,21 +11,22 @@ An [ExtensionAbilityType](../reference/apis/js-apis-bundleManager.md#extensionab
- [WorkSchedulerExtensionAbility](../reference/apis/js-apis-WorkSchedulerExtensionAbility.md): ExtensionAbility component of the work_scheduler type, which provides callbacks for Work Scheduler tasks. - [WorkSchedulerExtensionAbility](../reference/apis/js-apis-WorkSchedulerExtensionAbility.md): ExtensionAbility component of the work_scheduler type, which provides callbacks for Work Scheduler tasks.
- [InputMethodExtensionAbility](../reference/apis/js-apis-inputmethod.md): ExtensionAbility component of the input_method type, which provides an input method framework that can be used to hide the keyboard, obtain the list of installed input methods, display the dialog box for input method selection, and more. - [InputMethodExtensionAbility](../reference/apis/js-apis-inputmethod.md): ExtensionAbility component of the input_method type, which is used to develop input method applications.
- [ServiceExtensionAbility](../reference/apis/js-apis-app-ability-serviceExtensionAbility.md): ExtensionAbility component of the service type, which provides APIs related to background service scenarios. - [ServiceExtensionAbility](../reference/apis/js-apis-app-ability-serviceExtensionAbility.md): ExtensionAbility component of the service type, which provides APIs related to background service scenarios.
- [AccessibilityExtensionAbility](../reference/apis/js-apis-application-accessibilityExtensionAbility.md): ExtensionAbility component of the accessibility type, which provides APIs related to the accessibility feature. - [AccessibilityExtensionAbility](../reference/apis/js-apis-application-accessibilityExtensionAbility.md): ExtensionAbility component of the accessibility type, which provides APIs related to the accessibility feature.
- [DataShareExtensionAbility](../reference/apis/js-apis-application-dataShareExtensionAbility.md): ExtensionAbility component of the data_share type, which provides APIs for data sharing. - [DataShareExtensionAbility (for system applications only)](../reference/apis/js-apis-application-dataShareExtensionAbility.md): ExtensionAbility component of the data_share type, which provides APIs for data sharing.
- [StaticSubscriberExtensionAbility](../reference/apis/js-apis-application-staticSubscriberExtensionAbility.md): ExtensionAbility component of the static_subscriber type, which provides APIs for static broadcast. - [StaticSubscriberExtensionAbility](../reference/apis/js-apis-application-staticSubscriberExtensionAbility.md): ExtensionAbility component of the static_subscriber type, which provides APIs for static broadcast.
- [WindowExtensionAbility](../reference/apis/js-apis-application-windowExtensionAbility.md): ExtensionAbility component of the window type, which allows a system application to be embedded in and displayed over another application. - [WindowExtensionAbility (for system applications only)](../reference/apis/js-apis-application-windowExtensionAbility.md): ExtensionAbility component of the window type, which allows a system application to be embedded in and displayed over another application.
- [EnterpriseAdminExtensionAbility](../reference/apis/js-apis-EnterpriseAdminExtensionAbility.md): ExtensionAbility component of the enterprise_admin type, which provides APIs for processing enterprise management events, such as application installation events on devices and events indicating too many incorrect screen-lock password attempts. - [EnterpriseAdminExtensionAbility](../reference/apis/js-apis-EnterpriseAdminExtensionAbility.md): ExtensionAbility component of the enterprise_admin type, which provides APIs for processing enterprise management events, such as application installation events on devices and events indicating too many incorrect screen-lock password attempts.
> **NOTE**<br> > **NOTE**
>
> 1. Third-party applications cannot implement ServiceExtensionAbility, DataShareExtensionAbility, StaticSubscriberExtensionAbility, or WindowExtensionAbility. > 1. Third-party applications cannot implement ServiceExtensionAbility, DataShareExtensionAbility, StaticSubscriberExtensionAbility, or WindowExtensionAbility.
> >
> 2. To implement transaction processing in the background for a third-party application, use background tasks rather than ServiceExtensionAbility. For details, see [Background Task](../task-management/background-task-overview.md). > 2. To implement transaction processing in the background for a third-party application, use background tasks rather than ServiceExtensionAbility. For details, see [Background Task](../task-management/background-task-overview.md).
...@@ -45,7 +46,7 @@ The following uses [InputMethodExtensionAbility](../reference/apis/js-apis-input ...@@ -45,7 +46,7 @@ The following uses [InputMethodExtensionAbility](../reference/apis/js-apis-input
## Implementing ExtensionAbility of the Specified Type ## Implementing ExtensionAbility of the Specified Type
The following uses [FormExtensionAbility](../reference/apis/js-apis-app-form-formExtensionAbility.md) as an example. The widget framework provides the base class [FormExtensionAbility](../reference/apis/js-apis-app-form-formExtensionAbility.md). You derive this base class to create your own class (such as **MyFormExtensionAbility**), implement the callbacks, such as **onCreate()** and **onUpdateForm()**, to provide specific widget functionalities. For details, see [FormExtensionAbility](Widget-development-stage.md). The following uses [FormExtensionAbility](../reference/apis/js-apis-app-form-formExtensionAbility.md) as an example. The widget framework provides the base class [FormExtensionAbility](../reference/apis/js-apis-app-form-formExtensionAbility.md). You derive this base class to create your own class (such as **MyFormExtensionAbility**), implement the callbacks, such as **onCreate()** and **onUpdateForm()**, to provide specific widget functionalities. For details, see [FormExtensionAbility](service-widget-overview.md).
You do not need to care when to add or delete a widget. The lifecycle of the FormExtensionAbility instance and the lifecycle of the ExtensionAbility process where the FormExtensionAbility instance is located are scheduled and managed by FormManagerService. You do not need to care when to add or delete a widget. The lifecycle of the FormExtensionAbility instance and the lifecycle of the ExtensionAbility process where the FormExtensionAbility instance is located are scheduled and managed by FormManagerService.
...@@ -55,11 +56,11 @@ You do not need to care when to add or delete a widget. The lifecycle of the For ...@@ -55,11 +56,11 @@ You do not need to care when to add or delete a widget. The lifecycle of the For
> **NOTE** > **NOTE**
> >
> For an application, all ExtensionAbility components of the same type run in an independent process, whereas UIAbility, ServiceExtensionAbility, and DataShareExtensionAbility run in another independent process. For details, see [Process Model (Stage Model)](process-model-stage.md). > For an application, all ExtensionAbility components of the same type run in an independent process, whereas UIAbility, ServiceExtensionAbility, and DataShareExtensionAbility run in another independent process. For details, see [Process Model (Stage Model)](process-model-stage.md).
> >
> For example, an application has one UIAbility component, one ServiceExtensionAbility, one DataShareExtensionAbility, two FormExtensionAbility, and one ImeExtensionAbility. When the application is running, there are three processes: > For example, an application has one UIAbility component, one ServiceExtensionAbility, one DataShareExtensionAbility, two FormExtensionAbility, and one ImeExtensionAbility. When the application is running, there are three processes:
> >
> - UIAbility, ServiceExtensionAbility, and DataShareExtensionAbility run in an independent process. > - UIAbility, ServiceExtensionAbility, and DataShareExtensionAbility run in an independent process.
> >
> - The two FormExtensionAbility components run in an independent process. > - The two FormExtensionAbility components run in an independent process.
> >
> - The two ImeExtensionAbility components run in an independent process. > - The two ImeExtensionAbility components run in an independent process.
...@@ -8,8 +8,8 @@ During application development based on the Feature Ability (FA) model, the foll ...@@ -8,8 +8,8 @@ During application development based on the Feature Ability (FA) model, the foll
| Task| Introduction| Guide| | Task| Introduction| Guide|
| -------- | -------- | -------- | | -------- | -------- | -------- |
| Application component development| Use the PageAbility, ServiceAbility, DataAbility, and widgets of the FA model to develop applications.| - [Application- or Component-Level Configuration](application-component-configuration-fa.md)<br>- [PageAbility Component](pageability-overview.md)<br>- [ServiceAbility Component](serviceability-overview.md)<br>- [DataAbility Component](dataability-overview.md)<br>- [Widget Development](Widget-development-fa.md)<br>- [Context](application-context-fa.md)<br>- [Want](want-fa.md) | | Application component development| Use the PageAbility, ServiceAbility, DataAbility, and widgets of the FA model to develop applications.| - [Application- or Component-Level Configuration](application-component-configuration-fa.md)<br>- [PageAbility Component](pageability-overview.md)<br>- [ServiceAbility Component](serviceability-overview.md)<br>- [DataAbility Component](dataability-overview.md)<br>- [Widget Development](widget-development-fa.md)<br>- [Context](application-context-fa.md)<br>- [Want](want-fa.md)|
| Inter-process communication (IPC)| Learn the process model and common IPC modes of the FA model.| [Common Events](common-event-fa.md)<br>[Background Services](rpc.md) | | Process model| Learn the process model and common IPC modes of the FA model.| [Common Events](common-event-fa.md)<br>[Background Services](rpc.md)|
| Inter-thread communication| Learn the thread model and common inter-thread communication modes of the FA model.| [Inter-Thread Communication](itc-fa-overview.md)| | Thread model| Learn the thread model and common inter-thread communication modes of the FA model.| [Inter-Thread Communication](itc-fa-overview.md)|
| Mission management| Learn the basic concepts and typical scenarios of mission management in the FA model.| [Mission Management](mission-management-fa.md)| | Mission management| Learn the basic concepts and typical scenarios of mission management in the FA model.| [Mission Management](mission-management-fa.md)|
| Application configuration file| Learn the requirements for developing application configuration files in the FA model.| [Application Configuration File](config-file-fa.md) | | Application configuration file| Learn the requirements for developing application configuration files in the FA model.| [Application Configuration File](config-file-fa.md)|
...@@ -55,21 +55,21 @@ The table below describes the main APIs used for cross-device migration. For det ...@@ -55,21 +55,21 @@ The table below describes the main APIs used for cross-device migration. For det
Configure the application to support migration. Configure the application to support migration.
Set the **continuable** field in the **module.json5** file to **true**. The default value is **false**. If this parameter is set to **false**, the application cannot be continued on the target device. Set the **continuable** field in the **module.json5** file to **true**. The default value is **false**. If this parameter is set to **false**, the application cannot be continued on the target device.
```json ```json
{ {
"module": { "module": {
// ... ...
"abilities": [ "abilities": [
{ {
// ... ...
"continuable": true, "continuable": true,
} }
] ]
} }
} }
``` ```
Configure the application launch type. For details, see [UIAbility Component Launch Type](uiability-launch-type.md). Configure the application launch type. For details, see [UIAbility Component Launch Type](uiability-launch-type.md).
...@@ -83,19 +83,19 @@ The table below describes the main APIs used for cross-device migration. For det ...@@ -83,19 +83,19 @@ The table below describes the main APIs used for cross-device migration. For det
The sample code is as follows: The sample code is as follows:
```ts ```ts
import UIAbility from '@ohos.app.ability.UIAbility'; import UIAbility from '@ohos.app.ability.UIAbility';
import AbilityConstant from '@ohos.app.ability.AbilityConstant'; import AbilityConstant from '@ohos.app.ability.AbilityConstant';
onContinue(wantParam : {[key: string]: any}) { onContinue(wantParam : {[key: string]: any}) {
console.info(`onContinue version = ${wantParam.version}, targetDevice: ${wantParam.targetDevice}`) console.info(`onContinue version = ${wantParam.version}, targetDevice: ${wantParam.targetDevice}`)
let workInput = AppStorage.Get<string>('ContinueWork'); let workInput = AppStorage.Get<string>('ContinueWork');
// Set the user input data into wantParam. // Set the user input data into wantParam.
wantParam["work"] = workInput // set user input data into want params wantParam["work"] = workInput // set user input data into want params
console.info(`onContinue input = ${wantParam["input"]}`); console.info(`onContinue input = ${wantParam["input"]}`);
return AbilityConstant.OnContinueResult.AGREE return AbilityConstant.OnContinueResult.AGREE
} }
``` ```
5. Implement **onCreate()** and **onNewWant()** in the UIAbility of the target application to implement data restoration. 5. Implement **onCreate()** and **onNewWant()** in the UIAbility of the target application to implement data restoration.
- Implementation example of **onCreate** in the multi-instance scenario - Implementation example of **onCreate** in the multi-instance scenario
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
Multi-device coordination involves the following scenarios: Multi-device coordination involves the following scenarios:
- [Starting UIAbility and ServiceExtensionAbility Across Devices (No Data Returned)](#starting-uiability-and-serviceextensionability-across-devices-no-data-returned) - [Starting UIAbility or ServiceExtensionAbility Across Devices (No Data Returned)](#starting-uiability-or-serviceextensionability-across-devices-no-data-returned)
- [Starting UIAbility Across Devices (Data Returned)](#starting-uiability-across-devices-data-returned) - [Starting UIAbility Across Devices (Data Returned)](#starting-uiability-across-devices-data-returned)
...@@ -31,9 +31,9 @@ The figure below shows the multi-device collaboration process. ...@@ -31,9 +31,9 @@ The figure below shows the multi-device collaboration process.
- For better user experience, you are advised to use the **want** parameter to transmit data smaller than 100 KB. - For better user experience, you are advised to use the **want** parameter to transmit data smaller than 100 KB.
## Starting UIAbility and ServiceExtensionAbility Across Devices (No Data Returned) ## Starting UIAbility or ServiceExtensionAbility Across Devices (No Data Returned)
On device A, touch the **Start** button provided by the initiator application to start a specified UIAbility on device B. On device A, touch the **Start** button provided by the initiator application to start a specified UIAbility or ServiceExtensionAbility on device B.
### Available APIs ### Available APIs
...@@ -42,7 +42,9 @@ On device A, touch the **Start** button provided by the initiator application to ...@@ -42,7 +42,9 @@ On device A, touch the **Start** button provided by the initiator application to
| **API**| **Description**| | **API**| **Description**|
| -------- | -------- | | -------- | -------- |
| startAbility(want: Want, callback: AsyncCallback&lt;void&gt;): void; | Starts UIAbility and ServiceExtensionAbility. This API uses an asynchronous callback to return the result.| | startAbility(want: Want, callback: AsyncCallback&lt;void&gt;): void; | Starts a UIAbility or ServiceExtensionAbility. This API uses an asynchronous callback to return the result.|
| stopServiceExtensionAbility(want: Want, callback: AsyncCallback&lt;void&gt;): void; | Stops a ServiceExtensionAbility. This API uses an asynchronous callback to return the result.|
| stopServiceExtensionAbility(want: Want): Promise&lt;void&gt;; | Stops a ServiceExtensionAbility. This API uses a promise to return the result.|
### How to Develop ### How to Develop
...@@ -61,7 +63,7 @@ On device A, touch the **Start** button provided by the initiator application to ...@@ -61,7 +63,7 @@ On device A, touch the **Start** button provided by the initiator application to
// createDeviceManager is a system API. // createDeviceManager is a system API.
deviceManager.createDeviceManager('ohos.samples.demo', (err, dm) => { deviceManager.createDeviceManager('ohos.samples.demo', (err, dm) => {
if (err) { if (err) {
// ... ...
return return
} }
dmClass = dm dmClass = dm
...@@ -81,7 +83,7 @@ On device A, touch the **Start** button provided by the initiator application to ...@@ -81,7 +83,7 @@ On device A, touch the **Start** button provided by the initiator application to
} }
``` ```
4. Set the target component parameters, and call [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) to start UIAbility or ServiceExtensionAbility. 4. Set the target component parameters, and call [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) to start a UIAbility or ServiceExtensionAbility.
```ts ```ts
let want = { let want = {
...@@ -92,12 +94,28 @@ On device A, touch the **Start** button provided by the initiator application to ...@@ -92,12 +94,28 @@ On device A, touch the **Start** button provided by the initiator application to
} }
// context is the AbilityContext of the initiator UIAbility. // context is the AbilityContext of the initiator UIAbility.
this.context.startAbility(want).then(() => { this.context.startAbility(want).then(() => {
// ... ...
}).catch((err) => { }).catch((err) => {
// ... ...
}) })
``` ```
5. Call [stopServiceExtensionAbility](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstopserviceextensionability) to stop the ServiceExtensionAbility when it is no longer required on device B. (This API cannot be used to stop a UIAbility. Users must manually stop a UIAbility through task management.)
```ts
let want = {
deviceId: getRemoteDeviceId(),
bundleName: 'com.example.myapplication',
abilityName: 'FuncAbility',
moduleName: 'module1', // moduleName is optional.
}
// Stop the ServiceExtensionAbility started by calling startAbility().
this.context.stopServiceExtensionAbility(want).then(() => {
console.info("stop service extension ability success")
}).catch((err) => {
console.info("stop service extension ability err is " + JSON.stringify(err))
})
```
## Starting UIAbility Across Devices (Data Returned) ## Starting UIAbility Across Devices (Data Returned)
...@@ -121,7 +139,7 @@ On device A, touch the **Start** button provided by the initiator application to ...@@ -121,7 +139,7 @@ On device A, touch the **Start** button provided by the initiator application to
2. Display a dialog box to ask authorization from the user when the application is started for the first time. For details, see [Requesting User Authorization](../security/accesstoken-guidelines.md#requesting-user-authorization). 2. Display a dialog box to ask authorization from the user when the application is started for the first time. For details, see [Requesting User Authorization](../security/accesstoken-guidelines.md#requesting-user-authorization).
3. Set the target component parameters on the initiator, and call **startAbilityForResult()** to start the target UIAbility. **data** in the asynchronous callback is used to receive the information returned by the target UIAbility to the initiator UIAbility after the target UIAbility terminates itself. For details about how to implement **getRemoteDeviceId()**, see [Starting UIAbility and ServiceExtensionAbility Across Devices (No Data Returned)](#starting-uiability-and-serviceextensionability-across-devices-no-data-returned). 3. Set the target component parameters on the initiator, and call **startAbilityForResult()** to start the target UIAbility. **data** in the asynchronous callback is used to receive the information returned by the target UIAbility to the initiator UIAbility after the target UIAbility terminates itself. For details about how to implement **getRemoteDeviceId()**, see [Starting UIAbility or ServiceExtensionAbility Across Devices (No Data Returned)](#starting-uiability-or-serviceextensionability-across-devices-no-data-returned).
```ts ```ts
let want = { let want = {
...@@ -132,9 +150,9 @@ On device A, touch the **Start** button provided by the initiator application to ...@@ -132,9 +150,9 @@ On device A, touch the **Start** button provided by the initiator application to
} }
// context is the AbilityContext of the initiator UIAbility. // context is the AbilityContext of the initiator UIAbility.
this.context.startAbilityForResult(want).then((data) => { this.context.startAbilityForResult(want).then((data) => {
// ... ...
}).catch((err) => { }).catch((err) => {
// ... ...
}) })
``` ```
...@@ -152,7 +170,7 @@ On device A, touch the **Start** button provided by the initiator application to ...@@ -152,7 +170,7 @@ On device A, touch the **Start** button provided by the initiator application to
} }
// context is the AbilityContext of the target UIAbility. // context is the AbilityContext of the target UIAbility.
this.context.terminateSelfWithResult(abilityResult, (err) => { this.context.terminateSelfWithResult(abilityResult, (err) => {
// ... ...
}); });
``` ```
...@@ -161,17 +179,17 @@ On device A, touch the **Start** button provided by the initiator application to ...@@ -161,17 +179,17 @@ On device A, touch the **Start** button provided by the initiator application to
```ts ```ts
const RESULT_CODE: number = 1001; const RESULT_CODE: number = 1001;
// ... ...
// context is the UIAbilityContext of the initiator UIAbility. // context is the UIAbilityContext of the initiator UIAbility.
this.context.startAbilityForResult(want).then((data) => { this.context.startAbilityForResult(want).then((data) => {
if (data?.resultCode === RESULT_CODE) { if (data?.resultCode === RESULT_CODE) {
// Parse the information returned by the target UIAbility. // Parse the information returned by the target UIAbility.
let info = data.want?.parameters?.info let info = data.want?.parameters?.info
// ... ...
} }
}).catch((err) => { }).catch((err) => {
// ... ...
}) })
``` ```
...@@ -253,7 +271,7 @@ A system application can connect to a service on another device by calling [conn ...@@ -253,7 +271,7 @@ A system application can connect to a service on another device by calling [conn
let connectionId = this.context.connectServiceExtensionAbility(want, options); let connectionId = this.context.connectServiceExtensionAbility(want, options);
``` ```
For details about how to implement **getRemoteDeviceId()**, see [Starting UIAbility and ServiceExtensionAbility Across Devices (No Data Returned)](#starting-uiability-and-serviceextensionability-across-devices-no-data-returned). For details about how to implement **getRemoteDeviceId()**, see [Starting UIAbility or ServiceExtensionAbility Across Devices (No Data Returned)](#starting-uiability-or-serviceextensionability-across-devices-no-data-returned).
5. Disconnect the connection. Use **disconnectServiceExtensionAbility()** to disconnect from the background service. 5. Disconnect the connection. Use **disconnectServiceExtensionAbility()** to disconnect from the background service.
...@@ -313,12 +331,12 @@ The following describes how to implement multi-device collaboration through cros ...@@ -313,12 +331,12 @@ The following describes how to implement multi-device collaboration through cros
```json ```json
"abilities":[{ "abilities":[{
"name": ".CalleeAbility", "name": ".CalleeAbility",
"srcEntrance": "./ets/CalleeAbility/CalleeAbility.ts", "srcEntry": "./ets/CalleeAbility/CalleeAbility.ts",
"launchType": "singleton", "launchType": "singleton",
"description": "$string:CalleeAbility_desc", "description": "$string:CalleeAbility_desc",
"icon": "$media:icon", "icon": "$media:icon",
"label": "$string:CalleeAbility_label", "label": "$string:CalleeAbility_label",
"visible": true "exported": true
}] }]
``` ```
2. Import the **UIAbility** module. 2. Import the **UIAbility** module.
...@@ -426,10 +444,10 @@ The following describes how to implement multi-device collaboration through cros ...@@ -426,10 +444,10 @@ The following describes how to implement multi-device collaboration through cros
// Register the onRemoteStateChange listener of the CallerAbility. // Register the onRemoteStateChange listener of the CallerAbility.
try { try {
caller.onRemoteStateChange((str) => { caller.onRemoteStateChange((str) => {
console.log('Remote state changed ' + str); console.info('Remote state changed ' + str);
}); });
} catch (error) { } catch (error) {
console.log('Caller.onRemoteStateChange catch error, error.code: ${JSON.stringify(error.code)}, error.message: ${JSON.stringify(error.message)}'); console.info('Caller.onRemoteStateChange catch error, error.code: ${JSON.stringify(error.code)}, error.message: ${JSON.stringify(error.message)}');
} }
} }
}).catch((error) => { }).catch((error) => {
...@@ -438,7 +456,7 @@ The following describes how to implement multi-device collaboration through cros ...@@ -438,7 +456,7 @@ The following describes how to implement multi-device collaboration through cros
} }
``` ```
For details about how to implement **getRemoteDeviceId()**, see [Starting UIAbility and ServiceExtensionAbility Across Devices (No Data Returned)](#starting-uiability-and-serviceextensionability-across-devices-no-data-returned). For details about how to implement **getRemoteDeviceId()**, see [Starting UIAbility or ServiceExtensionAbility Across Devices (No Data Returned)](#starting-uiability-or-serviceextensionability-across-devices-no-data-returned).
5. Sends agreed parcelable data to the CalleeAbility. 5. Sends agreed parcelable data to the CalleeAbility.
1. The parcelable data can be sent to the CalleeAbility with or without a return value. The method and parcelable data must be consistent with those of the CalleeAbility. The following example describes how to send data to the CalleeAbility. 1. The parcelable data can be sent to the CalleeAbility with or without a return value. The method and parcelable data must be consistent with those of the CalleeAbility. The following example describes how to send data to the CalleeAbility.
......
# InputMethodExtensionAbility Development # InputMethodExtensionAbility
[InputMethodExtensionAbility](../reference/apis/js-apis-inputmethod-extension-ability.md) is an ExtensionAbility component of the inputMethod type that provides extension capabilities for the input method framework. ## When to Use
[InputMethodExtensionAbility](../reference/apis/js-apis-inputmethod-extension-ability.md), inherited from [ExtensionAbility](extensionability-overview.md), is used for developing input method applications.
InputMethodExtensionAbility can be started or connected by other application components to process transactions in the background based on the request of the caller. The entire lifecycle of the [InputMethodExtensionAbility](../reference/apis/js-apis-inputmethod-extension-ability.md) instance and the owning ExtensionAbility process is scheduled and managed by the input method framework. The input method framework provides the [InputMethodExtensionAbility](../reference/apis/js-apis-inputmethod-extension-ability.md) base class. Derive this base class to implement initialization and resource clearing.
[InputMethodExtensionAbility](../reference/apis/js-apis-inputmethod-extension-ability.md) provides related capabilities through [InputMethodExtensionContext](../reference/apis/js-apis-inputmethod-extension-context.md).
InputMethodExtensionAbility provides related capabilities through the [InputMethodExtensionContext](../reference/apis/js-apis-inputmethod-extension-context.md).
## Implementing an Input Method Application ## Implementing an Input Method Application
...@@ -13,15 +13,13 @@ InputMethodExtensionAbility provides related capabilities through the [InputMeth ...@@ -13,15 +13,13 @@ InputMethodExtensionAbility provides related capabilities through the [InputMeth
InputMethodExtensionAbility provides the **onCreate()** and **onDestory()** callbacks, as described below. Override them as required. InputMethodExtensionAbility provides the **onCreate()** and **onDestory()** callbacks, as described below. Override them as required.
- **onCreate** - **onCreate**
This callback is triggered when a service is created for the first time. You can perform initialization operations, for example, registering a common event listener. This callback is triggered when a service is created for the first time. You can perform initialization operations, for example, registering a common event listener.
> **NOTE** > **NOTE**
> >
> If a service has been created, starting it again does not trigger the **onCreate()** callback. > If a service has been created, starting it again does not trigger the **onCreate()** callback.
- **onDestroy** - **onDestroy**
This callback is triggered when the service is no longer used and the instance is ready for destruction. You can clear resources in this callback, for example, deregister the listener. This callback is triggered when the service is no longer used and the instance is ready for destruction. You can clear resources in this callback, for example, deregister the listener.
...@@ -29,7 +27,7 @@ InputMethodExtensionAbility provides the **onCreate()** and **onDestory()** call ...@@ -29,7 +27,7 @@ InputMethodExtensionAbility provides the **onCreate()** and **onDestory()** call
To implement an input method application, manually create an InputMethodExtensionAbility component in DevEco Studio. The procedure is as follows: To implement an input method application, manually create an InputMethodExtensionAbility component in DevEco Studio. The procedure is as follows:
In the **ets** directory of the target module, right-click and choose **New** > **Extention Ability** > **InputMethod** to a minimum template of InputMethodExtensionAbility. In the **ets** directory of the target module, right-click and choose **New** > **Extension Ability** > **InputMethod** to a minimum template of InputMethodExtensionAbility.
> **NOTE** > **NOTE**
> >
...@@ -54,7 +52,7 @@ The minimum template contains four files: **KeyboardController.ts**, **InputMeth ...@@ -54,7 +52,7 @@ The minimum template contains four files: **KeyboardController.ts**, **InputMeth
1. **InputMethodService.ts** file: 1. **InputMethodService.ts** file:
In this file, add the dependency package for importing InputMethodExtensionAbility. Customize a class that inherits from InputMethodExtensionAbility and add the required lifecycle callbacks. In the **InputMethodService.ts** file, add the dependency package for importing InputMethodExtensionAbility. Customize a class that inherits from InputMethodExtensionAbility and add the required lifecycle callbacks.
```ts ```ts
import InputMethodExtensionAbility from '@ohos.InputMethodExtensionAbility'; import InputMethodExtensionAbility from '@ohos.InputMethodExtensionAbility';
...@@ -70,7 +68,7 @@ The minimum template contains four files: **KeyboardController.ts**, **InputMeth ...@@ -70,7 +68,7 @@ The minimum template contains four files: **KeyboardController.ts**, **InputMeth
onDestroy() { onDestroy() {
console.log("onDestroy."); console.log("onDestroy.");
this.context.destroy(); this.keyboardController.onDestroy(); // Destroy the window and deregister the event listener.
} }
} }
``` ```
...@@ -109,7 +107,6 @@ The minimum template contains four files: **KeyboardController.ts**, **InputMeth ...@@ -109,7 +107,6 @@ The minimum template contains four files: **KeyboardController.ts**, **InputMeth
this.unRegisterListener(); // Deregister the event listener. this.unRegisterListener(); // Deregister the event listener.
let win = windowManager.findWindow(this.windowName); let win = windowManager.findWindow(this.windowName);
win.destroyWindow(); // Destroy the window. win.destroyWindow(); // Destroy the window.
this.mContext.terminateSelf(); // Terminate the InputMethodExtensionAbility service.
} }
private initWindow(): void // Initialize the window. private initWindow(): void // Initialize the window.
...@@ -159,7 +156,7 @@ The minimum template contains four files: **KeyboardController.ts**, **InputMeth ...@@ -159,7 +156,7 @@ The minimum template contains four files: **KeyboardController.ts**, **InputMeth
}) })
globalThis.inputAbility.on('inputStop', (imeId) => { globalThis.inputAbility.on('inputStop', (imeId) => {
if (imeId == "Bundle name/Ability name") { if (imeId == "Bundle name/Ability name") {
this.onDestroy(); this.mContext.destroy(); // Destroy the InputMethodExtensionAbility service.
} }
}); });
} }
...@@ -342,20 +339,20 @@ The minimum template contains four files: **KeyboardController.ts**, **InputMeth ...@@ -342,20 +339,20 @@ The minimum template contains four files: **KeyboardController.ts**, **InputMeth
} }
``` ```
Register the InputMethodExtensionAbility in the [module.json5 file](../quick-start/module-configuration-file.md) corresponding to the target module. Set **type** to **"inputMethod"** and **srcEntrance** to the code path of the InputMethodExtensionAbility component. 5. Register the InputMethodExtensionAbility in the [module.json5 file](../quick-start/module-configuration-file.md) corresponding to the **Module** project. Set **type** to **"inputMethod"** and **srcEntry** to the code path of the InputMethodExtensionAbility component.
```ts ```ts
{ {
"module": { "module": {
// ... ...
"extensionAbilities": [ "extensionAbilities": [
{ {
"description": "inputMethod", "description": "inputMethod",
"icon": "$media:icon", "icon": "$media:icon",
"name": "InputMethodExtAbility", "name": "InputMethodExtAbility",
"srcEntrance": "./ets/inputmethodextability/InputMethodService.ts", "srcEntry": "./ets/inputmethodextability/InputMethodService.ts",
"type": "inputMethod", "type": "inputMethod",
"visible": true, "exported": true,
} }
] ]
} }
...@@ -364,3 +361,47 @@ The minimum template contains four files: **KeyboardController.ts**, **InputMeth ...@@ -364,3 +361,47 @@ The minimum template contains four files: **KeyboardController.ts**, **InputMeth
## Restrictions
To reduce the risk of abuse of the InputMethodExtensionAbility by third-party applications, the invoking of APIs in the following modules is restricted in the InputMethodExtensionAbility:
> **NOTE**
>
> - If a restricted module is imported, no error is reported during compilation, but an incorrect value (**undefined**) is returned during running. As a result, the module does not take effect.
> - Currently, access to the [@ohos.multimedia.audio (Audio Management)](../reference/apis/js-apis-audio.md) module is allowed, with compliance with the following rules:
> - Users who deny the recording permission should still be allowed to use the non-voice-input features of the input method application.
> - Recording-related services are allowed only when the InputMethodExtensionAbility is in the foreground. For example, perform recording only when the soft keyboard is in the foreground and the user is proactively using the voice input method; stop recording when the application is switched to the background.
> - Applications will see increasingly stringent measures against violations with the preceding rules, and any violation may result in function exceptions.
**Restricted modules:**
- [@ohos.ability.featureAbility (FeatureAbility)](../reference/apis/js-apis-ability-featureAbility.md)
- [@ohos.ability.particleAbility (ParticleAbility)](../reference/apis/js-apis-ability-particleAbility.md)
- [@ohos.account.distributedAccount (Distributed Account Management)](../reference/apis/js-apis-distributed-account.md)
- [@ohos.backgroundTaskManager (Background Task Management)](../reference/apis/js-apis-backgroundTaskManager.md)
- [@ohos.bluetooth (Bluetooth)](../reference/apis/js-apis-bluetooth.md)
- [@ohos.bluetoothManager (Bluetooth)](../reference/apis/js-apis-bluetoothManager.md)
- [@ohos.connectedTag (Active Tags)](../reference/apis/js-apis-connectedTag.md)
- [@ohos.geolocation (Geolocation)](../reference/apis/js-apis-geolocation.md)
- [@ohos.geoLocationManager (Geolocation Manager)](../reference/apis/js-apis-geoLocationManager.md)
- [@ohos.nfc.cardEmulation (Standard NFC Card Emulation)](../reference/apis/js-apis-cardEmulation.md)
- [@ohos.nfc.controller (Standard NFC)](../reference/apis/js-apis-nfcController.md)
- [@ohos.nfc.tag (Standard NFC Tags)](../reference/apis/js-apis-nfcTag.md)
- [@ohos.reminderAgent (Reminder Agent)](../reference/apis/js-apis-reminderAgent.md)
- [@ohos.reminderAgentManager (reminderAgentManager)](../reference/apis/js-apis-reminderAgentManager.md)
- [@ohos.sensor (Sensor)](../reference/apis/js-apis-sensor.md)
- [@ohos.telephony.call (Call)](../reference/apis/js-apis-call.md)
- [@ohos.telephony.data (Cellular Data)](../reference/apis/js-apis-telephony-data.md)
- [@ohos.telephony.observer (observer)](../reference/apis/js-apis-observer.md)
- [@ohos.telephony.radio (Network Search)](../reference/apis/js-apis-radio.md)
- [@ohos.telephony.sim (SIM Management)](../reference/apis/js-apis-sim.md)
- [@ohos.telephony.sms (SMS)](../reference/apis/js-apis-sms.md)
- [@ohos.wallpaper (Wallpaper)](../reference/apis/js-apis-wallpaper.md)
- [@ohos.wifiext (WLAN Extension)](../reference/apis/js-apis-wifiext.md)
- [@ohos.wifiManager (WLAN)](../reference/apis/js-apis-wifiManager.md)
- [@ohos.wifiManagerExt (WLAN Extension Interface)](../reference/apis/js-apis-wifiManagerExt.md)
- [@system.geolocation (Geolocation)](../reference/apis/js-apis-system-location.md)
- [nfctech (Standard NFC Technologies)](../reference/apis/js-apis-nfctech.md)
- [tagSession (Standard NFC Tag Session)](../reference/apis/js-apis-tagSession.md)
...@@ -13,12 +13,12 @@ To develop the Emitter mode, perform the following steps: ...@@ -13,12 +13,12 @@ To develop the Emitter mode, perform the following steps:
// Define an event with eventId 1. // Define an event with eventId 1.
let event = { let event = {
eventId: 1 eventId: 1
}; };
// Trigger the callback after the event with eventId 1 is received. // Trigger the callback after the event with eventId 1 is received.
let callback = (eventData) => { let callback = (eventData) => {
console.info('event callback'); console.info('event callback');
}; };
// Subscribe to the event with eventId 1. // Subscribe to the event with eventId 1.
...@@ -29,21 +29,21 @@ To develop the Emitter mode, perform the following steps: ...@@ -29,21 +29,21 @@ To develop the Emitter mode, perform the following steps:
```ts ```ts
import emitter from "@ohos.events.emitter"; import emitter from "@ohos.events.emitter";
// Define an event with eventId 1 and priority Low. // Define an event with eventId 1 and priority Low.
let event = { let event = {
eventId: 1, eventId: 1,
priority: emitter.EventPriority.LOW priority: emitter.EventPriority.LOW
}; };
let eventData = { let eventData = {
data: { data: {
"content": "c", "content": "c",
"id": 1, "id": 1,
"isEmpty": false, "isEmpty": false,
} }
}; };
// Emit the event with eventId 1 and event content eventData. // Emit the event with eventId 1 and event content eventData.
emitter.emit(event, eventData); emitter.emit(event, eventData);
``` ```
...@@ -9,13 +9,13 @@ To develop the Worker mode, perform the following steps: ...@@ -9,13 +9,13 @@ To develop the Worker mode, perform the following steps:
1. Configure the **buildOption** field in the [module-level build-profile.json5](https://developer.harmonyos.com/en/docs/documentation/doc-guides/ohos-building-configuration-0000001218440654#section6887184182020) file of the project. 1. Configure the **buildOption** field in the [module-level build-profile.json5](https://developer.harmonyos.com/en/docs/documentation/doc-guides/ohos-building-configuration-0000001218440654#section6887184182020) file of the project.
```ts ```ts
"buildOption": { "buildOption": {
"sourceOption": { "sourceOption": {
"workers": [ "workers": [
"./src/main/ets/workers/worker.ts" "./src/main/ets/workers/worker.ts"
] ]
}
} }
}
``` ```
2. Create the **worker.ts** file based on the configuration in **build-profile.json5**. 2. Create the **worker.ts** file based on the configuration in **build-profile.json5**.
...@@ -27,9 +27,9 @@ To develop the Worker mode, perform the following steps: ...@@ -27,9 +27,9 @@ To develop the Worker mode, perform the following steps:
// Process messages from the main thread. // Process messages from the main thread.
parent.onmessage = function(message) { parent.onmessage = function(message) {
console.info("onmessage: " + message) console.info("onmessage: " + message)
// Send a message to the main thread. // Send a message to the main thread.
parent.postMessage("message from worker thread.") parent.postMessage("message from worker thread.")
} }
``` ```
...@@ -46,10 +46,10 @@ To develop the Worker mode, perform the following steps: ...@@ -46,10 +46,10 @@ To develop the Worker mode, perform the following steps:
// Process messages from the worker thread. // Process messages from the worker thread.
wk.onmessage = function(message) { wk.onmessage = function(message) {
console.info("message from worker: " + message) console.info("message from worker: " + message)
// Stop the worker thread based on service requirements. // Stop the worker thread based on service requirements.
wk.terminate() wk.terminate();
} }
``` ```
...@@ -57,23 +57,22 @@ To develop the Worker mode, perform the following steps: ...@@ -57,23 +57,22 @@ To develop the Worker mode, perform the following steps:
```ts ```ts
import worker from '@ohos.worker'; import worker from '@ohos.worker';
let wk = new worker.ThreadWorker("../workers/worker.ts"); let wk = new worker.ThreadWorker("../workers/worker.ts");
// Send a message to the worker thread. // Send a message to the worker thread.
wk.postMessage("message from main thread.") wk.postMessage("message from main thread.")
// Process messages from the worker thread. // Process messages from the worker thread.
wk.onmessage = function(message) { wk.onmessage = function(message) {
console.info("message from worker: " + message) console.info("message from worker: " + message)
// Stop the worker thread based on service requirements. // Stop the worker thread based on service requirements.
wk.terminate() wk.terminate();
} }
``` ```
> **NOTE** > **NOTE**
> >
> - If the relative path of **worker.ts** configured in **build-profile.json5** is **./src/main/ets/workers/worker.ts**, pass in the path **entry/ets/workers/worker.ts** when creating a worker thread in the stage model, and pass in the path **../workers/worker.ts** when creating a worker thread in the FA model. > - If the relative path of **worker.ts** configured in **build-profile.json5** is **./src/main/ets/workers/worker.ts**, pass in the path **entry/ets/workers/worker.ts** when creating a worker thread in the stage model, and pass in the path **../workers/worker.ts** when creating a worker thread in the FA model.
>
> - For details about the data types supported between the main thread and worker thread, see [Sequenceable Data Types](../reference/apis/js-apis-worker.md#sequenceable-data-types). > - For details about the data types supported between the main thread and worker thread, see [Sequenceable Data Types](../reference/apis/js-apis-worker.md#sequenceable-data-types).
# LifecycleApp Switching # LifecycleApp Switching
| API in the FA Model| Corresponding d.ts File in the Stage Model| Corresponding API in the Stage Model| | API in the FA Model| Corresponding d.ts File in the Stage Model| Corresponding API in the Stage Model|
| -------- | -------- | -------- | | -------- | -------- | -------- |
| onShow?(): void; | \@ohos.window.d.ts | [on(eventType: 'windowStageEvent', callback: Callback&lt;WindowStageEventType&gt;): void;](../reference/apis/js-apis-window.md#onwindowstageevent9)<br>Listens for the switching to the [foreground](../reference/apis/js-apis-window.md#windowstageeventtype9).| | onShow?(): void; | \@ohos.window.d.ts | [on(eventType: 'windowStageEvent', callback: Callback&lt;WindowStageEventType&gt;): void;](../reference/apis/js-apis-window.md#onwindowstageevent9)<br>Listens for the switching to the [foreground](../reference/apis/js-apis-window.md#windowstageeventtype9).|
| onHide?(): void; | \@ohos.window.d.ts | [on(eventType: 'windowStageEvent', callback: Callback&lt;WindowStageEventType&gt;): void;](../reference/apis/js-apis-window.md#onwindowstageevent9)<br>Listens for the switching to the [background](../reference/apis/js-apis-window.md#windowstageeventtype9).| | onHide?(): void; | \@ohos.window.d.ts | [on(eventType: 'windowStageEvent', callback: Callback&lt;WindowStageEventType&gt;): void;](../reference/apis/js-apis-window.md#onwindowstageevent9)<br>Listens for the switching to the [background](../reference/apis/js-apis-window.md#windowstageeventtype9).|
| onDestroy?(): void; | \@ohos.app.ability.UIAbility.d.ts | [onDestroy(): void;](../reference/apis/js-apis-app-ability-uiAbility.md#abilityondestroy) | | onDestroy?(): void; | \@ohos.app.ability.UIAbility.d.ts | [onDestroy(): void;](../reference/apis/js-apis-app-ability-uiAbility.md#abilityondestroy) |
| onCreate?(): void; | \@ohos.app.ability.UIAbility.d.ts | [onCreate(want: Want, param: AbilityConstant.LaunchParam): void;](../reference/apis/js-apis-app-ability-uiAbility.md#abilityoncreate) | | onCreate?(): void; | \@ohos.app.ability.UIAbility.d.ts | [onCreate(want: Want, param: AbilityConstant.LaunchParam): void;](../reference/apis/js-apis-app-ability-uiAbility.md#abilityoncreate) |
| onWindowDisplayModeChanged?(isShownInMultiWindow: boolean, newConfig: resourceManager.Configuration): void; | There is no corresponding API in the stage model.| No corresponding API is provided.| | onWindowDisplayModeChanged?(isShownInMultiWindow: boolean, newConfig: resourceManager.Configuration): void; | There is no corresponding API in the stage model.| No corresponding API is provided.|
| onStartContinuation?(): boolean; | There is no corresponding API in the stage model.| In the stage model, an application does not need to detect whether the continuation is successful (detected when the application initiates the continuation request). Therefore, the **onStartContinuation()** callback is deprecated.| | onStartContinuation?(): boolean; | There is no corresponding API in the stage model.| In the stage model, an application does not need to detect whether the continuation is successful (detected when the application initiates the continuation request). Therefore, the **onStartContinuation()** callback is deprecated.|
| onSaveData?(data: Object): boolean; | \@ohos.app.ability.UIAbility.d.ts | [onContinue(wantParam : {[key: string]: any}): AbilityConstant.OnContinueResult;](../reference/apis/js-apis-app-ability-uiAbility.md#abilityoncontinue) | | onSaveData?(data: Object): boolean; | \@ohos.app.ability.UIAbility.d.ts | [onContinue(wantParam : {[key: string]: any}): AbilityConstant.OnContinueResult;](../reference/apis/js-apis-app-ability-uiAbility.md#abilityoncontinue) |
| onCompleteContinuation?(result: number): void; | application\ContinueCallback.d.ts | [onContinueDone(result: number): void;](../reference/apis/js-apis-distributedMissionManager.md#continuecallback) | | onCompleteContinuation?(result: number): void; | application\ContinueCallback.d.ts | [onContinueDone(result: number): void;](../reference/apis/js-apis-distributedMissionManager.md#continuecallback) |
| onRestoreData?(data: Object): void; | \@ohos.app.ability.UIAbility.d.ts | [onCreate(want: Want, param: AbilityConstant.LaunchParam): void;](../reference/apis/js-apis-app-ability-uiAbility.md#abilityoncreate)<br>[onNewWant(want: Want, launchParams: AbilityConstant.LaunchParam): void;](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonnewwant)<br>In standard or singleton mode, the target ability completes data restoration in the **onCreate()** callback. In the callback, **launchParam.launchReason** is used to determine whether it is a continuation-based launch scenario. If it is, the data saved before continuation can be obtained from the **want** parameter.| | onRestoreData?(data: Object): void; | \@ohos.app.ability.UIAbility.d.ts | [onCreate(want: Want, param: AbilityConstant.LaunchParam): void;](../reference/apis/js-apis-app-ability-uiAbility.md#abilityoncreate)<br>[onNewWant(want: Want, launchParams: AbilityConstant.LaunchParam): void;](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonnewwant)<br>In multiton or singleton mode, the target ability completes data restoration in the **onCreate()** callback. In the callback, **launchParam.launchReason** is used to determine whether it is a continuation-based launch scenario. If it is, the data saved before continuation can be obtained from the **want** parameter.|
| onRemoteTerminated?(): void; | application\ContinueCallback.d.ts | [onContinueDone(result: number): void;](../reference/apis/js-apis-distributedMissionManager.md#continuecallback) | | onRemoteTerminated?(): void; | application\ContinueCallback.d.ts | [onContinueDone(result: number): void;](../reference/apis/js-apis-distributedMissionManager.md#continuecallback) |
| onSaveAbilityState?(outState: PacMap): void; | \@ohos.app.ability.UIAbility.d.ts | [onSaveState(reason: AbilityConstant.StateType, wantParam : {[key: string]: any}): AbilityConstant.OnSaveResult;](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonsavestate) | | onSaveAbilityState?(outState: PacMap): void; | \@ohos.app.ability.UIAbility.d.ts | [onSaveState(reason: AbilityConstant.StateType, wantParam : {[key: string]: any}): AbilityConstant.OnSaveResult;](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonsavestate) |
| onRestoreAbilityState?(inState: PacMap): void; | \@ohos.app.ability.UIAbility.d.ts | [onCreate(want: Want, param: AbilityConstant.LaunchParam): void;](../reference/apis/js-apis-app-ability-uiAbility.md#abilityoncreate)<br>After the application is restarted, the **onCreate()** callback is triggered. In the callback, **launchParam.launchReason** is used to determine whether it is a self-recovery scenario. If it is, the data saved before the restart can be obtained from the **want** parameter.| | onRestoreAbilityState?(inState: PacMap): void; | \@ohos.app.ability.UIAbility.d.ts | [onCreate(want: Want, param: AbilityConstant.LaunchParam): void;](../reference/apis/js-apis-app-ability-uiAbility.md#abilityoncreate)<br>After the application is restarted, the **onCreate()** callback is triggered. In the callback, **launchParam.launchReason** is used to determine whether it is a self-recovery scenario. If it is, the data saved before the restart can be obtained from the **want** parameter.|
......
# Mission Management and Launch Type # Mission and Launch Type
One UIAbility instance corresponds to one mission. The number of UIAbility instances is related to the UIAbility launch type, specified by **launchType**, which is configured in the **config.json** file in the FA model and the [module.json5](../quick-start/module-configuration-file.md) file in the stage model. One UIAbility instance corresponds to one mission. The number of UIAbility instances is related to the UIAbility launch type, specified by **launchType**, which is configured in the **config.json** file in the FA model and the [module.json5](../quick-start/module-configuration-file.md) file in the stage model.
...@@ -8,16 +8,19 @@ The following describes how the mission list manager manages the UIAbility insta ...@@ -8,16 +8,19 @@ The following describes how the mission list manager manages the UIAbility insta
- **singleton**: Only one UIAbility instance exists for an application. - **singleton**: Only one UIAbility instance exists for an application.
**Figure 1** Missions and singleton mode **Figure 1** Missions and singleton mode
![mission-and-singleton](figures/mission-and-singleton.png) ![mission-and-singleton](figures/mission-and-singleton.png)
- **standard**: Each time [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) is called, a **UIAbility** instance is created in the application process. - **multiton**: Each time [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) is called, a UIAbility instance is created in the application process.
**Figure 2** Missions and multiton mode
**Figure 2** Missions and standard mode ![mission-and-multiton](figures/mission-and-multiton.png)
![mission-and-standard](figures/mission-and-standard.png)
- **specified**: The ([onAcceptWant](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonacceptwant)) method of [AbilityStage](abilitystage.md) determines whether to create an instance. - **specified**: The ([onAcceptWant()](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonacceptwant)) method of [AbilityStage](abilitystage.md) determines whether to create a UIAbility instance.
**Figure 3** Missions and specified mode **Figure 3** Missions and specified mode
![mission-and-specified](figures/mission-and-specified.png) ![mission-and-specified](figures/mission-and-specified.png)
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
Before getting started with the development of mission management, be familiar with the following concepts related to mission management: Before getting started with the development of mission management, be familiar with the following concepts related to mission management:
- AbilityRecord: minimum unit for the system service to manage a UIAbility instance. It corresponds to a UIAbility component instance of an application. - AbilityRecord: minimum unit for the system service to manage a UIAbility instance. It corresponds to a UIAbility component instance of an application. A maximum of 512 UIAbility instances can be managed on the system service side.
- MissionRecord: minimum unit for mission management. One MissionRecord has only one AbilityRecord. In other words, a UIAbility component instance corresponds to a mission. - MissionRecord: minimum unit for mission management. One MissionRecord has only one AbilityRecord. In other words, a UIAbility component instance corresponds to a mission.
...@@ -30,42 +30,42 @@ Missions are managed by system applications (such as home screen), rather than t ...@@ -30,42 +30,42 @@ Missions are managed by system applications (such as home screen), rather than t
A UIAbility instance corresponds to an independent mission. Therefore, when an application calls [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) to start a UIAbility, a mission is created. A UIAbility instance corresponds to an independent mission. Therefore, when an application calls [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) to start a UIAbility, a mission is created.
To call [missionManager](../reference/apis/js-apis-application-missionManager.md) to manage missions, the home screen application must request the **ohos.permission.MANAGE_MISSIONS** permission. For details about the configuration, see [Declaring Permissions in the Configuration File](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file). 1. To call [missionManager](../reference/apis/js-apis-application-missionManager.md) to manage missions, the home screen application must request the **ohos.permission.MANAGE_MISSIONS** permission. For details about the configuration, see [Declaring Permissions in the Configuration File](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file).
You can use **missionManager** to manage missions, for example, listening for mission changes, obtaining mission information or snapshots, and clearing, locking, or unlocking missions. 2. You can use **missionManager** to manage missions, for example, listening for mission changes, obtaining mission information or snapshots, and clearing, locking, or unlocking missions.
```ts ```ts
import missionManager from '@ohos.app.ability.missionManager' import missionManager from '@ohos.app.ability.missionManager'
let listener = { let listener = {
// Listen for mission creation. // Listen for mission creation.
onMissionCreated: function (mission) { onMissionCreated: function (mission) {
console.info("--------onMissionCreated-------") console.info("--------onMissionCreated-------")
}, },
// Listen for mission destruction. // Listen for mission destruction.
onMissionDestroyed: function (mission) { onMissionDestroyed: function (mission) {
console.info("--------onMissionDestroyed-------") console.info("--------onMissionDestroyed-------")
}, },
// Listen for mission snapshot changes. // Listen for mission snapshot changes.
onMissionSnapshotChanged: function (mission) { onMissionSnapshotChanged: function (mission) {
console.info("--------onMissionSnapshotChanged-------") console.info("--------onMissionSnapshotChanged-------")
}, },
// Listen for switching the mission to the foreground. // Listen for switching the mission to the foreground.
onMissionMovedToFront: function (mission) { onMissionMovedToFront: function (mission) {
console.info("--------onMissionMovedToFront-------") console.info("--------onMissionMovedToFront-------")
}, },
// Listen for mission icon changes. // Listen for mission icon changes.
onMissionIconUpdated: function (mission, icon) { onMissionIconUpdated: function (mission, icon) {
console.info("--------onMissionIconUpdated-------") console.info("--------onMissionIconUpdated-------")
}, },
// Listen for mission name changes. // Listen for mission name changes.
onMissionLabelUpdated: function (mission) { onMissionLabelUpdated: function (mission) {
console.info("--------onMissionLabelUpdated-------") console.info("--------onMissionLabelUpdated-------")
}, },
// Listen for mission closure events. // Listen for mission closure events.
onMissionClosed: function (mission) { onMissionClosed: function (mission) {
console.info("--------onMissionClosed-------") console.info("--------onMissionClosed-------")
} }
}; };
// 1. Register a mission change listener. // 1. Register a mission change listener.
...@@ -73,56 +73,56 @@ You can use **missionManager** to manage missions, for example, listening for mi ...@@ -73,56 +73,56 @@ You can use **missionManager** to manage missions, for example, listening for mi
// 2. Obtain the latest 20 missions in the system. // 2. Obtain the latest 20 missions in the system.
missionManager.getMissionInfos("", 20, (error, missions) => { missionManager.getMissionInfos("", 20, (error, missions) => {
console.info("getMissionInfos is called, error.code = " + error.code); console.info("getMissionInfos is called, error.code = " + error.code);
console.info("size = " + missions.length); console.info("size = " + missions.length);
console.info("missions = " + JSON.stringify(missions)); console.info("missions = " + JSON.stringify(missions));
}); });
// 3. Obtain the detailed information about a mission. // 3. Obtain the detailed information about a mission.
let missionId = 11; // The mission ID 11 is only an example. let missionId = 11; // The mission ID 11 is only an example.
let mission = missionManager.getMissionInfo("", missionId).catch(function (err) { let mission = missionManager.getMissionInfo("", missionId).catch(function (err) {
console.info(err); console.info(err);
}); });
// 4. Obtain the mission snapshot. // 4. Obtain the mission snapshot.
missionManager.getMissionSnapShot("", missionId, (error, snapshot) => { missionManager.getMissionSnapShot("", missionId, (error, snapshot) => {
console.info("getMissionSnapShot is called, error.code = " + error.code); console.info("getMissionSnapShot is called, error.code = " + error.code);
console.info("bundleName = " + snapshot.ability.bundleName); console.info("bundleName = " + snapshot.ability.bundleName);
}) })
// 5. Obtain the low-resolution mission snapshot. // 5. Obtain the low-resolution mission snapshot.
missionManager.getLowResolutionMissionSnapShot("", missionId, (error, snapshot) => { missionManager.getLowResolutionMissionSnapShot("", missionId, (error, snapshot) => {
console.info("getLowResolutionMissionSnapShot is called, error.code = " + error.code); console.info("getLowResolutionMissionSnapShot is called, error.code = " + error.code);
console.info("bundleName = " + snapshot.ability.bundleName); console.info("bundleName = " + snapshot.ability.bundleName);
}) })
// 6. Lock or unlock the mission. // 6. Lock or unlock the mission.
missionManager.lockMission(missionId).then(() => { missionManager.lockMission(missionId).then(() => {
console.info("lockMission is called "); console.info("lockMission is called ");
}); });
missionManager.unlockMission(missionId).then(() => { missionManager.unlockMission(missionId).then(() => {
console.info("unlockMission is called "); console.info("unlockMission is called ");
}); });
// 7. Switch the mission to the foreground. // 7. Switch the mission to the foreground.
missionManager.moveMissionToFront(missionId).then(() => { missionManager.moveMissionToFront(missionId).then(() => {
console.info("moveMissionToFront is called "); console.info("moveMissionToFront is called ");
}); });
// 8. Clear a single mission. // 8. Clear a single mission.
missionManager.clearMission(missionId).then(() => { missionManager.clearMission(missionId).then(() => {
console.info("clearMission is called "); console.info("clearMission is called ");
}); });
// 9. Clear all missions. // 9. Clear all missions.
missionManager.clearAllMissions().catch(function (err) { missionManager.clearAllMissions().catch(function (err) {
console.info(err); console.info(err);
}); });
// 10. Deregister the mission change listener. // 10. Deregister the mission change listener.
missionManager.off('mission', listenerId, (error) => { missionManager.off('mission', listenerId, (error) => {
console.info("unregisterMissionListener"); console.info("unregisterMissionListener");
}) })
``` ```
......
...@@ -8,7 +8,7 @@ Figure 1 Mission snapshot of a UIAbility ...@@ -8,7 +8,7 @@ Figure 1 Mission snapshot of a UIAbility
![](figures/mission-list-recent.png) ![](figures/mission-list-recent.png)
You can also use [UIAbilityContext.setMissionIcon()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextsetmissionicon) and [UIAbilityContext.setMissionLabel()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextsetmissionlabel) to customize the icon and name for a mission snapshot. For example, for a UIAbility instance with the launch type set to **standard**, you can configure the icon and name for each mission snapshot based on different functions. You can also use [UIAbilityContext.setMissionIcon()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextsetmissionicon) and [UIAbilityContext.setMissionLabel()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextsetmissionlabel) to customize the icon and name for a mission snapshot. For example, for a UIAbility instance in multiton mode, you can configure the icon and name for each mission snapshot based on different functions.
This document describes the following operations: This document describes the following operations:
...@@ -21,8 +21,10 @@ Call [UIAbilityContext.setMissionIcon()](../reference/apis/js-apis-inner-applica ...@@ -21,8 +21,10 @@ Call [UIAbilityContext.setMissionIcon()](../reference/apis/js-apis-inner-applica
```ts ```ts
let imagePixelMap: PixelMap = undefined; // Obtain the PixelMap information. let imagePixelMap: PixelMap = undefined; // Obtain the PixelMap information.
this.context.setMissionIcon(imagePixelMap, (err) => { context.setMissionIcon(imagePixelMap, (err) => {
console.error(`setMissionLabel failed, code is ${err.code}, message is ${err.message}`); if (err.code) {
console.error(`Failed to set mission icon. Code is ${err.code}, message is ${err.message}`);
}
}) })
``` ```
...@@ -38,9 +40,9 @@ Call [UIAbilityContext.setMissionLabel()](../reference/apis/js-apis-inner-applic ...@@ -38,9 +40,9 @@ Call [UIAbilityContext.setMissionLabel()](../reference/apis/js-apis-inner-applic
```ts ```ts
this.context.setMissionLabel('test').then(() => { this.context.setMissionLabel('test').then(() => {
console.info('setMissionLabel succeeded.'); console.info('Succeeded in seting mission label.');
}).catch((err) => { }).catch((err) => {
console.error(`setMissionLabel failed, code is ${err.code}, message is ${err.message}`); console.error(`Failed to set mission label. Code is ${err.code}, message is ${err.message}`);
}); });
``` ```
...@@ -48,4 +50,4 @@ The display effect is shown below. ...@@ -48,4 +50,4 @@ The display effect is shown below.
Figure 3 Mission snapshot name Figure 3 Mission snapshot name
![](figures/mission-set-task-snapshot-label.png) ![](figures/mission-set-task-snapshot-label.png)
\ No newline at end of file
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
When switching an application from the FA model to the stage model, you must migrate the configurations under the **module** tag in the **config.json** file to the **module** tag in the **module.json5** file. When switching an application from the FA model to the stage model, you must migrate the configurations under the **module** tag in the **config.json** file to the **module** tag in the **module.json5** file.
### **Table 1** module comparison **Table 1** module comparison
| Field Name in the FA Model| Field Description| Field Name in the Stage Model| Difference| | Field Name in the FA Model| Field Description| Field Name in the Stage Model| Difference|
| -------- | -------- | -------- | -------- | | -------- | -------- | -------- | -------- |
...@@ -15,50 +15,50 @@ When switching an application from the FA model to the stage model, you must mig ...@@ -15,50 +15,50 @@ When switching an application from the FA model to the stage model, you must mig
| moduleType in the distro object| Type of the HAP file. The value can be **entry** or **feature**. For the HAR type, set this field to **har**.| type | The field name is changed.| | moduleType in the distro object| Type of the HAP file. The value can be **entry** or **feature**. For the HAR type, set this field to **har**.| type | The field name is changed.|
| installationFree in the distro object| Whether the HAP file supports the installation-free feature.| installationFree | The field name is changed.| | installationFree in the distro object| Whether the HAP file supports the installation-free feature.| installationFree | The field name is changed.|
| deliveryWithInstall in the distro object| Whether the HAP file is installed with the application.| deliveryWithInstall | The field name is changed.| | deliveryWithInstall in the distro object| Whether the HAP file is installed with the application.| deliveryWithInstall | The field name is changed.|
| metaData | Metadata of the HAP file.| metadata | See [Table 2](#table-2-metadata-comparison).| | metaData | Metadata of the HAP file.| metadata | For details, see Table 2.|
| abilities | All abilities in the current module.| abilities | See [Table 5](#table-5-abilities-comparison).| | abilities | All abilities in the current module.| abilities | For details, see Table 5.|
| js | A set of JS modules developed using ArkUI. Each element in the set represents the information about a JS module.| pages | The stage model retains **pages** under the **module** tag. The window configuration is the lower level of **pages**.| | js | A set of JS modules developed using ArkUI. Each element in the set represents the information about a JS module.| pages | The stage model retains **pages** under the **module** tag. The window configuration is the lower level of **pages**.|
| shortcuts | Shortcuts of the application.| shortcut_config.json| In the stage model, the **shortcut_config.json** file is defined in **resources/base/profile** in the development view.| | shortcuts | Shortcuts of the application.| shortcut_config.json| In the stage model, the **shortcut_config.json** file is defined in **resources/base/profile** in the development view.|
| reqPermissions | Permissions that the application requests from the system when it is running.| requestPermissions | The field name is changed.| | reqPermissions | Permissions that the application requests from the system when it is running.| requestPermissions | The field name is changed.|
| colorMode | Color mode of the application.| / | This configuration is not supported in the stage model.| | colorMode | Color mode of the application.| / | This configuration is not supported in the stage model.|
| distroFilter | Distribution rules of the application.| distroFilter_config.json| In the stage model, the **distroFilter_config.json** file is defined in **resources/base/profile** in the development view.| | distributionFilter | Distribution rules of the application.| distroFilter_config.json| In the stage model, the **distroFilter_config.json** file is defined in **resources/base/profile** in the development view.|
| reqCapabilities | Device capabilities required for running the application.| / | This configuration is not supported in the stage model.| | reqCapabilities | Device capabilities required for running the application.| / | This configuration is not supported in the stage model.|
| commonEvents | Common events.| common_event_config.json| In the stage model, the **common_event_config.json** file is defined in **resources/base/profile** in the development view.| | commonEvents | Common events.| common_event_config.json| In the stage model, the **common_event_config.json** file is defined in **resources/base/profile** in the development view.|
| entryTheme | Keyword of an OpenHarmony internal theme.| / | This configuration is not supported in the stage model.| | entryTheme | Keyword of an OpenHarmony internal theme.| / | This configuration is not supported in the stage model.|
### Table 2 metaData comparison **Table 2** metaData comparison
| Field Name Under metaData in the FA Model| Field Description| Field Name Under metaData in the Stage Model| Difference| | Field Name in the FA Model| Field Description| Field Name in the Stage Model| Difference|
| -------- | -------- | -------- | -------- | | -------- | -------- | -------- | -------- |
| parameters | Metadata of the parameters to be passed for calling the ability.| / | This configuration is not supported in the stage model.| | parameters | Metadata of the parameters to be passed for calling the ability.| / | This configuration is not supported in the stage model.|
| results | Metadata of the ability return value.| / | This configuration is not supported in the stage model.| | results | Metadata of the ability return value.| / | This configuration is not supported in the stage model.|
| customizeData | Custom metadata of the parent component. **parameters** and **results** cannot be configured in **application**.| metadata | See [Table 3](#table-3-comparison-between-customizedata-under-metadata-in-the-fa-model-and-metadata-in-the-stage-model).| | customizeData | Custom metadata of the parent component. **parameters** and **results** cannot be configured in **application**.| metadata | **For details**, see Table 3.|
### Table 3 Comparison between customizeData under metaData in the FA model and metadata in the stage model **Table 3** Comparison between customizeData under metaData in the FA model and metadata in the stage Model
| Field Name Under customizeData in metaData in the FA Model| Field Description| Field Name Under metaData in the Stage Model| Difference| | Field Name in the FA Model| Field Description| Field Name in the Stage Model| Difference|
| -------- | -------- | -------- | -------- | | -------- | -------- | -------- | -------- |
| name | Key name that identifies a data item. The value is a string with a maximum of 255 bytes.| name | None.| | name | Key name that identifies a data item. The value is a string with a maximum of 255 bytes.| name | None.|
| value | Value of the data item. The value is a string with a maximum of 255 bytes.| value | None.| | value | Value of the data item. The value is a string with a maximum of 255 bytes.| value | None.|
| extra | Format of the current custom data. The value is the resource value of **extra**.| resource | The field name is changed. For details, see [Table 4](#table 4-metadata-examples).| | extra | Format of the current custom data. The value is the resource value of **extra**.| resource | The field name is changed. For details, see Table 4.|
### Table 4 metaData examples **Table 4** metaData examples
| Example in the FA Model| Example in the Stage Model| | Example in the FA Model| Example in the Stage Model|
| -------- | -------- | | -------- | -------- |
| "meteData": {<br> "customizeDate": [{<br> "name": "label",<br> "value": "string",<br> "extra": "$string:label",<br> }]<br>} | "meteData": [{<br> "name": "label",<br> "value": "string",<br> "resource": "$string:label",<br>}] | | "meteData": {<br> "customizeDate": [{<br> "name": "label",<br> "value": "string",<br> "extra": "$string:label",<br> }]<br>} | "meteData": [{<br> "name": "label",<br> "value": "string",<br> "resource": "$string:label",<br>}] |
### Table 5 abilities comparison **Table 5** abilities comparison
| Field Name Under abilities in the FA Model| Field Description| Field Name Under abilities in the Stage Model| Difference| | Field Name Under abilities in the FA Model| Field Description| Field Name Under abilities in the Stage Model| Difference|
| -------- | -------- | -------- | -------- | | -------- | -------- | -------- | -------- |
| process | Name of the process running the application or ability.| / | The stage model does not support configuration of **process** under **abilities**. The configuration of **process** is available under the **module** tag.| | process | Name of the process running the application or ability.| / | The stage model does not support configuration of **process** under **abilities**. The configuration of **process** is available under the **module** tag.|
| uri | URI of the ability.| / | This configuration is not supported in the stage model.| | uri | URI of the ability.| / | This configuration is not supported in the stage model.|
| deviceCapability | Device capabilities required to run the ability.| / | This configuration is not supported in the stage model.| | deviceCapability | Device capabilities required to run the ability.| / | This configuration is not supported in the stage model.|
| metaData | Metadata of the ability.| metadata | See [Table 2](#table-2-metadata-comparison).| | metaData | Metadata of the ability.| metadata | For details, see Table 2.|
| type | Ability type.| / | This configuration is not supported in the stage model.| | type | Ability type.| / | This configuration is not supported in the stage model.|
| grantPermission | Whether permissions can be granted for any data in the ability.| / | The stage model does not support such a configuration under **abilities**.| | grantPermission | Whether permissions can be granted for any data in the ability.| / | The stage model does not support such a configuration under **abilities**.|
| readPermission | Permission required for reading data in the ability. This field applies only to the ability using the Data template.| / | In the stage model, this configuration is available under **extensionAbilities**, but not **abilities**.| | readPermission | Permission required for reading data in the ability. This field applies only to the ability using the Data template.| / | In the stage model, this configuration is available under **extensionAbilities**, but not **abilities**.|
...@@ -71,5 +71,5 @@ When switching an application from the FA model to the stage model, you must mig ...@@ -71,5 +71,5 @@ When switching an application from the FA model to the stage model, you must mig
| formsEnabled | Whether the ability can provide widgets.| / | This configuration is not supported in the stage model.| | formsEnabled | Whether the ability can provide widgets.| / | This configuration is not supported in the stage model.|
| forms | Information about the widgets used by the ability. This field is valid only when **formsEnabled** is set to **true**.| form_config.json| In the stage model, the **form_config.json** file is defined in **resources/base/profile** in the development view.| | forms | Information about the widgets used by the ability. This field is valid only when **formsEnabled** is set to **true**.| form_config.json| In the stage model, the **form_config.json** file is defined in **resources/base/profile** in the development view.|
| srcLanguage | Programming language used to develop the ability.| / | This configuration is not supported in the stage model.| | srcLanguage | Programming language used to develop the ability.| / | This configuration is not supported in the stage model.|
| srcPath | Path of the JS component code corresponding to the ability.| srcEntrance | Path of the JS code corresponding to the ability.| | srcPath | Path of the JS component code corresponding to the ability.| srcEntry | Path of the JS code corresponding to the ability.|
| uriPermission | Application data that the ability can access.| / | This configuration is not supported in the stage model.| | uriPermission | Application data that the ability can access.| / | This configuration is not supported in the stage model.|
...@@ -5,7 +5,8 @@ ...@@ -5,7 +5,8 @@
A single UIAbility component can implement multiple pages and redirection between these pages. The redirection relationship inside the UIAbility component is called page stack, which is managed by the ArkUI framework. For example, Page1 -&gt; Page2 -&gt; Page3 of UIAbility1 and PageA -&gt; PageB -&gt; PageC of UIAbility2 in the figure below are two page stacks. A single UIAbility component can implement multiple pages and redirection between these pages. The redirection relationship inside the UIAbility component is called page stack, which is managed by the ArkUI framework. For example, Page1 -&gt; Page2 -&gt; Page3 of UIAbility1 and PageA -&gt; PageB -&gt; PageC of UIAbility2 in the figure below are two page stacks.
**Figure 1** Page stack **Figure 1** Page stack
![mission-record](figures/mission-record.png) ![mission-record](figures/mission-record.png)
- A page stack is formed as follows (Steps 2, 3, 5, and 6 are page redirection and managed by ArkUI): - A page stack is formed as follows (Steps 2, 3, 5, and 6 are page redirection and managed by ArkUI):
......
...@@ -5,10 +5,10 @@ Depending on the launch type, the action performed when the PageAbility starts d ...@@ -5,10 +5,10 @@ Depending on the launch type, the action performed when the PageAbility starts d
**Table 1** PageAbility launch types **Table 1** PageAbility launch types
| Launch Type| Description| | Launch Type| Meaning| Description |
| -------- | -------- | | -------- | -------- | -------- |
| singleton | Each time **startAbility()** is called, if an ability instance of this type already exists in the application process, the instance is reused. There is only one ability instance of this type in **Recents**.<br>A typical scenario is as follows: When a user opens a video playback application and watches a video, returns to the home screen, and opens the video playback application again, the video that the user watched before returning to the home screen is still played.| | singleton | Singleton mode| Each time **startAbility()** is called, if an ability instance of this type already exists in the application process, the instance is reused. There is only one ability instance of this type in **Recents**.<br>A typical scenario is as follows: When a user opens a video playback application and watches a video, returns to the home screen, and opens the video playback application again, the video that the user watched before returning to the home screen is still played.|
| standard | Default type. Each time **startAbility()** is called, a new ability instance is created in the application process. Multiple ability instances of this type are displayed in **Recents**.<br>A typical scenario is as follows: When a user opens a document application and touches **New**, a new document task is created. Multiple new document missions are displayed in **Recents**.| | standard | Multiton mode| Default type. Each time **startAbility()** is called, a new ability instance is created in the application process. Multiple ability instances of this type are displayed in **Recents**.<br>A typical scenario is as follows: When a user opens a document application and touches **New**, a new document task is created. Multiple new document missions are displayed in **Recents**.|
You can set **launchType** in the **config.json** file to configure the launch type. The sample code is as follows: You can set **launchType** in the **config.json** file to configure the launch type. The sample code is as follows:
...@@ -16,13 +16,13 @@ You can set **launchType** in the **config.json** file to configure the launch t ...@@ -16,13 +16,13 @@ You can set **launchType** in the **config.json** file to configure the launch t
```json ```json
{ {
"module": { "module": {
// ... ...
"abilities": [ "abilities": [
{ {
// singleton mode. // singleton means the singleton mode.
// standard mode. // standard means the multiton mode.
"launchType": "standard", "launchType": "standard",
// ... ...
} }
] ]
} }
...@@ -30,7 +30,8 @@ You can set **launchType** in the **config.json** file to configure the launch t ...@@ -30,7 +30,8 @@ You can set **launchType** in the **config.json** file to configure the launch t
``` ```
When the PageAbility is started for the first time (either in standard or singleton mode), the [PageAbility lifecycle callbacks](pageability-lifecycle.md#table13118194914476) are triggered. When it is not started for the first time in singleton mode, the **onNewWant()** callback (as described in the table below) is triggered, but the **onCreate()** callback is not. When the PageAbility is started in multiton mode or it is started in singleton mode for the first time, the [PageAbility lifecycle callbacks](pageability-lifecycle.md#table13118194914476) are triggered. When it is not started for the first time in singleton mode, the **onNewWant()** callback (as described in the table below) is triggered, but the **onCreate()** callback is not.
**Table 2** Callbacks specific to the singleton mode **Table 2** Callbacks specific to the singleton mode
......
# Process Model (FA Model) # Process Model Overview (FA Model)
The OpenHarmony process model is shown below. The OpenHarmony process model is shown below.
......
# Process Model (Stage Model) # Process Model Overview (Stage Model)
The OpenHarmony process model is shown below. The OpenHarmony process model is shown below.
...@@ -15,7 +15,8 @@ The OpenHarmony process model is shown below. ...@@ -15,7 +15,8 @@ The OpenHarmony process model is shown below.
> NOTE > NOTE
> >
> You can create ServiceExtensionAbility and DataShareExtensionAbility only for system applications. > - You can create ServiceExtensionAbility and DataShareExtensionAbility only for system applications.
> - To view information about all running processes, run the **hdc shell** command to enter the shell CLI of the device, and run the **ps -ef** command.
A system application can apply for multi-process permissions (as shown in the following figure) and configure a custom process for an HAP. UIAbility, DataShareExtensionAbility, and ServiceExtensionAbility in the HAP run in the custom process. Different HAPs run in different processes by configuring different process names. A system application can apply for multi-process permissions (as shown in the following figure) and configure a custom process for an HAP. UIAbility, DataShareExtensionAbility, and ServiceExtensionAbility in the HAP run in the custom process. Different HAPs run in different processes by configuring different process names.
......
...@@ -21,11 +21,11 @@ To enable an ability to be called by any application, configure the **config.jso ...@@ -21,11 +21,11 @@ To enable an ability to be called by any application, configure the **config.jso
```ts ```ts
{ {
"module": { "module": {
// ... ...
"abilities": [ "abilities": [
{ {
"visible": "true", "visible": "true",
// ... ...
} }
] ]
} }
...@@ -33,4 +33,4 @@ To enable an ability to be called by any application, configure the **config.jso ...@@ -33,4 +33,4 @@ To enable an ability to be called by any application, configure the **config.jso
``` ```
If the ability contains **skills**, you are advised to set **visible** to **true** so that the ability can be [implicitly started](explicit-implicit-want-mappings.md#matching-rules-of-implicit-want) by other applications. If this attribute is set to **false**, the system returns **PERMISSION_DENIED** when other applications attempt to start the ability. In this case, a system application can request the [START_INVISIBLE_ABILITY](../security/permission-list.md) permission to start the ability. Example abilities with **visible** set to **false** are home screen, voice assistant, or search assistant. If the ability contains **skills**, you are advised to set **visible** to **true** so that the ability can be [implicitly started](explicit-implicit-want-mappings.md) by other applications. If this attribute is set to **false**, the system returns **PERMISSION_DENIED** when other applications attempt to start the ability. In this case, a system application can request the [START_INVISIBLE_ABILITY](../security/permission-list.md) permission to start the ability. Example abilities with **visible** set to **false** are home screen, voice assistant, or search assistant.
# Service Widget Overview
A service widget (also called widget) is a set of UI components that display important information or operations specific to an application. It provides users with direct access to a desired application service, without the need to open the application first. A widget usually appears as a part of the UI of another application (which currently can only be a system application, such as the home screen) and provides basic interactive features such as opening a UI page or sending a message.
## Service Widget Architecture
**Figure 1** Service widget architecture
![WidgetArchitecture](figures/WidgetArchitecture.png)
Before you get started, it would be helpful if you have a basic understanding of the following concepts:
- Widget host: an application that displays the widget content and controls the widget location. An example is the home screen in the preceding figure.
- Application icon: an application entry icon, clicking which starts the application process. The icon content does not support interactions.
- Widget: an interactive UI in various sizes. It may provide buttons to implement different functions, such as the button to [update the widget content](arkts-ui-widget-event-formextensionability.md) or [switch to an application](arkts-ui-widget-event-router.md).
- Card provider: an application that provides service widget content to be displayed. It controls the display content, display logic, and component click events triggered on a service widget.
- FormExtensionAbility: widget service logic module, which provides lifecycle callbacks invoked when a widget is created, destroyed, or updated.
- Widget page: widget UI module, which contains display and interaction information such as components, layouts, and events.
Below is the typical procedure of using the widget:
**Figure 2** Typical procedure of using the widget
![WidgetUse](figures/WidgetUse.png)
1. Touch and hold an application icon on the home screen to display the shortcut menu.
2. Touch **Service widget** to access the preview screen.
3. Touch the **Add to home** button. The widget is then added to the home screen.
## Widget UI Development Mode
In the stage model, the UI of a widget can be developed in [ArkTS](arkts-ui-widget-working-principles.md) or [JS](js-ui-widget-development.md).
- A widget developed in the ArkTS-based declarative development paradigm is called ArkTS widget.
- A widget developed in the JS-compatible web-like development paradigm is called JS widget.
ArkTS widgets and JS widgets have different implementation principles and features. The following table lists the differences in capabilities.
| Category| JS widget| ArkTS widget|
| -------- | -------- | -------- |
| Development paradigm| Web-like paradigm| Declarative paradigm|
| Component capability| Supported| Supported|
| Layout capability| Supported| Supported|
| Event capability| Supported| Supported|
| Custom animation| Not supported| Supported|
| Custom drawing| Not supported| Supported|
| Logic code execution (excluding the import capability)| Not supported| Supported|
As can be seen above, ArkTS widgets provide more capabilities and use cases than JS widgets. Therefore, ArkTS widgets are always recommended, except for the case where the widget consists of only static pages.
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册