diff --git a/CODEOWNERS b/CODEOWNERS index da4f5dd6a485dd877533114ae6f1fe75f4728ba5..74ad2b02259dc5bb6333c890478f150b442ea73a 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -12,1157 +12,4 @@ - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -[Release Notes] -zh-cn/release-notes/changelogs/ @ang-huawei - -[设备开发] -zh-cn/device-dev/ @li-yan339 @zengyawen - -[入门-快速入门] -zh-cn/application-dev/quick-start/start-overview.md @ge-yafang -zh-cn/application-dev/quick-start/start-with-ets-stage.md @ge-yafang - -[入门-开发基础知识-应用程序包基础知识与应用配置文件] -zh-cn/application-dev/quick-start/app*.md @nezha-father @changzheng6 @hou-xiangyu1029 @kongjing2 -zh-cn/application-dev/quick-start/module*.md @nezha-father @changzheng6 @hou-xiangyu1029 @kongjing2 -zh-cn/application-dev/quick-start/multi-hap*.md @nezha-father @changzheng6 @hou-xiangyu1029 @kongjing2 -zh-cn/application-dev/quick-start/deviceconfig-structure.md @nezha-father @changzheng6 @hou-xiangyu1029 @kongjing2 -zh-cn/application-dev/quick-start/shared-guide.md @nezha-father @changzheng6 @hou-xiangyu1029 @kongjing2 -zh-cn/application-dev/quick-start/har-package.md @nezha-father @changzheng6 @hou-xiangyu1029 @kongjing2 -zh-cn/application-dev/quick-start/in-app-hsp.md @nezha-father @changzheng6 @hou-xiangyu1029 @kongjing2 -zh-cn/application-dev/quick-start/quickfix*.md @nezha-father @changzheng6 @hou-xiangyu1029 @kongjing2 - -[入门-资源分类与访问] -zh-cn/application-dev/quick-start/resource-categories-and-access.md @Buda-Liu @ningningW @budda-wang @yangqing3 - -[入门-学习Arkts语言] -zh-cn/application-dev/quick-start/arkts-get-started.md @zhang_yixin13 @flyingwolf -zh-cn/application-dev/quick-start/introduction-to-arkts.md @zhang_yixin13 @flyingwolf -zh-cn/application-dev/quick-start/arkts-migration-background.md @zhang_yixin13 @flyingwolf -zh-cn/application-dev/quick-start/typescript-to-arkts-migration-guide.md @zhang_yixin13 @flyingwolf -zh-cn/application-dev/quick-start/arkts-more-cases.md @zhang_yixin13 @flyingwolf -zh-cn/application-dev/quick-start/arkts-bytecode-fundamentals.md @zhang_yixin13 @flyingwolf -zh-cn/application-dev/quick-start/arkts-bytecode-file-format.md @zhang_yixin13 @flyingwolf -zh-cn/application-dev/quick-start/arkts-bytecode-function-name.md @zhang_yixin13 @flyingwolf -zh-cn/application-dev/quick-start/arkts-high-performance-programming.md @zhang_yixin13 @flyingwolf - -zh-cn/application-dev/quick-start/arkts-basic-syntax-overview.md @zhang_yixin13 @luyuxuan1 @s10021109 @seaside_wu -zh-cn/application-dev/quick-start/arkts-declarative-ui-description.md @zhang_yixin13 @luyuxuan1 @s10021109 @seaside_wu -zh-cn/application-dev/quick-start/arkts-create-custom-components.md @zhang_yixin13 @luyuxuan1 @s10021109 @seaside_wu -zh-cn/application-dev/quick-start/arkts-page-custom-components-lifecycle.md @zhang_yixin13 @luyuxuan1 @s10021109 @seaside_wu -zh-cn/application-dev/quick-start/arkts-custom-components-freeze.md @zhang_yixin13 @luyuxuan1 @s10021109 @seaside_wu -zh-cn/application-dev/quick-start/arkts-builder.md @zhang_yixin13 @luyuxuan1 @s10021109 @seaside_wu -zh-cn/application-dev/quick-start/arkts-builderparam.md @zhang_yixin13 @luyuxuan1 @s10021109 @seaside_wu -zh-cn/application-dev/quick-start/arkts-wrapBuilder.md @zhang_yixin13 @luyuxuan1 @s10021109 @seaside_wu -zh-cn/application-dev/quick-start/arkts-style.md @zhang_yixin13 @luyuxuan1 @s10021109 @seaside_wu -zh-cn/application-dev/quick-start/arkts-extend.md @zhang_yixin13 @luyuxuan1 @s10021109 @seaside_wu -zh-cn/application-dev/quick-start/arkts-statestyles.md @zhang_yixin13 @luyuxuan1 @s10021109 @seaside_wu -zh-cn/application-dev/quick-start/arkts-state-management-overview.md @zhang_yixin13 @luyuxuan1 @s10021109 @seaside_wu -zh-cn/application-dev/quick-start/arkts-animatable-extend.md @zhang_yixin13 @luyuxuan1 @s10021109 @seaside_wu -zh-cn/application-dev/quick-start/arkts-require.md @zhang_yixin13 @luyuxuan1 @s10021109 @seaside_wu - -zh-cn/application-dev/quick-start/arkts-state-management-overview.md @zhang_yixin13 @luyuxuan1 @s10021109 @seaside_wu -zh-cn/application-dev/quick-start/arkts-state.md @zhang_yixin13 @luyuxuan1 @s10021109 @seaside_wu -zh-cn/application-dev/quick-start/arkts-prop.md @zhang_yixin13 @luyuxuan1 @s10021109 @seaside_wu -zh-cn/application-dev/quick-start/arkts-link.md @zhang_yixin13 @luyuxuan1 @s10021109 @seaside_wu -zh-cn/application-dev/quick-start/arkts-provide-and-consume.md @zhang_yixin13 @luyuxuan1 @s10021109 @seaside_wu -zh-cn/application-dev/quick-start/arkts-observed-and-objectlink.md @zhang_yixin13 @luyuxuan1 @s10021109 @seaside_wu -zh-cn/application-dev/quick-start/arkts-application-state-management-overview.md @zhang_yixin13 @luyuxuan1 @s10021109 @seaside_wu -zh-cn/application-dev/quick-start/arkts-localstorage.md @zhang_yixin13 @luyuxuan1 @s10021109 @seaside_wu -zh-cn/application-dev/quick-start/arkts-appstorage.md @zhang_yixin13 @luyuxuan1 @s10021109 @seaside_wu -zh-cn/application-dev/quick-start/arkts-persiststorage.md @zhang_yixin13 @luyuxuan1 @s10021109 @seaside_wu -zh-cn/application-dev/quick-start/arkts-environment.md @zhang_yixin13 @luyuxuan1 @s10021109 @seaside_wu -zh-cn/application-dev/quick-start/arkts-other-state-mgmt-functions-overview.md @zhang_yixin13 @luyuxuan1 @s10021109 @seaside_wu -zh-cn/application-dev/quick-start/arkts-watch.md @zhang_yixin13 @luyuxuan1 @s10021109 @seaside_wu -zh-cn/application-dev/quick-start/arkts-two-way-sync.md @zhang_yixin13 @luyuxuan1 @s10021109 @seaside_wu -zh-cn/application-dev/quick-start/arkts-track.md @zhang_yixin13 @luyuxuan1 @s10021109 @seaside_wu -zh-cn/application-dev/quick-start/arkts-mvvm.md @zhang_yixin13 @luyuxuan1 @s10021109 @seaside_wu -zh-cn/application-dev/quick-start/arkts-state-management-best-practices.md @zhang_yixin13 @luyuxuan1 @s10021109 @seaside_wu -zh-cn/application-dev/quick-start/properly-use-state-management-to-develope.md @zhang_yixin13 @luyuxuan1 @s10021109 @seaside_wu - -zh-cn/application-dev/quick-start/arkts-new-observedV2-and-trace.md @zhang_yixin13 @luyuxuan1 @s10021109 @seaside_wu -zh-cn/application-dev/quick-start/arkts-new-componentV2.md @zhang_yixin13 @luyuxuan1 @s10021109 @seaside_wu -zh-cn/application-dev/quick-start/arkts-new-local.md @zhang_yixin13 @luyuxuan1 @s10021109 @seaside_wu -zh-cn/application-dev/quick-start/arkts-new-param.md @zhang_yixin13 @luyuxuan1 @s10021109 @seaside_wu -zh-cn/application-dev/quick-start/arkts-new-once.md @zhang_yixin13 @luyuxuan1 @s10021109 @seaside_wu -zh-cn/application-dev/quick-start/arkts-new-event.md @zhang_yixin13 @luyuxuan1 @s10021109 @seaside_wu -zh-cn/application-dev/quick-start/arkts-new-monitor.md @zhang_yixin13 @luyuxuan1 @s10021109 @seaside_wu -zh-cn/application-dev/quick-start/arkts-new-Provider-and-Consumer.md @zhang_yixin13 @luyuxuan1 @s10021109 @seaside_wu -zh-cn/application-dev/quick-start/arkts-new-Computed.md @zhang_yixin13 @luyuxuan1 @s10021109 @seaside_wu -zh-cn/application-dev/quick-start/arkts-new-binding.md @zhang_yixin13 @luyuxuan1 @s10021109 @seaside_wu - -zh-cn/application-dev/quick-start/arkts-rendering-control-overview.md @zhang_yixin13 @luyuxuan1 @s10021109 @seaside_wu -zh-cn/application-dev/quick-start/arkts-rendering-control-ifelse.md @zhang_yixin13 @luyuxuan1 @s10021109 @seaside_wu -zh-cn/application-dev/quick-start/arkts-rendering-control-foreach.md @zhang_yixin13 @luyuxuan1 @s10021109 @seaside_wu -zh-cn/application-dev/quick-start/arkts-rendering-control-lazyforeach.md @zhang_yixin13 @luyuxuan1 @s10021109 @seaside_wu - -[开发-Ability Kit-元能力] -zh-cn/application-dev/kit-readme/Readme-Ability-Kit.md @huipeizi @ccllee @lxfycode @lixueqing513 -zh-cn/application-dev/application-models/ @huipeizi @ccllee @lxfycode @lixueqing513 -zh-cn/application-dev/application-models/uiability*.md @huipeizi @li-weifeng2 @lxfycode @lixueqing513 -zh-cn/application-dev/application-models/thread*.md @huipeizi @li-weifeng2 @lxfycode @lixueqing513 -zh-cn/application-dev/application-models/itc*.md @huipeizi @li-weifeng2 @lxfycode @lixueqing513 - - -[开发-Accessibility Kit] -zh-cn/application-dev/kit-readme/Readme-Accessibility-Kit.md @li-yan339 -zh-cn/application-dev/application-models/accessibilityKit.md @li-yan339 -zh-cn/application-dev/application-models/accessibilityextensionability.md @li-yan339 - - -[开发-ArkData] -zh-cn/application-dev/database @ge-yafang @feng-aiwen @gong-a-shi @logic42 @widecode @dboy190 -zh-cn/application-dev/database/data-mgmt-overview.md @ge-yafang @feng-aiwen @gong-a-shi @logic42 @widecode -zh-cn/application-dev/database/unified-data-definition-overview.md @ge-yafang @feng-aiwen @gong-a-shi @logic42 @widecode @dboy190 -zh-cn/application-dev/database/uniform-data-type-descriptors.md @ge-yafang @feng-aiwen @gong-a-shi @logic42 @widecode @dboy190 -zh-cn/application-dev/database/uniform-data-structure.md @ge-yafang @feng-aiwen @gong-a-shi @logic42 @widecode @dboy190 -zh-cn/application-dev/database/app-data-persistence-overview.md @ge-yafang @feng-aiwen @gong-a-shi @logic42 @widecode -zh-cn/application-dev/database/data-persistence-by-preferences.md @ge-yafang @feng-aiwen @gong-a-shi @logic42 @widecode -zh-cn/application-dev/database/data-persistence-by-kv-store.md @ge-yafang @feng-aiwen @gong-a-shi @logic42 @liuwenhui_ddmp @widecode -zh-cn/application-dev/database/data-persistence-by-rdb-store.md @ge-yafang @feng-aiwen @gong-a-shi @logic42 @widecode -zh-cn/application-dev/database/sync-app-data-across-devices-overview.md @ge-yafang @feng-aiwen @gong-a-shi @logic42 @widecode -zh-cn/application-dev/database/data-sync-of-rdb-store.md @ge-yafang @feng-aiwen @gong-a-shi @logic42 @widecode -zh-cn/application-dev/database/data-sync-of-kv-store.md @ge-yafang @feng-aiwen @gong-a-shi @logic42 @liuwenhui_ddmp @widecode -zh-cn/application-dev/database/data-sync-of-distributed-data-object.md @ge-yafang @feng-aiwen @gong-a-shi @logic42 @liuwenhui_ddmp @widecode -zh-cn/application-dev/database/data-reliability-security-overview.md @ge-yafang @feng-aiwen @gong-a-shi @logic42 @widecode -zh-cn/application-dev/database/data-backup-and-restore.md @ge-yafang @feng-aiwen @gong-a-shi @logic42 @widecode -zh-cn/application-dev/database/data-encryption.md @ge-yafang @feng-aiwen @gong-a-shi @logic42 @widecode -zh-cn/application-dev/database/access-control-by-device-and-data-level.md @ge-yafang @feng-aiwen @gong-a-shi @logic42 @widecode -zh-cn/application-dev/database/data-share-overview.md @ge-yafang @feng-aiwen @gong-a-shi @logic42 @widecode -zh-cn/application-dev/database/share-data-by-datashareextensionability.md @ge-yafang @feng-aiwen @gong-a-shi @logic42 @widecode -zh-cn/application-dev/database/share-data-by-silent-access.md @ge-yafang @feng-aiwen @gong-a-shi @logic42 @widecode -zh-cn/application-dev/database/unified-data-definition.md @ge-yafang @feng-aiwen @gong-a-shi @logic42 @widecode @dboy190 -zh-cn/application-dev/database/unified-data-channels.md @ge-yafang @feng-aiwen @gong-a-shi @logic42 @widecode @dboy190 -zh-cn/application-dev/database/native-relation-store-guidelines.md @ge-yafang @feng-aiwen @gong-a-shi @logic42 @widecode - - -[开发-ArkGraphics2D] -zh-cn/application-dev/graphics @ge-yafang @zhangqiang183 @zhouyaoying @zxg-gitee @nobuggers -zh-cn/application-dev/graphics/arkgraphics2D-introduction.md @ge-yafang @zhangqiang183 @zhouyaoying @zxg-gitee @nobuggers -zh-cn/application-dev/graphics/displaysync-overview.md @ge-yafang @zhangqiang183 @zhouyaoying @zxg-gitee @nobuggers @wind-zj -zh-cn/application-dev/graphics/displaysync-ui.md @ge-yafang @zhangqiang183 @zhouyaoying @zxg-gitee @nobuggers @wind-zj -zh-cn/application-dev/graphics/displaysync-xcomponent.md @ge-yafang @zhangqiang183 @zxg-gitee @nobuggers @wind-zj -zh-cn/application-dev/graphics/displaysync-animation.md @ge-yafang @zhangqiang183 @zhouyaoying @zxg-gitee @nobuggers @wind-zj -zh-cn/application-dev/graphics/drawing-js-guidelines.md @sqwlly @zxg-gitee @nobuggers @ge-yafang -zh-cn/application-dev/graphics/drawing-guidelines.md @sqwlly @zxg-gitee @nobuggers @ge-yafang -zh-cn/application-dev/graphics/native-window-guidelines.md @ge-yafang @zhangqiang183 @zhouyaoying @zxg-gitee @nobuggers -zh-cn/application-dev/graphics/native-buffer-guidelines.md @ge-yafang @zhangqiang183 @zhouyaoying @zxg-gitee @nobuggers -zh-cn/application-dev/graphics/native-image-guidelines.md @ge-yafang @zhangqiang183 @zhouyaoying @zxg-gitee @nobuggers -zh-cn/application-dev/graphics/native-vsync-guidelines.md @ge-yafang @zhangqiang183 @zhouyaoying @zxg-gitee @nobuggers - -[开发-ArkGraphics3D] -zh-cn/application-dev/graphics3d @ge-yafang @zhangqiang183 @zhouyaoying @zxg-gitee @nobuggers - -[开发-ArkTS] -zh-cn/application-dev/arkts-utils @ge-yafang @gongjunsong @weng-changcheng @blackstone-oh -zh-cn/application-dev/arkts-utils/arkts-commonlibrary-overview.md @ge-yafang @gongjunsong @weng-changcheng @blackstone-oh -zh-cn/application-dev/arkts-utils/concurrency-overview.md @ge-yafang @gongjunsong @weng-changcheng @blackstone-oh -zh-cn/application-dev/arkts-utils/async-concurrency-overview.md @ge-yafang @gongjunsong @weng-changcheng @blackstone-oh -zh-cn/application-dev/arkts-utils/single-io-development.md @ge-yafang @gongjunsong @weng-changcheng @blackstone-oh -zh-cn/application-dev/arkts-utils/multi-thread-concurrency-overview.md @ge-yafang @gongjunsong @weng-changcheng @blackstone-oh -zh-cn/application-dev/arkts-utils/taskpool-introduction.md @ge-yafang @gongjunsong @weng-changcheng @blackstone-oh -zh-cn/application-dev/arkts-utils/worker-introduction.md @ge-yafang @gongjunsong @weng-changcheng @blackstone-oh -zh-cn/application-dev/arkts-utils/taskpool-vs-worker.md @ge-yafang @gongjunsong @weng-changcheng @blackstone-oh -zh-cn/application-dev/arkts-utils/cpu-intensive-task-development.md @ge-yafang @gongjunsong @weng-changcheng @blackstone-oh -zh-cn/application-dev/arkts-utils/io-intensive-task-development.md @ge-yafang @gongjunsong @weng-changcheng @blackstone-oh -zh-cn/application-dev/arkts-utils/sync-task-development.md @ge-yafang @gongjunsong @weng-changcheng @blackstone-oh -zh-cn/application-dev/arkts-utils/actor-model-development-samples.md @ge-yafang @gongjunsong @weng-changcheng @blackstone-oh -zh-cn/application-dev/arkts-utils/serialization-support-types.md @ge-yafang @gongjunsong @weng-changcheng @blackstone-oh -zh-cn/application-dev/arkts-utils/multi-thread-safety.md @ge-yafang @gongjunsong @weng-changcheng @blackstone-oh -zh-cn/application-dev/arkts-utils/arkts-concurrent.md @ge-yafang @gongjunsong @weng-changcheng @blackstone-oh -zh-cn/application-dev/arkts-utils/arkts-sendable.md @ge-yafang @gongjunsong @weng-changcheng @blackstone-oh -zh-cn/application-dev/arkts-utils/container-overview.md @ge-yafang @gongjunsong @blackstone-oh -zh-cn/application-dev/arkts-utils/linear-container.md @ge-yafang @gongjunsong @blackstone-oh -zh-cn/application-dev/arkts-utils/nonlinear-container.md @ge-yafang @gongjunsong @blackstone-oh -zh-cn/application-dev/arkts-utils/xml-overview.md @ge-yafang @gongjunsong @blackstone-oh -zh-cn/application-dev/arkts-utils/xml-generation.md @ge-yafang @gongjunsong @blackstone-oh -zh-cn/application-dev/arkts-utils/xml-parsing.md @ge-yafang @gongjunsong @blackstone-oh -zh-cn/application-dev/arkts-utils/xml-conversion.md @ge-yafang @gongjunsong @blackstone-oh - - -[开发-ArkUI-UI开发] -zh-cn/application-dev/ui/arkui-overview.md @tomatodevboy @HelloCrease -zh-cn/application-dev/ui/arkts-ui-development-overview.md @tomatodevboy @HelloCrease -zh-cn/application-dev/ui/arkts-layout-development-overview.md @tomatodevboy @HelloCrease -zh-cn/application-dev/ui/arkts-layout-development-linear.md @crazyracing0726 @tomatodevboy @HelloCrease -zh-cn/application-dev/ui/arkts-layout-development-stack-layout.md @crazyracing0726 @tomatodevboy @HelloCrease -zh-cn/application-dev/ui/arkts-layout-development-flex-layout.md @crazyracing0726 @tomatodevboy @HelloCrease -zh-cn/application-dev/ui/arkts-layout-development-relative-layout.md @crazyracing0726 @tomatodevboy @HelloCrease -zh-cn/application-dev/ui/arkts-layout-development-grid-layout.md @crazyracing0726 @tomatodevboy @HelloCrease -zh-cn/application-dev/ui/arkts-layout-development-media-query.md @laigerendaqiu @tomatodevboy @HelloCrease -zh-cn/application-dev/ui/arkts-layout-development-create-list.md @yeyinglong_admin @cc520bf @tomatodevboy @HelloCrease -zh-cn/application-dev/ui/arkts-layout-development-create-grid.md @zcdqs @cc520bf @tomatodevboy @HelloCrease -zh-cn/application-dev/ui/arkts-layout-development-create-looping.md @yan-shuifeng @cc520bf @tomatodevboy @HelloCrease -zh-cn/application-dev/ui/arkts-common-components-button.md @zhangfanfan2 @tomatodevboy @HelloCrease -zh-cn/application-dev/ui/arkts-common-components-radio-button.md @zhangfanfan2 @tomatodevboy @HelloCrease -zh-cn/application-dev/ui/arkts-common-components-switch.md @zhangfanfan2 @tomatodevboy @HelloCrease -zh-cn/application-dev/ui/arkts-common-components-progress-indicator.md @yeyinglong_admin @cc520bf @tomatodevboy @HelloCrease -zh-cn/application-dev/ui/arkts-common-components-text-display.md @crazyracing0726 @tomatodevboy @HelloCrease -zh-cn/application-dev/ui/arkts-common-components-text-input.md @crazyracing0726 @tomatodevboy @HelloCrease -zh-cn/application-dev/ui/arkts-common-components-custom-dialog.md @zhangfanfan2 @luyuxuan1 @HelloCrease -zh-cn/application-dev/ui/arkts-common-components-video-player.md @keerecles @seaside_wu @tomatodevboy @HelloCrease -zh-cn/application-dev/ui/arkts-common-components-xcomponent.md @keerecles @laigerendaqiu @luyuxuan1 @HelloCrease -zh-cn/application-dev/ui/arkts-popup-and-menu-components-popup.md @zhangfanfan2 @luyuxuan1 @HelloCrease -zh-cn/application-dev/ui/arkts-popup-and-menu-components-menu.md @zhangfanfan2 @luyuxuan1 @HelloCrease -zh-cn/application-dev/ui/arkts-routing.md @raulnaruto_admin @luyuxuan1 @HelloCrease -zh-cn/application-dev/ui/arkts-navigation-navigation.md @jiangdayuan @raulnaruto_admin @tomatodevboy @HelloCrease -zh-cn/application-dev/ui/arkts-navigation-tabs.md @yan-shuifeng @cc520bf @tomatodevboy @HelloCrease -zh-cn/application-dev/ui/arkts-graphics-display.md @crazyracing0726 @tomatodevboy @HelloCrease -zh-cn/application-dev/ui/arkts-geometric-shape-drawing.md @keerecles @seaside_wu @luyuxuan1 @HelloCrease -zh-cn/application-dev/ui/arkts-drawing-customization-on-canvas.md @keerecles @seaside_wu @luyuxuan1 @HelloCrease -zh-cn/application-dev/ui/arkts-animation.md @lightningHo @huaweimaxuchu @luyuxuan1 @HelloCrease -zh-cn/application-dev/ui/arkts-attribute-animation-overview.md @lightningHo @huaweimaxuchu @luyuxuan1 @HelloCrease -zh-cn/application-dev/ui/arkts-attribute-animation-apis.md @lightningHo @huaweimaxuchu @luyuxuan1 @HelloCrease -zh-cn/application-dev/ui/arkts-custom-attribute-animation.md @lightningHo @huaweimaxuchu @luyuxuan1 @HelloCrease -zh-cn/application-dev/ui/arkts-transition-overview.md @lightningHo @huaweimaxuchu @luyuxuan1 @HelloCrease -zh-cn/application-dev/ui/arkts-enter-exit-transition.md @lightningHo @huaweimaxuchu @luyuxuan1 @HelloCrease -zh-cn/application-dev/ui/arkts-navigation-transition.md @lightningHo @huaweimaxuchu @luyuxuan1 @HelloCrease -zh-cn/application-dev/ui/arkts-modal-transition.md @lightningHo @huaweimaxuchu @luyuxuan1 @HelloCrease -zh-cn/application-dev/ui/arkts-shared-element-transition.md @lightningHo @huaweimaxuchu @luyuxuan1 @HelloCrease -zh-cn/application-dev/ui/arkts-page-transition-animation.md @lightningHo @huaweimaxuchu @luyuxuan1 @HelloCrease -zh-cn/application-dev/ui/arkts-component-animation.md @lightningHo @huaweimaxuchu @luyuxuan1 @HelloCrease -zh-cn/application-dev/ui/arkts-curve-overview.md @lightningHo @huaweimaxuchu @luyuxuan1 @HelloCrease -zh-cn/application-dev/ui/arkts-traditional-curve.md @lightningHo @huaweimaxuchu @luyuxuan1 @HelloCrease -zh-cn/application-dev/ui/arkts-spring-curve.md @lightningHo @huaweimaxuchu @luyuxuan1 @HelloCrease -zh-cn/application-dev/ui/arkts-animation-smoothing.md @lightningHo @huaweimaxuchu @luyuxuan1 @HelloCrease -zh-cn/application-dev/ui/arkts-blur-effect.md @lightningHo @huaweimaxuchu @luyuxuan1 @HelloCrease -zh-cn/application-dev/ui/arkts-shadow-effect.md @lightningHo @huaweimaxuchu @luyuxuan1 @HelloCrease -zh-cn/application-dev/ui/arkts-color-effect.md @lightningHo @luyuxuan1 @HelloCrease -zh-cn/application-dev/ui/arkts-event-overview.md @zhaojian2021 @jiangtao92 @luyuxuan1 @HelloCrease -zh-cn/application-dev/ui/arkts-common-events-touch-screen-event.md @zhaojian2021 @jiangtao92 @luyuxuan1 @HelloCrease -zh-cn/application-dev/ui/arkts-common-events-device-input-event.md @zhaojian2021 @jiangtao92 @luyuxuan1 @HelloCrease -zh-cn/application-dev/ui/arkts-common-events-focus-event.md @piggyguy @jiangtao92 @luyuxuan1 @HelloCrease -zh-cn/application-dev/ui/arkts-gesture-events-binding.md @zhaojian2021 @jiangtao92 @luyuxuan1 @HelloCrease -zh-cn/application-dev/ui/arkts-gesture-events-single-gesture.md @zhaojian2021 @jiangtao92 @luyuxuan1 @HelloCrease -zh-cn/application-dev/ui/arkts-gesture-events-combined-gestures.md @zhaojian2021 @jiangtao92 @luyuxuan1 @HelloCrease -zh-cn/application-dev/ui/arkts-user-defined.md @sunfei2021 @tomatodevboy @HelloCrease -zh-cn/application-dev/ui/arkts-user-defined-node.md @sunfei2021 @tomatodevboy @HelloCrease -zh-cn/application-dev/ui/arkts-user-defined-place-hoder.md @sunfei2021 @tomatodevboy @HelloCrease -zh-cn/application-dev/ui/arkts-user-defined-arktsNode-frameNode.md @sunfei2021 @tomatodevboy @HelloCrease -zh-cn/application-dev/ui/arkts-user-defined-arktsNode-renderNode.md @sunfei2021 @tomatodevboy @HelloCrease -zh-cn/application-dev/ui/arkts-user-defined-arktsNode-builderNode.md @sunfei2021 @tomatodevboy @HelloCrease -zh-cn/application-dev/ui/ndk-build-ui-overview.md @yan-shuifeng @tomatodevboy @HelloCrease -zh-cn/application-dev/ui/ndk-access-the-arkts-page.md @yan-shuifeng @tomatodevboy @HelloCrease -zh-cn/application-dev/ui/ndk-listen-to-component-events.md @yan-shuifeng @tomatodevboy @HelloCrease -zh-cn/application-dev/ui/ndk-bind-gesture-events.md @yan-shuifeng @tomatodevboy @HelloCrease -zh-cn/application-dev/ui/ndk-use-animation.md @yan-shuifeng @tomatodevboy @HelloCrease -zh-cn/application-dev/ui/ndk-loading-long-list.md @yan-shuifeng @tomatodevboy @HelloCrease -zh-cn/application-dev/ui/ndk-build-pop-up-window.md @yan-shuifeng @tomatodevboy @HelloCrease -zh-cn/application-dev/ui/ndk-build-custom-components.md @yan-shuifeng @tomatodevboy @HelloCrease -zh-cn/application-dev/ui/ndk-embed-arkts-components.md @yan-shuifeng @tomatodevboy @HelloCrease - -[开发-ArkUI-窗口管理] -zh-cn/application-dev/windowmanager/ @ge-yafang @zhangqiang183 @zhouyaoying @zxg-gitee @nobuggers @qinliwen -zh-cn/application-dev/application-models/windowextensionability.md @zhangqiang183 @ge-yafang @zhouyaoying @zxg-gitee @nobuggers @qinliwen - - -[开发-Arkweb] -zh-cn/application-dev/web/ @bigpumpkin @HelloCrease @litao33 @zhang-xinyue15 - - -[开发-Background Tasks Kit] -zh-cn/application-dev/task-management/background-task-overview.md @ningningW @yuanzhizhong @hmosdeveloper -zh-cn/application-dev/task-management/transient-task.md @ningningW @yuanzhizhong @hmosdeveloper -zh-cn/application-dev/task-management/continuous-task.md @ningningW @yuanzhizhong @hmosdeveloper -zh-cn/application-dev/task-management/work-scheduler.md @ningningW @yuanzhizhong @hmosdeveloper -zh-cn/application-dev/task-management/agent-powered-reminder.md @ningningW @yuanzhizhong @hmosdeveloper -zh-cn/application-dev/task-management/efficiency-resource-request.md @ningningW @yuanzhizhong @hmosdeveloper -zh-cn/application-dev/device-usage-statistics/ @ningningW @yuanzhizhong @hmosdeveloper - -[开发-Basic Services Kit-帐号] -zh-cn/application-dev/account/ @zengyawen - -[开发-Basic Services Kit-公共事件] -zh-cn/application-dev/application-models/common-event*.md @huipeizi @idanny @event_notification - -[开发-Basic Services Kit-设备管理] -zh-cn/application-dev/device/usb-overview.md @li-yan339 @Kevin-Lau @liuhonggang123 -zh-cn/application-dev/device/usb-guidelines.md @li-yan339 @Kevin-Lau @liuhonggang123 - -[开发-Basic Services Kit-升级服务] -zh-cn/application-dev/basic-services/update/Readme-CN.md @nezha-father -zh-cn/application-dev/basic-services/update/sample-server-overview.md @nezha-father -zh-cn/application-dev/basic-services/update/sample-server-guidelines.md @nezha-father - -[开发-CalendarManager Kit] -zh-cn/application-dev/calendarmanager @liuqian677 @jt_123456 @edollar -zh-cn/application-dev/kit-readme/Readme-CalendarManager-Kit.md @liuqian677 @jt_123456 @edollar -zh-cn/application-dev/calendarmanager/calendarmanager-overview.md @liuqian677 @jt_123456 @edollar -zh-cn/application-dev/calendarmanager/calendarmanager-guidelines.md @liuqian677 @jt_123456 @edollar - - -[开发-Connectivity Kit] -zh-cn/application-dev/communication/bluetooth/ @zhang_yixin13 @xujiang1981 @quanli125 -zh-cn/application-dev/communication/nfc/ @knpingan @zhang_yixin13 @projectmanagement-zhang @heli_bbd - - -[开发-Contacts Kit] -zh-cn/application-dev/telephony/contacts-intro.md @zhang_yixin13 - - -[开发-Core File Kit] -zh-cn/application-dev/file-management/ @foryourself - - -[开发-Driverdevelopment kit] -zh-cn/application-dev/application-models/driverextensionability.md @li-yan339 -zh-cn/application-dev/device/externaldevice-guidelines.md @li-yan339 - - - -[开发-Form Kit] -zh-cn/application-dev/form/ @Eiln @hehe9876 @nezha-father - - -[开发-DFX] -zh-cn/application-dev/dfx/ @foryourself - -[开发-IDL] -zh-cn/application-dev/IDL/ @huipeizi @ccllee @lxfycode @lixueqing513 - -[开发-IME kit] -zh-cn/application-dev/inputmethod/ @illybyy @murphy1984 @feng-aiwen @zhang_yixin13 @SuperShrimp @murphy1984 -zh-cn/application-dev/kit-readme/Readme-IME-Kit.md @illybyy @murphy1984 @feng-aiwen @zhang_yixin13 @SuperShrimp @murphy1984 -zh-cn/application-dev/inputmethod/Readme-CN.md @illybyy @murphy1984 @feng-aiwen @zhang_yixin13 @SuperShrimp @murphy1984 -zh-cn/application-dev/inputmethod/custom_input_box_guide.md @illybyy @murphy1984 @feng-aiwen @zhang_yixin13 @SuperShrimp @murphy1984 -zh-cn/application-dev/inputmethod/ime-kit-intro.md @illybyy @murphy1984 @feng-aiwen @zhang_yixin13 @SuperShrimp @murphy1984 -zh-cn/application-dev/inputmethod/input_method_subtype_guide.md @illybyy @murphy1984 @feng-aiwen @zhang_yixin13 @SuperShrimp @murphy1984 -zh-cn/application-dev/inputmethod/inputmethod_application_guide.md @illybyy @murphy1984 @feng-aiwen @zhang_yixin13 @SuperShrimp @murphy1984 -zh-cn/application-dev/inputmethod/switch_inputmehod_guide.md @illybyy @murphy1984 @feng-aiwen @zhang_yixin13 @SuperShrimp @murphy1984 - -[开发-Input kit] -zh-cn/application-dev/device/inputdevice-guidelines.md @hhh2 @ningningW @mayunteng @star-wind-snow-and-rain -zh-cn/application-dev/device/pointerstyle-guidelines.md @hhh2 @ningningW @mayunteng @star-wind-snow-and-rain -zh-cn/application-dev/device/inputmonitor-guidelines.md @hhh2 @ningningW @mayunteng @star-wind-snow-and-rain -zh-cn/application-dev/device/inputeventclient-guidelines.md @hhh2 @ningningW @mayunteng @star-wind-snow-and-rain -zh-cn/application-dev/device/inputconsumer-guidelines.md @hhh2 @ningningW @mayunteng @star-wind-snow-and-rain -zh-cn/application-dev/device/shortkey-guidelines.md @hhh2 @ningningW @mayunteng @star-wind-snow-and-rain -zh-cn/application-dev/device/input-overview.md @hhh2 @ningningW @mayunteng @star-wind-snow-and-rain - -[开发-IPC Kit] -zh-cn/application-dev/connectivity/ipc-rpc-overview.md @zhang_yixin13 @luodh0157 @zhaopeng_gitee @zhang-yang123321 -zh-cn/application-dev/connectivity/ipc-rpc-development-guideline.md @zhang_yixin13 @luodh0157 @zhaopeng_gitee @zhang-yang123321 -zh-cn/application-dev/connectivity/subscribe-remote-state.md @zhang_yixin13 @luodh0157 @zhaopeng_gitee @zhang-yang123321 - - - -[开发-Localization Kit] -zh-cn/application-dev/internationalization/ @ningningW @yliupy @yangqing3 @sunyaozu - - -[开发-Location Kit] -zh-cn/application-dev/device/device-location-overview.md @RayShih -zh-cn/application-dev/device/device-location-info.md @RayShih -zh-cn/application-dev/device/device-location-geocoding.md @RayShih - - -[开发-Media] -zh-cn/application-dev/media/ @zengyawen - - -[开发-MindSpore Lite Kit] -zh-cn/application-dev/ai/MindSpore-Lite-Kit-Introduction.md @ge-yafang @principal87 @limingjiang -zh-cn/application-dev/ai/ai-overview.md @ge-yafang @principal87 @limingjiang -zh-cn/application-dev/ai/mindspore-guidelines-based-js.md @ge-yafang @principal87 @jianghui58 @limingjiang -zh-cn/application-dev/ai/mindspore-guidelines-based-native.md @ge-yafang @principal87 @jianghui58 @limingjiang -zh-cn/application-dev/ai/mindspore-lite-guidelines.md @ge-yafang @principal87 @jianghui58 @limingjiang -zh-cn/application-dev/ai/mindspore-lite-js-guidelines.md @ge-yafang @principal87 @jianghui58 @limingjiang -zh-cn/application-dev/ai/mindspore-lite-offline-model-guidelines.md @ge-yafang @principal87 @jianghui58 @limingjiang - - -[开发-Multimodal Awareness Kit] -zh-cn/application-dev/kit-readme/Readme-MultimodalAwareness-Kit.md @mayunteng_1 @nezha-father @cococoler @alien0208 -zh-cn/application-dev/device/multimodalawareness-kit-intro.md @mayunteng_1 @nezha-father @cococoler @alien0208 -zh-cn/application-dev/device/stationary-guidelines.md @mayunteng_1 @nezha-father @cococoler @alien0208 - - -[开发-Network Kit] -zh-cn/application-dev/network/ @zhang_yixin13 @jiayanhong-hw @w30013702 @rain_myf - - -[开发-Neural NetWork Runtime Kit] -zh-cn/application-dev/napi/neural-network-runtime-guidelines.md @ge-yafang @principal87 @win10wei - - -[开发-NDK] -zh-cn/application-dev/napi/ @foryourself -zh-cn/application-dev/napi/rawfile-guidelines.md @ningningW @Buda-Liu @budda-wang @yangqing3 -zh-cn/application-dev/napi/usb-ddk-guidelines.md @li-yan339 @Kevin-Lau @liuhonggang123 - - -[开发-Notification Kit] -zh-cn/application-dev/notification/ @huipeizi @idanny @event_notification -zh-cn/application-dev/reference/apis-notification-kit/ @huipeizi @idanny @event_notification - - -[开发-Performance] -zh-cn/application-dev/performance/ @huipeizi -zh-cn/application-dev/performance/reduce-package-size.md @huipeizi @changzheng6 @hou-xiangyu1029 @kongjing2 - - -[开发-Security] -zh-cn/application-dev/security/ @zengyawen - - -[开发-Sensor Service Kit] -zh-cn/application-dev/device/sensor-overview.md @nezha-father @lixiangpeng221 @butterls @star-wind-snow-and-rain @lixiangpeng221 -zh-cn/application-dev/device/sensor-guidelines.md @nezha-father @lixiangpeng221 @butterls @star-wind-snow-and-rain -zh-cn/application-dev/device/sensorservice-kit-intro.md @nezha-father @lixiangpeng221 @butterls @star-wind-snow-and-rain -zh-cn/application-dev/device/vibrator-overview.md @nezha-father @lixiangpeng221 @butterls @star-wind-snow-and-rain -zh-cn/application-dev/device/vibrator-guidelines.md @nezha-father @lixiangpeng221 @butterls @star-wind-snow-and-rain -zh-cn/device-dev/subsystems/subsys-sensor-overview.md @nezha-father @lixiangpeng221 @butterls @star-wind-snow-and-rain -zh-cn/application-dev/kit-readme/Readme-Sensor-Service-Kit.md @nezha-father @lixiangpeng221 @butterls @star-wind-snow-and-rain -zh-cn/application-dev/kit-readme/Readme-Sensor-Service-Kit-as.md @nezha-father @lixiangpeng221 @butterls @star-wind-snow-and-rain -zh-cn/application-dev/device/sensor/sensor-overview-as.md @nezha-father @lixiangpeng221 @butterls @star-wind-snow-and-rain -zh-cn/application-dev/device/sensor/vibrator-guidelines-as.md @nezha-father @lixiangpeng221 @butterls @star-wind-snow-and-rain -zh-cn/application-dev/device/sensor/sensor-guidelines-as.md @nezha-father @lixiangpeng221 @butterls @star-wind-snow-and-rain - - -[开发-Telephony Kit] -zh-cn/application-dev/telephony/telephony-overview.md @zhang_yixin13 @jiayanhong-hw @w30013702 @dingxiaochen -zh-cn/application-dev/telephony/telephony-call.md @zhang_yixin13 @jiayanhong-hw @w30013702 @dingxiaochen -zh-cn/application-dev/telephony/telephony-sms.md @zhang_yixin13 @jiayanhong-hw @w30013702 @dingxiaochen - - -[开发-Test Kit] -zh-cn/application-dev/application-test/arkxtest-guidelines.md @ningningW @inter515 -zh-cn/application-dev/application-test/smartperf-guidelines.md @ningningW @niuguoliang @xielinnan -zh-cn/application-dev/application-test/wukong-guidelines.md @ningningW - -[开发-Webgl] -zh-cn/application-dev/webgl/ @ge-yafang @zhangqiang183 @wind_zj @zxg-gitee - -[开发-一多] -zh-cn/application-dev/key-features/multi-device-app-dev/ @HelloCrease @uhamc - -[开发-其他] -zh-cn/application-dev/device-usage-statistics/ @chenmingJay @ningningW @tangtiantian2021 @nan-xiansen @iceice1001 -zh-cn/application-dev/device/sample-server-overview.md @hu-zhiqiong @hughes802 @zhangzhengxue @mamba-ting -zh-cn/application-dev/device/sample-server-guidelines.md @hu-zhiqiong @hughes802 @zhangzhengxue @mamba-ting - - -[API参考-公共] -zh-cn/application-dev/reference/common/js-apis-logs.md @gongjunsong @ge-yafang @flyingwolf @blackstone-oh - - -[API参考-Ability Kit-元能力] -zh-cn/application-dev/reference/apis-ability-kit/js-apis-ability*.md @huipeizi @ccllee @lxfycode @lixueqing513 -zh-cn/application-dev/reference/apis-ability-kit/js-apis-application*.md @huipeizi @ccllee @lxfycode @lixueqing513 -zh-cn/application-dev/reference/apis-ability-kit/js-apis-app-*.md @huipeizi @ccllee @lxfycode @lixueqing513 -zh-cn/application-dev/reference/apis-ability-kit/js-apis-businessAbilityRouter.md @huipeizi @ccllee @lxfycode @lixueqing513 -zh-cn/application-dev/reference/apis-ability-kit/js-apis-continuation*.md @huipeizi @ccllee @lxfycode @lixueqing513 -zh-cn/application-dev/reference/apis-ability-kit/js-apis-inner-ability*.md @huipeizi @ccllee @lxfycode @lixueqing513 -zh-cn/application-dev/reference/apis-ability-kit/js-apis-inner-app*.md @huipeizi @ccllee @lxfycode @lixueqing513 -zh-cn/application-dev/reference/apis-ability-kit/js-apis-inner-wantAgent*.md @huipeizi @li-weifeng2 @lxfycode @lixueqing513 -zh-cn/application-dev/reference/apis-ability-kit/js-apis-uripermissionmanager.md @huipeizi @ccllee @lxfycode @lixueqing513 -zh-cn/application-dev/reference/apis-ability-kit/js-apis-wantAgent.md @huipeizi @li-weifeng2 @lxfycode @lixueqing513 -zh-cn/application-dev/reference/apis-ability-kit/errorcode-ability.md @huipeizi @ccllee @lxfycode @lixueqing513 -zh-cn/application-dev/reference/apis-ability-kit/errorcode-DistributedSchedule.md @huipeizi @ccllee @lxfycode @lixueqing513 - - - -[API参考-Ability Kit-包管理] -zh-cn/application-dev/reference/apis-ability-kit/js-apis-bundle*.md @nezha-father @changzheng6 @hou-xiangyu1029 @kongjing2 -zh-cn/application-dev/reference/apis-ability-kit/js-apis-appControl.md @nezha-father @changzheng6 @hou-xiangyu1029 @kongjing2 -zh-cn/application-dev/reference/apis-ability-kit/js-apis-defaultAppManager.md @nezha-father @changzheng6 @hou-xiangyu1029 @kongjing2 -zh-cn/application-dev/reference/apis-ability-kit/js-apis-distributedBundleManager.md @nezha-father @changzheng6 @hou-xiangyu1029 @kongjing2 -zh-cn/application-dev/reference/apis-ability-kit/js-apis-freeInstall.md @nezha-father @changzheng6 @hou-xiangyu1029 @kongjing2 -zh-cn/application-dev/reference/apis-ability-kit/js-apis-installer.md @nezha-father @changzheng6 @hou-xiangyu1029 @kongjing2 -zh-cn/application-dev/reference/apis-ability-kit/js-apis-launcherBundleManager.md @nezha-father @changzheng6 @hou-xiangyu1029 @kongjing2 -zh-cn/application-dev/reference/apis-ability-kit/js-apis-overlay.md @nezha-father @changzheng6 @hou-xiangyu1029 @kongjing2 -zh-cn/application-dev/reference/apis-ability-kit/js-apis-zlib.md @nezha-father @changzheng6 @hou-xiangyu1029 @kongjing2 -zh-cn/application-dev/reference/apis-ability-kit/errorcode-bundle.md @nezha-father @changzheng6 @hou-xiangyu1029 @kongjing2 -zh-cn/application-dev/reference/apis-ability-kit/errorcode-zlib.md @nezha-father @changzheng6 @hou-xiangyu1029 @kongjing2 - -[API参考-Ability Kit-分布式] -zh-cn/application-dev/reference/apis-ability-kit/js-apis-distributedMissionManager.md @chenmingJay @ningningW @nan-xiansen @iceice1001 - - -[API参考-Accessibility kit] -zh-cn/application-dev/reference/apis-accessibility-kit/js-apis-accessibility.md @mupceet @RayShih @mupceet @gaoxi785 @li-yan339 -zh-cn/application-dev/reference/apis-accessibility-kit/js-apis-accessibility-GesturePath.md @mupceet @RayShih @mupceet @gaoxi785 @li-yan339 -zh-cn/application-dev/reference/apis-accessibility-kit/js-apis-application-accessibilityExtensionAbility.md @mupceet @RayShih @mupceet @chengxingzhen @li-yan339 -zh-cn/application-dev/reference/apis-accessibility-kit/js-apis-inner-application-accessibilityExtensionContext.md @mupceet @RayShih @mupceet @chengxingzhen @li-yan339 -zh-cn/application-dev/reference/apis-accessibility-kit/js-apis-accessibility-config-sys.md @mupceet @RayShih @mupceet @gaoxi785 @li-yan339 -zh-cn/application-dev/reference/apis-accessibility-kit/errorcode-accessibility.md @RayShih @li-yan339 - - -[API参考-ArkGraphics2D] -zh-cn/application-dev/reference/apis-arkgraphics2d @zhangqiang183 @ge-yafang @liuchao92 @zxg-gitee @nobuggers @sqwlly @wind-zj -zh-cn/application-dev/reference/apis-arkgraphics2d/errorcode-colorspace-manager.md @zhangqiang183 @ge-yafang @liuchao92 @zxg-gitee -zh-cn/application-dev/reference/apis-arkgraphics2d/js-apis-colorSpaceManager.md @zhangqiang183 @ge-yafang @liuchao92 @zxg-gitee -zh-cn/application-dev/reference/apis-arkgraphics2d/js-apis-sendableColorSpaceManager.md @ge-yafang @liuchao92 @zxg-gitee -zh-cn/application-dev/reference/apis-arkgraphics2d/js-apis-effectKit.md @zhangqiang183 @wyl @ge-yafang @liuchao92 @zxg-gitee -zh-cn/application-dev/reference/apis-arkgraphics2d/js-apis-graphics-common2D.md @ge-yafang @zxg-gitee @nobuggers @sqwlly -zh-cn/application-dev/reference/apis-arkgraphics2d/js-apis-graphics-displaySync.md @ge-yafang @zxg-gitee @nobuggers @wind-zj -zh-cn/application-dev/reference/apis-arkgraphics2d/js-apis-graphics-drawing.md @ge-yafang @sqwlly @zxg-gitee @nobuggers -zh-cn/application-dev/reference/apis-arkgraphics2d/js-apis-graphics-text.md @ge-yafang @sqwlly @zxg-gitee @nobuggers -zh-cn/application-dev/reference/apis-arkgraphics2d/js-apis-uiEffect.md @ge-yafang @sqwlly @zxg-gitee @nobuggers -zh-cn/application-dev/reference/apis-arkgraphics2d/js-apis-uiEffect-sys.md @ge-yafang @sqwlly @zxg-gitee @nobuggers -zh-cn/application-dev/reference/apis-arkgraphics2d/js-apis-hdrCapability.md @ge-yafang @zxg-gitee @nobuggers @wind-zj -zh-cn/application-dev/reference/apis-arkgraphics2d/_drawing.md @zhangqiang183 @ge-yafang @liuchao92 @zxg-gitee @sqwlly @nobuggers -zh-cn/application-dev/reference/apis-arkgraphics2d/_native_display_soloist.md -zh-cn/application-dev/reference/apis-arkgraphics2d/_native_vsync.md @zhangqiang183 @ge-yafang @liuchao92 @zxg-gitee @nobuggers -zh-cn/application-dev/reference/apis-arkgraphics2d/_native_image.md @zhangqiang183 @ge-yafang @liuchao92 @zxg-gitee @nobuggers -zh-cn/application-dev/reference/apis-arkgraphics2d/_o_h___native_buffer.md @zhangqiang183 @ge-yafang @liuchao92 @zxg-gitee @nobuggers -zh-cn/application-dev/reference/apis-arkgraphics2d/effect_kit.md @zhangqiang183 @ge-yafang @liuchao92 @zxg-gitee @nobuggers -zh-cn/application-dev/reference/apis-arkgraphics2d/_native_window @zhangqiang183 @ge-yafang @liuchao92 @zxg-gitee @nobuggers - -[API参考-ArkGraphics3D] -zh-cn/application-dev/reference/apis-arkgraphics3d @zhangqiang183 @ge-yafang @zxg-gitee @nobuggers @sqwlly @wind-zj - -[API参考-ArkTS] -zh-cn/application-dev/reference/apis-arkts @ge-yafang @gongjunsong @blackstone-oh @weng-changcheng @yingguofeng -zh-cn/application-dev/reference/apis-arkts/errorcode-utils.md @ge-yafang @gongjunsong @blackstone-oh @weng-changcheng @yingguofeng -zh-cn/application-dev/reference/apis-arkts/js-apis-arraylist.md @gongjunsong @ge-yafang @flyingwolf @blackstone-oh @yingguofeng -zh-cn/application-dev/reference/apis-arkts/js-apis-treemap.md @gongjunsong @ge-yafang @flyingwolf @blackstone-oh @yingguofeng -zh-cn/application-dev/reference/apis-arkts/js-apis-treeset.md @gongjunsong @ge-yafang @flyingwolf @blackstone-oh @yingguofeng -zh-cn/application-dev/reference/apis-arkts/js-apis-stack.md @gongjunsong @ge-yafang @flyingwolf @blackstone-oh @yingguofeng -zh-cn/application-dev/reference/apis-arkts/js-apis-buffer.md @gongjunsong @ge-yafang @flyingwolf @blackstone-oh @yingguofeng -zh-cn/application-dev/reference/apis-arkts/js-apis-convertxml.md @gongjunsong @ge-yafang @flyingwolf @blackstone-oh @yingguofeng -zh-cn/application-dev/reference/apis-arkts/js-apis-deque.md @gongjunsong @ge-yafang @flyingwolf @blackstone-oh @yingguofeng -zh-cn/application-dev/reference/apis-arkts/js-apis-hashmap.md @gongjunsong @ge-yafang @flyingwolf @blackstone-oh @yingguofeng -zh-cn/application-dev/reference/apis-arkts/js-apis-hashset.md @gongjunsong @ge-yafang @flyingwolf @blackstone-oh @yingguofeng -zh-cn/application-dev/reference/apis-arkts/js-apis-lightweightmap.md @gongjunsong @ge-yafang @flyingwolf @blackstone-oh @yingguofeng -zh-cn/application-dev/reference/apis-arkts/js-apis-lightweightset.md @gongjunsong @ge-yafang @flyingwolf @blackstone-oh @yingguofeng -zh-cn/application-dev/reference/apis-arkts/js-apis-linkedlist.md @gongjunsong @ge-yafang @flyingwolf @blackstone-oh @yingguofeng -zh-cn/application-dev/reference/apis-arkts/js-apis-list.md @gongjunsong @ge-yafang @flyingwolf @blackstone-oh @yingguofeng -zh-cn/application-dev/reference/apis-arkts/js-apis-logs.md @gongjunsong @ge-yafang @flyingwolf @blackstone-oh @yingguofeng -zh-cn/application-dev/reference/apis-arkts/js-apis-plainarray.md @gongjunsong @ge-yafang @flyingwolf @blackstone-oh @yingguofeng -zh-cn/application-dev/reference/apis-arkts/js-apis-process.md @gongjunsong @ge-yafang @flyingwolf @blackstone-oh @yingguofeng -zh-cn/application-dev/reference/apis-arkts/js-apis-queue.md @gongjunsong @ge-yafang @flyingwolf @blackstone-oh @yingguofeng -zh-cn/application-dev/reference/apis-arkts/js-apis-uri.md @gongjunsong @ge-yafang @flyingwolf @blackstone-oh @yingguofeng -zh-cn/application-dev/reference/apis-arkts/js-apis-url.md @gongjunsong @ge-yafang @flyingwolf @blackstone-oh @yingguofeng -zh-cn/application-dev/reference/apis-arkts/js-apis-util.md @gongjunsong @ge-yafang @flyingwolf @blackstone-oh @yingguofeng -zh-cn/application-dev/reference/apis-arkts/js-apis-vector.md @gongjunsong @ge-yafang @flyingwolf @blackstone-oh @yingguofeng -zh-cn/application-dev/reference/apis-arkts/js-apis-xml.md @gongjunsong @ge-yafang @flyingwolf@blackstone-oh @yingguofeng -zh-cn/application-dev/reference/apis-arkts/js-apis-worker.md @gongjunsong @ge-yafang @flyingwolf @weng-changcheng @blackstone-oh -zh-cn/application-dev/reference/apis-arkts/js-apis-taskpool.md @gongjunsong @ge-yafang @flyingwolf @weng-changcheng @blackstone-oh - - - -[API参考-ArkData] -zh-cn/application-dev/reference/apis-arkdata @feng-aiwen @ge-yafang @gong-a-shi @logic42 @widecode -zh-cn/application-dev/reference/apis-arkdata/js-apis-data-commonType.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 @widecode -zh-cn/application-dev/reference/apis-arkdata/js-apis-data-ability.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 @widecode -zh-cn/application-dev/reference/apis-arkdata/js-apis-data-dataSharePredicates.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 @widecode -zh-cn/application-dev/reference/apis-arkdata/js-apis-data-distributedobject.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 @widecode -zh-cn/application-dev/reference/apis-arkdata/js-apis-distributedKVStore.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 @liuwenhui_ddmp @widecode -zh-cn/application-dev/reference/apis-arkdata/js-apis-data-preferences.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 @widecode -zh-cn/application-dev/reference/apis-arkdata/js-apis-data-relationalStore.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 @widecode -zh-cn/application-dev/reference/apis-arkdata/js-apis-data-unifiedDataChannel.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 @widecode @dboy190 -zh-cn/application-dev/reference/apis-arkdata/js-apis-data-uniformTypeDescriptor.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 @widecode @dboy190 -zh-cn/application-dev/reference/apis-arkdata/js-apis-data-ValuesBucket.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 @widecode -zh-cn/application-dev/reference/apis-arkdata/js-apis-application-DataShareExtensionAbility-sys.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 @widecode -zh-cn/application-dev/reference/apis-arkdata/js-apis-data-cloudData-sys.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 @widecode -zh-cn/application-dev/reference/apis-arkdata/js-apis-data-cloudExtension-sys.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 @widecode -zh-cn/application-dev/reference/apis-arkdata/js-apis-data-dataShare-sys.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 @widecode -zh-cn/application-dev/reference/apis-arkdata/js-apis-data-dataSharePredicates-sys.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 @widecode -zh-cn/application-dev/reference/apis-arkdata/js-apis-data-DataShareResultSet-sys.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 @widecode -zh-cn/application-dev/reference/apis-arkdata/js-apis-distributedKVStore-sys.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 @liuwenhui_ddmp @widecode -zh-cn/application-dev/reference/apis-arkdata/js-apis-data-relationalStore-sys.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 @widecode -zh-cn/application-dev/reference/apis-arkdata/js-apis-distributed-data.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 @widecode -zh-cn/application-dev/reference/apis-arkdata/js-apis-data-rdb.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 @widecode -zh-cn/application-dev/reference/apis-arkdata/js-apis-data-storage.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 @widecode -zh-cn/application-dev/reference/apis-arkdata/js-apis-system-storage.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 @widecode -zh-cn/application-dev/reference/apis-arkdata/js-apis-data-resultset.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 @widecode -zh-cn/application-dev/reference/apis-arkdata/_data.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 @widecode -zh-cn/application-dev/reference/apis-arkdata/_r_d_b.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 @widecode -zh-cn/application-dev/reference/apis-arkdata/errorcode-preferences.md @ge-yafang @feng-aiwen @gong-a-shi @logic42 -zh-cn/application-dev/reference/apis-arkdata/errorcode-distributed-dataObject.md @ge-yafang @feng-aiwen @gong-a-shi @logic42 -zh-cn/application-dev/reference/apis-arkdata/errorcode-distributedKVStore.md @ge-yafang @feng-aiwen @gong-a-shi @logic42 @liuwenhui_ddmp @widecode -zh-cn/application-dev/reference/apis-arkdata/errorcode-data-rdb.md @ge-yafang @feng-aiwen @gong-a-shi @logic42 -zh-cn/application-dev/reference/apis-arkdata/errorcode-datashare.md @ge-yafang @feng-aiwen @gong-a-shi @logic42 - - -[API参考-ArkUI-JS] -zh-cn/application-dev/reference/apis-arkui/js-service-widget-ui/ @HelloCrease - -[API参考-ArkUI-TS组件] -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-events-click.md @jiangtao92 @zhaojian2021 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-events-touch.md @jiangtao92 @zhaojian2021 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-events-show-hide.md @jiangtao92 @sunfei2021 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-events-drag-drop.md @jiangtao92 @piggyguy @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-events-key.md @jiangtao92 @benb365 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-focus-event.md @jiangtao92 @benb365 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-mouse-key.md @jiangtao92 @zhaojian2021 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-component-area-change-event.md @jiangtao92 @sunfei2021 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-component-visible-area-change-event.md @jiangtao92 @sunfei2021 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-events-keyboardshortcut.md @jiangtao92 @benb365 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-on-child-touch-test.md @jiangtao92 @piggyguy @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-size.md @laigerendaqiu @crazyracing0726 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-location.md @laigerendaqiu @crazyracing0726 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-layout-constraints.md @laigerendaqiu @crazyracing0726 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-flex-layout.md @laigerendaqiu @crazyracing0726 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-border.md @laigerendaqiu @crazyracing0726 @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-border-image.md @crazyracing0726 @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-background.md @jiangtao92 @sunfei2021 @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-opacity.md @lightningHo @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-visibility.md @jiangtao92 @sunfei2021 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-enable.md @jiangtao92 @zhaojian2021 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-overlay.md @jiangtao92 @benb365 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-z-order.md @jiangtao92 @sunfei2021 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-transformation.md @lightningHo @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-image-effect.md @lightningHo @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-sharp-clipping.md @lightningHo @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-grid.md @laigerendaqiu @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-gradient-color.md @lightningHo @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-popup.md @zhangfanfan2 @zhanghaibo0 @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-menu.md @zhangfanfan2 @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-focus.md @benb365 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-hover-effect.md @jiangtao92 @zhaojian2021 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-component-id.md @jiangtao92 @sunfei2021 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-polymorphic-style.md @jiangtao92 @piggyguy @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-restoreId.md @jiangtao92 @sunfei2021 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-foreground-color.md @lightningHo @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-foreground-blur-style.md @lightningHo @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-click-effect.md @lightningHo @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-accessibility.md @lmleon @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-attribute-modifier.md @jiangtao92 @sunfei2021 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-outline.md @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-touch-target.md @jiangtao92 @zhaojian2021 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-hit-test-behavior.md @jiangtao92 @zhaojian2021 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-modal-transition.md @raulnaruto_admin @cheng-feiwang @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-sheet-transition.md @raulnaruto_admin @cheng-feiwang @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-obscured.md @jiangtao92 @sunfei2021 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-text-style.md @jyj-0306 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-drag-drop.md @jiangtao92 @piggyguy @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-expand-safe-area.md @laigerendaqiu @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-renderfit.md @lightningHo @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-monopolize-events.md @zhaojian2021 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-cursor.md @zhaojian2021 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-use-effect-sys.md @lightningHo @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-image-effect-sys.md @lightningHo @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-background-sys.md @lightningHo @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-foreground-blur-style-sys.md @lightningHo @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-gesture-settings.md @jiangtao92 @zhaojian2021 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-gestures-tapgesture.md @jiangtao92 @zhaojian2021 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-gestures-longpressgesture.md @jiangtao92 @zhaojian2021 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-gestures-pangesture.md @jiangtao92 @zhaojian2021 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-gestures-pinchgesture.md @jiangtao92 @zhaojian2021 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-gestures-rotationgesture.md @jiangtao92 @zhaojian2021 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-gestures-swipegesture.md @jiangtao92 @zhaojian2021 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-combined-gestures.md @jiangtao92 @zhaojian2021 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-gesture-customize-judge.md @jiangtao92 @zhaojian2021 @tomatodevboy @HelloCrease - -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-container-alphabet-indexer.md @cc520bf @yeyinglong_admin @lihaoyn @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-blank.md @laigerendaqiu @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-button.md @zhangfanfan2 @youzhi92 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-calendarpicker.md @zhangfanfan2 @youzhi92 @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-checkbox.md @zhangfanfan2 @youzhi92 @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-checkboxgroup.md @zhangfanfan2 @youzhi92 @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-containerspan.md @jyj-0306 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-datapanel.md @lihaoyn @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-datepicker.md @zhangfanfan2 @youzhi92 @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-divider.md @laigerendaqiu @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-gauge.md @ileft201 @lihaoyn @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-image.md @crazyracing0726 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-imageanimator.md @crazyracing0726 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-imagespan.md @jyj-0306 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-loadingprogress.md @ileft201 @lihaoyn @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-marquee.md @jyj-0306 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-menu.md @zhangfanfan2 @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-menuitem.md @zhangfanfan2 @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-menuitemgroup.md @zhangfanfan2 @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md @raulnaruto_admin @jiangdayuan @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-navrouter.md @raulnaruto_admin @jiangdayuan @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-navdestination.md @raulnaruto_admin @jiangdayuan @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-nodecontainer.md @sunfei2021 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-patternlock.md @ileft201 @lihaoyn @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-progress.md @ileft201 @lihaoyn @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-qrcode.md @ileft201 @lihaoyn @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-radio.md @zhangfanfan2 @youzhi92 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-rating.md @zhangfanfan2 @youzhi92 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md @vviinnoo24 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-richtext.md @bigpumpkin @HelloCrease @litao33 @zhang-xinyue15 -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-scrollbar.md @cc520bf @yeyinglong_admin @lihaoyn @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-search.md @jyj-0306 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-select.md @zhangfanfan2 @youzhi92 @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-slider.md @zhangfanfan2 @youzhi92 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-span.md @jyj-0306 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-stepper.md @raulnaruto_admin @jiangdayuan @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-stepperitem.md @raulnaruto_admin @jiangdayuan @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-symbolSpan.md @jyj-0306 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-symbolGlyph.md @jyj-0306 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-text.md @jyj-0306 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-textarea.md @jyj-0306 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-textclock.md @ileft201 @lihaoyn @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-textinput.md @jyj-0306 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-textpicker.md @zhangfanfan2 @youzhi92 @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-texttimer.md @ileft201 @lihaoyn @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-timepicker.md @zhangfanfan2 @youzhi92 @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-toggle.md @zhangfanfan2 @youzhi92 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-xcomponent.md @laigerendaqiu @keerecles @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-component3d-sys.md @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-formcomponent-sys.md @arondave @hehe9876 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-image-sys.md @crazyracing0726 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-plugincomponent-sys.md @lmleon @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-remotewindow-sys.md @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-textinput-sys.md @jyj-0306 @tomatodevboy @HelloCrease - -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-container-badge.md @ileft20 @lihaoyn @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-container-column.md @laigerendaqiu @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-container-columnsplit.md @laigerendaqiu @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-container-counter.md @ileft20 @lihaoyn @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-container-flex.md @laigerendaqiu @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-container-flowitem.md @cc520bf @zcdqs @lihaoyn @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-container-folderstack.md @laigerendaqiu @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-container-formlink.md @arondave @hehe9876 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-container-gridcol.md @laigerendaqiu @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-container-gridrow.md @laigerendaqiu @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-container-grid.md @cc520bf @zcdqs @lihaoyn @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-container-griditem.md @cc520bf @zcdqs @lihaoyn @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-container-hyperlink.md @jyj-0306 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-container-list.md @cc520bf @yeyinglong_admin @lihaoyn @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-container-listitem.md @cc520bf @yeyinglong_admin @lihaoyn @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-container-listitemgroup.md @cc520bf @yeyinglong_admin @lihaoyn @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-container-navigator.md @raulnaruto_admin @jiangdayuan @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-container-panel.md @raulnaruto_admin @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-container-refresh.md @cc520bf @yeyinglong_admin @lihaoyn @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-container-relativecontainer.md @laigerendaqiu @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-container-row.md @laigerendaqiu @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-container-rowsplit.md @laigerendaqiu @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-container-scroll.md @cc520bf @yeyinglong_admin @lihaoyn @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-container-sidebarcontainer.md @raulnaruto_admin @jiangdayuan @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-container-stack.md @laigerendaqiu @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-container-swiper.md @cc520bf @zcdqs @lihaoyn @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-container-tabs.md @cc520bf @zcdqs @lihaoyn @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-container-tabcontent.md @cc520bf @zcdqs @lihaoyn @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-container-waterflow.md @cc520bf @zcdqs @lihaoyn @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-container-effectcomponent-sys.md @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-container-list-sys.md @cc520bf @yeyinglong_admin @lihaoyn @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-container-ui-extension-component-sys.md @dutie123 @tomatodevboy @HelloCrease - -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-media-components-video.md @laigerendaqiu @keerecles @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-drawing-components-circle.md @laigerendaqiu @keerecles @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-drawing-components-ellipse.md @laigerendaqiu @keerecles @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-drawing-components-line.md @laigerendaqiu @keerecles @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-drawing-components-polyline.md @laigerendaqiu @keerecles @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-drawing-components-polygon.md @laigerendaqiu @keerecles @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-drawing-components-path.md @laigerendaqiu @keerecles @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-drawing-components-rect.md @laigerendaqiu @keerecles @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-drawing-components-shape.md @laigerendaqiu @keerecles @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-components-canvas-canvas.md @laigerendaqiu @keerecles @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-components-canvas-canvasgradient.md @laigerendaqiu @keerecles @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-components-canvas-canvaspattern.md @laigerendaqiu @keerecles @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-canvasrenderingcontext2d.md @laigerendaqiu @keerecles @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-components-canvas-imagebitmap.md @laigerendaqiu @keerecles @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-components-canvas-imagedata.md @laigerendaqiu @keerecles @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-components-canvas-matrix2d.md @laigerendaqiu @keerecles @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-components-offscreencanvas.md @laigerendaqiu @keerecles @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-offscreencanvasrenderingcontext2d.md @laigerendaqiu @keerecles @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-components-canvas-path2d.md @laigerendaqiu @keerecles @tomatodevboy @HelloCrease - -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ohos-arkui-advanced-Chip.md @youzhi92 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ohos-arkui-advanced-ComposeListItem.md @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ohos-arkui-advanced-ComposeTitleBar.md @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ohos-arkui-advanced-Counter.md @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ohos-arkui-advanced-Dialog.md @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ohos-arkui-advanced-EditableTitleBar.md @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ohos-arkui-advanced-ExceptionPrompt.md @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ohos-arkui-advanced-Filter.md @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ohos-arkui-advanced-GridObjectSortComponent.md @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ohos-arkui-advanced-ProgressButton.md @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ohos-arkui-advanced-Popup.md @youzhi92 @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ohos-arkui-advanced-SegmentButton.md @youzhi92 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ohos-arkui-advanced-SelectionMenu.md @jyj-0306 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ohos-arkui-advanced-SelectTitleBar.md @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ohos-arkui-advanced-SplitLayout.md @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ohos-arkui-advanced-SubHeader.md @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ohos-arkui-advanced-SwipeRefresher.md @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ohos-arkui-advanced-TabTitleBar.md @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ohos-arkui-advanced-ToolBar.md @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ohos-arkui-advanced-TreeView.md @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ohos-arkui-advanced-FullScreenLaunchComponent.md @dutie123 @HelloCrease - -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-animatorproperty.md @lightningHo @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-explicit-animation.md @lightningHo @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-keyframeAnimateTo.md @lightningHo @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-page-transition-animation.md @lightningHo @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-transition-animation-component.md @lightningHo @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-transition-animation-shared-elements.md @lightningHo @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-transition-animation-geometrytransition.md @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-motion-path-animation.md @lightningHo @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-particle-animation.md @lightningHo @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-explicit-animatetoimmediately-sys.md @lightningHo @luyuxuan1 @HelloCrease - -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-methods-alert-dialog-box.md @zhangfanfan2 @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-methods-action-sheet.md @zhangfanfan2 @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-methods-custom-dialog-box.md @zhangfanfan2 @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-methods-calendarpicker-dialog.md @zhangfanfan2 @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-methods-datepicker-dialog.md @zhangfanfan2 @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-methods-timepicker-dialog.md @zhangfanfan2 @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-methods-textpicker-dialog.md @zhangfanfan2 @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-methods-menu.md @zhangfanfan2 @youzhi92 @luyuxuan1 @HelloCrease - -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-custom-component-lifecycle.md @seaside_wu @s10021109 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-custom-component-api.md @s10021109 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-state-management.md @seaside_wu @s10021109 @tomatodevboy @zhang_yixin13 -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-pixel-units.md @jiangtao92 @sunfei2021 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-appendix-enums.md @jiangtao92 @sunfei2021 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-types.md @jiangtao92 @sunfei2021 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-container-ability-component-sys.md @seaside_wu @keerecles @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-container-gridcontainer.md @crazyracing0726 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-click.md @jiangtao92 @zhaojian2021 @tomatodevboy @HelloCrease - -[API参考-ArkUI-ArkTS] -zh-cn/application-dev/reference/apis-arkui/js-apis-animator.md @lightningHo @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/js-apis-arkui-componentSnapshot.md @piggyguy @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/js-apis-arkui-componentUtils.md @piggyguy @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/js-apis-arkui-dragController.md @piggyguy @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/js-apis-arkui-drawableDescriptor.md @crazyracing0726 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/js-apis-arkui-inspector.md @HelloCrease -zh-cn/application-dev/reference/apis-arkui/js-apis-arkui-node.md @lightningHo @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/js-apis-arkui-observer.md @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/js-apis-arkui-UIContext.md @sunfei2021 @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/js-apis-curve.md @lightningHo @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/js-apis-font.md @HelloCrease -zh-cn/application-dev/reference/apis-arkui/js-apis-matrix4.md @lightningHo @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/js-apis-measure.md @jyj-0306 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/js-apis-mediaquery.md @laigerendaqiu @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/js-apis-plugincomponent.md @laigerendaqiu @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/js-apis-promptAction.md @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/js-apis-router.md @raulnaruto_admin @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/js-apis-getContext.md @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/js-apis-postCardAction.md @arondave @hehe9876 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/js-apis-arkui-drawableDescriptor-sys.md @crazyracing0726 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/js-apis-arkui-performancemonitor-sys.md @lushi1202 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/js-apis-devicestatus-draginteraction-sys.md @piggyguy @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/js-apis-plugincomponent-sys.md @seaside_wu @keerecles @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/js-apis-uiappearance-sys.md @lushi1202 @luyuxuan1 @HelloCrease -zh-cn/application-dev/reference/apis-arkui/js-apis-uiExtensionHost-sys.md @dutie123 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/js-apis-arkui-uiExtension.md @dutie123 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/js-apis-arkui-uiExtension-sys.md @dutie123 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/js-apis-arkui-builderNode.md @sunfei2021 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/js-apis-arkui-frameNode.md @sunfei2021 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/js-apis-arkui-graphics.md @sunfei2021 @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/js-apis-arkui-nodeController.md @lightningHo @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/js-apis-arkui-renderNode.md @lightningHo @tomatodevboy @HelloCrease -zh-cn/application-dev/reference/apis-arkui/js-apis-arkui-xcomponentNode.md @laigerendaqiu @sunfei2021 @tomatodevboy @HelloCrease - - -[API参考-ArkUI-Window] - -zh-cn/application-dev/reference/apis-arkui/js-apis-window.md @zhangqiang183 @ge-yafang @zhouyaoying @zxg-gitee @nobuggers @qinliwen -zh-cn/application-dev/reference/apis-arkui/js-apis-window-sys.md @zhangqiang183 @ge-yafang @zhouyaoying @zxg-gitee @nobuggers @qinliwen -zh-cn/application-dev/reference/apis-arkui/js-apis-display.md @hjoksky @achao @zhangqiang183 @ge-yafang @zhouyaoying @zxg-gitee @nobuggers @qinliwen -zh-cn/application-dev/reference/apis-arkui/js-apis-display-sys.md @hjoksky @achao @zhangqiang183 @ge-yafang @zhouyaoying @zxg-gitee @nobuggers @qinliwen -zh-cn/application-dev/reference/apis-arkui/js-apis-pipWindow.md @zhangqiang183 @ge-yafang @zhouyaoying @zxg-gitee @nobuggers @qinliwen -zh-cn/application-dev/reference/apis-arkui/js-apis-screen-sys.md @hjoksky @achao @zhangqiang183 @ge-yafang @zhouyaoying @zxg-gitee @nobuggers @qinliwen -zh-cn/application-dev/reference/apis-arkui/js-apis-screenshot-sys.md @hjoksky @achao @zhangqiang183 @ge-yafang @zhouyaoying @zxg-gitee @nobuggers @qinliwen -zh-cn/application-dev/reference/apis-arkui/js-apis-windowAnimationManager-sys.md @zhangqiang183 @ge-yafang @liuchao92 @zxg-gitee @qinliwen -zh-cn/application-dev/reference/apis-arkui/js-apis-application-WindowExtensionAbility-sys.md @zhangqiang183 @ge-yafang @zhouyaoying @zxg-gitee @nobuggers @qinliwen -zh-cn/application-dev/reference/apis-arkui/js-apis-inner-application-windowExtensionContext-sys.md @ge-yafang @zhouyaoying @zxg-gitee @nobuggers @qinliwen -zh-cn/application-dev/reference/apis-arkui/errorcode-window.md @ge-yafang @zhouyaoying @zxg-gitee @nobuggers @qinliwen -zh-cn/application-dev/reference/apis-arkui/errorcode-display.md @ge-yafang @achao @zhouyaoying @zxg-gitee @nobuggers @qinliwen - - - -[API参考-ArkWeb] -zh-cn/application-dev/reference/apis-arkweb/js-apis-webview.md @bigpumpkin @HelloCrease @litao33 @zhang-xinyue15 -zh-cn/application-dev/reference/apis-arkweb/ts-basic-components-web.md @bigpumpkin @HelloCrease @litao33 @zhang-xinyue15 -zh-cn/application-dev/reference/apis-arkweb/native_interface_arkweb.md @bigpumpkin @HelloCrease @litao33 @zhang-xinyue15 -zh-cn/application-dev/reference/apis-arkweb/errorcode-webview.md @bigpumpkin @HelloCrease @litao33 @zhang-xinyue15 - - -[API参考-Background Tasks Kit] -zh-cn/application-dev/reference/apis-backgroundtasks-kit/js-apis-reminderAgentManager.md @ningningW @yuanzhizhong @hmosdeveloper -zh-cn/application-dev/reference/apis-backgroundtasks-kit/js-apis-reminderAgentManager-sys.md @ningningW @yuanzhizhong @hmosdeveloper -zh-cn/application-dev/reference/apis-backgroundtasks-kit/js-apis-resourceschedule-backgroundTaskManager.md @ningningW @yuanzhizhong @hmosdeveloper -zh-cn/application-dev/reference/apis-backgroundtasks-kit/js-apis-resourceschedule-backgroundTaskManager-sys.md @ningningW @yuanzhizhong @hmosdeveloper -zh-cn/application-dev/reference/apis-backgroundtasks-kit/js-apis-resourceschedule-workScheduler.md @ningningW @yuanzhizhong @hmosdeveloper -zh-cn/application-dev/reference/apis-backgroundtasks-kit/js-apis-WorkSchedulerExtensionAbility.md @ningningW @yuanzhizhong @hmosdeveloper -zh-cn/application-dev/reference/apis-backgroundtasks-kit/js-apis-inner-application-WorkSchedulerExtensionContext.md @ningningW @yuanzhizhong @hmosdeveloper - -zh-cn/application-dev/reference/apis-backgroundtasks-kit/js-apis-resourceschedule-deviceStandby-sys.md @foolish-older-man @ningningW @yuanzhizhong -zh-cn/application-dev/reference/apis-backgroundtasks-kit/js-apis-resourceschedule-deviceUsageStatistics-sys.md @ningningW @yuanzhizhong @hmosdeveloper - -zh-cn/application-dev/reference/apis-backgroundtasks-kit/errorcode-backgroundTaskMgr.md @ningningW @yuanzhizhong @hmosdeveloper -zh-cn/application-dev/reference/apis-backgroundtasks-kit/errorcode-reminderAgentManager.md @ningningW @yuanzhizhong @hmosdeveloper -zh-cn/application-dev/reference/apis-backgroundtasks-kit/errorcode-workScheduler.md @ningningW @yuanzhizhong @hmosdeveloper -zh-cn/application-dev/reference/apis-backgroundtasks-kit/errorcode-DeviceUsageStatistics.md @ningningW @yuanzhizhong @hmosdeveloper - -[API参考-Basic Services Kit-配置策略] -zh-cn/application-dev/reference/apis-basic-services-kit/js-apis-configPolicy-sys.md @ningningW @yangqing3 @liubingbing - -[API参考-Basic Services Kit-帐号] -zh-cn/application-dev/reference/apis-basic-services-kit/js-apis-appAccount.md @zengyawen -zh-cn/application-dev/reference/apis-basic-services-kit/js-apis-distributed-account.md @zengyawen -zh-cn/application-dev/reference/apis-basic-services-kit/js-apis-osAccount.md @zengyawen -zh-cn/application-dev/reference/apis-basic-services-kit/js-apis-distributed-account-sys.md @zengyawen -zh-cn/application-dev/reference/apis-basic-services-kit/js-apis-osAccount-sys.md @zengyawen -zh-cn/application-dev/reference/apis-basic-services-kit/errorcode-account.md @zengyawen - -[API参考-Basic Services Kit-公共事件] -zh-cn/application-dev/reference/apis-basic-sevices-kit/js-apis-commonEvent*.md @huipeizi @idanny @event_notification -zh-cn/application-dev/reference/apis-basic-sevices-kit/js-apis-inner-commonEvent*.md @huipeizi @idanny @event_notification -zh-cn/application-dev/reference/apis-basic-sevices-kit/js-apis-emitter.md @huipeizi @idanny @event_notification -zh-cn/application-dev/reference/apis-basic-sevices-kit/common_event/commonEvent-definitions.md @huipeizi @idanny @event_notification -zh-cn/application-dev/reference/apis-basic-sevices-kit/common_event/commonEventManager-definitions.md @huipeizi @idanny @event_notification -zh-cn/application-dev/reference/apis-basic-sevices-kit/common_event/commonEvent-ability.md @huipeizi @idanny @event_notification -zh-cn/application-dev/reference/apis-basic-sevices-kit/common_event/commonEvent-bundleManager.md @huipeizi @idanny @event_notification -zh-cn/application-dev/reference/apis-basic-sevices-kit/errorcode-CommonEventService.md @huipeizi @idanny @event_notification - - -[API参考-Basic Services Kit-设备管理] -zh-cn/application-dev/reference/apis-basic-services-kit/js-apis-system-battery.md @li-yan339 @alien0208 -zh-cn/application-dev/reference/apis-basic-services-kit/js-apis-system-brightness.md @li-yan339 @alien0208 -zh-cn/application-dev/reference/apis-basic-services-kit/js-apis-battery-info.md @li-yan339 @alien0208 -zh-cn/application-dev/reference/apis-basic-services-kit/js-apis-power.md @li-yan339 @alien0208 -zh-cn/application-dev/reference/apis-basic-services-kit/js-apis-runninglock.md @li-yan339 @alien0208 -zh-cn/application-dev/reference/apis-basic-services-kit/js-apis-thermal.md @li-yan339 @alien0208 -zh-cn/application-dev/reference/apis-basic-services-kit/js-apis-usbManager.md @li-yan339 @Kevin-Lau @liuhonggang123 -zh-cn/application-dev/reference/apis-basic-services-kit/js-apis-usb*.md @li-yan339 @Kevin-Lau @liuhonggang123 -zh-cn/application-dev/reference/apis-basic-services-kit/js-apis-battery-info-sys.md @li-yan339 @alien0208 -zh-cn/application-dev/reference/apis-basic-services-kit/js-apis-batteryStatistics-sys.md @li-yan339 @alien0208 -zh-cn/application-dev/reference/apis-basic-services-kit/js-apis-brightness-sys.md @li-yan339 @alien0208 -zh-cn/application-dev/reference/apis-basic-services-kit/js-apis-charger-sys.md @li-yan339 @alien0208 -zh-cn/application-dev/reference/apis-basic-services-kit/js-apis-enterprise-usbManager-sys.md @liuzuming @ningningW @yangqing3 @caiminggang @li-yan339 -zh-cn/application-dev/reference/apis-basic-services-kit/js-apis-power-sys.md @li-yan339 @alien0208 -zh-cn/application-dev/reference/apis-basic-services-kit/js-apis-usbManager-sys.md @li-yan339 @Kevin-Lau @liuhonggang123 - -[API参考-Basic Services Kit-数据文件处理] -zh-cn/application-dev/reference/apis-basic-services-kit/js-apis-request-sys.md @liuqian677 @hanruofei @murphy1984 -zh-cn/application-dev/reference/apis-basic-services-kit/js-apis-request.md @liuqian677 @hanruofei @murphy1984 -zh-cn/application-dev/reference/apis-basic-services-kit/js-apis-system-request.md @liuqian677 @hanruofei @murphy1984 -zh-cn/application-dev/reference/apis-basic-services-kit/js-apis-update-sys.md @hughes802 @liuqian677 @zhangzhengxue @mamba-ting -zh-cn/application-dev/reference/apis-basic-services-kit/errorcode-request.md @liuqian677 @hanruofei @murphy1984 -zh-cn/application-dev/reference/apis-basic-services-kit/errorcode-update.md @hughes802 @liuqian677 @zhangzhengxue @mamba-ting - -[API参考-Basic Services Kit-时间时区、公共回调、系统设置] -zh-cn/application-dev/reference/common/js-apis-timer.md @liuqian677 @illybyy @murphy1984 @feng-aiwen @illybyy @murphy1984 -zh-cn/application-dev/reference/apis-basic-services-kit/commonEvent-screenlock.md @liuqian677 -zh-cn/application-dev/reference/apis-basic-services-kit/js-apis-system-timer-sys.md @liuqian677 @illybyy @murphy1984 @feng-aiwen @illybyy @murphy1984 -zh-cn/application-dev/reference/apis-basic-services-kit/js-apis-system-time.md @liuqian677 @illybyy @murphy1984 @feng-aiwen @illybyy @murphy1984 -zh-cn/application-dev/reference/apis-basic-services-kit/js-apis-system-date-time-sys.md @liuqian677 @illybyy @murphy1984 @feng-aiwen @illybyy @murphy1984 -zh-cn/application-dev/reference/apis-basic-services-kit/js-apis-nonsys-time.md @liuqian677 @illybyy @murphy1984 @feng-aiwen @illybyy @murphy1984 -zh-cn/application-dev/reference/apis-basic-services-kit/js-apis-nonsys-date-time.md @liuqian677 @illybyy @murphy1984 @feng-aiwen @illybyy @murphy1984 -zh-cn/application-dev/reference/apis-basic-services-kit/errorcode-time.md @liuqian677 @illybyy @murphy1984 @feng-aiwen @illybyy @murphy1984 -zh-cn/application-dev/reference/apis-basic-services-kit/js-apis-screen-lock-sys.md @liuqian677 @feng-aiwen @illybyy @murphy1984 @wangzhangjun -zh-cn/application-dev/reference/apis-basic-services-kit/js-apis-screen-lock.md @liuqian677 @feng-aiwen @illybyy @murphy1984 @wangzhangjun -zh-cn/application-dev/reference/apis-basic-services-kit/js-apis-wallpaper.md @liuqian677 @illybyy @murphy1984 @feng-aiwen @wangzhangjun -zh-cn/application-dev/reference/apis-basic-services-kit/js-apis-settings.md @xue-seu @liuqian677 -zh-cn/application-dev/reference/apis-basic-services-kit/js-apis-settings-sys.md @xue-seu @liuqian677 -zh-cn/application-dev/reference/apis-basic-services-kit/js-apis-wallpaper-sys.md @liuqian677 @illybyy @murphy1984 @feng-aiwen @wangzhangjun -zh-cn/application-dev/reference/apis-basic-services-kit/js-apis-WallpaperExtensionAbility-sys.md @liuqian677 @illybyy @murphy1984 @feng-aiwen @wangzhangjun -zh-cn/application-dev/reference/apis-basic-services-kit/errorcode-screenlock.md @liuqian677 @feng-aiwen @illybyy @murphy1984 @wangzhangjun -zh-cn/application-dev/reference/apis-basic-services-kit/js-apis-system-capability*.md @gongjunsong @ge-yafang @flyingwolf @blackstone-oh - -[API参考-Basic Services Kit-启动恢复] -zh-cn/application-dev/reference/apis-basic-services-kit/js-apis-system-parameterV9.md @mupceet @liuqian677 @handyohos @nan-xiansen -zh-cn/application-dev/reference/apis-basic-services-kit/js-apis-device-info.md @mupceet @liuqian677 @handyohos @smartltt - - -[API参考-CalendarManager Kit] -zh-cn/application-dev/reference/apis-calendar-kit/ @liuqian677 @jt_123456 @edollar - - -[API参考-Connectivity Kit-bluetooth] -zh-cn/application-dev/reference/apis-connectivity-kit/js-apis-bluetooth-a2dp.md @zhang_yixin13 @xujiang1981 @quanli125 -zh-cn/application-dev/reference/apis-connectivity-kit/js-apis-bluetooth-access.md @zhang_yixin13 @xujiang1981 @quanli125 -zh-cn/application-dev/reference/apis-connectivity-kit/js-apis-bluetooth-baseProfile.md @zhang_yixin13 @xujiang1981 @quanli125 -zh-cn/application-dev/reference/apis-connectivity-kit/js-apis-bluetooth-ble.md @zhang_yixin13 @xujiang1981 @quanli125 -zh-cn/application-dev/reference/apis-connectivity-kit/js-apis-bluetooth-connection.md @zhang_yixin13 @xujiang1981 @quanli125 -zh-cn/application-dev/reference/apis-connectivity-kit/js-apis-bluetooth-constant.md @zhang_yixin13 @xujiang1981 @quanli125 -zh-cn/application-dev/reference/apis-connectivity-kit/js-apis-bluetooth-hfp.md @zhang_yixin13 @xujiang1981 @quanli125 -zh-cn/application-dev/reference/apis-connectivity-kit/js-apis-bluetooth-hid.md @zhang_yixin13 @xujiang1981 @quanli125 -zh-cn/application-dev/reference/apis-connectivity-kit/js-apis-bluetooth-map.md @zhang_yixin13 @xujiang1981 @quanli125 -zh-cn/application-dev/reference/apis-connectivity-kit/js-apis-bluetooth-pan.md @zhang_yixin13 @xujiang1981 @quanli125 -zh-cn/application-dev/reference/apis-connectivity-kit/js-apis-bluetooth-pbap.md @zhang_yixin13 @xujiang1981 @quanli125 -zh-cn/application-dev/reference/apis-connectivity-kit/js-apis-bluetooth-socket.md @zhang_yixin13 @xujiang1981 @quanli125 -zh-cn/application-dev/reference/apis-connectivity-kit/js-apis-bluetoothManager.md @zhang_yixin13 @xujiang1981 @quanli125 -zh-cn/application-dev/reference/apis-connectivity-kit/js-apis-bluetooth-a2dp-sys.md @zhang_yixin13 @xujiang1981 @quanli125 -zh-cn/application-dev/reference/apis-connectivity-kit/js-apis-bluetooth-access-sys.md @zhang_yixin13 @xujiang1981 @quanli125 -zh-cn/application-dev/reference/apis-connectivity-kit/js-apis-bluetooth-baseProfile-sys.md @zhang_yixin13 @xujiang1981 @quanli125 -zh-cn/application-dev/reference/apis-connectivity-kit/js-apis-bluetooth-connection-sys.md @zhang_yixin13 @xujiang1981 @quanli125 -zh-cn/application-dev/reference/apis-connectivity-kit/js-apis-bluetooth-constant-sys.md @zhang_yixin13 @xujiang1981 @quanli125 -zh-cn/application-dev/reference/apis-connectivity-kit/js-apis-bluetooth-hfp-sys.md @zhang_yixin13 @xujiang1981 @quanli125 -zh-cn/application-dev/reference/apis-connectivity-kit/js-apis-bluetooth-hid-sys.md @zhang_yixin13 @xujiang1981 @quanli125 -zh-cn/application-dev/reference/apis-connectivity-kit/js-apis-bluetooth-pan-sys.md @zhang_yixin13 @xujiang1981 @quanli125 -zh-cn/application-dev/reference/apis-connectivity-kit/js-apis-bluetooth-pbap-sys.md @zhang_yixin13 @xujiang1981 @quanli125 -zh-cn/application-dev/reference/apis-connectivity-kit/js-apis-bluetooth-map-sys.md @zhang_yixin13 @xujiang1981 @quanli125 -zh-cn/application-dev/reference/apis-connectivity-kit/js-apis-bluetooth-wearDetection-sys.md @zhang_yixin13 @xujiang1981 @quanli125 -zh-cn/application-dev/reference/apis-connectivity-kit/js-apis-bluetoothManager-sys.md @zhang_yixin13 @xujiang1981 @quanli125 -zh-cn/application-dev/reference/apis-connectivity-kit/errorcode-bluetoothManager.md @zhang_yixin13 @xujiang1981 @quanli125 - -[API参考-Connectivity Kit-wifi] -zh-cn/application-dev/reference/apis-connectivity-kit/js-apis-wifi.md @legendtau @zhang_yixin13 @xiangkejin123 -zh-cn/application-dev/reference/apis-connectivity-kit/js-apis-wifiext.md @legendtau @zhang_yixin13 @xiangkejin123 -zh-cn/application-dev/reference/apis-connectivity-kit/js-apis-wifiManager.md @legendtau @zhang_yixin13 @xiangkejin123 -zh-cn/application-dev/reference/apis-connectivity-kit/js-apis-wifiManagerExt.md @legendtau @zhang_yixin13 @xiangkejin123 -zh-cn/application-dev/reference/apis-connectivity-kit/js-apis-wifiManager-sys.md @legendtau @zhang_yixin13 @xiangkejin123 -zh-cn/application-dev/reference/apis-connectivity-kit/errorcode-wifi.md @legendtau @zhang_yixin13 @xiangkejin123 - -[API参考-Connectivity Kit-nfc] -zh-cn/application-dev/reference/apis-connectivity-kit/js-apis-cardEmulation.md @knpingan @zhang_yixin13 @projectmanagement-zhang @heli_bbd -zh-cn/application-dev/reference/apis-connectivity-kit/js-apis-connectedTag.md @knpingan @zhang_yixin13 @projectmanagement-zhang @heli_bbd -zh-cn/application-dev/reference/apis-connectivity-kit/js-apis-tagSession.md @knpingan @zhang_yixin13 @projectmanagement-zhang @heli_bbd -zh-cn/application-dev/reference/apis-connectivity-kit/js-apis-nfctech.md @knpingan @zhang_yixin13 @projectmanagement-zhang @heli_bbd -zh-cn/application-dev/reference/apis-connectivity-kit/js-apis-secureElement.md @knpingan @zhang_yixin13 @projectmanagement-zhang @heli_bbd -zh-cn/application-dev/reference/apis-connectivity-kit/js-apis-nfcController.md @knpingan @zhang_yixin13 @projectmanagement-zhang @heli_bbd -zh-cn/application-dev/reference/apis-connectivity-kit/js-apis-nfcTag.md @knpingan @zhang_yixin13 @projectmanagement-zhang @heli_bbd -zh-cn/application-dev/reference/apis-connectivity-kit/js-apis-cardEmulation-sys.md @knpingan @zhang_yixin13 @projectmanagement-zhang @heli_bbd -zh-cn/application-dev/reference/apis-connectivity-kit/js-apis-nfcTag-sys.md @knpingan @zhang_yixin13 @projectmanagement-zhang @heli_bbd -zh-cn/application-dev/reference/apis-connectivity-kit/errorcode-nfc.md @knpingan @zhang_yixin13 @projectmanagement-zhang @heli_bbd -zh-cn/application-dev/reference/apis-connectivity-kit/errorcode-se.md @knpingan @zhang_yixin13 @projectmanagement-zhang @heli_bbd - - -[API参考-Contacts Kit] -zh-cn/application-dev/reference/apis-contacts-kit/ @zhang_yixin13 - - -[API参考-Core File Kit] -zh-cn/application-dev/reference/apis-core-file-kit/ @foryourself - - -[API参考-DFX] -zh-cn/application-dev/reference/apis-performance-analysis-kit/ @foryourself - - - -[API参考-Distributedservice Kit] -zh-cn/application-dev/reference/apis-distributedservice-kit/ @intermilano @william-ligang @liuhonggang123 @li-yan339 -zh-cn/application-dev/reference/apis-distributedservice-kit/js-apis-devicestatus-cooperate.md @mayunteng_1 @liuhaonan2 @hu-zhiqiong @cococoler @alien0208 - - -[API参考-Driverdevelopment kit] -zh-cn/application-dev/reference/apis-driverdevelopment-kit/ @li-yan339 - - -[API参考-Form Kit] -zh-cn/application-dev/reference/apis-form-kit/ @arondave @hehe9876 @nezha-fathe - - - -[API参考-IME kit] -zh-cn/application-dev/reference/apis-ime-kit/ @illybyy @murphy1984 @feng-aiwen @zhang_yixin13 @SuperShrimp @murphy1984 - - -[API参考-Input Kit] -zh-cn/application-dev/reference/apis-input-kit/ @hhh2 @ningningW @mayunteng @star-wind-snow-and-rain - - -[API参考-IPC Kit] -zh-cn/application-dev/reference/apis-ipc-kit/js-apis-rpc.md @luodh0157 @zhang_yixin13 @zhaopeng_gitee @zhang-yang123321 - -[API参考-Localization Kit] -zh-cn/application-dev/reference/apis-Localization-kit/js-apis-i18n.md @ningningW @yliupy @yangqing3 @sunyaozu -zh-cn/application-dev/reference/apis-Localization-kit/js-apis-intl.md @ningningW @yliupy @yangqing3 @sunyaozu -zh-cn/application-dev/reference/apis-Localization-kit/js-apis-i18n-sys.md @ningningW @yliupy @yangqing3 @sunyaozu -zh-cn/application-dev/reference/apis-Localization-kit/errorcode-i18n.md @ningningW @yliupy @yangqing3 @sunyaozu -zh-cn/application-dev/reference/apis-Localization-kit/js-apis-resource-manager.md @ningningW @budda-wang @yangqing3 -zh-cn/application-dev/reference/apis-Localization-kit/rawfile.md @ningningW @budda-wang @yangqing3 -zh-cn/application-dev/reference/apis-Localization-kit/raw__dir_8h.md @ningningW @budda-wang @yangqing3 -zh-cn/application-dev/reference/apis-Localization-kit/raw__file__manager_8h.md @ningningW @budda-wang @yangqing3 -zh-cn/application-dev/reference/apis-Localization-kit/raw__file_8h.md @ningningW @budda-wang @yangqing3 -zh-cn/application-dev/reference/apis-Localization-kit/_raw_file_descriptor.md @ningningW @budda-wang @yangqing3 -zh-cn/application-dev/reference/apis-Localization-kit/_raw_file_descriptor64.md @ningningW @budda-wang @yangqing3 -zh-cn/application-dev/reference/apis-Localization-kit/errorcode-resource-manager.md @ningningW @budda-wang @yangqing3 -zh-cn/application-dev/napi/rawfile-guidelines.md @ningningW @budda-wang @yangqing3 - -[API参考-Location Kit] -zh-cn/application-dev/reference/apis-location-kit/ @cheng_guohong @RayShih @cheng_guohong @xiangkejin123 - - -[API参考-Media] -zh-cn/application-dev/reference/apis-audio-kit/ @zengyawen -zh-cn/application-dev/reference/apis-avcodec-kit/ @zengyawen -zh-cn/application-dev/reference/apis-avsession-kit/ @zengyawen -zh-cn/application-dev/reference/apis-camera-kit/ @zengyawen -zh-cn/application-dev/reference/apis-drm-kit/ @zengyawen -zh-cn/application-dev/reference/apis-image-kit/ @zengyawen -zh-cn/application-dev/reference/apis-media-kit/ @zengyawen -zh-cn/application-dev/reference/apis-media-library-kit/ @zengyawen - - - -[API参考-MDM Kit] -zh-cn/application-dev/reference/apis-mdm-kit/ @liuzuming @ningningW @yangqing3 - - -[API参考-MindSpore Lite Kit] -zh-cn/application-dev/apis-mindspore-lite-kit/apis/js-apis-mindSporeLite.md @ge-yafang @principal87 @jianghui58 @limingjiang -zh-cn/application-dev/apis-mindspore-lite-kit/apis/js-apis-intelligentVoice-sys.md @ge-yafang @principal87 @jinjunewn @limingjiang -zh-cn/application-dev/apis-mindspore-lite-kit/apis/errorcode-intelligentVoice.md @ge-yafang @principal87 @jinjunewn @limingjiang -zh-cn/application-dev/apis-mindspore-lite-kit/apis/_mind_spore.md @ge-yafang @principal87 @jianghui58 @limingjiang - - -[API参考-Multimodal Awareness Kit] -zh-cn/application-dev/reference/apis-multimodalawareness-kit/Readme-CN.md @mayunteng_1 @nezha-father @cococoler @alien0208 -zh-cn/application-dev/reference/apis-multimodalawareness-kit/js-apis-stationary.md @mayunteng_1 @nezha-father @cococoler @alien0208 - - -[API参考-Network Kit] -zh-cn/application-dev/reference/apis-network-kit/ @jiayanhong-hw @zhang_yixin13 @w30013702 @rain_myf - - -[API参考-Neural NetWork Runtime Kit] -zh-cn/application-dev/reference/apis-neural-network-runtime-kit/_neural_network_runtime.md @ge-yafang @principal87 @win10wei - - -[API参考-Notification Kit] -zh-cn/application-dev/reference/apis-notification-kit/js-apis-inner-notification*.md @huipeizi @idanny @event_notification -zh-cn/application-dev/reference/apis-notification-kit/errorcode-notification.md @huipeizi @idanny @event_notification -zh-cn/application-dev/reference/apis-notification-kit/errorcode-DistributedNotificationService.md @huipeizi @idanny @event_notification - - -[API参考-Security] -zh-cn/application-dev/reference/apis-crypto-architecture-kit/ @zengyawen -zh-cn/application-dev/reference/apis-data-loss-prevention-kit/ @zengyawen -zh-cn/application-dev/reference/apis-device-certificate-kit/ @zengyawen -zh-cn/application-dev/reference/apis-universal-keystore-kit/ @zengyawen -zh-cn/application-dev/reference/apis-user-authentication-kit/ @zengyawen -zh-cn/application-dev/reference/apis-ability-kit/js-apis-abilityAccessCtrl.md @zengyawen -zh-cn/application-dev/reference/apis-ability-kit/js-apis-abilityAccessCtrl-sys.md @zengyawen -zh-cn/application-dev/reference/apis-ability-kit/js-apis-privacyManager-sys.md @zengyawen -zh-cn/application-dev/reference/apis-ability-kit/js-apis-permissionrequestresult.md @zengyawen -zh-cn/application-dev/reference/apis-ability-kit/errorcode-access-token.md @zengyawen - - -[API参考-Sensor Service Kit] -zh-cn/application-dev/reference/apis-sensor-service-kit/Readme-CN.md @nezha-father @lixiangpeng221 @butterls @star-wind-snow-and-rain -zh-cn/application-dev/reference/apis-sensor-service-kit/js-apis-sensor-sys.md @nezha-father @lixiangpeng221 @butterls @star-wind-snow-and-rain -zh-cn/application-dev/reference/apis-sensor-service-kit/js-apis-sensor.md @nezha-father @lixiangpeng221 @butterls @star-wind-snow-and-rain -zh-cn/application-dev/reference/apis-sensor-service-kit/js-apis-vibrator.md @nezha-father @lixiangpeng221 @butterls @star-wind-snow-and-rain -zh-cn/application-dev/reference/apis-sensor-service-kit/js-apis-system-sensor.md @nezha-father @lixiangpeng221 @butterls @star-wind-snow-and-rain -zh-cn/application-dev/reference/apis-sensor-service-kit/js-apis-system-vibrate.md @nezha-father @lixiangpeng221 @butterls @star-wind-snow-and-rain -zh-cn/application-dev/reference/apis-sensor-service-kit/_sensor.md @nezha-father @lixiangpeng221 @butterls @star-wind-snow-and-rain -zh-cn/application-dev/reference/apis-sensor-service-kit/_vibrator.md @nezha-father @lixiangpeng221 @butterls @star-wind-snow-and-rain -zh-cn/application-dev/reference/apis-sensor-service-kit/oh_sensor_8h.md @nezha-father @lixiangpeng221 @butterls @star-wind-snow-and-rain -zh-cn/application-dev/reference/apis-sensor-service-kit/oh_sensor_type_8h.md @nezha-father @lixiangpeng221 @butterls @star-wind-snow-and-rain -zh-cn/application-dev/reference/apis-sensor-service-kit/vibrator_8h.md @nezha-father @lixiangpeng221 @butterls @star-wind-snow-and-rain -zh-cn/application-dev/reference/apis-sensor-service-kit/vibrator_type_8h.md @nezha-father @lixiangpeng221 @butterls @star-wind-snow-and-rain -zh-cn/application-dev/reference/apis-sensor-service-kit/_vibrator_attribute.md @nezha-father @lixiangpeng221 @butterls @star-wind-snow-and-rain -zh-cn/application-dev/reference/apis-sensor-service-kit/_vibrator_file_description.md @nezha-father @lixiangpeng221 @butterls @star-wind-snow-and-rain -zh-cn/application-dev/reference/apis-sensor-service-kit/errorcode-sensor.md @nezha-father @lixiangpeng221 @butterls @star-wind-snow-and-rain -zh-cn/application-dev/reference/apis-sensor-service-kit/errorcode-vibrator.md @nezha-father @lixiangpeng221 @butterls @star-wind-snow-and-rain - - -[API参考-Telephony Kit] -zh-cn/application-dev/reference/apis-telephony-kit/ @jiayanhong-hw @zhang_yixin13 @w30013702 @dingxiaochen - - -[API参考-Test Kit] -zh-cn/application-dev/reference/apis-tesk-kit/js-apis-testRunner.md @ningningW -zh-cn/application-dev/reference/apis-tesk-kit/js-apis-app-ability-abilityDelegatorRegistry.md @ningningW -zh-cn/application-dev/reference/apis-tesk-kit/js-apis-uitest.md @inter515 @ningningW @inter515 @jiyong -zh-cn/application-dev/reference/apis-tesk-kit/errorcode-uitest.md @ningningW @inter515 @jiyong -zh-cn/application-dev/reference/apis-basic-services-kit/js-apis-deviceAttest-sys.md @ningningW @jiyong - -[工具-元能力、包管理、通知等] -zh-cn/application-dev/tools/aa-tool.md @huipeizi @ccllee @lxfycode @lixueqing513 -zh-cn/application-dev/tools/bm-tool.md @nezha-father @changzheng6 @hou-xiangyu1029 @kongjing2 -zh-cn/application-dev/tools/packing-tool.md @nezha-father @changzheng6 @hou-xiangyu1029 @kongjing2 -zh-cn/application-dev/tools/unpacking-tool.md @nezha-father @changzheng6 @hou-xiangyu1029 @kongjing2 -zh-cn/application-dev/tools/app-check-tool.md @nezha-father @changzheng6 @hou-xiangyu1029 @kongjing2 -zh-cn/application-dev/tools/cem-tool.md @huipeizi @idanny @event_notification -zh-cn/application-dev/tools/anm-tool.md @huipeizi @idanny @event_notification - - -[FAQ] -zh-cn/application-dev/faqs/ @zengyawen -zh-cn/application-dev/faqs/faqs-ability.md @huipeizi @ccllee @lxfycode @lixueqing513 -zh-cn/application-dev/faqs/faqs-bundle-management.md @huipeizi @changzheng6 @hou-xiangyu1029 @kongjing2 -zh-cn/application-dev/faqs/faqs-event-notification.md @huipeizi @idanny @event_notification +*/ \ No newline at end of file diff --git a/README.md b/README.md index 4373a4cb960c165e3176c025db7e914b2a2614c9..63aeaeceafbdc0138510b3a153513b6d0d93c5d5 100644 --- a/README.md +++ b/README.md @@ -18,11 +18,17 @@ This repository stores device and application development documents provided by - master: the latest version. - - OpenHarmony 4.1 Release. [Learn more](en/release-notes/OpenHarmony-v4.1-release.md) + - OpenHarmony 5.0.2 (API Level 14). [Learn more](en/release-notes/OpenHarmony-v5.0.2-release.md) - - OpenHarmony 4.0 Release. [Learn more](en/release-notes/OpenHarmony-v4.0-release.md) + - OpenHarmony 5.0.1 (API Level 13). [Learn more](en/release-notes/OpenHarmony-v5.0.1-release.md) - - OpenHarmony 3.2 Release. [Learn more](en/release-notes/OpenHarmony-v3.2-release.md) + - OpenHarmony 5.0.0 Release (API Level 12). [Learn more](en/release-notes/OpenHarmony-v5.0.0-release.md) + + - OpenHarmony 4.1 Release (API Level 11). [Learn more](en/release-notes/OpenHarmony-v4.1-release.md) + + - OpenHarmony 4.0 Release (API Level 10). [Learn more](en/release-notes/OpenHarmony-v4.0-release.md) + + - OpenHarmony 3.2 Release (API Level 9). [Learn more](en/release-notes/OpenHarmony-v3.2-release.md) This version is upgraded to OpenHarmony 3.2.3 Release. [Learn more](en/release-notes/OpenHarmony-v3.2.3-release.md) diff --git a/README_zh.md b/README_zh.md index cab0c61f0d62cba8aef96739d278eb864635cb1d..f665ee65345cf05b811b4e62cc075cae285729e8 100644 --- a/README_zh.md +++ b/README_zh.md @@ -18,13 +18,17 @@ - master:最新开发版本。 - - OpenHarmony 5.0.0 Release版本:点击[此处](zh-cn/release-notes/OpenHarmony-v5.0.0-release.md)了解版本详情。 + - OpenHarmony 5.0.2 Release版本(API Level 14):点击[此处](zh-cn/release-notes/OpenHarmony-v5.0.2-release.md)了解版本详情。 - - OpenHarmony 4.1 Release版本:点击[此处](zh-cn/release-notes/OpenHarmony-v4.1-release.md)了解版本详情。 + - OpenHarmony 5.0.1 Release版本(API Level 13):点击[此处](zh-cn/release-notes/OpenHarmony-v5.0.1-release.md)了解版本详情。 - - OpenHarmony 4.0 Release版本:点击[此处](zh-cn/release-notes/OpenHarmony-v4.0-release.md)了解版本详情。 + - OpenHarmony 5.0.0 Release版本(API Level 12):点击[此处](zh-cn/release-notes/OpenHarmony-v5.0.0-release.md)了解版本详情。 - - OpenHarmony 3.2 Release版本:点击[此处](zh-cn/release-notes/OpenHarmony-v3.2-release.md)了解版本详情。 + - OpenHarmony 4.1 Release版本(API Level 11):点击[此处](zh-cn/release-notes/OpenHarmony-v4.1-release.md)了解版本详情。 + + - OpenHarmony 4.0 Release版本(API Level 10):点击[此处](zh-cn/release-notes/OpenHarmony-v4.0-release.md)了解版本详情。 + + - OpenHarmony 3.2 Release版本(API Level 9):点击[此处](zh-cn/release-notes/OpenHarmony-v3.2-release.md)了解版本详情。 该版本已更新至OpenHarmony 3.2.3 Release,点击[此处](zh-cn/release-notes/OpenHarmony-v3.2.3-release.md)了解版本详情。 diff --git a/en/application-dev/ads-service/oaid/oaid-service-sys.md b/en/application-dev/ads-service/oaid/oaid-service-sys.md index e84d68fad69e3abe04406efb5aaba1ea17db81a8..9edd6cd418f17756010c772c5fb135b9f3c1d4c6 100644 --- a/en/application-dev/ads-service/oaid/oaid-service-sys.md +++ b/en/application-dev/ads-service/oaid/oaid-service-sys.md @@ -4,9 +4,7 @@ The OAID changes in the following scenarios: - A user restores the factory settings of the device. - -- A system application configures its bundle name in the **etc/advertising/oaid/oaid_service_config.json** file in the device's system directory and calls the **resetOAID()** API to reset the OAID. Note that the bundle name should be appended to the array in the file and separated with others by commas (,). - +- A system application configures its bundle name in the **etc/advertising/oaid/oaid_service_config.json** file in the device's system directory and calls the **resetOAID()** API to reset the OAID. Note that the bundle name should be appended to the array in the file and separated with others by commas (,). The following describes how to configure a system application to reset the OAID. ## Available APIs @@ -18,7 +16,7 @@ The following describes how to configure a system application to reset the OAID. ## How to Develop -1. In the **module.json5** file of the module, configure the [ohos.permission.APP_TRACKING_CONSENT](../../security/AccessToken/permissions-for-all.md#ohospermissionapp_tracking_consent) permission. The sample code is as follows: +1. In the **module.json5** file of the module, configure the [ohos.permission.APP_TRACKING_CONSENT](../../security/AccessToken/permissions-for-all-user.md#ohospermissionapp_tracking_consent) permission. The sample code is as follows: ```ts { "module": { @@ -38,7 +36,7 @@ The following describes how to configure a system application to reset the OAID. } ``` -2. Request authorization from the user in a dialog box when the application is started. For details about how to obtain the context, see [Context](../../application-models/application-context-stage.md). The sample code is as follows: + Request authorization from the user in a dialog box when the application is started. For details about how to obtain the context, see [Context](../../application-models/application-context-stage.md). The sample code is as follows: ```ts import abilityAccessCtrl from '@ohos.abilityAccessCtrl'; import { BusinessError } from '@ohos.base'; @@ -64,7 +62,7 @@ The following describes how to configure a system application to reset the OAID. } ``` -3. Call **resetOAID()** (a system API) to reset the OAID. The sample code is as follows: +2. Call **resetOAID()** (a system API) to reset the OAID. The sample code is as follows: ```ts import identifier from '@ohos.identifier.oaid'; import hilog from '@ohos.hilog'; @@ -76,3 +74,5 @@ The following describes how to configure a system application to reset the OAID. hilog.error(0x0000, 'testTag', '%{public}s', `reset oaid catch error: ${err.code} ${err.message}`); } ``` + + \ No newline at end of file diff --git a/en/application-dev/ads-service/oaid/oaid-service.md b/en/application-dev/ads-service/oaid/oaid-service.md index 406f97958e974f93951fa0c6132363a0c4e852f5..6f1ebe9d78e5d4c1e99fafd24eefc5044fcb7d67 100644 --- a/en/application-dev/ads-service/oaid/oaid-service.md +++ b/en/application-dev/ads-service/oaid/oaid-service.md @@ -1,8 +1,13 @@ # OAID Service -## When to Use +## -An Open Anonymous Device Identifier (OAID) is a non-permanent device identifier. The OAID service is useful for media application developers, ad platforms, and tracking platforms alike. Specifically, it provides personalized ads for users while protecting their personal data privacy, and also interact with third-party tracking platforms to provide conversion attribution analysis for advertisers. + +### When to Use + +An Open Anonymous Device Identifier (OAID) is a non-permanent device identifier. + +The OAID service is useful for media application developers, ad platforms, and tracking platforms alike. Specifically, it provides personalized ads for users while protecting their personal data privacy, and also interact with third-party tracking platforms to provide conversion attribution analysis for advertisers. An OAID is a 32-bit Universally Unique Identifier (UUID) generated using a Huawei algorithm. The format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx. @@ -23,18 +28,14 @@ The OAID changes in the following scenarios: | [getOAID](../../reference/apis-ads-kit/js-apis-oaid.md#identifiergetoaid-1)(callback: AsyncCallback<string>):  void | Obtains an OAID. This API uses an asynchronous callback to return the result.| > **NOTE** -> To call **getOAID()**, the application must request the permission **ohos.permission.APP_TRACKING_CONSENT** and user authorization. Three situations are possible: -> -> - If the application has configured the permission **ohos.permission.APP_TRACKING_CONSENT** and the permission is allowed, the OAID is returned. -> - If the application has configured the permission **ohos.permission.APP_TRACKING_CONSENT** and the permission is disallowed, 00000000-0000-0000-0000-000000000000 is returned. -> - If the application has not configured the permission **ohos.permission.APP_TRACKING_CONSENT**, 00000000-0000-0000-0000-000000000000 is returned. +> To call **getOAID()**, the application must request the permission **ohos.permission.APP_TRACKING_CONSENT** and user authorization. Three situations are possible:
+> 1. If the application has configured the permission **ohos.permission.APP_TRACKING_CONSENT** and the permission is allowed, the OAID is returned.
+> 2. If the application has configured the permission **ohos.permission.APP_TRACKING_CONSENT** and the permission is disallowed, 00000000-0000-0000-0000-000000000000 is returned.
+> 3. If the application has not configured the permission **ohos.permission.APP_TRACKING_CONSENT**, 00000000-0000-0000-0000-000000000000 is returned. -## How to Develop -1. In the **module.json5** file of the module, configure the permission [ohos.permission.APP_TRACKING_CONSENT](../../security/AccessToken/permissions-for-all.md#ohospermissionapp_tracking_consent), which is a user_grant permission. In this case, the **reason** and **abilities** fields are mandatory. For details about the configuration, see [Declaring Permissions in the Configuration File](../../security/AccessToken/declare-permissions.md#declaring-permissions-in-the-configuration-file). - - The sample code is as follows: - +### How to Develop +1. In the **module.json5** file of the module, configure the permission [ohos.permission.APP_TRACKING_CONSENT](../../security/AccessToken/permissions-for-all-user.md#ohospermissionapp_tracking_consent), which is a user_grant permission. In this case, the **reason** and **abilities** fields are mandatory. For details about the configuration, see [Declaring Permissions in the Configuration File](../../security/AccessToken/declare-permissions.md#declaring-permissions-in-the-configuration-file). The sample code is as follows: ```ts { "module": { @@ -54,10 +55,7 @@ The OAID changes in the following scenarios: } ``` -2. To obtain the OAID, the application must call **requestPermissionFromUser** to obtain the corresponding permission. For details about how to obtain the context, see [Context](../../application-models/application-context-stage.md). - - The sample code is as follows: - +2. To obtain the OAID, the application must call **requestPermissionFromUser** to obtain the corresponding permission. For details about how to obtain the context, see [Context](../../application-models/application-context-stage.md). The sample code is as follows: ```ts import { identifier } from '@kit.AdsKit'; import { abilityAccessCtrl, common } from '@kit.AbilityKit'; diff --git a/en/application-dev/ai/mindspore/mindspore-guidelines-based-native.md b/en/application-dev/ai/mindspore/mindspore-guidelines-based-native.md index b5ab4b5463c8d27161f1c8c4f880649003a41e22..c80f28ad4f87a7357c4d9e9746cfed340b5bc317 100644 --- a/en/application-dev/ai/mindspore/mindspore-guidelines-based-native.md +++ b/en/application-dev/ai/mindspore/mindspore-guidelines-based-native.md @@ -15,7 +15,7 @@ Image classification can be used to recognize objects in images and is widely us 1. Select an image classification model. 2. Use the MindSpore Lite inference model on the device to classify the selected images. -## Environment Preparation +## Environment Setup Install DevEco Studio 4.1 or later, and update the SDK to API version 11 or later. @@ -190,7 +190,7 @@ Call [MindSpore](../../reference/apis-mindspore-lite-kit/_mind_spore.md) to impl *buffer = nullptr; } - OH_AI_ModelHandle CreateMSLiteModel(void *modelBuffer, size_t modelSize) { + OH_AI_ContextHandle CreateMSLiteContext(void *modelBuffer) { // Set executing context for model. auto context = OH_AI_ContextCreate(); if (context == nullptr) { @@ -202,7 +202,12 @@ Call [MindSpore](../../reference/apis-mindspore-lite-kit/_mind_spore.md) to impl OH_AI_DeviceInfoSetEnableFP16(cpu_device_info, true); OH_AI_ContextAddDeviceInfo(context, cpu_device_info); + + LOGI("MS_LITE_LOG: Build MSLite context success.\n"); + return context; + } + OH_AI_ModelHandle CreateMSLiteModel(void *modelBuffer, size_t modelSize, OH_AI_ContextHandle context) { // Create model auto model = OH_AI_ModelCreate(); if (model == nullptr) { @@ -257,7 +262,6 @@ Call [MindSpore](../../reference/apis-mindspore-lite-kit/_mind_spore.md) to impl // Predict model. auto predict_ret = OH_AI_ModelPredict(model, inputs, &outputs, nullptr, nullptr); if (predict_ret != OH_AI_STATUS_SUCCESS) { - OH_AI_ModelDestroy(&model); LOGE("MS_LITE_ERR: MSLite Predict error.\n"); return OH_AI_STATUS_LITE_ERROR; } @@ -323,15 +327,22 @@ Call [MindSpore](../../reference/apis-mindspore-lite-kit/_mind_spore.md) to impl return error_ret; } LOGI("MS_LITE_LOG: Read model file success"); - auto model = CreateMSLiteModel(modelBuffer, modelSize); + + auto context = CreateMSLiteContext(modelBuffer); + if (context == nullptr) { + LOGE("MS_LITE_ERR: MSLiteFwk Build context failed.\n"); + return error_ret; + } + auto model = CreateMSLiteModel(modelBuffer, modelSize, context); if (model == nullptr) { - OH_AI_ModelDestroy(&model); + OH_AI_ContextDestroy(&context); LOGE("MS_LITE_ERR: MSLiteFwk Build model failed.\n"); return error_ret; } int ret = RunMSLiteModel(model, input_data); if (ret != OH_AI_STATUS_SUCCESS) { OH_AI_ModelDestroy(&model); + OH_AI_ContextDestroy(&context); LOGE("MS_LITE_ERR: RunMSLiteModel failed.\n"); return error_ret; } @@ -346,6 +357,7 @@ Call [MindSpore](../../reference/apis-mindspore-lite-kit/_mind_spore.md) to impl napi_set_element(env, out_data, i, element); } OH_AI_ModelDestroy(&model); + OH_AI_ContextDestroy(&context); LOGI("MS_LITE_LOG: Exit runDemo()"); return out_data; } @@ -477,5 +489,3 @@ console.info('MS_LITE_LOG: *** Finished MSLite Demo ***'); Touch the **photo** button on the device screen, select an image, and touch **OK**. The top 4 categories of the image are displayed below the image. - - diff --git a/en/application-dev/ai/mindspore/mindspore-lite-guidelines.md b/en/application-dev/ai/mindspore/mindspore-lite-guidelines.md index 1cf13be0f97590b9019a1bf3bb918f11c8d1c84b..90f7fca4f982a2850d1eace6f12408c68234cb1a 100644 --- a/en/application-dev/ai/mindspore/mindspore-lite-guidelines.md +++ b/en/application-dev/ai/mindspore/mindspore-lite-guidelines.md @@ -24,7 +24,7 @@ APIs involved in MindSpore Lite model inference are categorized into context API | API | Description | | ------------------ | ----------------- | -|OH_AI_ContextHandle OH_AI_ContextCreate()|Creates a context object.| +|OH_AI_ContextHandle OH_AI_ContextCreate()|Creates a context object. This API must be used together with **OH_AI_ContextDestroy**.| |void OH_AI_ContextSetThreadNum(OH_AI_ContextHandle context, int32_t thread_num)|Sets the number of runtime threads.| | void OH_AI_ContextSetThreadAffinityMode(OH_AI_ContextHandle context, int mode)|Sets the affinity mode for binding runtime threads to CPU cores, which are classified into large, medium, and small cores based on the CPU frequency. You only need to bind the large or medium cores, but not small cores. |OH_AI_DeviceInfoHandle OH_AI_DeviceInfoCreate(OH_AI_DeviceType device_type)|Creates a runtime device information object.| @@ -177,12 +177,13 @@ The development process consists of the following main steps: if (ret != OH_AI_STATUS_SUCCESS) { printf("OH_AI_ModelBuildFromFile failed, ret: %d.\n", ret); OH_AI_ModelDestroy(&model); + OH_AI_ContextDestroy(&context); return ret; } ``` 4. Input data. - + Before executing model inference, you need to populate data to the input tensor. In this example, random data is used to populate the model. ```c @@ -191,6 +192,7 @@ The development process consists of the following main steps: if (inputs.handle_list == NULL) { printf("OH_AI_ModelGetInputs failed, ret: %d.\n", ret); OH_AI_ModelDestroy(&model); + OH_AI_ContextDestroy(&context); return ret; } // Use random data to populate the tensor. @@ -198,6 +200,7 @@ The development process consists of the following main steps: if (ret != OH_AI_STATUS_SUCCESS) { printf("GenerateInputDataWithRandom failed, ret: %d.\n", ret); OH_AI_ModelDestroy(&model); + OH_AI_ContextDestroy(&context); return ret; } ``` @@ -213,6 +216,7 @@ The development process consists of the following main steps: if (ret != OH_AI_STATUS_SUCCESS) { printf("OH_AI_ModelPredict failed, ret: %d.\n", ret); OH_AI_ModelDestroy(&model); + OH_AI_ContextDestroy(&context); return ret; } ``` @@ -225,7 +229,7 @@ The development process consists of the following main steps: // Obtain the output tensor and print the information. for (size_t i = 0; i < outputs.handle_num; ++i) { OH_AI_TensorHandle tensor = outputs.handle_list[i]; - int64_t element_num = OH_AI_TensorGetElementNum(tensor); + long long element_num = OH_AI_TensorGetElementNum(tensor); printf("Tensor name: %s, tensor size is %zu ,elements num: %lld.\n", OH_AI_TensorGetName(tensor), OH_AI_TensorGetDataSize(tensor), element_num); const float *data = (const float *)OH_AI_TensorGetData(tensor); @@ -243,8 +247,9 @@ The development process consists of the following main steps: If the MindSpore Lite inference framework is no longer needed, you need to destroy the created model. ```c - // Destroy the model. + // Release the model and context. OH_AI_ModelDestroy(&model); + OH_AI_ContextDestroy(&context); ``` ## Verification @@ -265,7 +270,7 @@ The development process consists of the following main steps: ) ``` - To use ohos-sdk for cross compilation, you need to set the native toolchain path for the CMake tool as follows: `-DCMAKE_TOOLCHAIN_FILE="/xxx/native/build/cmake/ohos.toolchain.cmake"`. - + - The toolchain builds a 64-bit application by default. To build a 32-bit application, add the following configuration: `-DOHOS_ARCH="armeabi-v7a"`. 2. Run the CMake tool. @@ -280,8 +285,9 @@ The development process consists of the following main steps: The inference is successful if the output is similar to the following: ```shell - # ./QuickStart ./mobilenetv2.ms + # ./demo ./mobilenetv2.ms Tensor name: Softmax-65, tensor size is 4004 ,elements num: 1001. output data is: 0.000018 0.000012 0.000026 0.000194 0.000156 0.001501 0.000240 0.000825 0.000016 0.000006 0.000007 0.000004 0.000004 0.000004 0.000015 0.000099 0.000011 0.000013 0.000005 0.000023 0.000004 0.000008 0.000003 0.000003 0.000008 0.000014 0.000012 0.000006 0.000019 0.000006 0.000018 0.000024 0.000010 0.000002 0.000028 0.000372 0.000010 0.000017 0.000008 0.000004 0.000007 0.000010 0.000007 0.000012 0.000005 0.000015 0.000007 0.000040 0.000004 0.000085 0.000023 ``` + diff --git a/en/application-dev/ai/mindspore/mindspore-lite-train-guidelines.md b/en/application-dev/ai/mindspore/mindspore-lite-train-guidelines.md index 3e142c23a52616bbcd8cf45820c5af1e18927fab..3de53d09772930727cdd2dae453bb8e4c8355460 100644 --- a/en/application-dev/ai/mindspore/mindspore-lite-train-guidelines.md +++ b/en/application-dev/ai/mindspore/mindspore-lite-train-guidelines.md @@ -12,7 +12,7 @@ The following table list some APIs for using MindSpore Lite for model training. | API | Description | | ------------------ | ----------------- | -|OH_AI_ContextHandle OH_AI_ContextCreate()|Creates a context object.| +|OH_AI_ContextHandle OH_AI_ContextCreate()|Creates a context object. This API must be used together with **OH_AI_ContextDestroy**.| |OH_AI_DeviceInfoHandle OH_AI_DeviceInfoCreate(OH_AI_DeviceType device_type)|Creates a runtime device information object.| |void OH_AI_ContextDestroy(OH_AI_ContextHandle *context)|Destroys a context object.| |void OH_AI_ContextAddDeviceInfo(OH_AI_ContextHandle context, OH_AI_DeviceInfoHandle device_info)|Adds a runtime device information object.| @@ -112,6 +112,7 @@ The development process consists of the following main steps: if (ret != OH_AI_STATUS_SUCCESS) { printf("OH_AI_TrainModelBuildFromFile failed, ret: %d.\n", ret); OH_AI_ModelDestroy(&model); + OH_AI_ContextDestroy(&context); return ret; } ``` @@ -126,6 +127,7 @@ The development process consists of the following main steps: if (inputs.handle_list == NULL) { printf("OH_AI_ModelGetInputs failed, ret: %d.\n", ret); OH_AI_ModelDestroy(&model); + OH_AI_ContextDestroy(&context); return ret; } @@ -134,6 +136,7 @@ The development process consists of the following main steps: if (ret != OH_AI_STATUS_SUCCESS) { printf("GenerateInputDataWithRandom failed, ret: %d.\n", ret); OH_AI_ModelDestroy(&model); + OH_AI_ContextDestroy(&context); return ret; } ``` @@ -148,6 +151,7 @@ The development process consists of the following main steps: if (ret != OH_AI_STATUS_SUCCESS) { printf("OH_AI_ModelSetTrainMode failed, ret: %d.\n", ret); OH_AI_ModelDestroy(&model); + OH_AI_ContextDestroy(&context); return ret; } @@ -156,6 +160,7 @@ The development process consists of the following main steps: if (ret != OH_AI_STATUS_SUCCESS) { printf("OH_AI_RunStep failed, ret: %d.\n", ret); OH_AI_ModelDestroy(&model); + OH_AI_ContextDestroy(&context); return ret; } printf("Train Step Success.\n"); @@ -171,6 +176,7 @@ The development process consists of the following main steps: if (ret != OH_AI_STATUS_SUCCESS) { printf("OH_AI_ExportModel train failed, ret: %d.\n", ret); OH_AI_ModelDestroy(&model); + OH_AI_ContextDestroy(&context); return ret; } printf("Export Train Model Success.\n"); @@ -180,6 +186,7 @@ The development process consists of the following main steps: if (ret != OH_AI_STATUS_SUCCESS) { printf("OH_AI_ExportModel inference failed, ret: %d.\n", ret); OH_AI_ModelDestroy(&model); + OH_AI_ContextDestroy(&context); return ret; } printf("Export Inference Model Success.\n"); @@ -190,8 +197,9 @@ The development process consists of the following main steps: If the MindSpore Lite inference framework is no longer needed, you need to destroy the created model. ```c - // Delete model. + // Delete model and context. OH_AI_ModelDestroy(&model); + OH_AI_ContextDestroy(&context); ``` @@ -303,6 +311,7 @@ int ModelPredict(char* model_file) { if (ret != OH_AI_STATUS_SUCCESS) { printf("OH_AI_ModelBuildFromFile failed, ret: %d.\n", ret); OH_AI_ModelDestroy(&model); + OH_AI_ContextDestroy(&context); return ret; } @@ -311,6 +320,7 @@ int ModelPredict(char* model_file) { if (inputs.handle_list == NULL) { printf("OH_AI_ModelGetInputs failed, ret: %d.\n", ret); OH_AI_ModelDestroy(&model); + OH_AI_ContextDestroy(&context); return ret; } @@ -319,6 +329,7 @@ int ModelPredict(char* model_file) { if (ret != OH_AI_STATUS_SUCCESS) { printf("GenerateInputDataWithRandom failed, ret: %d.\n", ret); OH_AI_ModelDestroy(&model); + OH_AI_ContextDestroy(&context); return ret; } @@ -328,6 +339,7 @@ int ModelPredict(char* model_file) { if (ret != OH_AI_STATUS_SUCCESS) { printf("MSModelPredict failed, ret: %d.\n", ret); OH_AI_ModelDestroy(&model); + OH_AI_ContextDestroy(&context); return ret; } @@ -347,6 +359,7 @@ int ModelPredict(char* model_file) { } OH_AI_ModelDestroy(&model); + OH_AI_ContextDestroy(&context); return OH_AI_STATUS_SUCCESS; } @@ -398,6 +411,7 @@ int TrainDemo(int argc, const char **argv) { if (ret != OH_AI_STATUS_SUCCESS) { printf("OH_AI_TrainModelBuildFromFile failed, ret: %d.\n", ret); OH_AI_ModelDestroy(&model); + OH_AI_ContextDestroy(&context); return ret; } @@ -406,6 +420,7 @@ int TrainDemo(int argc, const char **argv) { if (inputs.handle_list == NULL) { printf("OH_AI_ModelGetInputs failed, ret: %d.\n", ret); OH_AI_ModelDestroy(&model); + OH_AI_ContextDestroy(&context); return ret; } @@ -414,6 +429,7 @@ int TrainDemo(int argc, const char **argv) { if (ret != OH_AI_STATUS_SUCCESS) { printf("GenerateInputDataWithRandom failed, ret: %d.\n", ret); OH_AI_ModelDestroy(&model); + OH_AI_ContextDestroy(&context); return ret; } @@ -422,6 +438,7 @@ int TrainDemo(int argc, const char **argv) { if (ret != OH_AI_STATUS_SUCCESS) { printf("OH_AI_ModelSetTrainMode failed, ret: %d.\n", ret); OH_AI_ModelDestroy(&model); + OH_AI_ContextDestroy(&context); return ret; } @@ -430,6 +447,7 @@ int TrainDemo(int argc, const char **argv) { if (ret != OH_AI_STATUS_SUCCESS) { printf("OH_AI_RunStep failed, ret: %d.\n", ret); OH_AI_ModelDestroy(&model); + OH_AI_ContextDestroy(&context); return ret; } printf("Train Step Success.\n"); @@ -439,6 +457,7 @@ int TrainDemo(int argc, const char **argv) { if (ret != OH_AI_STATUS_SUCCESS) { printf("OH_AI_ExportModel train failed, ret: %d.\n", ret); OH_AI_ModelDestroy(&model); + OH_AI_ContextDestroy(&context); return ret; } printf("Export Train Model Success.\n"); @@ -448,12 +467,14 @@ int TrainDemo(int argc, const char **argv) { if (ret != OH_AI_STATUS_SUCCESS) { printf("OH_AI_ExportModel inference failed, ret: %d.\n", ret); OH_AI_ModelDestroy(&model); + OH_AI_ContextDestroy(&context); return ret; } printf("Export Inference Model Success.\n"); - // Delete model. + // Delete model and context. OH_AI_ModelDestroy(&model); + OH_AI_ContextDestroy(&context); // Use The Exported Model to predict ret = ModelPredict(strcat(export_infer_model, ".ms")); diff --git a/en/application-dev/ai/nnrt/Neural-Network-Runtime-Kit-Introduction.md b/en/application-dev/ai/nnrt/Neural-Network-Runtime-Kit-Introduction.md index a4aa38921126ffaa20376cf75d586e4129db0232..3f8a87301625f0ead3880adfcf4071e1dba9b4e5 100644 --- a/en/application-dev/ai/nnrt/Neural-Network-Runtime-Kit-Introduction.md +++ b/en/application-dev/ai/nnrt/Neural-Network-Runtime-Kit-Introduction.md @@ -20,7 +20,7 @@ As shown in Figure 1, in addition to native APIs, NNRt logically consists of the 6. **Model cache**: Save the built model objects into a file or a segment of memory in the cache. During next model build, model objects can be directly loaded from the file or segment of memory in the cache, greatly improving the build speed. 7. **Offline model inference**: Directly use model files (offline models for short) dedicated to the AI hardware for inference. Specifically, use the model converter provided by the AI hardware vendor to convert the original training model into the offline model file corresponding to the AI hardware, deploy the offline model file in the application, and pass the model file to the NNRt offline model build API for inference. Offline models can be used only for build and inference on the corresponding AI hardware. That is, inference across AI hardware is not supported. The offline models are specific to the AI hardware and therefore, the build speed is usually fast. -** Figure 1** NNRt architecture +**Figure 1** NNRt architecture !["NNRt architecture"](figures/neural_network_runtime_intro.jpg) diff --git a/en/application-dev/ai/nnrt/figures/neural_network_runtime_intro.jpg b/en/application-dev/ai/nnrt/figures/neural_network_runtime_intro.jpg new file mode 100644 index 0000000000000000000000000000000000000000..18e377791ffeb0ca9b3bc8456a21cbc9872b3b2e Binary files /dev/null and b/en/application-dev/ai/nnrt/figures/neural_network_runtime_intro.jpg differ diff --git a/en/application-dev/ai/nnrt/figures/neural_network_runtime_intro.png b/en/application-dev/ai/nnrt/figures/neural_network_runtime_intro.png deleted file mode 100644 index 1b3225ad79116c7a91ce5c4d276caa1d04cdc3a7..0000000000000000000000000000000000000000 Binary files a/en/application-dev/ai/nnrt/figures/neural_network_runtime_intro.png and /dev/null differ diff --git a/en/application-dev/application-models/Readme-EN.md b/en/application-dev/application-models/Readme-EN.md index 41328ed1c20ce6ffe59ef3525bcc4fcaa24f86e9..c7e6952c94f09eac4129116861ccb3ee15822f37 100644 --- a/en/application-dev/application-models/Readme-EN.md +++ b/en/application-dev/application-models/Readme-EN.md @@ -1,28 +1,31 @@ -# Ability Kit +# Ability Kit - [Introduction to Ability Kit](abilitykit-overview.md) - [Application Models](application-models.md) -- Stage Model Development +- Stage Model Development - [Stage Model Development Overview](stage-model-development-overview.md) - - Stage Model Application Components + - Stage Model Application Components - [Application- or Component-Level Configuration](application-component-configuration-stage.md) - - UIAbility Component + - UIAbility Component - [UIAbility Overview](uiability-overview.md) - [UIAbility Lifecycle](uiability-lifecycle.md) - [UIAbility Launch Type](uiability-launch-type.md) - [UIAbility Usage](uiability-usage.md) - [Data Synchronization Between UIAbility and UI Page](uiability-data-sync-with-ui.md) - [Starting UIAbility in the Same Application](uiability-intra-device-interaction.md) + - [UIAbility Backup and Restore](ability-recover-guideline.md) - [ExtensionAbility Component](extensionability-overview.md) - [ServiceExtensionAbility (for System Applications Only)](serviceextensionability.md) + - [UIServiceExtensionAbility (for System Applications Only)](uiserviceextension-sys.md) - [UIExtensionAbility (for System Applications Only)](uiextensionability.md) - [AutoFillExtensionAbility (for System Applications Only)](autofillextensionablility-guide.md) + - [UIServiceExtensionAbility](uiserviceextension.md) - [EmbeddedUIExtensionAbility](embeddeduiextensionability.md) - [AbilityStage Component Container](abilitystage.md) - [Context](application-context-stage.md) - - Want + - Want - [Want Overview](want-overview.md) - [Matching Rules of Explicit Want and Implicit Want](explicit-implicit-want-mappings.md) - [Using Explicit Want to Start an Application Component](ability-startup-with-explicit-want.md) @@ -30,13 +33,13 @@ - [Component Startup Rules (Stage Model)](component-startup-rules.md) - [AppStartup](app-startup.md) - - Inter-Device Application Component Interaction (Hopping) + - Inter-Device Application Component Interaction (Hopping) - [Hopping Overview](inter-device-interaction-hop-overview.md) - [Cross-Device Migration](hop-cross-device-migration.md) - [Multi-device Collaboration](hop-multi-device-collaboration.md) - [Subscribing to System Environment Variable Changes](subscribe-system-environment-variable-changes.md) - - Inter-Application Redirection + - Inter-Application Redirection - [Overview of Application Redirection](link-between-apps-overview.md) - Starting a Specified Application - [Overview of Starting a Specified Application](app-startup-overview.md) @@ -53,24 +56,26 @@ - [Using startAbilityByType to Start an Email Application](start-email-apps.md) - [Using mailto to Start an Email Application](start-email-apps-by-mailto.md) - [Using startAbilityByType to Start a Financial Application](start-finance-apps.md) + - [Using startAbilityByType to Start a Flight Application](start-flight-apps.md) + - [Using startAbilityByType to Start an Express Delivery Application](start-express-apps.md) - [Using startAbilityByType to Start an Image Editing Application](photoEditorExtensionAbility.md) - [Using startAbility to Start a File Application](file-processing-apps-startup.md) - [Starting a System Application](system-app-startup.md) - [Process Model (Stage Model)](process-model-stage.md) - [Thread Model (Stage Model)](thread-model-stage.md) - - Mission Management (for System Applications Only) + - Mission Management (for System Applications Only) - [Mission Management Scenarios](mission-management-overview.md) - - [Mission and Launch Type](mission-management-launch-type.md) + - [Mission Management and Launch Type](mission-management-launch-type.md) - [Page Stack and Mission List](page-mission-stack.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) -- FA Model Development +- FA Model Development - [FA Model Development Overview](fa-model-development-overview.md) - - FA Model Application Components + - FA Model Application Components - [Application- or Component-Level Configuration](application-component-configuration-fa.md) - - PageAbility Component Development + - PageAbility Component Development - [PageAbility Overview](pageability-overview.md) - [PageAbility Configuration](pageability-configuration.md) - [PageAbility Lifecycle](pageability-lifecycle.md) @@ -78,19 +83,21 @@ - [Creating a PageAbility](create-pageability.md) - [Starting a Local PageAbility](start-local-pageability.md) - [Stopping a PageAbility](stop-pageability.md) + - [Starting a Remote PageAbility (for System Applications Only)](start-remote-pageability.md) + - [Starting a Specified Page](start-page.md) - [Window Properties](window-properties.md) - [Requesting Permissions](request-permissions.md) - [Redirection Rules](redirection-rules.md) - - ServiceAbility Component Development + - ServiceAbility Component Development - [ServiceAbility Overview](serviceability-overview.md) - [ServiceAbility Configuration](serviceability-configuration.md) - [ServiceAbility Lifecycle](serviceability-lifecycle.md) - [Creating a ServiceAbility](create-serviceability.md) - [Starting a ServiceAbility](start-serviceability.md) - [Connecting to a ServiceAbility](connect-serviceability.md) - - DataAbility Component Development + - DataAbility Component Development - [DataAbility Overview](dataability-overview.md) - [DataAbility Configuration](dataability-configuration.md) - [DataAbility Lifecycle](dataability-lifecycle.md) @@ -108,25 +115,25 @@ - [Application Configuration File](config-file-fa.md) -- Development of Component Interaction Between the FA Model and Stage Model +- Development of Component Interaction Between the FA Model and Stage Model - [Component Interaction Between the FA Model and Stage Model](fa-stage-interaction-overview.md) - [Starting a UIAbility from the FA Model](start-uiability-from-fa.md) - [Connecting to a ServiceExtensionAbility from the FA Model](bind-serviceextensionability-from-fa.md) - [Accessing a DataShareExtensionAbility from the FA Model](access-datashareextensionability-from-fa.md) - [Starting a PageAbility from the Stage Model](start-pageability-from-stage.md) - [Connecting to a ServiceAbility from the Stage Model](bind-serviceability-from-stage.md) -- Switching from the FA Model to the Stage Model +- Switching from the FA Model to the Stage Model - [Model Switching Overview](model-switch-overview.md) - - Configuration File Switching + - Configuration File Switching - [Differences in Configuration Files](configuration-file-diff.md) - [Switching of app and deviceConfig](app-deviceconfig-switch.md) - [Switching of module](module-switch.md) - - Component Switching + - Component Switching - [PageAbility Switching](pageability-switch.md) - [ServiceAbility Switching](serviceability-switch.md) - [DataAbility Switching](dataability-switch.md) - [Widget Switching](widget-switch.md) - - API Switching + - API Switching - [API Switching Overview](api-switch-overview.md) - [Context Switching](context-switch.md) - [featureAbility Switching](featureability-switch.md) diff --git a/en/application-dev/application-models/ability-recover-guideline.md b/en/application-dev/application-models/ability-recover-guideline.md new file mode 100644 index 0000000000000000000000000000000000000000..c7b99152ca676dcded81b6fbdcdc4f2f53b3ac67 --- /dev/null +++ b/en/application-dev/application-models/ability-recover-guideline.md @@ -0,0 +1,72 @@ +# UIAbility Backup and Restore + +## When to Use + +When an application runs in the background, factors such as system resource control may cause the application to close or its process to terminate, which might result in the loss of user data. However, if the application has enabled the [UIAbility](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md) backup and restore feature within [UIAbilityContext](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md) and saved temporary data, it can restore the previous state and data (including the page stack and the data stored in the [onSaveState](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md#uiabilityonsavestate) callback) when it restarts after being closed, maintaining a seamless user experience. + +> **NOTE** +> +> If the application is stopped normally, the UIAbility backup process is not triggered. If the application is started normally (for example, by calling the **startAbility** API or clicking the icon), the UIAbility restore process is not triggered. + +## Working Mechanism +- UIAbility data backup: After an application transitions to the [onBackground](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md#uiabilityonbackground) lifecycle, the system automatically calls [onSaveState](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md#uiabilityonsavestate) to back up data. +- UIAbility data restore: The restored [Want](../reference/apis-ability-kit/js-apis-app-ability-want.md) data can be obtained from the [onCreate](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md#uiabilityoncreate) lifecycle of the application, and the page stack data can be restored in the [onWindowStageCreate](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md#uiabilityonwindowstagecreate) lifecycle of the application. + +## Constraints + +- The UIAbility backup and restore feature supports multiple instances. Backup data is stored in the application sandbox path as files for seven days. + +- Backup data is stored in the form of [WantParams](../reference/apis-ability-kit/js-apis-app-ability-want.md). Due to serialization constraints, the maximum data volume supported is 200 KB. + +- Data restore is unavailable after device restart. + +- The data backup and restore feature is unavailable for a [UIExtensionAbility](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md). + +## Available APIs + +The UIAbility backup and restore API is provided by the [UIAbilityContext](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md) module. You can directly use **this.context** in the [UIAbility](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md) to call them. For details, see [How to Develop](#how-to-develop). + +| API | Description | +| ------------------------------------------------------------ | ---------------------------------------------------- | +| setRestoreEnabled(enabled: boolean): void | Sets whether to enable restore when the UIAbility is switched back from the background.| + +[setRestoreEnabled](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextsetrestoreenabled14) must be called during application initialization (before [onForeground](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md#uiabilityonforeground) is invoked). For example, it can be called in the [onCreate](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md#uiabilityoncreate) callback of the UIAbility. + + +## How to Develop + +To enable UIAbility backup and restore during application module initialization, refer to the code snippet below. + +```ts +import { UIAbility } from '@kit.AbilityKit'; + +export default class EntryAbility extends UIAbility { + onCreate() { + console.info("[Demo] EntryAbility onCreate"); + this.context.setRestoreEnabled(true); + } +} +``` + +To proactively save data and restore the data when the UIAbility is started, refer to the code snippet below. + +```ts +import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; + +export default class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) { + console.info("[Demo] EntryAbility onCreate"); + this.context.setRestoreEnabled(true); + if (want && want.parameters) { + let recoveryMyData = want.parameters["myData"]; + } + } + + onSaveState(state:AbilityConstant.StateType, wantParams: Record) { + // Ability has called to save app data + console.log("[Demo] EntryAbility onSaveState"); + wantParams["myData"] = "my1234567"; + return AbilityConstant.OnSaveResult.ALL_AGREE; + } +} +``` diff --git a/en/application-dev/application-models/abilitystage.md b/en/application-dev/application-models/abilitystage.md index bef10b4cfe7fdc769ad94e70dae50550cfceddae..8339d1a9ae24a66e5247b32cb4d64eff344feea5 100644 --- a/en/application-dev/application-models/abilitystage.md +++ b/en/application-dev/application-models/abilitystage.md @@ -1,7 +1,7 @@ # AbilityStage Component Container -[AbilityStage](../reference/apis-ability-kit/js-apis-app-ability-abilityStage.md) is a component container at the [module](../quick-start/application-package-structure-stage.md) level. When the [HAP](../quick-start/hap-package.md) of an application is loaded for the first time, an AbilityStage instance is created. You can perform operations such as initialization on the instance. +[AbilityStage](../reference/apis-ability-kit/js-apis-app-ability-abilityStage.md) is a component container at the [module](../quick-start/application-package-overview.md#multi-module design mechanism) level. When the [HAP](../quick-start/hap-package.md) of an application is loaded for the first time, an AbilityStage instance is created. You can perform operations such as initialization on the instance. An AbilityStage instance corresponds to a module. diff --git a/en/application-dev/application-models/access-datashareextensionability-from-fa.md b/en/application-dev/application-models/access-datashareextensionability-from-fa.md index 1c968aed1561bcf4bf9f746ce73f5b342a7e4326..47e5b62209a6c2ec8bd8cabe2326b51b89c00c25 100644 --- a/en/application-dev/application-models/access-datashareextensionability-from-fa.md +++ b/en/application-dev/application-models/access-datashareextensionability-from-fa.md @@ -5,9 +5,9 @@ Regardless of the FA model or stage model, the data read/write function consists of the client and server. -- In the FA model, the client uses the **DataAbilityHelper** class to provide external APIs, and the server uses the **DataAbility** class to provide database read and write services. +- In the FA model, the client uses [DataAbilityHelper](../reference/apis-ability-kit/js-apis-inner-ability-dataAbilityHelper.md) to provide external APIs, and the server uses [DataAbility](dataability-overview.md) to provide database read and write services. -- In the stage model, the client uses the **DataShareHelper** class to provide external APIs, and the server uses the **DataShareExtensionAbility** class to provide database read and write services. +- In the stage model, the client uses [DataShareHelper](../reference/apis-arkdata/js-apis-data-dataShare-sys.md#datasharehelper) to provide external APIs, and the server uses [DataShareExtensionAbility](../reference/apis-arkdata/js-apis-application-dataShareExtensionAbility-sys.md) to provide database read and write services If the client uses the FA model whereas the server is upgraded to the stage model, the client cannot access the server. @@ -31,7 +31,7 @@ Instead of manual modification, the system adopts the following processing: ![FAvsStage-uri](figures/FAvsStage-uri.png) -3. The **DataShareHelper** class implements only certain APIs of **DataAbilityHelper**. For details about the APIs, see the table below. +2. The **DataShareHelper** class implements only certain APIs of **DataAbilityHelper**. For details about the APIs, see the table below. **Table 1** API compatibility when the FA model accesses a DataShareExtensionAbility of the stage model diff --git a/en/application-dev/application-models/actions-entities.md b/en/application-dev/application-models/actions-entities.md index 409a9738724ee3d8da1d23edad9e4c511723276f..dbfb2ab7f889cf8bd4fc3e5c232f70a21726fb42 100644 --- a/en/application-dev/application-models/actions-entities.md +++ b/en/application-dev/application-models/actions-entities.md @@ -4,9 +4,9 @@ > > Due to the generalized use of the fields **action** and **entities**, the system lacks control over the behavior of applications declaring **action** and **entities**. This loophole allows malicious applications to make false declarations, hijacking traffic and rendering post-redirection features inoperative. As such, the system intends to deprecate unnecessary **action** and **entities**. You are advised to [start an application of the specified type](./start-intent-panel.md). -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-ability-kit/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 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-ability-kit/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 **ACTION_VIEW_DATA**, the application component that supports access to the website is matched. Declaring the **action** field in Want indicates that the invoked application should support the declared operation. The **actions** field under [skills](../quick-start/module-configuration-file.md#skills) in the configuration file indicates the operations supported by the application. Common **actions** values are as follows. For details, see [action](../reference/apis-ability-kit/js-apis-ability-wantConstant.md#action). -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. @@ -17,9 +17,9 @@ The following **action** values are available: - **ACTION_VIEW_MULTIPLE_DATA**: action of launching the UI for sending multiple data records. -The **entities** field specifies the additional category information (such as browser and video player) of the target component. It is a supplement to action in implicit [Want](../reference/apis-ability-kit/js-apis-app-ability-want.md). 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 specifies the additional category information (such as browser and video player) of the target component. It is a supplement to action in implicit [Want](../reference/apis-ability-kit/js-apis-app-ability-want.md). 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](../quick-start/module-configuration-file.md#skills) in the configuration file indicates the categories supported by the application. Common **entities** values are as follows. For details, see [entity](../reference/apis-ability-kit/js-apis-ability-wantConstant.md#entity). -The following **entities** values are available: +**Common entities values** - **ENTITY_DEFAULT**: default category, which is meaningless. diff --git a/en/application-dev/application-models/app-linking-startup.md b/en/application-dev/application-models/app-linking-startup.md index 1717e2391f709bd3c946ec0727e7faf8ac505383..1e3b4d83667dabec99f184dbc97038d12ac5808a 100644 --- a/en/application-dev/application-models/app-linking-startup.md +++ b/en/application-dev/application-models/app-linking-startup.md @@ -36,6 +36,11 @@ Configure the [module.json5 file](../quick-start/module-configuration-file.md) o * The **uris** field must contain an element whose **scheme** is **https** and **host** is a domain name address. * **domainVerify** must be set to **true**. +> **NOTE** +> +> By default, the **skills** field contains a **skill** object, which is used to identify the application entry. Application redirection links should not be configured in this object. Instead, separate **skill** objects should be used. If there are multiple redirection scenarios, create different **skill** objects under **skills**. Otherwise, the configuration does not take effect. + + For example, the configuration below declares that the application is associated with the domain name www.example.com. ```json @@ -46,6 +51,14 @@ For example, the configuration below declares that the application is associated { // ... "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + }, { "entities": [ // entities must contain "entity.system.browsable". @@ -67,7 +80,7 @@ For example, the configuration below declares that the application is associated ], // domainVerify must be set to true. "domainVerify": true - } + } // Add a skill object for redirection. If there are multiple redirection scenarios, create multiple skill objects. ] } ] diff --git a/en/application-dev/application-models/app-startup.md b/en/application-dev/application-models/app-startup.md index ac5de1341af1e25a15016f935ed4db70c272cff5..7a8313b94447db0671939acc0334c56cc7883bbf 100644 --- a/en/application-dev/application-models/app-startup.md +++ b/en/application-dev/application-models/app-startup.md @@ -3,11 +3,11 @@ ## Overview -During application initialization, a series of startup tasks are triggered. If these tasks are concentratedly placed within the [onCreate](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md#uiabilityoncreate) lifecycle of the [UIAbility](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md) of the application's main module ([module](../quick-start/application-package-overview.md#module-types) of the entry type), they must be executed sequentially on the main thread, which significantly affects the application launch speed. In addition, when there are too many tasks, complex dependencies between them make the code difficult to maintain. +During application launch, a series of startup tasks are often required. If all these tasks are placed within the [onCreate](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md#uiabilityoncreate) lifecycle of the [UIAbility](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md) in the application's main module ([module](../quick-start/application-package-overview.md#module-types) of the entry type), they can only be executed sequentially on the main thread, which significantly affects the application launch speed. In addition, when there are too many tasks, complex dependencies between them make the code difficult to maintain. -AppStartup offers an efficient approach to application initialization. By enabling the asynchronous initiation of startup tasks, it ensures a smoother startup process. The centralized configuration of task execution order and interdependencies in a single file simplifies and clarifies the startup codebase, enhancing maintainability. +AppStartup offers an efficient approach to application launch. By supporting asynchronous initiation of startup tasks, it ensures a smoother startup process. The centralized configuration of execution order and dependencies of multiple startup tasks in a single file simplifies and clarifies the startup codebase, enhancing maintainability. -AppStartup supports startup tasks in automatic or manual mode. By default, the automatic mode is used. During the creation of an [AbilityStage](../reference/apis-ability-kit/js-apis-app-ability-abilityStage.md), the configured startup tasks are loaded and executed in automatic mode. You can also call [startupManager.run](../reference/apis-ability-kit/js-apis-app-appstartup-startupManager.md#startupmanagerrun) to execute the startup tasks in manual mode after a UIAbility is created. +AppStartup supports startup tasks in automatic or manual mode. By default, automatic mode is used. During the creation of an [AbilityStage](../reference/apis-ability-kit/js-apis-app-ability-abilityStage.md), the configured startup tasks are loaded and executed in automatic mode. You can also call [startupManager.run](../reference/apis-ability-kit/js-apis-app-appstartup-startupManager.md#startupmanagerrun) to execute the startup tasks in manual mode after a UIAbility is created. **Figure 1** Startup procedure @@ -21,7 +21,7 @@ AppStartup supports startup tasks in automatic or manual mode. By default, the a ## Development Process -1. [Defining an AppStartup Configuration File](#defining-an-appstartup-configuration-file): Create an AppStartup configuration file in the resource file directory, add the configuration about startup tasks, and reference the configuration file in [module.json5](../quick-start/module-configuration-file.md). +1. [Defining an AppStartup Configuration File](#defining-an-appstartup-configuration-file): Create an AppStartup configuration file in the resource file directory, add the configuration about startup tasks, and reference this configuration file in [module.json5](../quick-start/module-configuration-file.md). 2. [Setting Startup Parameters](#setting-startup-parameters): In the startup parameter file, set parameters such as the timeout interval and startup task listener. 3. [Adding a Startup Task for Each Component to Be Initialized](#adding-a-startup-task-for-each-component-to-be-initialized): Implement the [StartupTask](../reference/apis-ability-kit/js-apis-app-appstartup-startupTask.md) interface. @@ -29,7 +29,7 @@ AppStartup supports startup tasks in automatic or manual mode. By default, the a ### Defining an AppStartup Configuration File -1. Create a AppStartup configuration file in the **resources/base/profile** directory of the application's main module ([module](../quick-start/application-package-overview.md#module-types) of the entry type). The file name can be customized. The following uses **startup_config.json** as an example. +1. Create an AppStartup configuration file in the **resources/base/profile** directory of the application's main module ([module](../quick-start/application-package-overview.md#module-types) of the entry type). The file name can be customized. The following uses **startup_config.json** as an example. 2. In the **startup_config.json** file, add the configuration for each startup task in sequence. @@ -109,22 +109,22 @@ AppStartup supports startup tasks in automatic or manual mode. By default, the a **Table 1** Fields in the startup_config.json file - | Field| Description| Data Type| Default Value Allowed| + | Field| Description| Data Type| Optional| | -------- | -------- | -------- | -------- | - | startupTasks | Configuration about the startup tasks. For details, see the following table.| Object array| No| - | configEntry | Path of the startup parameter file.| String| No| + | startupTasks | Configuration about the startup tasks. For details, see the following table.| Object array| Mandatory| + | configEntry | Path of the startup parameter file.| String| Mandatory| **Table 2** Description of startupTasks - | Field| Description| Data Type| Default Value Allowed| + | Field| Description| Data Type| Optional| | -------- | -------- | -------- | -------- | - | name | Class name of the startup task.| String| No| - | srcEntry | Path of the file corresponding to the startup task.| String| No| - | dependencies | Array holding the class names of other startup tasks on which the startup task depends.| Object array| Yes (initial value: left empty)| - | excludeFromAutoStart | Whether to exclude the automatic mode. For details, see [Changing the Startup Mode](#optional-changing-the-startup-mode).
- **true**: manual mode.
- **false**: automatic mode.| Boolean| Yes (initial value: **false**)| - | runOnThread | Thread where the startup task is executed.
- **mainThread**: executed in the main thread.
- **taskPool**: executed in an asynchronous thread.| String| Yes (initial value: **mainThread**)| - | waitOnMainThread | Whether the main thread needs to wait until the startup task finishes execution. This parameter is valid only when **runOnThread** is set to **taskPool**.
- **true**: The main thread loads the application home page only the startup task finishes execution.
- **false**: The main thread does not wait for the startup task to finish execution.| Boolean| Yes (initial value: **true**)| + | name | Name of the startup task, which can be customized. It is recommended that the name be the same as the class name.| String| Mandatory| + | srcEntry | Path of the file corresponding to the startup task.| String| Mandatory| + | dependencies | Array holding the class names of other startup tasks on which this task depends.| Object array| Optional, defaults to an empty array| + | excludeFromAutoStart | Whether to exclude automatic mode. For details, see [Changing the Startup Mode](#optional-changing-the-startup-mode).
- **true**: manual mode.
- **false**: automatic mode.| Boolean| Optional, defaults to **false**| + | runOnThread | Thread where the startup task is executed.
- **mainThread**: executed in the main thread.
- **taskPool**: executed in an asynchronous thread.| String| Optional, defaults to **mainThread**| + | waitOnMainThread | Whether the main thread needs to wait until the startup task finishes execution. This parameter is valid only when **runOnThread** is set to **taskPool**.
- **true**: The main thread loads the application home page only the startup task finishes execution.
- **false**: The main thread does not wait for the startup task to finish execution.| Boolean| Optional, defaults to **true**| 3. Add the index of the AppStartup configuration file to the **appStartup** tag in the [module.json5 file](../quick-start/module-configuration-file.md). @@ -218,8 +218,8 @@ export default class StartupTask_001 extends StartupTask { AppStartup provides automatic and manual mode. By default, the automatic mode is used. However, you can change the mode to manual as required. -- Automatic mode: After an AbilityStage is created, the startup task is automatically executed. -- Manual mode: After a UIAbility is created, you need to manually call the API to execute the startup task. Modules that are infrequently used do not need to be initialized when the application is started. You can change the startup mode of these modules to manual. After the application is started, you can call [startupManager.run](../reference/apis-ability-kit/js-apis-app-appstartup-startupManager.md#startupmanagerrun) to execute the startup task. +- Automatic mode: After an AbilityStage is created, startup tasks are automatically executed. +- Manual mode: After a UIAbility is created, you need to manually call the API to execute the startup task. Modules that are infrequently used do not need to be initialized when the application is launched. You can change the startup mode of these modules to manual. After the application is started, you can call [startupManager.run](../reference/apis-ability-kit/js-apis-app-appstartup-startupManager.md#startupmanagerrun) to execute the startup task. The following uses the **onCreate** lifecycle of the UIAbility as an example to describe how to manually trigger a startup task. The sample code is as follows: @@ -231,13 +231,13 @@ import { BusinessError } from '@kit.BasicServicesKit'; export default class EntryAbility extends UIAbility { onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate'); - let startParams = ['StartupTask_005', 'StartupTask_006']; + let startParams = ["StartupTask_005", "StartupTask_006"]; try { startupManager.run(startParams).then(() => { console.log('StartupTest startupManager run then, startParams = '); }).catch((error: BusinessError) => { - console.info("StartupTest promise catch error, error = " + JSON.stringify(error)); - console.info("StartupTest promise catch error, startParams = " + console.info('StartupTest promise catch error, error = ' + JSON.stringify(error)); + console.info('StartupTest promise catch error, startParams = ' + JSON.stringify(startParams)); }) } catch (error) { @@ -261,7 +261,7 @@ import { startupManager } from '@kit.AbilityKit'; @Component struct Index { @State message: string = 'Manual Mode' - @State startParams: Array = ['StartupTask_006']; + @State startParams: Array = ["StartupTask_006"]; build() { RelativeContainer() { @@ -284,4 +284,4 @@ struct Index { } } ``` - + diff --git a/en/application-dev/application-models/app-uri-config.md b/en/application-dev/application-models/app-uri-config.md index e4bd922dd5055f52d90062e0a8bf275ec6cf7f75..30c457954bcb2412ca3a95f17865dd0c0118831e 100644 --- a/en/application-dev/application-models/app-uri-config.md +++ b/en/application-dev/application-models/app-uri-config.md @@ -1,7 +1,7 @@ # Application Link Description ## Description of uris -**uris** declared in **skills** of the **module.json5** file contains the following fields. +**uris** declared in [skills](../quick-start/module-configuration-file.md#skills) of the [module.json5 file](../quick-start/module-configuration-file.md) contains the following fields. > **NOTE** > @@ -36,6 +36,11 @@ URIs can be expressed in different formats based on the available fields. Among ### Description of linkFeature +> **NOTE** +> +> The number of **linkFeature** declared in a bundle cannot exceed 150. + + The use of the **linkFeature** field enables an application to deliver a more user-friendly redirection experience. (The declaration of the **linkFeature** field must be reviewed by the application market before being released.) The use scenarios are as follows: 1. Identification of applications of the same type: When the caller starts a vertical application (for example, navigation applications), the system identifies the matched applications based on the **linkFeature** field and displays the applications on the vertical domain panel. diff --git a/en/application-dev/application-models/application-component-configuration-stage.md b/en/application-dev/application-models/application-component-configuration-stage.md index a4d9f6e284c32c44faf577d917f4f241b37c419a..a6b9f9be1b5e843d871930d5fe62e5999de8eb08 100644 --- a/en/application-dev/application-models/application-component-configuration-stage.md +++ b/en/application-dev/application-models/application-component-configuration-stage.md @@ -7,12 +7,12 @@ During application development, you must configure tags to identify an applicati The bundle name is specified by the **bundleName** field in the [app.json5 file](../quick-start/app-configuration-file.md) in the **AppScope** directory of the project. This field identifies an application and must be globally unique. You are advised to use the reverse domain name notation, for example, *com.example.demo*, where the first part is the domain suffix **com**, the second part is the vendor/individual name, and the third part is the application name, which can be of multiple levels. ## Configuring Icons and Labels -Icons and labels are usually configured together. They 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). Since 5.0.3.800, DevEco Studio does not forcibly verify the **icons** and **labels** in the **module.json5** file. Therefore, you can configure them in either **module.json5** or **app.json5**. +Icons and labels are usually configured together. They 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). In DevEco Studio 5.0.3.800 and later versions, the **icon** and **label** fields are optional in the **module.json5** file, but mandatory in the **app.json5** file. This means that you can skip **icons** and **labels** in the **module.json5** file. ### Generation Mechanism * If the HAP file contains UIAbility configuration, the following scenarios are possible: - * If the **icon** and **label** fields under **abilities** of the **module.json5** file are configured, and under **skills** of the corresponding ability, **entities** contains **entity.system.home** and **actions** contains **ohos.want.action.home**, the system returns the icon and label configured in **module.json5**. If there are multiple abilities that meet the requirements, the system returns the icon and label specified for the ability corresponding to **mainElement** in **module.json5**. + * If the **icon** and **label** fields under **abilities** of the **module.json5** file are configured, and under **skills** of the corresponding ability, **entities** contains **entity.system.home** and **actions** contains **ohos.want.action.home** or **action.system.home**, the system returns the icon and label configured in **module.json5**. If there are multiple abilities that meet the requirements, the system returns the icon and label specified for the ability corresponding to **mainElement** in **module.json5**. * If the **icon** and **label** fields under **abilities** of the **module.json5** file are not configured, the system returns the icon and label configured in **app.json5**. @@ -20,13 +20,15 @@ Icons and labels are usually configured together. They correspond to the **icon* ### Use Scenarios - + - Used to display an application on an application screen, for example, application list in **Settings**, or permissions requested by the application in **Settings > Privacy manager**. - Used to display an application on the home screen. for example, applications displayed on the home screen or in **Recents**. + The following figure shows the effect. - + ![application-component-configuration-stage-app-module](figures/application-component-configuration-stage-app-module.png) + ### Configuration Example diff --git a/en/application-dev/application-models/application-context-stage.md b/en/application-dev/application-models/application-context-stage.md index 51cfcd95c32c239a33b68e1af710ee2d8137b52d..89a1cdd926805b35d5049e2234a3df0a777efa53 100644 --- a/en/application-dev/application-models/application-context-stage.md +++ b/en/application-dev/application-models/application-context-stage.md @@ -26,7 +26,7 @@ } } ``` - + > **NOTE** > > For details about how to obtain the context of a **UIAbility** instance on the page, see [Obtaining the Context of UIAbility](uiability-usage.md#obtaining-the-context-of-uiability). @@ -81,135 +81,88 @@ This topic describes how to use the context in the following scenarios: ### Obtaining Application File Paths -The [base class Context](../reference/apis-ability-kit/js-apis-inner-application-context.md) provides the capability of obtaining application file paths. [ApplicationContext](../reference/apis-ability-kit/js-apis-inner-application-applicationContext.md), [AbilityStageContext](../reference/apis-ability-kit/js-apis-inner-application-abilityStageContext.md), [UIAbilityContext](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md), and [ExtensionContext](../reference/apis-ability-kit/js-apis-inner-application-extensionContext.md) inherit this capability. The application file paths are a type of application sandbox paths. For details, see [Application Sandbox Directory](../file-management/app-sandbox-directory.md). - -The application file paths obtained by the preceding contexts are different. - -- The application file path obtained through [ApplicationContext](../reference/apis-ability-kit/js-apis-inner-application-applicationContext.md) is at the application level. This path is recommended for storing global application information, and the files in the path will be deleted when the application is uninstalled. - - | Name| Path| - | -------- | -------- | - | bundleCodeDir | \/el1/bundle| - | cacheDir | \/\/base/cache| - | filesDir | \/\/base/files| - | preferencesDir | \/\/base/preferences| - | tempDir | \/\/base/temp| - | databaseDir | \/\/database| - | distributedFilesDir | \/el2/distributedFiles| - | cloudFileDir12+ | \/el2/cloud| - - The sample code is as follows: - - ```ts - import { common } from '@kit.AbilityKit'; - import { hilog } from '@kit.PerformanceAnalysisKit'; - import { promptAction } from '@kit.ArkUI'; +The [base class Context](../reference/apis-ability-kit/js-apis-inner-application-context.md) provides the capability of obtaining application file paths. [ApplicationContext](../reference/apis-ability-kit/js-apis-inner-application-applicationContext.md), [AbilityStageContext](../reference/apis-ability-kit/js-apis-inner-application-abilityStageContext.md), [UIAbilityContext](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md), and [ExtensionContext](../reference/apis-ability-kit/js-apis-inner-application-extensionContext.md) inherit this capability. However, the specific paths retrieved can differ based on the type of the context used. - const TAG: string = '[Page_Context]'; - const DOMAIN_NUMBER: number = 0xFF00; +- [ApplicationContext](../reference/apis-ability-kit/js-apis-inner-application-applicationContext.md): This context provides access to the application-level file path, which is used to store global application information. Files in this path are removed when the application is uninstalled. +- [AbilityStageContext](../reference/apis-ability-kit/js-apis-inner-application-abilityStageContext.md), [UIAbilityContext](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md), and [ExtensionContext](../reference/apis-ability-kit/js-apis-inner-application-extensionContext.md): These contexts provide access to [module-level](../quick-start/application-package-overview.md) file paths. Files in these paths are removed when the corresponding [HAP](../quick-start/hap-package.md) or [HSP](../quick-start/in-app-hsp.md) module is uninstalled. Uninstalling an HAP or HSP module does not affect files under the application-level path unless all HAP and HSP modules of the application are uninstalled. - @Entry - @Component - struct Page_Context { - private context = getContext(this) as common.UIAbilityContext; - - build() { - Column() { - //... - List({ initialIndex: 0 }) { - ListItem() { - Row() { - //... - } - .onClick(() => { - let applicationContext = this.context.getApplicationContext(); - let cacheDir = applicationContext.cacheDir; - let tempDir = applicationContext.tempDir; - let filesDir = applicationContext.filesDir; - let databaseDir = applicationContext.databaseDir; - let bundleCodeDir = applicationContext.bundleCodeDir; - let distributedFilesDir = applicationContext.distributedFilesDir; - let preferencesDir = applicationContext.preferencesDir; - let cloudFileDir = applicationContext.cloudFileDir; - // Obtain the application file path. - let filePath = tempDir + 'test.txt'; - hilog.info(DOMAIN_NUMBER, TAG, `filePath: ${filePath}`); - if (filePath !== null) { - promptAction.showToast({ - message: filePath - }); - } - }) - } - //... - } - //... - } - //... - } - } - ``` + - UIAbilityContext: This context can be used to obtain the file paths of the module containing the UIAbility. + - ExtensionContext: This context can be used to obtain the file paths of the module containing the ExtensionAbility. + - AbilityStageContext: Given that AbilityStageContext is initialized earlier than UIAbilityContext and ExtensionContext, it is typically used to obtain file paths within the AbilityStage. -- The application file path obtained through [AbilityStageContext](../reference/apis-ability-kit/js-apis-inner-application-abilityStageContext.md), [UIAbilityContext](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md), and [ExtensionContext](../reference/apis-ability-kit/js-apis-inner-application-extensionContext.md) is at the [HAP](../quick-start/hap-package.md) level. This path is recommended for storing HAP-related information, and the files in this path are deleted when the HAP is uninstalled. However, the deletion does not affect the files in the application-level path unless all HAPs of the application are uninstalled. +>**NOTE** +> +> The application file paths are a type of application sandbox paths. For details, see [Application Sandbox Directory](../file-management/app-sandbox-directory.md). - | Name| Path| - | -------- | -------- | - | bundleCodeDir | \/el1/bundle| - | cacheDir | \/\/base/**haps/\**/cache| - | filesDir | \/\/base/**haps/\**/files| - | preferencesDir | \/\/base/**haps/\**/preferences| - | tempDir | \/\/base/**haps/\**/temp| - | databaseDir | \/\/database/**\**| - | distributedFilesDir | \/el2/distributedFiles/**\**| - | cloudFileDir12+ | \/el2/cloud/**\**| +**Table 1** Description of application file paths obtained by different types of contexts +| Name| Description| Path Obtained by ApplicationContext| Path Obtained by AbilityStageContext, UIAbilityContext, and ExtensionContext| +| -------- | -------- | -------- | -------- | +| bundleCodeDir | Bundle code directory.| \/el1/bundle| \/el1/bundle| +| cacheDir | Cache directory.| \/\/base/cache| \/\/base/**haps/\**/cache| +| filesDir | File directory.| \/\/base/files| \/\/base/**haps/\**/files| +| preferencesDir | Preferences directory.| \/\/base/preferences| \/\/base/**haps/\**/preferences| +| tempDir | Temporary directory.| \/\/base/temp| \/\/base/**haps/\**/temp| +| databaseDir | Database directory.| \/\/database| \/\/database/**\**| +| distributedFilesDir | Distributed file directory.| \/el2/distributedFiles| \/el2/distributedFiles/| +| resourceDir11+ | Resource directory.
**NOTE**
You are required to manually create the **resfile** directory in **\\resource**.| N/A| \/el1/bundle/**\**/resources/resfile| +| cloudFileDir12+ | Cloud file directory.| \/el2/cloud| \/el2/cloud/| - The sample code is as follows: +This section uses ApplicationContext as an example to describe how to obtain the application file path, create a file in the path, and read and write the file. The sample code is as follows: ```ts import { common } from '@kit.AbilityKit'; + import { buffer } from '@kit.ArkTS'; + import { fileIo, ReadOptions } from '@kit.CoreFileKit'; import { hilog } from '@kit.PerformanceAnalysisKit'; - import { promptAction } from '@kit.ArkUI'; const TAG: string = '[Page_Context]'; const DOMAIN_NUMBER: number = 0xFF00; @Entry @Component - struct Page_Context { + struct Index { + @State message: string = 'Hello World'; private context = getContext(this) as common.UIAbilityContext; build() { - Column() { - //... - List({ initialIndex: 0 }) { - ListItem() { - Row() { - //... - } - .onClick(() => { - let cacheDir = this.context.cacheDir; - let tempDir = this.context.tempDir; - let filesDir = this.context.filesDir; - let databaseDir = this.context.databaseDir; - let bundleCodeDir = this.context.bundleCodeDir; - let distributedFilesDir = this.context.distributedFilesDir; - let preferencesDir = this.context.preferencesDir; - let cloudFileDir = applicationContext.cloudFileDir; - // Obtain the application file path. - let filePath = tempDir + 'test.txt'; - hilog.info(DOMAIN_NUMBER, TAG, `filePath: ${filePath}`); - if (filePath !== null) { - promptAction.showToast({ - message: filePath - }); - } - }) + Row() { + Column() { + Text(this.message) + // ... + Button() { + Text('create file') + // ... + .onClick(() => { + let applicationContext = this.context.getApplicationContext(); + // Obtain the application file path. + let filesDir = applicationContext.filesDir; + hilog.info(DOMAIN_NUMBER, TAG, `filePath: ${filesDir}`); + // Create and open the file if it does not exist. Open the file if it already exists. + let file = fileIo.openSync(filesDir + '/test.txt', fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE); + // Write data to the file. + let writeLen = fileIo.writeSync(file.fd, "Try to write str."); + hilog.info(DOMAIN_NUMBER, TAG, `The length of str is: ${writeLen}`); + // Create an ArrayBuffer object with a size of 1024 bytes to store the data read from the file. + let arrayBuffer = new ArrayBuffer(1024); + // Set the offset and length to read. + let readOptions: ReadOptions = { + offset: 0, + length: arrayBuffer.byteLength + }; + // Read the file content to the ArrayBuffer object and return the number of bytes that are actually read. + let readLen = fileIo.readSync(file.fd, arrayBuffer, readOptions); + // Convert the ArrayBuffer object into a Buffer object and output it as a string. + let buf = buffer.from(arrayBuffer, 0, readLen); + hilog.info(DOMAIN_NUMBER, TAG, `the content of file: ${buf.toString()}`); + // Close the file. + fileIo.closeSync(file); + }) } - //... + // ... } - //... + // ... } - //... + // ... } } ``` @@ -316,7 +269,7 @@ struct Page_Context { ### Obtaining the Context of Other Modules in the Current Application Call [createModuleContext(context: Context, moduleName: string)](../reference/apis-ability-kit/js-apis-app-ability-application.md#applicationcreatemodulecontext12) to obtain the context of another module in the current application. After obtaining the context, you can obtain the resource information of that module. - + ```ts import { common, application } from '@kit.AbilityKit'; import { promptAction } from '@kit.ArkUI'; @@ -344,12 +297,12 @@ Call [createModuleContext(context: Context, moduleName: string)](../reference/ap console.info(`CreateModuleContext success, data: ${JSON.stringify(data)}`); if (data !== null) { promptAction.showToast({ - message: ('Context obtained.') + message: ('Context obtained') }); } }) .catch((err: BusinessError) => { - console.error(`CeateMudleContext failed, err code:${err.code}, err msg: ${err.message}`); + console.error(`CreateModuleContext failed, err code:${err.code}, err msg: ${err.message}`); }); }) } diff --git a/en/application-dev/application-models/application-models.md b/en/application-dev/application-models/application-models.md index 821a37de6140fdb3b4a69393602081bc142d3b4b..0289e6bc7617ae6b76d7eb10791a70f126828e55 100644 --- a/en/application-dev/application-models/application-models.md +++ b/en/application-dev/application-models/application-models.md @@ -50,6 +50,6 @@ The table below describes their differences in detail. | -------- | -------- | -------- | | **Application component**| 1. Component classification
![fa-model-component](figures/fa-model-component.png)
- PageAbility: supports user interaction via the UI. For details, see [PageAbility Component Overview](pageability-overview.md).
- ServiceAbility: provides background services without the UI. For details, see [ServiceAbility Component Overview](serviceability-overview.md).
- DataAbility: provides the data sharing capability without the UI. For details, see [DataAbility Component Overview](dataability-overview.md).
2. Development mode
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
![stage-model-component](figures/stage-model-component.png)
- UIAbility: supports user interaction with the UI. For details, see [UIAbility Component Overview](uiability-overview.md).
- ExtensionAbility: provides scenario-specific extension capabilities (such as widget and input methods). For details, see [ExtensionAbility Component Overview](extensionability-overview.md).
2. Development mode
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:
1. Main process
2. Render process
For details, see [Process Model](process-model-fa.md).| There are three types of processes:
1. Main process
2. ExtensionAbility process
3. Render process
For details, see [Process Model](process-model-stage.md).| -| **Thread model**| 1. ArkTS engine instance creation
A process can run multiple application component instances, and each application component instance runs in an independent ArkTS engine instance.
2. Thread model
Each ArkTS engine instance is created on an independent thread (non-main thread). The main thread does not have an ArkTS engine instance.
3. Intra-process object sharing: not supported.
For details, see [Thread Model](thread-model-fa.md).| 1. ArkTS engine instance creation
A process can run multiple application component instances, and all application component instances share one ArkTS engine instance.
2. Thread model
The ArkTS engine instance is created on the main thread.
3. Intra-process object sharing: supported.
For details, see [Thread Model](thread-model-stage.md).| +| **Thread model**| 1. ArkTS engine instance creation
A process can run multiple instances of application components, and each instance runs in an independent ArkTS engine instance.
2. Thread model
Each ArkTS engine instance is created on an independent thread (non-main thread). The main thread does not have an ArkTS engine instance.
3. Intra-process object sharing: not supported.
For details, see [Thread Model](thread-model-fa.md).| 1. ArkTS engine instance creation
A process can run multiple application component instances, and all application component instances share one ArkTS engine instance.
2. Thread model
The ArkTS engine instance is created on the main thread.
3. Intra-process object sharing: supported.
For details, see [Thread Model](thread-model-stage.md).| |**Mission management model**| - A mission is created for each PageAbility component instance.
- Missions are stored persistently until they are deleted by users or the number of missions exceeds the maximum (customized based on the product configuration).
- PageAbility components do not form a stack structure.| - A mission is created for each UIAbility component instance.
- Missions are stored persistently until they are deleted by users or the number of missions exceeds the maximum (customized based on the product configuration).
- UIAbility components do not form a stack structure.| | **Configuration file**| The **config.json** file contains the application, HAP, and application component information.
For details, see [Application Configuration File Overview (FA Model)](../quick-start/application-configuration-file-overview-fa.md).| The **app.json5** file contains the application information, and the **module.json5** file contains the HAP and application component information.
For details, see [Application Configuration File Overview (Stage Model)](../quick-start/application-configuration-file-overview-stage.md).| diff --git a/en/application-dev/application-models/canopenlink.md b/en/application-dev/application-models/canopenlink.md index 0685288b83b2b4ff4b8cb966a97a1279820eb858..06dd28dd4b81df8c16aeb5874d610d02169489c4 100644 --- a/en/application-dev/application-models/canopenlink.md +++ b/en/application-dev/application-models/canopenlink.md @@ -13,7 +13,6 @@ For details about the matching rules, see [Matching Rules of Explicit Want and I 1. Configure the [querySchemes](../quick-start/module-configuration-file.md) field in the **module.json5** file of the entry module to declare the URL schemes. - A configuration example is as follows: ```json { "module": { @@ -28,7 +27,6 @@ For details about the matching rules, see [Matching Rules of Explicit Want and I 2. Import the **ohos.bundle.bundleManager** module. 3. Call **canOpenLink**. - The sample code is as follows: ```ts import { bundleManager } from '@kit.AbilityKit'; import { BusinessError } from '@kit.BasicServicesKit'; @@ -46,7 +44,6 @@ For details about the matching rules, see [Matching Rules of Explicit Want and I ### Procedure for the Target Application Configure the [uris](../quick-start/module-configuration-file.md#skills) field in the **module.json5** file. -A configuration example is as follows: ```json { "module": { diff --git a/en/application-dev/application-models/component-startup-rules.md b/en/application-dev/application-models/component-startup-rules.md index 027c7e85640b1b1b72916150a5d367e5260b921e..8704dbaf8861b412b056ff1478dacd8d6502a12e 100644 --- a/en/application-dev/application-models/component-startup-rules.md +++ b/en/application-dev/application-models/component-startup-rules.md @@ -26,7 +26,7 @@ In view of this, the system formulates a set of component startup rules, as foll If the **exported** field of the component is set to **true**, the component can be called by other applications. If the field is set to **false**, the component cannot be called by other applications. If this is the case, you must also verify the permission **ohos.permission.START_INVISIBLE_ABILITY**, which is available only for system applications. For details about the **exported** fields, see [abilities](../quick-start/module-configuration-file.md#abilities). -- Before starting a UIAbility component of a background application, verify the permission **ohos.permission.START_ABILITIES_FROM_BACKGROUND**, which is available only for system applications. +- Before starting a UIAbility component of a background application, the caller must verify the permission ohos.permission.START_ABILITIES_FROM_BACKGROUND, which is available only for system applications. > **NOTE** > diff --git a/en/application-dev/application-models/deep-linking-startup.md b/en/application-dev/application-models/deep-linking-startup.md index 0696c9532fcc44f557240f6a1329730127dd0c7d..5a9be6ed35085e3da0f0f8ad024671a451f38a14 100644 --- a/en/application-dev/application-models/deep-linking-startup.md +++ b/en/application-dev/application-models/deep-linking-startup.md @@ -7,13 +7,17 @@ In Deep Linking, the system, based on the passed-in URI, searches for the applic Deep Linking searches for an application based on the URI matching rules in implicit Want mechanism and starts the matching application. For details about the URI matching rules of implicit Want, see [Matching Rules of uri](explicit-implicit-want-mappings.md#matching-rules-of-uri). -## Configuring the module.json5 File for the Target Application +## Procedure for the Target Application -To be accessed by other applications, an application must configure the [skills](../quick-start/module-configuration-file.md#skills) field of the [module.json5 file](../quick-start/module-configuration-file.md). The value of **scheme** under **uri** can be customized. It can be any string that does not contain special characters or start with **ohos**. +### Configuring the module.json5 File + +To be accessed by other applications, an application must configure the [skills](../quick-start/module-configuration-file.md#skills) field of the [module.json5 file](../quick-start/module-configuration-file.md). > **NOTE** > -> The value of **scheme** in Deep Linking cannot be **https**, **http**, or **file**. Otherwise, the default system browser is started. +> By default, the **skills** field contains a **skill** object, which is used to identify the application entry. Application redirection links should not be configured in this object. Instead, separate **skill** objects should be used. If there are multiple redirection scenarios, create different **skill** objects under **skills**. Otherwise, the configuration does not take effect. +> +> In Deep Linking, the **scheme** value can be customized to any string that does not contain special characters and does not start with **ohos**. It is generally recommended to avoid using **https**, **http**, or **file** to prevent the default system browser from being launched. A configuration example is as follows: @@ -26,6 +30,14 @@ A configuration example is as follows: { // ... "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + }, { "actions": [ // actions cannot be empty. Otherwise, matching the target application fails. @@ -39,7 +51,7 @@ A configuration example is as follows: "host": "www.example.com" } ] - } + } // Add a skill object for redirection. If there are multiple redirection scenarios, create multiple skill objects. ] } ] @@ -47,6 +59,32 @@ A configuration example is as follows: } ``` +### Obtaining and Parsing the Link Passed by the Caller + +In the **onCreate()** or **onNewWant()** lifecycle callback of the UIAbility of the target application, obtain and parse the Link passed by the caller. + +```ts +// EntryAbility.ets is used as an example. +import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { url } from '@kit.ArkTS'; + +export default class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + // Obtain the input link information from want. + // For example, the input URL is link://www.example.com/programs?action=showall. + let uri = want?.uri; + if (uri) { + // Parse the query parameter from the link. You can perform subsequent processing based on service requirements. + let urlObject = url.URL.parseURL(want?.uri); + let action = urlObject.params.get('action'); + // For example, if action is set to showall, all programs are displayed. + if (action === "showall") { + // ... + } + } + } +} +``` ## Implementing Application Redirection (Required for the Caller Application) diff --git a/en/application-dev/application-models/extensionability-overview.md b/en/application-dev/application-models/extensionability-overview.md index e69453d113c683c286e1297ab3fa7c063cadc3a2..10dc78d530ac527762000e16b4830fa14ef9fcc8 100644 --- a/en/application-dev/application-models/extensionability-overview.md +++ b/en/application-dev/application-models/extensionability-overview.md @@ -10,23 +10,24 @@ The table below lists the ExtensionAbility types defined in the system. > **NOTE** > -> - The column **Allow Third-Party Apps to Implement** specifies whether third-party applications can inherit the **ExtensionAbility** parent class and implement their own service logic for a type of ExtensionAbility. The value **Y** means that third-party applications can implement their own service logic for a type of ExtensionAbility, **N** means the opposite. -> - The column **Allow Third-Party Apps to Access** specifies whether third-party applications can access external services provided by a type of ExtensionAbility. The value **Y** means that third-party applications can access external services provided by a certain type of ExtensionAbility, **N** means that they cannot access external services, and **NA** means that no external services are provided. -> - The column **Allow Independent ExtensionAbility Sandbox** specifies whether an independent sandbox is provided for an ExtensionAbility. In versions earlier than API version 12, an application and its ExtensionAbilities use the same sandbox. Since API version 12, a new ExtensionAbility uses an independent sandbox. Currently, the InputMethodExtensionAbility runs in an independent sandbox for security purposes. The value **Y** means that an independent sandbox is provided for an ExtensionAbility, and **N** means that no independent sandbox is provided for an ExtensionAbility. -> - The column **Allow ExtensionAbilities to Access Sendable Data in Strict Mode** specifies whether an ExtensionAbility can access sendable data in strict mode. Sendable data is implemented by configuring [data-group-ids](../security/app-provision-structure.md#bundle-info) and [dataGroupIds](../quick-start/module-configuration-file.md#extensionabilities) of the application. Strict access indicates that the sendable data is read-only, and non-strict access indicates that the data can be read and written. The value **Y** means that an ExtensionAbility uses strict mode to access sendable data, that is, it can read sendable data. The value **N** means that an ExtensionAbility uses non-strict mode to access sendable data, that is, it can read and write sendable data. +> - The column **Allow Third-Party Apps to Implement** specifies whether third-party applications can inherit the **ExtensionAbility** parent class and implement their own service logic for a type of ExtensionAbility. +> - The column **Allow Third-Party Apps to Access** specifies whether third-party applications can access external services provided by a type of ExtensionAbility. +> - The column **Allow Independent ExtensionAbility Sandbox** specifies whether an independent sandbox is provided for an ExtensionAbility. In versions earlier than API version 12, an application and its ExtensionAbilities use the same sandbox. Since API version 12, a new ExtensionAbility uses an independent sandbox. Currently, the InputMethodExtensionAbility runs in an independent sandbox for security purposes. +> - The column **Allow ExtensionAbilities to Access Sendable Data in Strict Mode** specifies whether an ExtensionAbility can access sendable data in strict mode. Sendable data is implemented by configuring [data-group-ids](../security/app-provision-structure.md#bundle-info) and [dataGroupIds](../quick-start/module-configuration-file.md#extensionabilities) of the application. Strict access indicates that the sendable data is read-only, and non-strict access indicates that the data can be read and written. System applications are not restricted. They can implement all the ExtensionAbility types defined in the system and access external services provided by all the ExtensionAbility types. | ExtensionAbility Type | Description| Allow Third-Party Apps to Implement | Allow Third-Party Apps to Access | Allow Independent ExtensionAbility Sandbox | Allow ExtensionAbilities to Access Sendable Data in Strict Mode | | ------------------------ | -------- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | - | [FormExtensionAbility](../reference/apis-form-kit/js-apis-app-form-formExtensionAbility.md) | ExtensionAbility component of the FORM type, which provides APIs related to [widgets](../form/formkit-overview.md). | Y | N | N | N | -| [WorkSchedulerExtensionAbility](../reference/apis-backgroundtasks-kit/js-apis-WorkSchedulerExtensionAbility.md) | ExtensionAbility component of the WORK_SCHEDULER type, which provides callbacks for [deferred tasks](../task-management/work-scheduler.md). | Y | NA | N | N | -| [InputMethodExtensionAbility](../reference/apis-ime-kit/js-apis-inputmethod-extension-ability.md) | ExtensionAbility component of the INPUT_METHOD type, which is used to develop [input method applications](../inputmethod/ime-kit-intro.md). | Y | Y | Y | N if you have enabled the full mode in input method management
Y if you have not enabled the full mode in input method management| -| [BackupExtensionAbility](../reference/apis-core-file-kit/js-apis-application-backupExtensionAbility.md) | ExtensionAbility component of the BACKUP type, which provides APIs for [backing up and restoring application data](../file-management/app-file-backup-overview.md). | Y | NA | N | N | -| [DriverExtensionAbility](../reference/apis-driverdevelopment-kit/js-apis-app-ability-driverExtensionAbility.md) | ExtensionAbility component of the DRIVER type, which provides the [driver-related extension framework](../device/driver/driverextensionability.md). | Y | Y | N | N | -| [EmbeddedUIExtensionAbility](../reference/apis-ability-kit/js-apis-app-ability-embeddedUIExtensionAbility.md) | ExtensionAbility component of the EMBEDDED_UI type, which provides the [embedded UI across processes](embeddeduiextensionability.md).| Y | Y | N | N | -| [ShareExtensionAbility](../reference/apis-ability-kit/js-apis-app-ability-shareExtensionAbility.md) | ExtensionAbility component of the SHARE type, which is used to extend the sharing template service.| Y | Y | N | N | + | [FormExtensionAbility](../reference/apis-form-kit/js-apis-app-form-formExtensionAbility.md) | ExtensionAbility component of the FORM type, which provides APIs related to [widgets](../form/formkit-overview.md). | Yes| No| No| In non-strict mode, sendable data can be read and written.| +| [WorkSchedulerExtensionAbility](../reference/apis-backgroundtasks-kit/js-apis-WorkSchedulerExtensionAbility.md) | ExtensionAbility component of the WORK_SCHEDULER type, which provides callbacks for [deferred tasks](../task-management/work-scheduler.md). | Yes| N/A| No| In non-strict mode, sendable data can be read and written.| +| [InputMethodExtensionAbility](../reference/apis-ime-kit/js-apis-inputmethod-extension-ability.md) | ExtensionAbility component of the INPUT_METHOD type, which is used to develop [input method applications](../inputmethod/ime-kit-intro.md). | Yes| Yes| Yes| If full mode is enabled in input method management (in non-strict mode), sendable data can be read and written. If full mode is not enabled (in strict mode), sendable data can be read only.| +| [BackupExtensionAbility](../reference/apis-core-file-kit/js-apis-application-backupExtensionAbility.md) | ExtensionAbility component of the BACKUP type, which provides APIs for [backing up and restoring application data](../file-management/app-file-backup-overview.md). | Yes| N/A| No| In non-strict mode, sendable data can be read and written.| +| [DriverExtensionAbility](../reference/apis-driverdevelopment-kit/js-apis-app-ability-driverExtensionAbility.md) | ExtensionAbility component of the DRIVER type, which provides the [driver-related extension framework](../device/driver/driverextensionability.md). | Yes| Yes| No| In non-strict mode, sendable data can be read and written.| +| [EmbeddedUIExtensionAbility](../reference/apis-ability-kit/js-apis-app-ability-embeddedUIExtensionAbility.md) | ExtensionAbility component of the EMBEDDED_UI type, which provides the [embedded UI across processes](embeddeduiextensionability.md).| Yes| Yes| No| In non-strict mode, sendable data can be read and written.| +| [ShareExtensionAbility](../reference/apis-ability-kit/js-apis-app-ability-shareExtensionAbility.md) | ExtensionAbility component of the SHARE type, which is used to extend the sharing template service.| Yes| Yes| No| In non-strict mode, sendable data can be read and written.| +| [FenceExtension](../reference/apis-location-kit/js-apis-app-ability-FenceExtensionAbility.md) | ExtensionAbility component of the FENCE type, which provides the [geofence](../device/location/fenceExtensionAbility.md) capability.| Yes| No| No| In non-strict mode, sendable data can be read and written.| @@ -45,7 +46,7 @@ The following uses [InputMethodExtensionAbility](../reference/apis-ime-kit/js-ap The following uses [FormExtensionAbility](../reference/apis-form-kit/js-apis-app-form-formExtensionAbility.md) as an example. The widget framework provides the base class **FormExtensionAbility**. You can derive this base class to create your own class (for example, **MyFormExtensionAbility**) and implement the callbacks, such as **onCreate()** and [onUpdateForm()](../reference/apis-form-kit/js-apis-app-form-formExtensionAbility.md#onupdateform), to provide specific widget features. For details, see [Service Widget](../form/formkit-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](../reference/apis-ability-kit/js-apis-app-ability-extensionAbility.md) process where the FormExtensionAbility instance is located are 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](../reference/apis-ability-kit/js-apis-app-ability-extensionAbility.md) process where the FormExtensionAbility instance is located are scheduled and managed by FormManagerService. ![form_extension](figures/form_extension.png) diff --git a/en/application-dev/application-models/figures/AccessibilityFramework.png b/en/application-dev/application-models/figures/AccessibilityFramework.png new file mode 100644 index 0000000000000000000000000000000000000000..786233e6ac160972f62b9786397eb077f7ee767c Binary files /dev/null and b/en/application-dev/application-models/figures/AccessibilityFramework.png differ diff --git a/en/application-dev/application-models/figures/UIServiceExtension-bidirectionalcommunication.png b/en/application-dev/application-models/figures/UIServiceExtension-bidirectionalcommunication.png new file mode 100644 index 0000000000000000000000000000000000000000..bde142e406fae077adbabd52c94a04aa7651dd50 Binary files /dev/null and b/en/application-dev/application-models/figures/UIServiceExtension-bidirectionalcommunication.png differ diff --git a/en/application-dev/application-models/figures/UIServiceExtension-lifecycle.png b/en/application-dev/application-models/figures/UIServiceExtension-lifecycle.png new file mode 100644 index 0000000000000000000000000000000000000000..539fcc3d797c8283edf685a1fc7470e01dc70a3f Binary files /dev/null and b/en/application-dev/application-models/figures/UIServiceExtension-lifecycle.png differ diff --git a/en/application-dev/application-models/figures/WidgerCameraCard.png b/en/application-dev/application-models/figures/WidgerCameraCard.png deleted file mode 100644 index 55e62cdb8791ca6bbc95b7ea4c054e93270ce7a6..0000000000000000000000000000000000000000 Binary files a/en/application-dev/application-models/figures/WidgerCameraCard.png and /dev/null differ diff --git a/en/application-dev/application-models/figures/app-startup-procedure.png b/en/application-dev/application-models/figures/app-startup-procedure.png index d78d1d382595f1d8f8fd67235754c0c9670cc4ef..a861c783ad3c644d50c8c32a0e5cf967b4fbeaef 100644 Binary files a/en/application-dev/application-models/figures/app-startup-procedure.png and b/en/application-dev/application-models/figures/app-startup-procedure.png differ diff --git a/en/application-dev/application-models/figures/application-component-configuration-stage-app-module-1.png b/en/application-dev/application-models/figures/application-component-configuration-stage-app-module-1.png new file mode 100644 index 0000000000000000000000000000000000000000..5db852e92eb2f4bd782df5c370d3028c7cc65cb1 Binary files /dev/null and b/en/application-dev/application-models/figures/application-component-configuration-stage-app-module-1.png differ diff --git a/en/application-dev/application-models/figures/common-event.png b/en/application-dev/application-models/figures/common-event.png deleted file mode 100644 index fe2591d12d5f2c570d7be942d33ec330a6eb6c98..0000000000000000000000000000000000000000 Binary files a/en/application-dev/application-models/figures/common-event.png and /dev/null differ diff --git a/en/application-dev/application-models/figures/component-startup-inner-stage.png b/en/application-dev/application-models/figures/component-startup-inner-stage.png index 6aab67e9142fd9037bf2f9da1d89db0b4a743b50..e6e0f8f74a4879e72d7a2e13ef28ca537947f215 100644 Binary files a/en/application-dev/application-models/figures/component-startup-inner-stage.png and b/en/application-dev/application-models/figures/component-startup-inner-stage.png differ diff --git a/en/application-dev/application-models/figures/component-startup-inter-stage.png b/en/application-dev/application-models/figures/component-startup-inter-stage.png index 40dd6abb971113d853d1cafab2422f19c95332cc..dec5519b65e571f21944f4b1f760e1ec9254eeb5 100644 Binary files a/en/application-dev/application-models/figures/component-startup-inter-stage.png and b/en/application-dev/application-models/figures/component-startup-inter-stage.png differ diff --git a/en/application-dev/application-models/figures/hop-cross-device-migration6.png b/en/application-dev/application-models/figures/hop-cross-device-migration6.png deleted file mode 100644 index 5cc5cb2ca17b8bddf4776928f01c2bee63905cb2..0000000000000000000000000000000000000000 Binary files a/en/application-dev/application-models/figures/hop-cross-device-migration6.png and /dev/null differ diff --git a/en/application-dev/application-models/figures/hop-cross-device-migration7.png b/en/application-dev/application-models/figures/hop-cross-device-migration7.png deleted file mode 100644 index f476e00b8e253e3d6b2fe4bd547674a0448554b4..0000000000000000000000000000000000000000 Binary files a/en/application-dev/application-models/figures/hop-cross-device-migration7.png and /dev/null differ diff --git a/en/application-dev/application-models/figures/hop-cross-device-migration8.png b/en/application-dev/application-models/figures/hop-cross-device-migration8.png deleted file mode 100644 index ec39a1b7aee3adea32e6f84a2b25758ac03a69b0..0000000000000000000000000000000000000000 Binary files a/en/application-dev/application-models/figures/hop-cross-device-migration8.png and /dev/null differ diff --git a/en/application-dev/application-models/figures/start-express-panel.png b/en/application-dev/application-models/figures/start-express-panel.png new file mode 100644 index 0000000000000000000000000000000000000000..82f320c76925a8eb5a3fce09ba1c413b958fa3d6 Binary files /dev/null and b/en/application-dev/application-models/figures/start-express-panel.png differ diff --git a/en/application-dev/application-models/figures/start-finance-panel.png b/en/application-dev/application-models/figures/start-finance-panel.png index 1ead6627e73bfd6ddef90d742fb0f80a0923d8d8..027623fc9f08ebaeaa273e37526ab5e38472ea08 100644 Binary files a/en/application-dev/application-models/figures/start-finance-panel.png and b/en/application-dev/application-models/figures/start-finance-panel.png differ diff --git a/en/application-dev/application-models/figures/start-flight-panel.png b/en/application-dev/application-models/figures/start-flight-panel.png new file mode 100644 index 0000000000000000000000000000000000000000..82f320c76925a8eb5a3fce09ba1c413b958fa3d6 Binary files /dev/null and b/en/application-dev/application-models/figures/start-flight-panel.png differ diff --git a/en/application-dev/application-models/figures/start-mail-panel.png b/en/application-dev/application-models/figures/start-mail-panel.png index 205ac73d4121ae7dd75b58bcd23508ef32786d9d..5f7cbec5c5d6c9855cfa2c87239dceb801993911 100644 Binary files a/en/application-dev/application-models/figures/start-mail-panel.png and b/en/application-dev/application-models/figures/start-mail-panel.png differ diff --git a/en/application-dev/application-models/figures/start-navigation-panel.png b/en/application-dev/application-models/figures/start-navigation-panel.png index 1050cbc2a421b6ae4db98f842091624b764979d6..9d6f54d27fdb2a95507cbcb0fcb00d13dfdc8575 100644 Binary files a/en/application-dev/application-models/figures/start-navigation-panel.png and b/en/application-dev/application-models/figures/start-navigation-panel.png differ diff --git a/en/application-dev/application-models/figures/uiability-launch-type3-principle.png b/en/application-dev/application-models/figures/uiability-launch-type3-principle.png new file mode 100644 index 0000000000000000000000000000000000000000..e4dfa9f8748ae5e2b750fe447b3b47e184d3a8d9 Binary files /dev/null and b/en/application-dev/application-models/figures/uiability-launch-type3-principle.png differ diff --git a/en/application-dev/application-models/file-processing-apps-startup.md b/en/application-dev/application-models/file-processing-apps-startup.md index 6ab62208910f22bafa8a654af3cb2f1ce23b5e56..40faede6f818ab1e81c435f90b1c87e461a13a38 100644 --- a/en/application-dev/application-models/file-processing-apps-startup.md +++ b/en/application-dev/application-models/file-processing-apps-startup.md @@ -14,12 +14,13 @@ You can call [startAbility](../reference/apis-ability-kit/js-apis-inner-applicat **Table 1** Description of [want](../reference/apis-ability-kit/js-apis-app-ability-want.md) in startAbility -| Parameter| Type | Mandatory| Description | +| Parameter| Type | Mandatory| Description | |----------|--------|----------|----------| -| uri | string | Yes | URI of the file to open. This parameter is used together with **type**.
The URI format is file:\/\/bundleName\/path.
- **file**: indicates a file URI.
- **bundleName**: specifies the owner of the file.
- **path**: specifies the application sandbox path of the file. | -| type | string | No | Type of the file to open. [UTD](../database/uniform-data-type-descriptors.md) is recommended, for example, **'general.plain-text'** and **'general.image'**. The [MIME type](https://www.iana.org/assignments/media-types/media-types.xhtml?utm_source=ld246.com) is also supported, for example, **'text/xml'** and **'image/*'**.
**NOTE**
1. The **type** field is optional. If it is not passed, the system attempts to match the file type based on the URI suffix. If it is passed, ensure that it is the same as the file type specified in the URI. Otherwise, no proper application can be matched. For details about the mappings between file name extensions and file types, see [Prebuilt UTDs](../database/uniform-data-type-list.md).
2. **\*/\*** is not supported. | -| parameters | Record | No | Custom parameters that are defined by the system and assigned values by developers as required. For details, see Table 2.| -| flags | number | No| Processing mode. For details, see Table 3.| +| uri | string | Yes | URI of the file to open. This parameter is used together with **type**.
The URI format is file:\/\/bundleName\/path.
- **file**: indicates a file URI.
- **bundleName**: specifies the owner of the file.
- **path**: specifies the application sandbox path of the file.| +| type | string | No | Type of the file to open. [UTD](../database/uniform-data-type-descriptors.md) is recommended, for example, **'general.plain-text'** and **'general.image'**. The [MIME type](https://www.iana.org/assignments/media-types/media-types.xhtml?utm_source=ld246.com) is also supported, for example, **'text/xml'** and **'image/*'**.
**NOTE**
1. The **type** field is optional. If it is not passed, the system attempts to match the file type based on the URI suffix. If it is passed, ensure that it is the same as the file type specified in the URI. Otherwise, no proper application can be matched. For details about the mappings between file name extensions and file types, see [Prebuilt UTDs](../database/uniform-data-type-list.md).
2. **\*/\*** is not supported. +| parameters | Record | No | Custom parameters that are defined by the system and assigned values by developers as required. For details, see Table 2. | +| flags | number | No| Processing mode. For details, see Table 3. | + **Table 2** Description of [parameters](../reference/apis-ability-kit/js-apis-app-ability-wantConstant.md#params) @@ -48,6 +49,7 @@ You can call [startAbility](../reference/apis-ability-kit/js-apis-inner-applicat import { fileUri } from '@kit.CoreFileKit'; import { UIAbility, Want, common, wantConstant } from '@kit.AbilityKit'; import { BusinessError } from '@kit.BasicServicesKit'; + import { window } from '@kit.ArkUI'; ``` 2. Obtain the [application file paths](application-context-stage.md#obtaining-application-file-paths). @@ -91,7 +93,7 @@ You can call [startAbility](../reference/apis-ability-kit/js-apis-inner-applicat ``` 4. Call the API to start the target application. - + ```ts // xxx.ets export default class EntryAbility extends UIAbility { @@ -165,7 +167,7 @@ You can call [startAbility](../reference/apis-ability-kit/js-apis-inner-applicat ```ts // xxx.ets import fs from '@ohos.file.fs'; - import { Want } from '@kit.AbilityKit'; + import { Want, AbilityConstant } from '@kit.AbilityKit'; import { BusinessError } from '@kit.BasicServicesKit'; export default class EntryAbility extends UIAbility { diff --git a/en/application-dev/application-models/hop-cross-device-migration.md b/en/application-dev/application-models/hop-cross-device-migration.md index 5f89071d7946a21ecfd741a983be3b75299cd02e..805682c76b11e0f8df4247b7cce3679c27e6522a 100644 --- a/en/application-dev/application-models/hop-cross-device-migration.md +++ b/en/application-dev/application-models/hop-cross-device-migration.md @@ -51,19 +51,19 @@ The following figure shows the cross-device migration process when a migration r 1. Configure the **continuable** tag under **abilities** in the [module.json5 file](../quick-start/module-configuration-file.md). - ```json - { - "module": { - // ... - "abilities": [ - { - // ... - "continuable": true, // Configure the UIAbility to support migration. - } - ] - } - } - ``` + ```json + { + "module": { + // ... + "abilities": [ + { + // ... + "continuable": true, // Configure the UIAbility to support migration. + } + ] + } + } + ``` > **NOTE** > @@ -73,49 +73,61 @@ The following figure shows the cross-device migration process when a migration r When a migration is triggered for the [UIAbility](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md), [onContinue()](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md#uiabilityoncontinue) is called on the source device. You can use either synchronous or asynchronous mode to save the data in this callback to implement application compatibility check and migration decision. - - Saving data to migrate: You can save the data to migrate in key-value pairs in **wantParam**. - - Checking application compatibility: You can obtain the application version on the target device from **wantParam.version** in the **onContinue()** callback and compare it with the application version on the source device. - - - Making a migration decision: You can determine whether migration is supported based on the return value of **onContinue()**. For details about the return values, see [AbilityConstant.OnContinueResult](../reference/apis-ability-kit/js-apis-app-ability-abilityConstant.md#oncontinueresult). + 1. Saving data to migrate: You can save the data to migrate in key-value pairs in **wantParam**. + + 2. (Optional) Checking application compatibility: You can obtain the application version on the target device from **wantParam.version** in the **onContinue()** callback and compare it with the application version on the source device. If the version compatibility check fails, the application should notify users of the cause of the migration failure. + + > **NOTE** + > + > If the compatibility issues have little or no impact on migration experience, you can skip this check. + + 3. Returning the migration result: You can determine whether migration is supported based on the return value of **onContinue()**. For details about the return values, see [AbilityConstant.OnContinueResult](../reference/apis-ability-kit/js-apis-app-ability-abilityConstant.md#oncontinueresult). + Certain fields (listed in the table below) in **wantParam** passed in to **onContinue()** are preconfigured in the system. You can use these fields for service processing. When defining custom `wantParam` data, do not use the same keys as the preconfigured ones to prevent data exceptions due to system overwrites. + | Field|Description| | ---- | ---- | | version | Version the application on the target device.| | targetDevice | Network ID of the target device.| - + ```ts import { AbilityConstant, UIAbility } from '@kit.AbilityKit'; import { hilog } from '@kit.PerformanceAnalysisKit'; - + import { promptAction } from '@kit.ArkUI'; + const TAG: string = '[MigrationAbility]'; const DOMAIN_NUMBER: number = 0xFF00; - + export default class MigrationAbility extends UIAbility { // Prepare data to migrate in onContinue. onContinue(wantParam: Record):AbilityConstant.OnContinueResult { let targetVersion = wantParam.version; let targetDevice = wantParam.targetDevice; hilog.info(DOMAIN_NUMBER, TAG, `onContinue version = ${targetVersion}, targetDevice: ${targetDevice}`); - - // Obtain the application version on the source device. - let versionSrc: number = -1; // Enter the version number obtained. - + + // The application can set the minimum compatible version based on the source version, which can be obtained from the versionCode field in the app.json5 file. This is to prevent incompatibility caused because the target version is too earlier. + let versionThreshold: number = -1; // Use the minimum version supported by the application. // Compatibility verification - if (targetVersion !== versionSrc) { + if (targetVersion < versionThreshold) { + // It is recommended that users be notified of the reason why the migration is rejected if the version compatibility check fails. + promptAction.showToast({ + message: 'The target application version is too early to continue. Update the application and try again.', + duration: 2000 + }) // Return MISMATCH when the compatibility check fails. return AbilityConstant.OnContinueResult.MISMATCH; } - + // Save the data to migrate in the custom field (for example, data) of wantParam. const continueInput = 'Data to migrate'; wantParam['data'] = continueInput; - + return AbilityConstant.OnContinueResult.AGREE; } } ``` - + 3. For the UIAbility on the target device, implement [onCreate()](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md#uiabilityoncreate) or [onNewWant()](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md#uiabilityonnewwant) to restore the data and load the UI. The APIs to call vary according to the launch types, as shown below. @@ -127,11 +139,11 @@ The following figure shows the cross-device migration process when a migration r > When an application is launched as a result of a migration, the [onWindowStageRestore()](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md#uiabilityonwindowstagerestore) lifecycle callback function, rather than [onWindowStageCreate()](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md#uiabilityonwindowstagecreate), is triggered following **onCreate()** or **onNewWant()**. This sequence occurs for both cold and hot starts. > > If you have performed some necessary initialization operations during application launch in **onWindowStageCreate()**, you must perform the same initialization operations in **onWindowStageRestore()** after the migration to avoid application exceptions. - + - The **launchReason** parameter in the **onCreate()** or **onNewWant()** callback specifies whether the launch is triggered as a result of a migration (whether the value is **CONTINUATION**). - You can obtain the saved data from the [want](../reference/apis-ability-kit/js-apis-app-ability-want.md) parameter. - To use system-level page stack restoration, you must call [restoreWindowStage()](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextrestorewindowstage) to trigger page restoration with page stacks before **onCreate()** or **onNewWant()** is complete. For details, see [On-Demand Page Stack Migration](./hop-cross-device-migration.md#on-demand-page-stack-migration). - + ```ts import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; import { hilog } from '@kit.PerformanceAnalysisKit'; @@ -278,6 +290,7 @@ To implement special scenarios, for example, where migration is required only fo > **NOTE** > > Currently, only the page stack implemented based on the router module can be automatically restored. The page stack implemented using the **Navigation** component cannot be automatically restored. +> > If an application uses the **Navigation** component for routing, you can disable default page stack migration by setting [SUPPORT_CONTINUE_PAGE_STACK_KEY](../reference/apis-ability-kit/js-apis-app-ability-wantConstant.md#params) to **false**. In addition, save the page (or page stack) to be migrated in **want**, and manually load the specified page on the target device. By default, the page stack is restored during the migration of a [UIAbility](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md). Before [onCreate()](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md#uiabilityoncreate) or [onNewWant()](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md#uiabilityonnewwant) finishes the execution, call [restoreWindowStage()](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md#restore) to pass in the current window context, which will be used for page stack loading and restoration. The **restoreWindowStage()** API must be executed in a synchronous API. If it is executed during an asynchronous callback, there is a possibility that the page fails to be loaded during application startup. @@ -354,13 +367,14 @@ export default class MigrationAbility extends UIAbility { } ``` -### Supporting Cross-Device Migration Between Different Abilities in the Same Application +### Migrating Between Abilities in the Same Application Across Devices Generally, the same ability is involved during a cross-device migration. However, different ability names may be configured for the same service on different device types, resulting in different abilities. To support migration in this scenario, you can configure the **continueType** flag under **abilities** in the [module.json5](../quick-start/module-configuration-file.md) file for association. The values of the **continueType** tag of the two abilities must be the same. The following is an example: > **NOTE** > > The value of **continueType** must be unique in an application. The value is a string of a maximum of 127 bytes consisting of letters, digits, and underscores (_). + > > The **continueType** tag is a string array. If multiple fields are configured, only the first field takes effect. ```json @@ -410,7 +424,9 @@ By default, the target application on the peer device is not started immediately } } ``` -With quick start, the target application starts while waiting for the data to migration, minimizing the duration that users wait for the migration to complete. Note that, for the first migration with quick start enabled, the [onCreate()](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md#uiabilityoncreate) or [onNewWant()](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md#uiabilityonnewwant) callback is triggered, in which **launchReason** is **PREPARE_CONTINUATION**. The introduce of the **launchReason** parameter solves problems related to redirection and timing. It also provides a loading screen during quick startup, delivering a better experience. The following figure shows the quick start process. +With quick start, the target application starts while waiting for the data to migration, minimizing the duration that users wait for the migration to complete. Note that, for the first migration with quick start enabled, the [onCreate()](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md#uiabilityoncreate) or [onNewWant()](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md#uiabilityonnewwant) callback is triggered, in which **launchReason** is **PREPARE_CONTINUATION**. The introduction of the **launchReason** parameter solves problems related to redirection and timing. It also provides a loading screen during quick startup. + +The following figure shows the quick start process. ![hop-cross-device-migration](figures/continue_quick_start.png) @@ -475,7 +491,7 @@ export default class MigrationAbility extends UIAbility { } ``` -When the target application is quickly started, the [onWindowStageCreate()](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md#uiabilityonwindowstagecreate) and [onWindowStageRestore()](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md#uiabilityonwindowstagerestore) callbacks are triggered in sequence. Generally, in **onWindowStageCreate()**, you call [loadContent()](../reference/apis-arkui/js-apis-window.md#loadcontent9) to load the page. This API throws an asynchronous task to load the home page. This asynchronous task is not synchronous with **onWindowStageRestore()**. If UI-related APIs (such as route APIs) are used in **onWindowStageRestore()**, the invoking time may be earlier than the home page loading time. To ensure the normal loading sequence, you can use [setTimeout()](../reference/common/js-apis-timer.md#settimeout) to throw an asynchronous task for related operations. For details, see the sample code. +When the target application is quickly started, the [onWindowStageCreate()](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md#uiabilityonwindowstagecreate) and [onWindowStageRestore()](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md#uiabilityonwindowstagerestore) callbacks are triggered in sequence. Generally, in **onWindowStageCreate()**, you call [loadContent()](../reference/apis-arkui/js-apis-window.md#loadcontent9) to load the page. This API throws an asynchronous task to load the home page. This asynchronous task is not synchronous with **onWindowStageRestore()**. If UI-related APIs (such as route APIs) are used in **onWindowStageRestore()**, the invoking time may be earlier than the home page loading time. To ensure the normal loading sequence, you can use [setTimeout()](../reference/common/js-apis-timer.md#settimeout) to throw an asynchronous task for related operations. The sample code is as follows: @@ -599,8 +615,10 @@ On the source device, save the data to migrate to a distributed [data object](.. > **NOTE** > -> Distributed data objects must be activated before being made persistent. Therefore, the **save()** API must be called after setSessionId(). +> Distributed data objects must be activated before being made persistent. Therefore, the **save()** API must be called after **setSessionId()**. +> > For applications that need to exit from the source device after migration, use **await** to wait until the **save()** API finishes execution. This prevents the application from exiting before data is saved. Since API version 12, an asynchronous **onContinue()** API is provided for this scenario. +> > Currently, the **sessionId** field in **wantParams** is occupied by the system in the migration process. You are advised to define another key in **wantParams** to store the ID to avoid data exceptions. The sample code is as follows: @@ -683,9 +701,11 @@ In [onCreate()](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md#u > **NOTE** > -> 1. The distributed data object of the peer device to be added to the network cannot be a temporary variable. This is because the callback of the **on()** API may be executed after **onCreate()** or **onNewWant()** finishes execution. If the temporary variable is released, a null pointer exception may occur. You can use a class member variable to avoid this problem. -> 2. The attributes of the object used to create the distributed data object on the peer device must be undefined before the distributed data object is activated. Otherwise, the source data will be overwritten after new data is added to the network, and data restoration will fail. -> 3. Before activating the distributed data object, call **on()** to listen for the restore event. This helps prevent data restoration failure caused by event missing. +> The distributed data object of the peer device to be added to the network cannot be a temporary variable. This is because the callback of the **on()** API may be executed after **onCreate()** or **onNewWant()** finishes execution. If the temporary variable is released, a null pointer exception may occur. You can use a class member variable to avoid this problem. +> +> The attributes of the object used to create the distributed data object on the peer device must be undefined before the distributed data object is activated. Otherwise, the source data will be overwritten after new data is added to the network, and data restoration will fail. +> +> Before activating the distributed data object, call **on()** to listen for the restore event. This helps prevent data restoration failure caused by event missing. The sample code is as follows: diff --git a/en/application-dev/application-models/inter-device-interaction-hop-overview.md b/en/application-dev/application-models/inter-device-interaction-hop-overview.md index 33f3bb437b3018f0c6be19c96704027ff726c9e1..3b48dd46ccfb8b095b22941cc3fec4d652ea5ba4 100644 --- a/en/application-dev/application-models/inter-device-interaction-hop-overview.md +++ b/en/application-dev/application-models/inter-device-interaction-hop-overview.md @@ -23,7 +23,7 @@ Distributed operations across devices are called hopping, which is further class Multi-device collaboration provides users with more efficient and immersive experience than with a single device. Multi-device collaboration is used in the following typical scenarios: - Scenario 1: You open the same note on devices A and B. On device A, you select images from the local Gallery, insert them to the note, and edit them. On device B, you edit the text. - - Scenario 2: : You are chatting with a customer on device A, and the customer asks for a file, which is stored on device B. You can use the chat software to open the file application on device B, select the required file, and send it back to device A. Then, you use the chat software to send it to the customer. From the perspective of application development, multi-device collaboration enables different UIAbility or ServiceExtensionAbility components to run simultaneously or alternately on multiple devices to provide a complete service, or enables the same UIAbility and ServiceExtensionAbility component to run simultaneously on multiple devices to provide a complete service. + - Scenario 2: : You are chatting with a customer on device A, and the customer asks for a file, which is stored on device B. You can use the chat software to open the file application on device B, select the required file, and send it back to device A. Then, you use the chat software to send it to the customer. From the perspective of application development, multi-device collaboration enables different [UIAbility](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md) or [ServiceExtensionAbility](../reference/apis-ability-kit/js-apis-app-ability-serviceExtensionAbility-sys.md) components to run simultaneously or alternately on multiple devices to provide a complete service, or enables the same UIAbility and ServiceExtensionAbility component to run simultaneously on multiple devices to provide a complete service. ## Hopping Architecture diff --git a/en/application-dev/application-models/mission-set-icon-name-for-task-snapshot.md b/en/application-dev/application-models/mission-set-icon-name-for-task-snapshot.md index 2a0f47113a8b1ee3244aa2f1ea52e4a1bf12ddc5..056ccc169d62f1d83f98efaaf0e8f2ce57e20d96 100644 --- a/en/application-dev/application-models/mission-set-icon-name-for-task-snapshot.md +++ b/en/application-dev/application-models/mission-set-icon-name-for-task-snapshot.md @@ -66,7 +66,7 @@ const DOMAIN_NUMBER: number = 0xFF00; let context: common.UIAbilityContext = this.context; // UIAbilityContext // Set a name for the mission snapshot. context.setMissionLabel('test').then(() => { - hilog.info(DOMAIN_NUMBER, TAG, 'Succeeded in seting mission label.'); + hilog.info(DOMAIN_NUMBER, TAG, 'Succeeded in setting mission label.'); }).catch((err: BusinessError) => { hilog.error(DOMAIN_NUMBER, TAG, `Failed to set mission label. Code is ${err.code}, message is ${err.message}`); }); diff --git a/en/application-dev/application-models/photoEditorExtensionAbility.md b/en/application-dev/application-models/photoEditorExtensionAbility.md index 22fc707d16cca546eb4e7f02dc676a5ad6a9a870..2362da3233dc6a18c3c05e857b02e92e22464441 100644 --- a/en/application-dev/application-models/photoEditorExtensionAbility.md +++ b/en/application-dev/application-models/photoEditorExtensionAbility.md @@ -112,7 +112,6 @@ For details about the APIs, see [PhotoEditorExtensionAbility](../reference/apis- return null; } this.originalImage = pixmap; - fileIo.closeSync(file); return pixmap; } catch(e) { hilog.info(0x0000, TAG, `ReadImage failed:${e}`); @@ -235,7 +234,6 @@ On the UIAbility or UIExtensionAbility page, you can use **startAbilityByType** let timeStamp = Date.now(); // Copy the image to the application sandbox path. fileIo.copyFileSync(file.fd, context.filesDir + `/original-${timeStamp}.jpg`); - fileIo.closeSync(file); this.filePath = context.filesDir + `/original-${timeStamp}.jpg`; this.originalImage = fileUri.getUriFromPath(this.filePath); @@ -320,7 +318,6 @@ struct Index { return null; } this.editedImage = pixmap; - fileIo.closeSync(file); return pixmap; } catch(e) { hilog.info(0x0000, TAG, `readImage failed:${e}`); @@ -369,7 +366,6 @@ struct Index { let timeStamp = Date.now(); // Copy the image to the application sandbox path. fileIo.copyFileSync(file.fd, context.filesDir + `/original-${timeStamp}.jpg`); - fileIo.closeSync(file); this.filePath = context.filesDir + `/original-${timeStamp}.jpg`; this.originalImage = fileUri.getUriFromPath(this.filePath); diff --git a/en/application-dev/application-models/process-model-stage.md b/en/application-dev/application-models/process-model-stage.md index ee27e29101a3fea080e3a83644e40b319042aef9..ebfebd122fffcb6644f8cdab222aa1a9332bc74a 100644 --- a/en/application-dev/application-models/process-model-stage.md +++ b/en/application-dev/application-models/process-model-stage.md @@ -1,13 +1,19 @@ # Process Model (Stage Model) +A process is the basic unit for a system to allocate resources, and is the basis of an operating system structure. The process model is shown below. - -- All UIAbility, ServiceExtensionAbility, and DataShareExtensionAbility components of an application (with the same bundle name) run in an independent process, which is **Main process** in green in the figure. -- All ExtensionAbility components of the same type (except ServiceExtensionAbility and DataShareExtensionAbility) of an application (with the same bundle name) run in an independent process, such as **FormExtensionAbility process**, **InputMethodExtensionAbility process**, and other **ExtensionAbility process** in blue in the figure. +- Generally, all UIAbility, ServiceExtensionAbility, and DataShareExtensionAbility components of an application (with the same bundle name) run in an independent process, which is **Main process** in green in the figure. +- All ExtensionAbility components of the same type (except ServiceExtensionAbility and DataShareExtensionAbility) of an application (with the same bundle name) run in an independent process, such as **FormExtensionAbility process**, **InputMethodExtensionAbility process**, and other **ExtensionAbility process** in blue in the figure. - WebView has an independent render process, which is **Render process** in yellow in the figure. +> **NOTE** +> +> For 2-in-1 devices, you can set a specific HAP or UIAbility to run in an independent process. +> - To enable a HAP to run in an independent process, set the **isolationMode** field in the **module.json5** file to **isolationOnly** (running only in an independent process) or **isolationFirst** (running in an independent process preferentially). +> - To enable a UIAbility to run in an independent process, set the **isolationProcess** field in the **module.json5** file to **true** and return a unique process ID in the [onNewProcessRequest](../reference/apis-ability-kit/js-apis-app-ability-abilityStage.md) callback. + **Figure 1** Process model ![process-model](figures/process-model.png) @@ -17,7 +23,7 @@ The process model is shown below. > - 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. In this way, the UIAbilities, DataShareExtensionAbilities, and ServiceExtensionAbilities in the HAP run in the custom process. For details about how to request the permissions, see [Application Privilege Configuration](../../device-dev/subsystems/subsys-app-privilege-config-guide.md). To configure a custom process for an HAP, use **process** in [module.json5](../quick-start/module-configuration-file.md#tags-in-the-configuration-file). **Figure 2** Multi-process @@ -28,5 +34,3 @@ The system provides the following inter-process communication (IPC) mechanism: [Common Events](../basic-services/common-event/common-event-overview.md): This mechanism is used in one-to-many communication scenarios. Multiple subscribers may receive events at the same time. - - \ No newline at end of file diff --git a/en/application-dev/application-models/serviceextensionability.md b/en/application-dev/application-models/serviceextensionability.md index f47a2e64822fcdae0b979db97e76ef9ab94839ce..ac4a657f518a01a3817f8664c655fa376b532cbd 100644 --- a/en/application-dev/application-models/serviceextensionability.md +++ b/en/application-dev/application-models/serviceextensionability.md @@ -4,7 +4,7 @@ [ServiceExtensionAbility](../reference/apis-ability-kit/js-apis-app-ability-serviceExtensionAbility-sys.md) is an [ExtensionAbility](../reference/apis-ability-kit/js-apis-app-ability-extensionAbility.md) component of the SERVICE type that provides capabilities related to background services. It holds an internal [ServiceExtensionContext](../reference/apis-ability-kit/js-apis-inner-application-serviceExtensionContext-sys.md), which provides a variety of APIs for external systems. -In this document, the started ServiceExtensionAbility is called the server, and the component that starts the ServiceExtensionAbility is called the client. +In this document, the component that starts or connects to a ServiceExtensionAbility is called the client, and the ServiceExtensionAbility is called the server. A ServiceExtensionAbility can be started or connected by other components to process transactions in the background based on the request of the caller. System applications can call the [startServiceExtensionAbility()](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext-sys.md#uiabilitycontextstartserviceextensionability) method to start background services or call the [connectServiceExtensionAbility()](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextconnectserviceextensionability) method to connect to background services. Third-party applications can call only **connectServiceExtensionAbility()** to connect to background services. The differences between starting and connecting to a ServiceExtensionAbility are as follows: @@ -66,9 +66,9 @@ The [ServiceExtensionAbility](../reference/apis-ability-kit/js-apis-app-ability- Only system applications can implement a [ServiceExtensionAbility](../reference/apis-ability-kit/js-apis-app-ability-serviceExtensionAbility-sys.md). You must make the following preparations before development: -- **Switching to the full SDK**: All the APIs provided by the **ServiceExtensionAbility** class are marked as system APIs and hidden by default. Therefore, you must manually obtain the full SDK from the mirror and switch to it in DevEco Studio. For details, see [Guide to Switching to Full SDK](../faqs/full-sdk-switch-guide.md). +- **Switching to the full SDK**: All the APIs provided by the **ServiceExtensionAbility** class are marked as system APIs and hidden by default. Therefore, you must manually obtain the full SDK from the mirror and switch to it in DevEco Studio. For details, see [Switching to Full SDK](../faqs/full-sdk-switch-guide.md). -- **Requesting the AllowAppUsePrivilegeExtension privilege**: Only applications with the **AllowAppUsePrivilegeExtension** privilege can implement a ServiceExtensionAbility. For details about how to request the privilege, see [Application Privilege Configuration Guide](../../device-dev/subsystems/subsys-app-privilege-config-guide.md). +- **Requesting the AllowAppUsePrivilegeExtension privilege**: Only applications with the **AllowAppUsePrivilegeExtension** privilege can implement a ServiceExtensionAbility. For details about how to request the privilege, see [Application Privilege Configuration](../../device-dev/subsystems/subsys-app-privilege-config-guide.md). ### Defining IDL APIs @@ -203,7 +203,7 @@ To manually create a ServiceExtensionAbility in the DevEco Studio project, perfo ## Starting a Background Service (for System Applications Only) -A system application uses the [startServiceExtensionAbility()](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext-sys.md#uiabilitycontextstartserviceextensionability) method to start a background service. The [onRequest()](../reference/apis-ability-kit/js-apis-app-ability-serviceExtensionAbility-sys.md#serviceextensionabilityonrequest) callback is invoked, through which the background service receives the **Want** object passed by the caller. After the background service is started, its lifecycle is independent of that of the client. In other words, even if the client is destroyed, the background service remains alive. Therefore, the background service must be stopped by calling [terminateSelf()](../reference/apis-ability-kit/js-apis-inner-application-serviceExtensionContext-sys.md#serviceextensioncontextterminateself) when its work is complete. Alternatively, another component can call [stopServiceExtensionAbility()](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext-sys.md#abilitycontextstopserviceextensionability) to stop the background service. +A system application uses the [startServiceExtensionAbility()](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext-sys.md#uiabilitycontextstartserviceextensionability) method to start a background service. The [onRequest()](../reference/apis-ability-kit/js-apis-app-ability-serviceExtensionAbility-sys.md#serviceextensionabilityonrequest) callback is invoked, through which the background service receives the Want object passed by the caller. After the background service is started, its lifecycle is independent of the client. In other words, even if the client is destroyed, the background service remains alive. Therefore, the background service must be stopped by calling [terminateSelf()](../reference/apis-ability-kit/js-apis-inner-application-serviceExtensionContext-sys.md#serviceextensioncontextterminateself) when its work is complete. Alternatively, another component can call [stopServiceExtensionAbility()](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext-sys.md#abilitycontextstopserviceextensionability) to stop the background service. > **NOTE** > **startServiceExtensionAbility()**, **stopServiceExtensionAbility()**, and **terminateSelf()** provided by the **ServiceExtensionContext** class are system APIs and cannot be called by third-party applications. @@ -634,7 +634,7 @@ When a ServiceExtensionAbility is used to provide sensitive services, the client - **Verifying the client identity based on callerTokenId** - Call the [getCallingTokenId()](../reference/apis-ipc-kit/js-apis-rpc.md#getcallingtokenid) method to obtain the token ID of the client, and then call the [verifyAccessTokenSync()](../reference/apis-ability-kit/js-apis-abilityAccessCtrl.md#verifyaccesstokensync) method to check whether the client has the required permission. Currently, the system does not support permission customization. Therefore, only [system-defined permissions](../security/AccessToken/permissions-for-all.md) can be verified. The sample code is as follows: + Call the [getCallingTokenId()](../reference/apis-ipc-kit/js-apis-rpc.md#getcallingtokenid) method to obtain the token ID of the client, and then call the [verifyAccessTokenSync()](../reference/apis-ability-kit/js-apis-abilityAccessCtrl.md#verifyaccesstokensync) method to check whether the client has the required permission. Currently, the system does not support permission customization. Therefore, only [system-defined permissions](../security/AccessToken/app-permissions.md) can be verified. The sample code is as follows: ```ts import { abilityAccessCtrl, bundleManager } from '@kit.AbilityKit'; @@ -671,9 +671,7 @@ When a ServiceExtensionAbility is used to provide sensitive services, the client let callerTokenId = rpc.IPCSkeleton.getCallingTokenId(); let accessManger = abilityAccessCtrl.createAtManager(); - /* The permission to be verified varies depending on the service requirements. - * ohos.permission.GET_BUNDLE_INFO_PRIVILEGED is only an example. - */ + // The permission to be verified varies depending on the service requirements. ohos.permission.GET_BUNDLE_INFO_PRIVILEGED is only an example. let grantStatus = accessManger.verifyAccessTokenSync(callerTokenId, 'ohos.permission.GET_BUNDLE_INFO_PRIVILEGED'); if (grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_DENIED) { hilog.info(DOMAIN_NUMBER, TAG, 'PERMISSION_DENIED'); diff --git a/en/application-dev/application-models/start-email-apps.md b/en/application-dev/application-models/start-email-apps.md index 252aeabc97cb6e1da148dd2e6c3330a622d04998..3225e739023cf5471331324c20b74b65085c7d87 100644 --- a/en/application-dev/application-models/start-email-apps.md +++ b/en/application-dev/application-models/start-email-apps.md @@ -15,7 +15,7 @@ If the **type** field in **startAbilityByType** is set to **mail**, **wantParam* | body | string | No | Email body. | | ability.params.stream | string[ ] | No | Email attachments (URI list of the attachments). | | ability.want.params.uriPermissionFlag | [wantConstant.Flags](../reference/apis-ability-kit/js-apis-app-ability-wantConstant.md#flags) | No | At least the read permission must be granted on the email attachments. This parameter is mandatory when **ability.params.stream** is specified.| -| sceneType | number | No | 1: Send an email. The default value is **1**. | +| sceneType | number | No | Intent scene, which indicates the purpose of the current request. 1: Send an email. The default value is **1**. | > **NOTE** > @@ -24,7 +24,7 @@ If the **type** field in **startAbilityByType** is set to **mail**, **wantParam* > * For parameters of the string[] type displayed in the vertical domain panel of email applications, all elements in the array must be encoded using **encodeURI**. ## Developing a Caller Application -1. Import the **ohos.app.ability.common** module. +1. Import the module. ```ts import { common, wantConstant } from '@kit.AbilityKit'; ``` @@ -96,7 +96,7 @@ If the **type** field in **startAbilityByType** is set to **mail**, **wantParam* 2. Parse and process the parameters transferred from the panel. ```ts - UIAbility::onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void + UIAbility.onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void ``` The **want.parameters** parameter contains the following parameters, which may be slightly different from the ones passed in by the caller. diff --git a/en/application-dev/application-models/start-express-apps.md b/en/application-dev/application-models/start-express-apps.md new file mode 100644 index 0000000000000000000000000000000000000000..3a8a261df465449a0594ce40cc35328ba92ad38e --- /dev/null +++ b/en/application-dev/application-models/start-express-apps.md @@ -0,0 +1,183 @@ +# Using startAbilityByType to Start an Express Delivery Application + +This topic describes how to open the vertical domain panel of express delivery applications. + +For example, in a messaging application, when a user receives a delivery tracking number, the application can identify this number and provide a link for querying the package. After the user touches the link, the application calls [UIAbilityContext.startAbilityByType](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartabilitybytype11) or [UIExtensionContentSession.startAbilityByType](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionContentSession.md#uiextensioncontentsessionstartabilitybytype11) to open a panel. This panel displays all available applications on the device that support express delivery query, enabling the user to select and switch to the application that meets their needs. + +## Parameters on the Express Delivery Application Panel + +If the **type** field in **startAbilityByType** is set to **express**, the intent scenario of express delivery query is supported. The corresponding **wantParam** parameter contains the following properties. + + +| Name | Type | Mandatory| Description | +| --------- | ------ | ---- | -------------------------------------- | +| sceneType | number | No | Intent scene, which indicates the purpose of the current request. The default value is **1**. In express delivery query scenarios, set it to **1** or leave it empty.| +| expressNo | string | Yes | Express delivery tracking number. | + + +## Developing a Caller Application + +1. Import the module. + ```ts + import { common } from '@kit.AbilityKit'; + ``` +2. Construct parameters and call the **startAbilityByType** API. + + ```ts + let context = getContext(this) as common.UIAbilityContext; + let wantParam: Record = { + 'sceneType': 1, + 'expressNo': 'SF123456' + }; + let abilityStartCallback: common.AbilityStartCallback = { + onError: (code: number, name: string, message: string) => { + console.log(`onError code ${code} name: ${name} message: ${message}`); + }, + onResult: (result)=>{ + console.log(`onResult result: ${JSON.stringify(result)}`); + } + } + + context.startAbilityByType("express", wantParam, abilityStartCallback, + (err) => { + if (err) { + console.error(`startAbilityByType fail, err: ${JSON.stringify(err)}`); + } else { + console.log(`success`); + } + }); + + ``` + + Effect + + ![Effect example](./figures/start-express-panel.png) + +## Developing a Target Application + +1. Configure [uris](../quick-start/module-configuration-file.md#skills) in the **module.json5** file. + 1. Set the **linkFeature** field to declare the features supported by the application so that the system can match the application against all the installed applications on the device. The options are as follows: + | Value | Description | + | ------------ | -------------------- | + | QueryExpress | Declares that the application supports express delivery query.| + 2. Set **scheme**, **host**, **port**, and **path** or **pathStartWith** to match the URIs in Want to distinguish different features. + ```json + { + "abilities": [ + { + "skills": [ + { + "uris": [ + { + "scheme": "express", + "host": "queryExpress", + "path": "", + "linkFeature": "QueryExpress" + } + ] + } + ] + } + ] + } + ``` + +2. Parse parameters and perform corresponding processing. + + ```ts + UIAbility.onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void + ``` + + The **want.uri** parameter carries the URI corresponding to **linkFeature** configured by the target application. + + The **want.parameters** parameter carries the parameters transferred by the caller application, as described in the table below. + + | Name | Type | Mandatory| Description | + | --------- | ------ | ---- | -------- | + | expressNo | string | Yes | Express delivery tracking number.| + + + +**Sample Code** + +```ts +import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; + +const TAG = 'EntryAbility' + +export default class EntryAbility extends UIAbility { + windowStage: window.WindowStage | null = null; + + uri?: string; + expressNo?: string; + + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + hilog.info(0x0000, TAG, `onCreate, want=${JSON.stringify(want)}`); + super.onCreate(want, launchParam); + this.parseWant(want); + } + + onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): void { + hilog.info(0x0000, TAG, `onNewWant, want=${JSON.stringify(want)}`); + super.onNewWant(want, launchParam); + this.parseWant(want); + if (!this.windowStage) { + hilog.error(0x0000, TAG, 'windowStage is null'); + this.context.terminateSelf(); + return; + } + this.loadPage(this.windowStage); + } + + private parseWant(want: Want): void { + this.uri = want.uri as string | undefined; + this.expressNo = want.parameters?.expressNo as string | undefined; + } + + private loadPage(windowStage: window.WindowStage): void { + hilog.info(0x0000, TAG, `loadPage, uri=${this.uri}`); + if (this.uri === 'express://queryExpress') { + // Build express delivery query parameters. + const storage: LocalStorage = new LocalStorage({ + "expressNo": this.expressNo + } as Record); + // Display the express delivery query page. + windowStage.loadContent('pages/QueryExpressPage', storage) + } else { + // Display the home page by default. + windowStage.loadContent('pages/Index', (err) => { + if (err.code) { + hilog.error(0x0000, TAG, 'Failed to load the content. Cause: %{public}s', + JSON.stringify(err) ?? ''); + return; + } + hilog.info(0x0000, TAG, 'Succeeded in loading the content.'); + }); + } + } + + onDestroy(): void { + hilog.info(0x0000, TAG, `onDestroy`); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + hilog.info(0x0000, TAG, `onWindowStageCreate`); + this.windowStage = windowStage; + this.loadPage(this.windowStage); + } + + onWindowStageDestroy(): void { + hilog.info(0x0000, TAG, '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground(): void { + hilog.info(0x0000, TAG, '%{public}s', 'Ability onForeground'); + } + + onBackground(): void { + hilog.info(0x0000, TAG, '%{public}s', 'Ability onBackground'); + } +} +``` diff --git a/en/application-dev/application-models/start-finance-apps.md b/en/application-dev/application-models/start-finance-apps.md index 91ce78c056de907eb60d160b3678bda52f117c54..bc5e9137736fe5adfb25d8268de77c7739b90bec 100644 --- a/en/application-dev/application-models/start-finance-apps.md +++ b/en/application-dev/application-models/start-finance-apps.md @@ -8,11 +8,11 @@ If the **type** field in **startAbilityByType** is set to **finance**, **wantPar | Name | Type | Mandatory| Description| | -------------------- | ------------------------------------------------------------ | -------- | -------- | -| sceneType | number | No| The options are as follows: 1: transfer; 2: credit card repayment. The default value is **1**.| +| sceneType | number | No| Intent scene, which indicates the purpose of the current request. The options are as follows: 1: transfer; 2: credit card repayment. The default value is **1**.| | bankCardNo | string | No | Bank card number.| ## Developing a Caller Application -1. Import the **ohos.app.ability.common** module. +1. Import the module. ```ts import { common } from '@kit.AbilityKit'; ``` @@ -87,7 +87,7 @@ If the **type** field in **startAbilityByType** is set to **finance**, **wantPar 2. Parse and process the parameters transferred from the panel. ```ts - UIAbility::onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void + UIAbility.onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void ``` The **want.uri** parameter carries the URI corresponding to **linkFeature** configured by the target application. diff --git a/en/application-dev/application-models/start-flight-apps.md b/en/application-dev/application-models/start-flight-apps.md new file mode 100644 index 0000000000000000000000000000000000000000..af2107cf64e355f6280d83dfc5ec0ea164ce2f3c --- /dev/null +++ b/en/application-dev/application-models/start-flight-apps.md @@ -0,0 +1,228 @@ +# Using startAbilityByType to Start a Flight Application + +This topic describes how to open the vertical domain panel of flight applications. + +For example, in a travel scheduling application, if a user inputs the flight number for an upcoming journey, the application can identify this flight number and provide a link to track the flight status. After the user touches the link, the application calls [UIAbilityContext.startAbilityByType](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartabilitybytype11) or [UIExtensionContentSession.startAbilityByType](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionContentSession.md#uiextensioncontentsessionstartabilitybytype11) to open a panel. This panel displays all available applications on the device that support flight query, enabling the user to select and switch to the application that meets their needs. + +## Parameters on the Flight Application Panel + +If the **type** field in **startAbilityByType** is set to **flight**, two intent scenarios are supported: flight query by flight number and by origin and destination. The corresponding **wantParam** parameter contains the following properties. + +- Flight query by flight number + + | Name | Type | Mandatory| Description | + | ------------- | ------ | ---- | ------------------------------------------------------------ | + | sceneType | number | No | Intent scene, which indicates the purpose of the current request. The default value is **1**. In scenarios of flight query by flight number, set it to **1** or leave it empty. | + | flightNo | string | Yes | Flight number, which is a two-digit code of the airline company plus a dight.| + | departureDate | string | No | Flight departure date, in the format of YYYY-MM-DD. | + +- Flight query by origin and destination + + | Name | Type | Mandatory| Description | + | -------------------- | ---------------------- | ---- | -------------------------------------------------------- | + | sceneType | number | Yes | Intent scene, which indicates the purpose of the current request. In scenarios of flight query by origin and destination, set it to **2**. | + | originLocation | string | Yes | Departure place. | + | destinationLocation | string | Yes | Destination. | + | departureDate | string | No | Flight departure date, in the format of YYYY-MM-DD. | + + +## Developing a Caller Application + +1. Import the module. + ```ts + import { common } from '@kit.AbilityKit'; + ``` + +2. Construct parameters and call the **startAbilityByType** API. + + ```ts + let context = getContext(this) as common.UIAbilityContext; + let wantParam: Record = { + 'sceneType': 1, + 'flightNo': 'ZH1509', + 'departureDate': '2024-10-01' + }; + let abilityStartCallback: common.AbilityStartCallback = { + onError: (code: number, name: string, message: string) => { + console.log(`onError code ${code} name: ${name} message: ${message}`); + }, + onResult: (result)=>{ + console.log(`onResult result: ${JSON.stringify(result)}`); + } + } + + context.startAbilityByType("flight", wantParam, abilityStartCallback, + (err) => { + if (err) { + console.error(`startAbilityByType fail, err: ${JSON.stringify(err)}`); + } else { + console.log(`success`); + } + }); + ``` + Effect + + ![Effect example](./figures/start-flight-panel.png) + +## Developing a Target Application + +1. Configure [uris](../quick-start/module-configuration-file.md#skills) in the **module.json5** file. + 1. Set the **linkFeature** field to declare the features supported by the application so that the system can match the application against all the installed applications on the device. The options are as follows: + | Value | Description | + | ----------- | ------------------------ | + | QueryByFlightNo | Declares that the application supports flight query by flight number. | + | QueryByLocation | Declares that the application supports flight query by origin and destination.| + 2. Set **scheme**, **host**, **port**, and **path** or **pathStartWith** to match the URIs in Want to distinguish different features. + ```json + { + "abilities": [ + { + "skills": [ + { + "uris": [ + { + "scheme": "flight", + "host": "queryByFlightNo", + "path": "", + "linkFeature": "QueryByFlightNo" + }, + { + "scheme": "flight", + "host": "queryByLocation", + "path": "", + "linkFeature": "QueryByLocation" + } + ] + } + ] + } + ] + } + ``` + +2. Parse parameters and perform corresponding processing. + + ```ts + UIAbility.onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void + ``` + + The **want.uri** parameter carries the URI corresponding to **linkFeature** configured by the target application. + + **want.parameters** carries the parameters passed by the caller, which vary in different scenarios. + + - Flight query by flight number + + | Name | Type | Mandatory| Description | + | -------------------- | ------ | ---- | ---------------------------------------------------- | + | flightNo | string | Yes | Flight number, which is a two-digit code of the airline company plus a dight. | + | departureDate | string | No | Flight departure date, in the format of YYYY-MM-DD. If this field is left blank, it indicates the current day. | + + - Flight query by origin and destination + + | Name | Type | Mandatory| Description | + | -------------------- | ------ | ---- | -------------------------------------------------- | + | originLocation | string | Yes | Departure place. | + | destinationLocation | string | Yes | Destination. | + | departureDate | string | No | Flight departure date, in the format of YYYY-MM-DD. If this field is left blank, it indicates the current day. | + + The application can develop different style pages based on the features defined in [linkFeature](../quick-start/module-configuration-file.md#skills), such as flight query by flight number or by origin and destination, as well as the received URI and parameters. + +**Sample Code** + +```ts +import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; + +const TAG = 'EntryAbility' + +export default class EntryAbility extends UIAbility { + windowStage: window.WindowStage | null = null; + + uri?: string; + flightNo?: string; + departureDate?: string; + originLocation?: string; + destinationLocation?: string; + + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + hilog.info(0x0000, TAG, `onCreate, want=${JSON.stringify(want)}`); + super.onCreate(want, launchParam); + this.parseWant(want); + } + + onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): void { + hilog.info(0x0000, TAG, `onNewWant, want=${JSON.stringify(want)}`); + super.onNewWant(want, launchParam); + this.parseWant(want); + if (!this.windowStage) { + hilog.error(0x0000, TAG, 'windowStage is null'); + this.context.terminateSelf(); + return; + } + this.loadPage(this.windowStage); + } + + private parseWant(want: Want): void { + this.uri = want.uri as string | undefined; + this.flightNo = want.parameters?.flightNo as string | undefined; + this.departureDate = want.parameters?.departureDate as string | undefined; + this.originLocation = want.parameters?.originLocation as string | undefined; + this.destinationLocation = want.parameters?.destinationLocation as string | undefined; + } + + private loadPage(windowStage: window.WindowStage): void { + hilog.info(0x0000, TAG, `loadPage, uri=${this.uri}`); + if (this.uri === 'flight://queryByFlightNo') { + // Construct parameters for scenarios of flight query by flight number. + const storage: LocalStorage = new LocalStorage({ + "flightNo": this.flightNo, + "departureDate": this.departureDate + } as Record); + // Display the page for querying flights by flight number. + windowStage.loadContent('pages/QueryByFlightNoPage', storage) + } else if (this.uri === 'flight://queryByLocation') { + // Construct parameters for scenarios of flight query by origin and destination. + const storage: LocalStorage = new LocalStorage({ + "originLocation": this.originLocation, + "destinationLocation": this.destinationLocation, + "departureDate": this.departureDate + } as Record); + // Display the page for querying flights by origin and destination. + windowStage.loadContent('pages/QueryByLocationPage', storage) + } else { + // Display the home page by default. + windowStage.loadContent('pages/Index', (err) => { + if (err.code) { + hilog.error(0x0000, TAG, 'Failed to load the content. Cause: %{public}s', + JSON.stringify(err) ?? ''); + return; + } + hilog.info(0x0000, TAG, 'Succeeded in loading the content.'); + }); + } + } + + onDestroy(): void { + hilog.info(0x0000, TAG, `onDestroy`); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + hilog.info(0x0000, TAG, `onWindowStageCreate`); + this.windowStage = windowStage; + this.loadPage(this.windowStage); + } + + onWindowStageDestroy(): void { + hilog.info(0x0000, TAG, '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground(): void { + hilog.info(0x0000, TAG, '%{public}s', 'Ability onForeground'); + } + + onBackground(): void { + hilog.info(0x0000, TAG, '%{public}s', 'Ability onBackground'); + } +} +``` diff --git a/en/application-dev/application-models/start-navigation-apps.md b/en/application-dev/application-models/start-navigation-apps.md index 92c52004b84f86ee6a13b4e753f6e3a905970ac3..de6ef28da69ff35d382d57146324a79878807323 100644 --- a/en/application-dev/application-models/start-navigation-apps.md +++ b/en/application-dev/application-models/start-navigation-apps.md @@ -15,7 +15,7 @@ If the **type** field in **startAbilityByType** is set to **navigation**, three | Name | Type | Mandatory| Description | | -------------------- | ---------------------- | ---- | ---------------------------------------------------- | - | sceneType | number | No | Intent. The default value is **1**. In route planning scenarios, set it to **1** or leave it empty. | + | sceneType | number | No | Intent scene, which indicates the purpose of the current request. The default value is **1**. In route planning scenarios, set it to **1** or leave it empty. | | originName | string | No | Name of the source. | | originLatitude | number | No | Latitude of the source. | | originLongitude | number | No | Longitude of the source. | @@ -30,7 +30,7 @@ If the **type** field in **startAbilityByType** is set to **navigation**, three | Name | Type | Mandatory| Description | | -------------------- | ---------------------- | ---- | ----------------- | - | sceneType | number | Yes | Intent. Set it to **2** for navigation scenarios.| + | sceneType | number | Yes | Intent scene, which indicates the purpose of the current request. Set it to **2** for navigation scenarios.| | destinationName | string | No | Name of the destination. | | destinationLatitude | number | Yes | Latitude of the destination. | | destinationLongitude | number | Yes | Longitude of the destination. | @@ -40,21 +40,21 @@ If the **type** field in **startAbilityByType** is set to **navigation**, three | Name | Type | Mandatory| Description | | --------------- | ------ | ---- | --------------------- | - | sceneType | number | Yes | Intent. Set it to **3** for place search scenarios.| + | sceneType | number | Yes | Intent scene, which indicates the purpose of the current request. Set it to **3** for place search scenarios.| | destinationName | string | Yes | Name of the destination. | ## Developing a Caller Application -1. Import the **ohos.app.ability.common** module. +1. Import the module. ```ts import { common } from '@kit.AbilityKit'; ``` 2. Construct parameters and call the **startAbilityByType** API. You need to obtain the POI IDs of the destination and origin from each map system and pass the parameters **destinationPoiIds** and **originPoiIds** based on the mappings. - - + + ```ts let context = getContext(this) as common.UIAbilityContext; let wantParam: Record = { @@ -63,10 +63,10 @@ If the **type** field in **startAbilityByType** is set to **navigation**, three 'destinationLongitude': 118.78315, 'destinationName': 'No.xx, xx Road, xx City', 'destinationPoiIds': { - 1: '1111', // Key 1 indicates Petal Maps, and the value must be a POI in Petal Maps. + 1:'1111', // Key 1 indicates Petal Maps, and the value must be a POI in Petal Maps. 2:'2222' // Key 2 indicates AutoNavi Map, and the value must be a POI in AutoNavi Map. } as Record, - 'originName': 'xx Park in xx City', + 'originName': 'xx Park in xx City', 'originLatitude': 31.060844, 'originLongitude': 120.78315, 'originPoiIds': { @@ -108,44 +108,43 @@ If the **type** field in **startAbilityByType** is set to **navigation**, three | RoutePlan | The application supports route planning. | | PlaceSearch | The application supports place search. | 2. Set **scheme**, **host**, **port**, and **path** or **pathStartWith** to match the URIs in Want to distinguish different features. - - ```json - { - "abilities": [ + ```json + { + "abilities": [ + { + "skills": [ { - "skills": [ + "uris": [ + { + "scheme": "maps", // It is for reference only. Ensure that the declared URI can be started by external systems. + "host": "navigation", + "path": "", + "linkFeature": "Navigation" // Declare that the application supports navigation. + }, + { + "scheme": "maps", // It is for reference only. Ensure that the declared URI can be started by external systems. + "host": "routePlan", + "path": "", + "linkFeature": "RoutePlan" // Declare that the application supports route planning. + }, { - "uris": [ - { - "scheme": "maps", // It is for reference only. Ensure that the declared URI can be started by external systems. - "host": "navigation", - "path": "", - "linkFeature": "Navigation" // Declare that the application supports navigation. - }, - { - "scheme": "maps", // It is for reference only. Ensure that the declared URI can be started by external systems. - "host": "routePlan", - "path": "", - "linkFeature": "RoutePlan" // Declare that the application supports route planning. - }, - { - "scheme": "maps", // It is for reference only. Ensure that the declared URI can be started by external systems. - "host": "search", - "path": "", - "linkFeature": "PlaceSearch" // Declare that the application supports place search. - } - ] + "scheme": "maps", // It is for reference only. Ensure that the declared URI can be started by external systems. + "host": "search", + "path": "", + "linkFeature": "PlaceSearch" // Declare that the application supports place search. } ] } ] - } - ``` - + } + ] + } + ``` + 2. Parse parameters and perform corresponding processing. ```ts - UIAbility::onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void + UIAbility.onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void ``` The **want.uri** parameter carries the URI corresponding to **linkFeature** configured by the target application. @@ -181,7 +180,7 @@ If the **type** field in **startAbilityByType** is set to **navigation**, three | --------------- | ------ | ---- | -------- | | destinationName | string | Yes | Name of the destination.| - The application can develop different style pages based on the features defined in [linkFeature](../quick-start/module-configuration-file.md#skills), such as route planning, navigation, and place search, as well as the received URI and parameters. +The application can develop different style pages based on the features defined in [linkFeature](../quick-start/module-configuration-file.md#skills), such as route planning, navigation, and place search, as well as the received URI and parameters. **Sample Code** diff --git a/en/application-dev/application-models/storage-switch.md b/en/application-dev/application-models/storage-switch.md index 9a32ebd60f84f7553d906948a1982d7fa82a5869..806f137a7f88401890085c1ba149e05a4ecbd767 100644 --- a/en/application-dev/application-models/storage-switch.md +++ b/en/application-dev/application-models/storage-switch.md @@ -1,15 +1,13 @@ # Storage 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| | -------- | -------- | -------- | -| GetStorageOptions | There is no corresponding API in the stage model.| The stage model uses **Prefereces** to replace **Storage** and has redesigned the input parameters.| -| SetStorageOptions | There is no corresponding API in the stage model.| The stage model uses **Prefereces** to replace **Storage** and has redesigned the input parameters.| -| ClearStorageOptions | There is no corresponding API in the stage model.| The stage model uses **Prefereces** to replace **Storage** and has redesigned the input parameters.| -| DeleteStorageOptions | There is no corresponding API in the stage model.| The stage model uses **Prefereces** to replace **Storage** and has redesigned the input parameters.| +| GetStorageOptions | There is no corresponding API in the stage model.| The stage model uses **Preferences** to replace **Storage** and has redesigned the input parameters.| +| SetStorageOptions | There is no corresponding API in the stage model.| The stage model uses **Preferences** to replace **Storage** and has redesigned the input parameters.| +| ClearStorageOptions | There is no corresponding API in the stage model.| The stage model uses **Preferences** to replace **Storage** and has redesigned the input parameters.| +| DeleteStorageOptions | There is no corresponding API in the stage model.| The stage model uses **Preferences** to replace **Storage** and has redesigned the input parameters.| | [static get(options: GetStorageOptions): void;](../reference/apis-arkdata/js-apis-system-storage.md#storageget) | \@ohos.data.preferences.d.ts | [get(key: string, defValue: ValueType, callback: AsyncCallback<ValueType>): void;](../reference/apis-arkdata/js-apis-data-preferences.md#get)
[get(key: string, defValue: ValueType): Promise<ValueType>;](../reference/apis-arkdata/js-apis-data-preferences.md#get-1) | | [static set(options: SetStorageOptions): void;](../reference/apis-arkdata/js-apis-system-storage.md#storageset) | \@ohos.data.preferences.d.ts | [put(key: string, value: ValueType, callback: AsyncCallback<void>): void;](../reference/apis-arkdata/js-apis-data-preferences.md#put)
[put(key: string, value: ValueType): Promise<void>;](../reference/apis-arkdata/js-apis-data-preferences.md#put-1) | | [static clear(options?: ClearStorageOptions): void;](../reference/apis-arkdata/js-apis-system-storage.md#storageclear) | \@ohos.data.preferences.d.ts | [clear(callback: AsyncCallback<void>): void;](../reference/apis-arkdata/js-apis-data-preferences.md#clear)
[clear(): Promise<void>;](../reference/apis-arkdata/js-apis-data-preferences.md#clear-1) | | [static delete(options: DeleteStorageOptions): void;](../reference/apis-arkdata/js-apis-system-storage.md#storagedelete) | \@ohos.data.preferences.d.ts | [delete(key: string, callback: AsyncCallback<void>): void;](../reference/apis-arkdata/js-apis-data-preferences.md#delete)
[delete(key: string): Promise<void>;](../reference/apis-arkdata/js-apis-data-preferences.md#delete-1) | - - \ No newline at end of file diff --git a/en/application-dev/application-models/thread-model-fa.md b/en/application-dev/application-models/thread-model-fa.md index e899f6d1fa25234e53a6cbc6868869f98f3759ae..5826fd43abaad7715db4864e3b2ee27756260e18 100644 --- a/en/application-dev/application-models/thread-model-fa.md +++ b/en/application-dev/application-models/thread-model-fa.md @@ -24,5 +24,3 @@ Based on the thread model, different services run on different threads. Service > **NOTE** > > The FA model provides an independent thread for each ability. Emitter is mainly used for event synchronization within the ability thread, between a pair of ability threads, or between the ability thread and worker thread. - - \ No newline at end of file diff --git a/en/application-dev/application-models/thread-model-stage.md b/en/application-dev/application-models/thread-model-stage.md index 56235db215cd47e6b3d141bbb0aa1ccf7f69d199..d7ba1fcd1dd1540cf3612a46475dcf1720f7de7d 100644 --- a/en/application-dev/application-models/thread-model-stage.md +++ b/en/application-dev/application-models/thread-model-stage.md @@ -1,5 +1,7 @@ # Thread Model (Stage Model) +A thread is the basic unit for the operating system to perform computing and scheduling. It is an execution flow within a [process](./process-model-stage.md) and shares the resources of the process. A process can contain multiple threads. + ## Thread Type There are three types of threads in the stage model: - Main thread diff --git a/en/application-dev/application-models/uiability-launch-type.md b/en/application-dev/application-models/uiability-launch-type.md index 0a06bbb953385fb947aa90dfa09bc66046762e58..a33ed26f2873e68a8a46d0907675269494289445 100644 --- a/en/application-dev/application-models/uiability-launch-type.md +++ b/en/application-dev/application-models/uiability-launch-type.md @@ -12,11 +12,11 @@ The launch type of the [UIAbility](../reference/apis-ability-kit/js-apis-app-abi > **NOTE** > -> **standard** is the former name of **multiton** and provides the same effect as the multiton mode. +> standard is the former name of multiton and provides the same effect as the multiton mode. ## Singleton -**singleton** is the default launch type. +singleton is the default launch type. Each time [startAbility()](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) is called, if a [UIAbility](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md) instance of this type already exists in the application process, the instance is reused. In other words, UIAbility of this type can have only one instance in the system, meaning that only one mission is displayed in the system application Recents. @@ -74,13 +74,23 @@ To use the multiton mode, set **launchType** in the [module.json5 file](../quick ## Specified -The **specified** mode is used in some special scenarios. For example, in a document application, you may want a document instance to be created each time you create a document, and you may also want to use the same document instance when you open an existing document. +The specified mode is used in some special scenarios. For example, in a document application, you may want a document instance to be created each time you create a document, and you may also want to use the same document instance when you open an existing document. -**Figure 3** Demonstration effect in specified mode +**Figure 3** Principle in specified mode -![uiability-launch-type3](figures/uiability-launch-type3.gif) +![uiability-launch-type3-principle](figures/uiability-launch-type3-principle.png) + +This section assumes that an application has two [UIAbility](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md) instances: EntryAbility and SpecifiedAbility, and EntryAbility will start SpecifiedAbility in specified mode. The basic principle is as follows: + + 1. EntryAbility calls [startAbility()](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) and sets a unique key in the **parameters** field of [Want](../reference/apis-ability-kit/js-apis-app-ability-want.md) to identify SpecifiedAbility. + 2. Before starting SpecifiedAbility, the system invokes the [onAcceptWant()](../reference/apis-ability-kit/js-apis-app-ability-abilityStage.md#abilitystageonacceptwant) lifecycle callback of the corresponding [AbilityStage](../reference/apis-ability-kit/js-apis-app-ability-abilityStage.md) to obtain the key that identifies the target UIAbility. + 3. The system matches the UIAbility based on the key obtained. + * If a UIAbility instance is matched, that UIAbility instance is started, and its [onNewWant()](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md#uiabilityonnewwant) lifecycle callback is invoked. + * If no UIAbility instance is matched, a new UIAbility instance is created, and its [onCreate()](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md#uiabilityoncreate) and [onWindowStageCreate()](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md#uiabilityonwindowstagecreate) lifecycle callbacks are invoked. -In the following example, there are two [UIAbility](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md) components: EntryAbility and SpecifiedAbility (with the launch type **specified**). To start SpecifiedAbility from EntryAbility, proceed as follows: +**Figure 4** Demonstration effect in specified mode + +![uiability-launch-type3](figures/uiability-launch-type3.gif) 1. In SpecifiedAbility, set **launchType** in the [module.json5 file](../quick-start/module-configuration-file.md) to **specified**. @@ -98,7 +108,7 @@ In the following example, there are two [UIAbility](../reference/apis-ability-ki } ``` -2. Create a unique string key for the SpecifiedAbility instance. Each time [startAbility()](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) is called, the application, based on the key, identifies the UIAbility instance used to respond to the request. In EntryAbility, add a custom parameter, for example, **instanceKey**, to the [want](../reference/apis-ability-kit/js-apis-app-ability-want.md) parameter in [startAbility()](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) to distinguish the UIAbility instances. +2. In EntryAbility, pass the custom parameter **instanceKey** as the unique identifier into the [want](../reference/apis-ability-kit/js-apis-app-ability-want.md) parameter in [startAbility()](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) to specify the target UIAbility instance. In the example, **instanceKey** is set to **'KEY'**. ```ts // Configure a unique key for each UIAbility instance. @@ -123,7 +133,7 @@ In the following example, there are two [UIAbility](../reference/apis-ability-ki Row() { Column() { // ... - Button()// ... + Button() .onClick(() => { let context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext; // context is the UIAbilityContext of the initiator UIAbility. @@ -145,7 +155,7 @@ In the following example, there are two [UIAbility](../reference/apis-ability-ki this.KEY_NEW = this.KEY_NEW + 'a'; }) // ... - Button()// ... + Button() .onClick(() => { let context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext; // context is the UIAbilityContext of the initiator UIAbility. @@ -175,9 +185,7 @@ In the following example, there are two [UIAbility](../reference/apis-ability-ki } ``` -3. Before SpecifiedAbility is started, the [onAcceptWant()](../reference/apis-ability-kit/js-apis-app-ability-abilityStage.md#abilitystageonacceptwant) callback of the corresponding AbilityStage instance is invoked to obtain the key of the target [UIAbility](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md). If a UIAbility instance matching the key exists, the system starts the UIAbility instance and invokes its [onNewWant()](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md#uiabilityonnewwant) callback. Otherwise, the system creates a new UIAbility instance and invokes its [onCreate()](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md#uiabilityoncreate) and [onWindowStageCreate()](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md#uiabilityonwindowstagecreate) callbacks. - - In the sample code, the [onAcceptWant()](../reference/apis-ability-kit/js-apis-app-ability-abilityStage.md#abilitystageonacceptwant) callback uses the passed [want](../reference/apis-ability-kit/js-apis-app-ability-want.md) parameter to obtain the custom parameter **instanceKey**. The service logic returns a key string based on the **instanceKey** parameter to identify the UIAbility instance. If the returned key maps to a started UIAbility instance, the system pulls the UIAbility instance back to the foreground and gives it the focus. If the returned key does not map to a started UIAbility instance, the system creates a new UIAbility instance and starts it. +3. Set the UIAbility identifier based on the [onAcceptWant()](../reference/apis-ability-kit/js-apis-app-ability-abilityStage.md#abilitystageonacceptwant) lifecycle callback of SpecifiedAbility. In the example, the identifier is set to **SpecifiedAbilityInstance_KEY**. ```ts import { AbilityStage, Want } from '@kit.AbilityKit'; @@ -187,7 +195,7 @@ In the following example, there are two [UIAbility](../reference/apis-ability-ki // In the AbilityStage instance of the callee, a key string corresponding to a UIAbility instance is returned for UIAbility whose launch type is specified. // In this example, SpecifiedAbility of module1 is returned. if (want.abilityName === 'SpecifiedFirstAbility' || want.abilityName === 'SpecifiedSecondAbility') { - // The returned key string is a custom string. + // The returned KEY string is a custom string. if (want.parameters) { return `SpecifiedAbilityInstance_${want.parameters.instanceKey}`; } diff --git a/en/application-dev/application-models/uiability-lifecycle.md b/en/application-dev/application-models/uiability-lifecycle.md index 0b509dfeb87337941aa62d0ae3db27043e40778c..66bd13d1d155f73c09b9a358e64711e4e3db121d 100644 --- a/en/application-dev/application-models/uiability-lifecycle.md +++ b/en/application-dev/application-models/uiability-lifecycle.md @@ -39,8 +39,9 @@ export default class EntryAbility extends UIAbility { After the [UIAbility](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md) instance is created but before it enters the Foreground state, the system creates a WindowStage instance and triggers the [onWindowStageCreate()](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md#uiabilityonwindowstagecreate) callback. You can set UI loading and WindowStage event subscription in the callback. -**Figure 2** WindowStageCreate and WindowStageDestroy -![Ability-Life-Cycle-WindowStage](figures/Ability-Life-Cycle-WindowStage.png) +**Figure 2** WindowStageCreate and WindowStageDestroy + +![Ability-Life-Cycle-WindowStage](figures/Ability-Life-Cycle-WindowStage.png) In the **onWindowStageCreate()** callback, use [loadContent()](../reference/apis-arkui/js-apis-window.md#loadcontent9) to set the page to be loaded, and call [on('windowStageEvent')](../reference/apis-arkui/js-apis-window.md#onwindowstageevent9) to subscribe to [WindowStage events](../reference/apis-arkui/js-apis-window.md#windowstageeventtype9), for example, having or losing focus, switching to the foreground or background, or becoming interactive or non-interactive in the foreground. @@ -146,7 +147,7 @@ export default class EntryAbility extends UIAbility { onWindowStageWillDestroy(windowStage: window.WindowStage) { // Release the resources obtained through the windowStage object. - // Unsubscribe from the WindowStage events (having or losing focus, switching to the foreground or background, or becoming interactive or non-interactive in the foreground) in the onWindowStageDestroy() callback. + // Unsubscribe from the WindowStage events (having or losing focus, switching to the foreground or background, or becoming interactive or non-interactive in the foreground) in the onWindowStageWillDestroy() callback. try { if (this.windowStage) { this.windowStage.off('windowStageEvent'); diff --git a/en/application-dev/application-models/uiability-overview.md b/en/application-dev/application-models/uiability-overview.md index 17cd69f8491e8e352791c269b81db724fd380546..805c245e28de4ea06864a727fc7e2f0b6b4284a2 100644 --- a/en/application-dev/application-models/uiability-overview.md +++ b/en/application-dev/application-models/uiability-overview.md @@ -7,9 +7,9 @@ UIAbility is a type of application component that provides the UI for user inter The following design philosophy is behind UIAbility: -1. Native support for cross-device migration and multi-device collaboration at the application component level +1. Support for cross-device migration and multi-device collaboration at the application component level -2. Support for multiple device types and window modes +2. Native support for multiple device types and window modes diff --git a/en/application-dev/application-models/uiability-startup-adjust.md b/en/application-dev/application-models/uiability-startup-adjust.md index c41e212a94f421698e7dd0407b8522d550df0602..c75b2710741d3075da53c809cf2f6626085edb47 100644 --- a/en/application-dev/application-models/uiability-startup-adjust.md +++ b/en/application-dev/application-models/uiability-startup-adjust.md @@ -1,8 +1,5 @@ # Switching from Explicit Want Redirection to Linking Redirection - -## Overview - Since API version 12, it is not recommended that third-party applications start other applications by specifying an ability (implicit Want mode). Instead, the [linking mode](app-startup-overview.md#application-links) is recommended. This section describes how to switch from explicit Want mode to linking mode. @@ -12,7 +9,7 @@ This section describes how to switch from explicit Want mode to linking mode. 1. Install the application on your device. In the [module.json5 file](../quick-start/module-configuration-file.md) of the UIAbility, configure **entities**, **actions**, and **uri** under **skills**. - The **actions** field must contain **ohos.want.action.viewData**. - The **entities** field must contain **entity.system.browsable**. - - The **uris** field must contain an element whose **scheme** is **https**. **domainVerify** must be set to **true**. For details about the URI matching rules, see [Matching Rules of uri](explicit-implicit-want-mappings.md#matching-rules-of-uri). If **domainVerify** is set to **true**, domain name verification is enabled. In this case, the target application must pass domain name verification during App Linking. For details about how to configure the App Linking domain name, see [Using App Linking for Application Redirection](app-linking-startup.md). + - The **uris** field must contain an element whose **scheme** is **https**. **domainVerify** must be set to **true**. For details about the URI matching rules, see [Matching Rules of uri](explicit-implicit-want-mappings.md#matching-rules-of-uri). If **domainVerify** is set to **true**, domain name verification is enabled. In this case, the target application must pass domain name verification during App Linking. For details about how to configure the App Linking domain name, see App Linking. ```json { @@ -48,8 +45,6 @@ This section describes how to switch from explicit Want mode to linking mode. - If **appLinkingOnly** in **options** is set to **true**, the target application must pass domain name verification (Internet connection required). A unique matching item or an unmatched result will be returned. - If **appLinkingOnly** in **options** is set to **false**, the system preferentially attempts to start the target application in App Linking mode. If no matching application is found, the system starts the application in Deep Linking mode. - For details, see [Using App Linking for Application Redirection](app-linking-startup.md). - ```ts import { common } from '@kit.AbilityKit'; import OpenLinkOptions from '@ohos.app.ability.OpenLinkOptions'; @@ -69,6 +64,7 @@ This section describes how to switch from explicit Want mode to linking mode. .margin({ bottom: '12vp' }) .onClick(() => { let context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext; + // When using startAbility to explicitly start other UIAbilities, the openLink API is recommended. // let want: Want = { // bundleName: "com.test.example", // moduleName: "entry", @@ -113,7 +109,7 @@ This section describes how to switch from explicit Want mode to linking mode. - The **actions** field must contain **ohos.want.action.viewData**. - The **entities** field must contain **entity.system.browsable**. - - The **uris** field must contain an element whose **scheme** is **https**. **domainVerify** must be set to **true**. For details about the URI matching rules, see [Matching Rules of uri](explicit-implicit-want-mappings.md#matching-rules-of-uri). If **domainVerify** is set to **true**, domain name verification is enabled. In this case, the target application must pass domain name verification during App Linking. For details about how to configure the App Linking domain name, see [Using App Linking for Application Redirection](app-linking-startup.md). + - The **uris** field must contain an element whose **scheme** is **https**. **domainVerify** must be set to **true**. For details about the URI matching rules, see [Matching Rules of uri](explicit-implicit-want-mappings.md#matching-rules-of-uri). If **domainVerify** is set to **true**, domain name verification is enabled. In this case, the target application must pass domain name verification during App Linking. For details about how to configure the App Linking domain name, see App Linking. ```json { @@ -145,12 +141,10 @@ This section describes how to switch from explicit Want mode to linking mode. } ``` -2. Call [openLink](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextopenlink12) to trigger redirection. The redirected-to link and [options](../reference/apis-ability-kit/js-apis-app-ability-openLinkOptions.md) must be passed in, but the bundle name, module name, and ability name are not required. The system matches the application that meets the skills configuration based on the link. **AbilityResult** is transferred to the callback function through input parameters and returned to the caller application when the ability is terminated. The startup success or failure result is returned through a promise. +2. Call [openLink](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextopenlink12) to trigger redirection. The redirected-to link and [options](../reference/apis-ability-kit/js-apis-app-ability-openLinkOptions.md) must be passed in, but the bundle name, module name, and ability name are not required. The system matches the application that meets the skills configuration based on the link. **AbilityResult** is transferred to the callback function through input parameters and returned to the caller application when the ability is terminated. The startup success or failure result is returned through a promise.
- If **appLinkingOnly** in **options** is set to **true**, the target application must pass domain name verification (Internet connection required). A unique matching item or an unmatched result will be returned. - If **appLinkingOnly** in **options** is set to **false**, the system preferentially attempts to start the target application in App Linking mode. If no matching application is found, the system starts the application in Deep Linking mode. - For details, see [Using App Linking for Application Redirection](app-linking-startup.md). - ```ts import { common } from '@kit.AbilityKit'; import OpenLinkOptions from '@ohos.app.ability.OpenLinkOptions'; @@ -170,6 +164,7 @@ This section describes how to switch from explicit Want mode to linking mode. .margin({ bottom: '12vp' }) .onClick(() => { let context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext; + // When using startAbility to explicitly start other UIAbilities, the openLink API is recommended. // let want: Want = { // bundleName: "com.test.example", // moduleName: "entry", diff --git a/en/application-dev/application-models/uiserviceextension-sys.md b/en/application-dev/application-models/uiserviceextension-sys.md new file mode 100644 index 0000000000000000000000000000000000000000..2e11ac17059809df92a7f983e4531f46d77ec8ef --- /dev/null +++ b/en/application-dev/application-models/uiserviceextension-sys.md @@ -0,0 +1,421 @@ +# UIServiceExtensionAbility (for System Applications Only) + +## Overview + +[UIServiceExtensionAbility](../reference/apis-ability-kit/js-apis-app-ability-uiServiceExtensionAbility-sys.md) is an [ExtensionAbility](../reference/apis-ability-kit/js-apis-app-ability-extensionAbility.md) component of the UIService type. It provides UI pages (such as preview pages) and background service capabilities. This component internally holds a [UIServiceExtensionContext](../reference/apis-ability-kit/js-apis-inner-application-uiserviceExtensionContext-sys.md), which provides a variety of APIs for external systems. + +In this document, the component that starts or connects to a UIServiceExtensionAbility is called the client, and the UIServiceExtensionAbility is called the server. + +An application can use a UIServiceExtensionAbility in two modes: +- Call [startUIServiceExtensionAbility()](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartuiserviceextensionability14) in the [UIAbilityContext](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md), [UIExtensionContext](../reference/apis-ability-kit/js-apis-inner-application-uiExtensionContext.md), or [ServiceExtensionContext](../reference/apis-ability-kit/js-apis-inner-application-serviceExtensionContext-sys.md) class to start a UIServiceExtensionAbility. +- Call [connectUIServiceExtensionAbility()](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextconnectuiserviceextensionability14) in the [UIAbilityContext](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md) or [UIExtensionContext](../reference/apis-ability-kit/js-apis-inner-application-uiExtensionContext.md) class to connect to a UIServiceExtensionAbility. + +Note the following: + +- Only one window is created during the start or connection of the UIServiceExtensionAbility. +- If the window fails to be created or is destroyed, the UIServiceExtensionAbility is automatically destroyed. +- The start, connection, and disconnection operations can be performed only in the main thread, but not in the Worker and TaskPool threads. +- Applications can start and connect to a UIServiceExtensionAbility provided by the system only when they gain focus in the foreground. + +## Lifecycle + +The UIServiceExtensionAbility provides the following lifecycle callbacks: [onCreate()](../reference/apis-ability-kit/js-apis-app-ability-uiServiceExtensionAbility-sys.md#uiserviceextensionabilityoncreate), [onWindowWillCreate()](../reference/apis-ability-kit/js-apis-app-ability-uiServiceExtensionAbility-sys.md#uiserviceextensionabilityonwindowwillcreate), [onWindowDidCreate()](../reference/apis-ability-kit/js-apis-app-ability-uiServiceExtensionAbility-sys.md#uiserviceextensionabilityonwindowdidcreate), [onRequest()](../reference/apis-ability-kit/js-apis-app-ability-uiServiceExtensionAbility-sys.md#uiserviceextensionabilityonrequest), [onConnect()](../reference/apis-ability-kit/js-apis-app-ability-uiServiceExtensionAbility-sys.md#uiserviceextensionabilityonconnect), [onDisconnect()](../reference/apis-ability-kit/js-apis-app-ability-uiServiceExtensionAbility-sys.md#uiserviceextensionabilityondisconnect), [onData()](../reference/apis-ability-kit/js-apis-app-ability-uiServiceExtensionAbility-sys.md#uiserviceextensionabilityondata), and [onDestroy()](../reference/apis-ability-kit/js-apis-app-ability-uiServiceExtensionAbility-sys.md#uiserviceextensionabilityondestroy). Override them as required. The figure below shows the lifecycle transitions. + + **Figure 1** UIServiceExtensionAbility lifecycle + +![UIServiceExtensionAbility-lifecycle](figures/UIServiceExtension-lifecycle.png) + + + +- **onCreate** + + This callback is invoked when a UIServiceExtensionAbility is created for the first time. You can perform initialization operations, for example, registering a common event listener, in this callback. + + > **NOTE** + > + > If the UIServiceExtensionAbility has been created, starting it again does not trigger the **onCreate()** callback. + +- **onRequest** + + This callback is invoked when another component calls [startUIServiceExtensionAbility()](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartuiserviceextensionability14) to start a UIServiceExtensionAbility. After This callback is invoked, the UIServiceExtensionAbility is started and runs in the foreground. This callback is invoked each time [startUIServiceExtensionAbility()](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartuiserviceextensionability14) is called. + +- **onWindowWillCreate** + + This callback is invoked before a window is created. Through this callback, you can pass window parameters to the system. If **config.windowAttribute** is set to **window.ExtensionWindowAttribute.SUB_WINDOW**, a subwindow is created. If it is set to **window.ExtensionWindowAttribute.SYSTEM_WINDOW**, a system window is created. + + Currently, both the subwindow and system window can be created for the UIServiceExtensionAbility started by [UIAbilityContext](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md) and [UIExtensionContext](../reference/apis-ability-kit/js-apis-inner-application-uiExtensionContext.md), but only the system window can be created for the UIServiceExtensionAbility started by [ServiceExtensionContext](../reference/apis-ability-kit/js-apis-inner-application-serviceExtensionContext-sys.md). In addition, only one window is created for a UIServiceExtensionAbility. + +- **onWindowDidCreate** + + This callback is invoked when a window is created. You can operate the window through a [Window](../reference/apis-arkui/js-apis-window-sys.md#window) object. You can use [window.on('windowVisibilityChange')](../reference/apis-arkui/js-apis-window.md#onwindowvisibilitychange11) to bind and process window events, such as window showing, hiding, and destruction. + +- **onConnect** + + This callback is invoked when another component calls [connectUIServiceExtensionAbility()](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextconnectuiserviceextensionability14) to connect to a UIServiceExtensionAbility. In this callback, a remote proxy object, namely, [UIServiceHostProxy](../reference/apis-ability-kit/js-apis-inner-application-uiservicehostproxy-sys.md), is returned, through which the server communicates with the client. For the same client, if the values of **DeviceId**, **BundleName**, **ModuleName**, and **AbilityName** in the want object and the callback object are the same, [onConnect()](../reference/apis-ability-kit/js-apis-app-ability-serviceExtensionAbility-sys.md#serviceextensionabilityonconnect) is invoked only for the first connection. If any of them is different, [onConnect()](../reference/apis-ability-kit/js-apis-app-ability-serviceExtensionAbility-sys.md#serviceextensionabilityonconnect) is invoked again. + +- **onData** + + This callback is invoked to receive data sent by the caller through [UIServiceProxy](../reference/apis-ability-kit/js-apis-inner-application-uiserviceproxy.md). + +- **onDisconnect** + + This callback is invoked when the connection is interrupted, which occurs when the client exits or [disconnectServiceExtensionAbility()](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextdisconnectuiserviceextensionability14) is called. + +- **onDestroy** + + This callback is invoked when a UIServiceExtensionAbility is no longer required and the instance is ready for destruction. You can clear resources, for example, deregistering the listener, in this callback. + +## Implementing an Extension Base Class of the UIService Type + +### Preparations + +Only system applications can implement a UIServiceExtensionAbility. You must make the following preparations before development: + +- **Switching to the full SDK**: All the APIs provided by the UIServiceExtensionAbility class are marked as system APIs and hidden by default. Therefore, you must manually obtain the full SDK from the mirror and switch to it in DevEco Studio. For details, see [Switching to Full SDK](../faqs/full-sdk-switch-guide.md). + +- **Requesting the AllowAppUsePrivilegeExtension privilege**: Only applications with the **AllowAppUsePrivilegeExtension** privilege can implement a UIServiceExtensionAbility. For details about how to request the privilege, see [Application Privilege Configuration](../../device-dev/subsystems/subsys-app-privilege-config-guide.md). + +### Creating a UIServiceExtensionAbility + +To manually create a UIServiceExtensionAbility in a project in DevEco Studio, perform the following steps: + +1. In the **ets** directory of the target module, right-click and choose **New > Directory** to create a directory named [UIServiceExtension](../reference/apis-ability-kit/js-apis-app-ability-uiServiceExtensionAbility-sys.md). + +2. In the **UIServiceExt** directory, right-click and choose **New > ArkTS File** to create a file named **UIServiceExt.ets**. + + ``` + ├── ets + │ ├── UIServiceExt + │ │ ├── UIServiceExt.ets + ``` + +3. In the **UIServiceExt.ets** file, import the UIServiceExtensionAbility module. Customize a class that inherits from the UIServiceExtensionAbility and implement the lifecycle callbacks. + + ```ts + import { common, UIServiceExtensionAbility, Want } from '@kit.AbilityKit'; + import { hilog } from '@kit.PerformanceAnalysisKit'; + import { window } from '@kit.ArkUI'; + + export default class UIServiceExtAbility extends UIServiceExtensionAbility { + // Create a UIServiceExtensionAbility. + onCreate(want: Want) { + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate'); + } + // Callback for request processing. + onRequest(want: Want, startId: number) { + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onRequest'); + } + // Callback invoked when a connection is set up. + onConnect(want: Want, proxy: common.UIServiceHostProxy) { + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onConnect'); + } + // Callback invoked when a connection is interrupted. + onDisconnect(want: Want, proxy: common.UIServiceHostProxy) { + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDisconnect'); + } + // Callback invoked when a window is about to create. + onWindowWillCreate(config: window.ExtensionWindowConfig): void { + hilog.info(0x0000, TestTag, '%{public}s', 'Ability onWindowWillCreate'); + let rect: window.Rect = { + left: 100, top: 100, width: 500, height: 500 + }; + config.windowRect = rect; + // Create a subwindow. + config.windowName = 'sub_window' + config.windowAttribute = window.ExtensionWindowAttribute.SUB_WINDOW; + config.windowRect = rect; + config.subWindowOptions = { + title: 'sub_window_title', + decorEnabled: true, + // Whether the window is a modal window. + isModal: false + } + hilog.info(0x0000, TestTag, '%{public}s', 'Ability onWindowWillCreate end'); + } + // Callback invoked when a window is created. + onWindowDidCreate(window: window.Window) { + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowDidCreate'); + window.setUIContent('uiservice/page/WindowPage') + window.showWindow() + } + // Callback invoked to receive data. + onData(proxy: common.UIServiceHostProxy, data: Record) { + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onData'); + } + // Callback invoked to destroy the instance. + onDestroy() { + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy'); + } + } + ``` + +4. Register the UIServiceExtensionAbility in the [module.json5 file](../quick-start/module-configuration-file.md) of the module in the project. Set **type** to **"uiService"** and **srcEntry** to the code path of the UIServiceExtensionAbility component. + + ```json + { + "module": { + // ... + "extensionAbilities": [ + { + "name": "UIServiceExtAbility", + "icon": "$media:icon", + "description": "uiService", + "type": "uiService", + "exported": true, + "srcEntry": "./ets/UIServiceExtAbility/UIServiceExtAbility.ets" + } + ] + } + } + ``` + +### Starting a UIServiceExtensionAbility + +An application calls [startUIServiceExtensionAbility()](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartuiserviceextensionability14) to start a UIServiceExtensionAbility. The [onRequest()](../reference/apis-ability-kit/js-apis-app-ability-uiServiceExtensionAbility-sys.md#uiserviceextensionabilityonrequest) callback is invoked, through which the background service receives the **Want** object passed by the caller. Once the UIServiceExtensionAbility is started, its lifecycle is independent of the client. In other words, even if the client is destroyed, the background service remains alive. However, the service is destroyed if the window fails to be created or is destroyed. Therefore, the background service must be stopped by calling [terminateSelf()](../reference/apis-ability-kit/js-apis-inner-application-uiserviceExtensionContext-sys.md#uiserviceextensioncontextterminateself13) of [UIServiceExtensionContext](../reference/apis-ability-kit/js-apis-inner-application-uiserviceExtensionContext-sys.md) when its work is complete. + +Start a new UIServiceExtensionAbility in a system application. For details about how to obtain the context, see [Obtaining the Context of UIAbility](uiability-usage.md#obtaining-the-context-of-uiability). + + +```ts +import { common, Want } from '@kit.AbilityKit'; +import { BusinessError } from '@kit.BasicServicesKit'; + +@Entry +@Component +struct Index { + build() { + Column() { + Row() { + // Create a Start button. + Button('start ability') + .enabled(true) + .onClick(() => { + let context = getContext(this) as common.UIAbilityContext; + let startWant: Want = { + bundleName: 'com.acts.uiserviceextensionability', + abilityName: 'UiServiceExtAbility', + }; + try { + // Start the UIServiceExtensionAbility. + context.startUIServiceExtensionAbility(startWant).then(() => { + console.log('startUIServiceExtensionAbility success'); + }).catch((error: BusinessError) => { + console.log('startUIServiceExtensionAbility error', JSON.stringify(error)); + }) + } catch (err) { + console.log('startUIServiceExtensionAbility failed', JSON.stringify(err)); + } + }) + } + } + } +} +``` + +### Connecting to a UIServiceExtensionAbility + +An application can use [connectUIServiceExtensionAbility()](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextconnectuiserviceextensionability14) to connect to a service (specified in the [Want](../reference/apis-ability-kit/js-apis-app-ability-want.md) object). The [onConnect()](../reference/apis-ability-kit/js-apis-app-ability-serviceExtensionAbility-sys.md#serviceextensionabilityonconnect) callback is invoked, through which the service receives the [Want](../reference/apis-ability-kit/js-apis-app-ability-want.md) object passed by the caller. In this way, a connection is established. + +When the client calls [connectUIServiceExtensionAbility()](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextconnectuiserviceextensionability14) to connect to the server, the client receives a [UIServiceProxy](../reference/apis-ability-kit/js-apis-inner-application-uiserviceproxy.md) object returned by the server and saves it. Through this proxy object, the client sends data to the server, and disconnects from the server by calling [disconnectServiceExtensionAbility()](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextdisconnectuiserviceextensionability14). + +- Call [connectUIServiceExtensionAbility()](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextconnectuiserviceextensionability14) to connect to a UIServiceExtensionAbility. For details about how to obtain the context, see [Obtaining the Context of UIAbility](uiability-usage.md#obtaining-the-context-of-uiability). + ```ts + import { common, Want } from '@kit.AbilityKit'; + import { BusinessError } from '@kit.BasicServicesKit'; + + @Entry + @Component + struct Page_UIServiceExtensionAbility { + @State uiServiceProxy: common.UIServiceProxy | null = null; + + build() { + Column() { + //... + Row() { + //... + }.onClick(() => { + const context = getContext(this) as common.UIAbilityContext; + const want: Want = { + deviceId: '', + bundleName: 'com.example.myapplication', + abilityName: '' + }; + // Define a callback. + const callback: common.UIServiceExtensionConnectCallback = { + onData: (data: Record): void => { + console.log('onData:', JSON.stringify(data)); + }, + onDisconnect: (): void => { + console.log('onDisconnect'); + } + }; + // Connect to the UIServiceExtensionAbility. + context.connectUIServiceExtensionAbility(want, callback).then((uiServiceProxy: common.UIServiceProxy) => { + this.uiServiceProxy = uiServiceProxy; + console.log('connectUIServiceExtensionAbility success'); + }).catch((error: BusinessError) => { + console.log('connectUIServiceExtensionAbility failed', JSON.stringify(error)); + }) + }) + } + } + } + ``` + +- Call [disconnectUIServiceExtensionAbility()](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextdisconnectuiserviceextensionability14) to disconnect from a UIServiceExtensionAbility. + ```ts + import { common } from '@kit.AbilityKit'; + import { BusinessError } from '@kit.BasicServicesKit'; + + @Entry + @Component + struct Page_UIServiceExtensionAbility { + @State uiServiceProxy: common.UIServiceProxy | null = null; + + build() { + Column() { + //... + Row() { + //... + }.onClick(() => { + const context = getContext(this) as common.UIAbilityContext; + // this.uiServiceProxy is the proxy object saved during connection. + context.disconnectUIServiceExtensionAbility(this.uiServiceProxy).then(() => { + console.log('disconnectUIServiceExtensionAbility success'); + }).catch((error: BusinessError) => { + console.log('disconnectUIServiceExtensionAbility failed', JSON.stringify(error)); + }) + }) + } + } + } + ``` + + + +## Bidirectional Communication Between the Client and Server + +After a UIServiceExtensionAbility is started, the following operations are possible: + +1. The client calls [connectUIServiceExtensionAbility()](../reference/apis-ability-kit/js-apis-inner-application-uiExtensionContext.md#uiextensioncontextconnectuiserviceextensionability14) to obtain a [UIServiceProxy](../reference/apis-ability-kit/js-apis-inner-application-uiserviceproxy.md) object, through which it can send data to the server. +2. The server obtains a [UIServiceHostProxy](../reference/apis-ability-kit/js-apis-inner-application-uiservicehostproxy-sys.md) object through the [onConnect()](../reference/apis-ability-kit/js-apis-app-ability-uiServiceExtensionAbility-sys.md#uiserviceextensionabilityonconnect) callback and sends data to the client through this proxy. + +![UIServiceExtensionAbility-bidirectionalcommunication](figures/UIServiceExtension-bidirectionalcommunication.png) + + +### Communication Between the Client and Server +- Data transmission on the client + + The client connects to the server through [connectUIServiceExtensionAbility()](../reference/apis-ability-kit/js-apis-inner-application-uiExtensionContext.md#uiextensioncontextconnectuiserviceextensionability14) and obtains a [UIServiceProxy](../reference/apis-ability-kit/js-apis-inner-application-uiserviceproxy.md) object. The client calls [sendData()](../reference/apis-ability-kit/js-apis-inner-application-uiserviceproxy.md#uiserviceproxysenddata) of the proxy object to send data to the server. The server receives data through the [onData()](../reference/apis-ability-kit/js-apis-app-ability-uiServiceExtensionAbility-sys.md#uiserviceextensionabilityondata) callback. + ```ts + import { common, Want} from '@kit.AbilityKit'; + import { BusinessError } from '@kit.BasicServicesKit'; + + @Entry + @Component + struct Index { + comProxy: common.UIServiceProxy | null = null; + connectCallback : common.UIServiceExtensionConnectCallback = { + onData:(data: Record) => { + console.log("received data", JSON.stringify(data)); + }, + onDisconnect:() => { + console.log("onDisconnect"); + } + } + + build() { + Column() { + Row() { + // Create a Connect button. + Button("connect ability") + .enabled(true) + .onClick(() => { + let context = getContext(this) as common.UIAbilityContext; + let startWant:Want = { + bundleName: 'com.acts.uiserviceextensionability', + abilityName: 'UiServiceExtAbility', + }; + try { + // Connect to the UIServiceExtensionAbility. + context.connectUIServiceExtensionAbility(startWant, this.connectCallback).then((proxy: common.UIServiceProxy) => { + this.comProxy = proxy; + let formData: Record = { + 'test': 'test' + }; + try { + this.comProxy.sendData(formData); + } catch (err) { + console.log('sendData failed', JSON.stringify(err)); + }; + }).catch((err: BusinessError) => { + console.log("connectUIServiceExtensionAbility failed", JSON.stringify(err)); + }); + } catch(err) { + console.log("connectUIServiceExtensionAbility failed", JSON.stringify(err)); + } + }) + } + } + } + } + ``` + +- Data transmission on the server + + The server receives data transferred by the client through [onData()](../reference/apis-ability-kit/js-apis-app-ability-uiServiceExtensionAbility-sys.md#uiserviceextensionabilityondata). Through the [UIServiceHostProxy](../reference/apis-ability-kit/js-apis-inner-application-uiservicehostproxy-sys.md) object, which is saved during the connection, the server calls [sendData()](../reference/apis-ability-kit/js-apis-inner-application-uiservicehostproxy-sys.md#uiservicehostproxysenddata) to send data to the client. + ```ts + import { common, Want, UIServiceExtensionAbility} from '@kit.AbilityKit'; + import { window } from '@kit.ArkUI'; + + export default class MyServiceExtAbility extends UIServiceExtensionAbility { + comProxy : common.UIServiceHostProxy | null = null; + // Callback invoked when a UIServiceExtensionAbility is created. + onCreate(want: Want) { + console.log('UIServiceExtensionAbility onCreate'); + } + + // Callback for request processing. + onRequest(want: Want, startId: number) { + console.log('UIServiceExtensionAbility onRequest'); + } + + // Callback invoked when a connection is set up. + onConnect(want: Want, proxy: common.UIServiceHostProxy) { + console.log('UIServiceExtensionAbility onConnect'); + this.comProxy = proxy; + } + + // Callback invoked when a connection is interrupted. + onDisconnect(want: Want, proxy: common.UIServiceHostProxy) { + console.log('UIServiceExtensionAbility onDisconnect'); + this.comProxy = null; + } + + // Callback invoked to receive data. + onData(proxy: common.UIServiceHostProxy, data: Record) { + console.log('UIServiceExtensionAbility onData'); + try { + let formData: Record = { + 'Data' : 'reply message' + }; + proxy.sendData(formData); + } catch (err) { + console.log('sendData failed',JSON.stringify(err)); + }; + + } + + onWindowWillCreate(extensionWindowConfig: window.ExtensionWindowConfig) { + console.log('UIServiceExtensionAbility onWindowWillCreate'); + } + + onWindowDidCreate(window: window.Window) { + console.log('UIServiceExtensionAbility onWindowDidCreate'); + } + + onDestroy() { + console.log('UIServiceExtensionAbility onDestroy'); + } + } + ``` diff --git a/en/application-dev/application-models/uiserviceextension.md b/en/application-dev/application-models/uiserviceextension.md new file mode 100644 index 0000000000000000000000000000000000000000..eb8ab998d06b3291b3d71e9f0842edd3f87c7fd4 --- /dev/null +++ b/en/application-dev/application-models/uiserviceextension.md @@ -0,0 +1,123 @@ +# UIServiceExtensionAbility + +## Overview + +UIServiceExtensionAbility is an [ExtensionAbility](../reference/apis-ability-kit/js-apis-app-ability-extensionAbility.md) component of the UIService type. It provides UI pages (such as preview pages) and background service capabilities. This component internally holds a UIServiceExtensionContext, which provides a variety of APIs for external systems. + +In this document, the component that starts or connects to a UIServiceExtensionAbility is called the client, and the UIServiceExtensionAbility is called the server. + +An application can use a UIServiceExtensionAbility in two modes: +- Call [startUIServiceExtensionAbility()](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartuiserviceextensionability14) in the [UIExtensionContext](../reference/apis-ability-kit/js-apis-inner-application-uiExtensionContext.md) class to start a UIServiceExtensionAbility. +- Call [connectUIServiceExtensionAbility()](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextconnectuiserviceextensionability14) in the [UIAbilityContext](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md) or [UIExtensionContext](../reference/apis-ability-kit/js-apis-inner-application-uiExtensionContext.md) class to connect to a UIServiceExtensionAbility. + + +> **NOTE** +> +> 1. Third-party applications can use a UIServiceExtensionAbility but cannot implement a UIServiceExtensionAbility. (The implementation requires system permissions.) +> +> 2. Third-party applications can connect to a UIServiceExtensionAbility provided by a system application only when they gain focus in the foreground. +> +> 3. The UIServiceExtensionAbility lifecycle is closely related to the window it binds. It is destroyed once the window is destroyed. + + +## Starting a UIServiceExtensionAbility + +An application (client) calls [startUIServiceExtensionAbility()](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartuiserviceextensionability14) to start a UIServiceExtensionAbility. Once the UIServiceExtensionAbility is started, its lifecycle is independent of the client. Even if the client is destroyed, the background service remains alive. However, the service is destroyed if the window fails to be created or is destroyed. + + +For details about how to obtain the context, see [Obtaining the Context of UIAbility](uiability-usage.md#obtaining-the-context-of-uiability). + +```ts +import { common, Want } from '@kit.AbilityKit'; +import { BusinessError } from '@kit.BasicServicesKit'; + +@Entry +@Component +struct Index { + build() { + Column() { + Row() { + // Create a Start button. + Button('start ability') + .enabled(true) + .onClick(() => { + let context = getContext(this) as common.UIAbilityContext; + let startWant: Want = { + bundleName: 'com.acts.uiserviceextensionability', + abilityName: 'UiServiceExtAbility', + }; + try { + // Start the UIServiceExtensionAbility. + context.startUIServiceExtensionAbility(startWant).then(() => { + console.log('startUIServiceExtensionAbility success'); + }).catch((error: BusinessError) => { + console.log('startUIServiceExtensionAbility error', JSON.stringify(error)); + }) + } catch (err) { + console.log('startUIServiceExtensionAbility failed', JSON.stringify(err)); + } + }) + } + } + } +} +``` + +## Connecting to a UIServiceExtensionAbility + +The client connects to the server through [connectUIServiceExtensionAbility()](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextconnectuiserviceextensionability14) and obtains a [UIServiceProxy](../reference/apis-ability-kit/js-apis-inner-application-uiserviceproxy.md) object. The client calls [sendData()](../reference/apis-ability-kit/js-apis-inner-application-uiserviceproxy.md#uiserviceproxysenddata) of the proxy object to send data to the server. The server calls the system API **onData()** of the UIServiceExtensionAbility class to receive data from the client. + + +```ts +import { common, Want } from '@kit.AbilityKit'; +import { BusinessError } from '@kit.BasicServicesKit'; + +@Entry +@Component +struct Index { + comProxy: common.UIServiceProxy | null = null; + connectCallback : common.UIServiceExtensionConnectCallback = { + onData:(data: Record) => { + console.log("received data", JSON.stringify(data)); + }, + onDisconnect:() => { + console.log("onDisconnect "); + } + } + + build() { + Column() { + Row() { + // Create a Connect button. + Button("connect ability") + .enabled(true) + .onClick(() => { + let context = getContext(this) as common.UIAbilityContext; + let startWant:Want = { + bundleName: 'com.acts.uiserviceextensionability', + abilityName: 'UiServiceExtAbility', + }; + try { + // Connect to the UIServiceExtensionAbility. + context.connectUIServiceExtensionAbility(startWant, this.connectCallback).then((proxy: common.UIServiceProxy) => { + this.comProxy = proxy; + let formData: Record = { + 'test': 'test' + }; + try { + this.comProxy.sendData(formData); + } catch (err) { + console.log('sendData failed', JSON.stringify(err)); + }; + }).catch((err: BusinessError) => { + console.log("connectUIServiceExtensionAbility failed", JSON.stringify(err)); + }); + } catch(err) { + console.log("connectUIServiceExtensionAbility failed", JSON.stringify(err)); + }; + }) + } + } +} +} +``` diff --git a/en/application-dev/application-test/Readme-EN.md b/en/application-dev/application-test/Readme-EN.md index e7f7280007a0540f9eb12178adfad4359ec08989..4364e57f6ca6fe8e433d893d157db6c2266250fa 100644 --- a/en/application-dev/application-test/Readme-EN.md +++ b/en/application-dev/application-test/Readme-EN.md @@ -1,4 +1,4 @@ -# Test Kit (Application Test Service) +# Test Kit - [arkXtest User Guide](arkxtest-guidelines.md) - [SmartPerf User Guide](smartperf-guidelines.md) diff --git a/en/application-dev/application-test/arkxtest-guidelines.md b/en/application-dev/application-test/arkxtest-guidelines.md index 621ab26a4074741297a877f4d7d9497e7511ab0d..b4e8816075bbff9b4c07f8b55ade97e37c92c884 100644 --- a/en/application-dev/application-test/arkxtest-guidelines.md +++ b/en/application-dev/application-test/arkxtest-guidelines.md @@ -38,7 +38,7 @@ arkXtest is divided into two parts: unit test framework and UI test framework. 1. Open DevEco Studio and create a project, in which the **ohos** directory is where the test script is located. -2. Open the **.ets** file of the module to be tested in the project directory. Move the cursor to any position in the code, and then right-click and choose **Show Context Actions** > **Create Ohos Test** or press **Alt+Enter** and choose **Create Ohos Test** to create a test class. For more details, see [DevEco Studio User Guide](https://developer.harmonyos.com/en/docs/documentation/doc-guides-V3/harmonyos_jnit_jsunit-0000001092459608-V3?catalogVersion=V3#section13366184061415). +2. Open the .ets file of the module to be tested in the project directory. Move the cursor to any position in the code, and then right-click and choose **Show Context Actions** > **Create Ohos Test** or press **Alt+Enter** and choose **Create Ohos Test** to create a test class. For more details, see [DevEco Studio User Guide](https://developer.harmonyos.com/en/docs/documentation/doc-guides-V3/harmonyos_jnit_jsunit-0000001092459608-V3?catalogVersion=V3#section13366184061415). @@ -121,7 +121,7 @@ export default function abilityTest() { } ``` -2. Write test code in the **.test.ets** file under **ohosTest** > **ets** > **test**. +2. Write test code in the .test.ets file under **ohosTest** > **ets** > **test**. ```ts import { describe, it, expect } from '@ohos/hypium'; @@ -203,7 +203,7 @@ The table below lists the keywords in **aa** test commands. | Keyword | Abbreviation| Description | Example | | ------------- | ------------ | -------------------------------------- | ---------------------------------- | -| --bundleName | -b | Application bundle name. | - b com.test.example | +| --bundleName | -b | Application bundle name. | - b com.test.example | | --packageName | -p | Application module name, which is applicable to applications developed in the FA model. | - p com.test.example.entry | | --moduleName | -m | Application module name, which is applicable to applications developed in the stage model. | -m entry | | NA | -s | \ pair.| - s unittest /ets/testrunner/OpenHarmonyTestRunner | @@ -213,7 +213,7 @@ The framework supports multiple test case execution modes, which are triggered b | Name | Description | Value | Example | | ------------ | ----------------------------------------------------------------------------- | ------------------------------------------------------------ | ----------------------------------------- | | unittest | **OpenHarmonyTestRunner** object used for test case execution. | **OpenHarmonyTestRunner** or custom runner name. | - s unittest OpenHarmonyTestRunner | -| class | Test suite or test case to be executed. | {describeName}#{itName}, {describeName} | -s class attributeTest#testAttributeIt | +| class | Test suite or test case to be executed. | {describeName}#{itName}, {describeName} | -s class attributeTest#testAttributeIt | | notClass | Test suite or test case that does not need to be executed. | {describeName}#{itName}, {describeName} | -s notClass attributeTest#testAttributeIt | | itName | Test case to be executed. | {itName} | -s itName testAttributeIt | | timeout | Timeout interval for executing a test case. | Positive integer (unit: ms). If no value is set, the default value **5000** is used. | -s timeout 15000 | @@ -421,7 +421,7 @@ The following describes the fields in the recording data: "MAX_VEL": "40000", // Maximum velocity. "VELO": "0.000000", // Hands-off velocity. "W1_BOUNDS": "{"bottom":361,"left":37,"right":118,"top":280}", // Starting component bounds. - "W1_HIER": "ROOT,3,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0", // Starting component hierarchy. + "W1_HIER": "ROOT,3,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0", // Starting component hierarchy. "W1_ID": "", // ID of the starting component. "W1_Text": "", // Text of the starting component. "W1_Type": "Image", // Type of the starting component. @@ -443,18 +443,18 @@ The following describes the fields in the recording data: ### Injecting Simulated UI Operations -| Command | Mandatory| Description | +| Command | Mandatory| Description | |------|------|-----------------| | help | Yes | Displays help information about the uiInput commands.| -| click | Yes | Simulates a click event. | -| doubleClick | Yes | Simulates a double-click event. | -| longClick | Yes | Simulates a long-click event. | -| fling | Yes | Simulates a fling event. | -| swipe | Yes | Simulates a swipe event. | -| drag | Yes | Simulates a drag event. | +| click | Yes | Simulates a click event. | +| doubleClick | Yes | Simulates a double-click event. | +| longClick | Yes | Simulates a long-click event. | +| fling | Yes | Simulates a fling event. | +| swipe | Yes | Simulates a swipe event. | +| drag | Yes | Simulates a drag event. | | dircFling | Yes | Simulates a directional fling event. | -| inputText | Yes | Simulates a text input event. | -| keyEvent | Yes | Simulates a physical key event (such as pressing a keyboard key, pressing the power key, returning to the previous page, or returning to the home screen) or a key combination. | +| inputText | Yes | Simulates text input in a text box. | +| keyEvent | Yes | Simulates a physical key event (such as pressing a keyboard key, pressing the power key, returning to the previous page, or returning to the home screen) or a key combination. | #### Example of Running the click/doubleClick/longClick Commands @@ -477,30 +477,30 @@ hdc shell uitest uiInput longClick 100 100 #### Example of Running the uiInput fling Command -| Parameter | Mandatory | Description | +| Parameter | Mandatory | Description | |------|------------------|-----------------| -| from_x | Yes | The x-coordinate of the start point.| -| from_y | Yes | The y-coordinate of the start point.| +| from_x | Yes | The x-coordinate of the start point.| +| from_y | Yes | The y-coordinate of the start point.| | to_x | Yes | The x-coordinate of the stop point.| | to_y | Yes | The y-coordinate of the stop point.| -| swipeVelocityPps_ | No | Fling speed, in px/s. Value range: 200 to 40000.
The default value is 600.| -| stepLength_ | No| The step length. The default value is the sliding distance divided by 50.
To achieve better simulation effect, you are advised to use the default values. | +| swipeVelocityPps_ | No | Swipe speed, in px/s. The value ranges from 200 to 40000.
The default value is **600**.| +| stepLength_ | No| Step length. The default value is the swipe distance divided by 50.
To achieve better simulation effect, you are advised to use the default value. | ```shell # Execute the fling event. The default value of stepLength_ is used. hdc shell uitest uiInput fling 10 10 200 200 500 -``` +``` #### Example of Running the uiInput swipe/drag Command -| Parameter | Mandatory | Description | +| Parameter | Mandatory | Description | |------|------------------|-----------------| -| from_x | Yes | The x-coordinate of the start point.| -| from_y | Yes | The y-coordinate of the start point.| +| from_x | Yes | The x-coordinate of the start point.| +| from_y | Yes | The y-coordinate of the start point.| | to_x | Yes | The x-coordinate of the stop point.| | to_y | Yes | The y-coordinate of the stop point.| -| swipeVelocityPps_ | No | Swipe speed, in px/s. Value range: 200 to 40000.
The default value is 600.| +| swipeVelocityPps_ | No | Swipe speed, in px/s. Value range: 200 to 40000.
The default value is 600.| ```shell # Execute the swipe event. @@ -514,9 +514,9 @@ hdc shell uitest uiInput drag 10 10 100 100 500 | Parameter | Mandatory | Description| |-------------------|-------------|----------| -| direction | No| Fling direction, which can be **0**, **1**, **2**, or **3**. The default value is **0**.
The value **0** indicates leftward fling, **1** indicates rightward fling, **2** indicates upward fling, and **3** indicates downward fling. | -| swipeVelocityPps_ | No| Fling speed, in px/s. Value range: 200 to 40000.
The default value is 600. | -| stepLength | No | The step length.
The default value is the sliding distance divided by 50. To achieve better simulation effect, you are advised to use the default values.| +| direction | No| Fling direction, which can be **0**, **1**, **2**, or **3**. The default value is **0**.
The value **0** indicates leftward fling, **1** indicates rightward fling, **2** indicates upward fling, and **3** indicates downward fling. | +| swipeVelocityPps_ | No| Swipe speed, in px/s. Value range: 200 to 40000.
The default value is 600. | +| stepLength | No | Step length.
The default value is the swipe distance divided by 50. To achieve better simulation effect, you are advised to use the default value.| ```shell # Execute the leftward fling event. @@ -531,9 +531,9 @@ hdc shell uitest uiInput dircFling 3 #### Example of Running the uiInput inputText Command -| Parameter | Mandatory | Description| +| Parameter | Mandatory | Description| |------|------------------|----------| -| point_x | Yes | The x-coordinate of the input box.| +| point_x | Yes | The x-coordinate of the input box.| | point_y | Yes | The y-coordinate of the input box.| | text | Yes | Text in the input box. | @@ -544,9 +544,9 @@ hdc shell uitest uiInput inputText 100 100 hello #### Example of Running the uiInput keyEvent Command -| Parameter | Mandatory | Description| +| Parameter | Mandatory | Description| |------|------|----------| -| keyID1 | Yes | ID of a physical key, which can be **KeyCode**, **Back**, **Home**, or **Power**.
When the value is set to **Back**, **Home**, or **Power**, the combination keys are not supported.| +| keyID1 | Yes | ID of a physical key, which can be **KeyCode**, **Back**, **Home**, or **Power**.
When the value is set to **Back**, **Home**, or **Power**, the combination keys are not supported.| | keyID2 | No | ID of a physical key.| | keyID3 | No | ID of a physical key.| @@ -555,9 +555,9 @@ hdc shell uitest uiInput inputText 100 100 hello > A maximum of three key values can be passed. For details about the key values, see [KeyCode](../reference/apis-input-kit/js-apis-keycode.md). ```shell -# Return to the home page. +# Back to home page. hdc shell uitest uiInput keyEvent Home -# Return to the last page. +# Back to the last page. hdc shell uitest uiInput keyEvent Back # Perform a key combination to copy and paste text. hdc shell uitest uiInput keyEvent 2072 2038 @@ -577,8 +577,10 @@ hdc shell uitest start-daemon >**NOTE** > > You need to enable the developer mode for the device. +> > Only the test HAP started by the **aa test** ability can call the ability of the UiTest. -> The [Ability Privilege Level (APL)](../security/AccessToken/app-permission-mgmt-overview.md#basic-concepts-in-the-permission-mechanism) of the test HAP must be **system_basic** or **normal**. +> +> The [Ability Privilege Level (APL)](../security/AccessToken/app-permission-mgmt-overview.md#basic-concepts-in-the-permission-mechanism) of the test HAP must be **system_basic** or **normal**. ## Examples @@ -643,7 +645,7 @@ For details about how to simulate a window size adjustment and direction specifi ### FAQs About Unit Test Cases -1. The logs in the test case are printed after the test case result +**1. What should I do if logs in the test case are printed after the test case result?** **Problem** @@ -657,7 +659,7 @@ More than one asynchronous API is called in the test case.
In principle, logs If more than one asynchronous API is called, you are advised to encapsulate the API invoking into the promise mode. -**Error "fail to start ability" is reported during test case execution** +**2. What should I do if the message "error: fail to start ability" is reported during test case execution?** **Problem** @@ -671,7 +673,7 @@ An error occurs during the packaging of the test package, and the test framework Check whether the test package contains the **OpenHarmonyTestRunner.abc** file. If the file does not exist, rebuild and pack the file and perform the test again. -Test case execution timeout +**3. What should I do if a timeout error is reported during case execution?** **Problem** @@ -679,7 +681,7 @@ After the test case execution is complete, the console displays the error messag **Possible Causes** -1. The test case is executed through an asynchronous interface, but the **done** function is not executed during the execution. As a result, the test case execution does not end until it times out. +1. The test case is executed through an asynchronous API, but the **done** function is not executed during the execution. As a result, the test case execution does not end until it times out. 2. The time taken for API invocation is longer than the timeout interval set for test case execution. @@ -694,7 +696,7 @@ After the test case execution is complete, the console displays the error messag 3. Check the code logic and assertion result of the test case and make sure that the assertion is passed. ### FAQs About UI Test Cases -**The failure log contains "Get windows failed/GetRootByWindow failed"** +**1. What should I do if the failure log contains "Get windows failed/GetRootByWindow failed"?** **Problem** @@ -712,7 +714,7 @@ Run the following command, restart the device, and execute the test case again: hdc shell param set persist.ace.testmode.enabled 1 ``` -**The failure log contains "uitest-api does not allow calling concurrently"** +**2. What should I do if the failure log contains "uitest-api does not allow calling concurrently"?** **Problem** @@ -730,7 +732,7 @@ The UI test case fails to be executed. The HiLog file contains the error message 2. Do not execute UI test cases in multiple processes. -**The failure log contains "does not exist on current UI! Check if the UI has changed after you got the widget object"** +**3. What should I do if the failure log contains "does not exist on current UI! Check if the UI has changed after you got the widget object"?** **Problem** diff --git a/en/application-dev/application-test/smartperf-guidelines.md b/en/application-dev/application-test/smartperf-guidelines.md index 958ff96098f078721176d544292b6fa0cf027cd6..1ff68f23a440196cb9fe495655b4c042f1799786 100644 --- a/en/application-dev/application-test/smartperf-guidelines.md +++ b/en/application-dev/application-test/smartperf-guidelines.md @@ -4,9 +4,9 @@ SmartPerf Device is a reliable, easy-to-use performance and power consumption test tool. In this tool, you can monitor the performance and power consumption of your application and device with quantitative indicators, such as FPS, CPU, GPU, RAM, and Temp. -Targeted at devices with or without screens, SmartPerf Device provides two modes: Device-hap and Device-daemon. Device-hap is applicable to devices with screens and provides a visualized, intuitive UI that simplifies your operations. You can start and pause a test with a floating window, view performance data in real time, and save the test results for further analysis. Device-daemon is applicable to devices with and without screens and works with shell commands. +Targeted at devices with or without screens, SmartPerf Device provides two modes: Device-hap and Device-daemon. Device-hap is applicable to devices with screens and provides a visualized, intuitive UI that simplifies your operations. You can start and pause a test with a floating window, view performance data in real time, and save the test results for further analysis. Device-daemon is applicable to devices with and without screens and works with shell commands. -### The following are the available indicators: +### Indicators - CPU: The tool reads the frequencies and usage of CPU cores on the test device on a per second basis to measure the CPU usage of the target application. Sustained high CPU may lead to overheating. - GPU: The tool reads the GPU frequency and load information of the test device on a per second basis to measure the GPU usage of the target application. High GPU usage can lead to performance drops and application slowdowns. @@ -23,14 +23,13 @@ The figure below demonstrates the main functions of SmartPerf Device. Set data c ## Constraints -1. Device-daemon and Device-hap are pre-installed since API version 9. +1. Device-daemon and Device-hap are pre-installed since API version 9. 2. Device-daemon must be connected to a hardware device, and Device-hap can only be used on devices with a screen. -3. Before using the Device-Daemon, configure the [HDC environment](https://gitee.com/openharmony/developtools_hdc). +3. Before using Device-Daemon, configure the [hdc environment](https://gitee.com/openharmony/developtools_hdc). - ## SmartPerf Device-hap The RK3568 development board is used as an example below. @@ -47,7 +46,7 @@ Start SmartPerf Device-hap. On the home screen, click **Select an app**. After the target application is selected, return to the start page and set the test indicators. You can also change the test name (which includes the name of the target application and the test time and will be displayed in the report), and specify whether to capture traces and whether to enable the screenshot feature. When you are done, click the **Start** button at the bottom. -### Using the Floating Window to Manage Data Collection. +### Using the Floating Window to Manage Data Collection To start collection, touch **Start** in the floating window. To pause, touch the timer in the floating window. To resume, touch the timer again. To view the collected data in real time, double-touch the timer. To stop, touch and hold the timer.
You can drag the floating window to anywhere you like. @@ -68,14 +67,14 @@ Click **Report** to access the report list. Touch a report to view its details. ### Collection Prerequisites -#### Switch to shell. +#### Switching to Shell ``` C:\Users\issusser>hdc shell # ``` -#### Start and view the daemon process. +#### Starting and Viewing the daemon Process ``` C:\Users\issusser>hdc shell @@ -88,7 +87,7 @@ Click **Report** to access the report list. Touch a report to view its details. # ``` -#### View the help information. +#### Viewing the Help Information @@ -164,9 +163,9 @@ Click **Report** to access the report list. Touch a report to view its details. | -c |No| Collects the CPU frequency and usage.
When the application bundle name is set, the system and application CPU information is collected.
Otherwise, only the system CPU information is collected. | | -g |No| Collects the GPU frequency and load information. | | -f |No| Collects the screen refresh rate and frame rate of the target application. The application bundle name must be specified. | -| -t |No| Collects the temperature of the GPU and system chip. | +| -t |No| Collects the temperature of GPU and system chip. | | -r |No| Collects the memory.
When the application bundle name is set, the system and application memory information is obtained.
Otherwise, only the system memory information is obtained. | -| -snapshot |No| Takes screenshots. | +| -snapshot |No| Takes a screenshot. | | -net |No| Collects the network speed. | | -VIEW |No| Sets the view layer. You must obtain the layer name first. | | -d |No| Collects the DDR data. | @@ -180,43 +179,51 @@ Click **Report** to access the report list. Touch a report to view its details. ``` # SP_daemon -N 2 -c - order:0 timestamp=1503078645909 - order:1 cpu0Frequency=1992000 - order:2 cpu0Usage=34.042553 - order:3 cpu0idleUsage=65.957447 - order:4 cpu0ioWaitUsage=0.000000 - order:5 cpu0irqUsage=0.000000 - order:6 cpu0niceUsage=0.000000 - order:7 cpu0softIrqUsage=0.000000 - order:8 cpu0systemUsage=15.957447 - order:9 cpu0userUsage=18.085106 - order:10 cpu1Frequency=1992000 - order:11 cpu1Usage=43.877551 - order:12 cpu1idleUsage=56.122449 - order:13 cpu1ioWaitUsage=0.000000 - order:14 cpu1irqUsage=0.000000 - order:15 cpu1niceUsage=0.000000 - order:16 cpu1softIrqUsage=0.000000 - order:17 cpu1systemUsage=17.346939 - order:18 cpu1userUsage=26.530612 - order:19 cpu2Frequency=1992000 - order:20 cpu2Usage=38.043478 - order:21 cpu2idleUsage=61.956522 - order:22 cpu2ioWaitUsage=0.000000 - order:23 cpu2irqUsage=0.000000 - order:24 cpu2niceUsage=0.000000 - order:25 cpu2softIrqUsage=0.000000 - order:26 cpu2systemUsage=11.956522 - order:27 cpu2userUsage=26.086957 - order:28 cpu3Frequency=1992000 - order:29 cpu3Usage=68.421053 - order:30 cpu3idleUsage=31.578947 - order:31 cpu3ioWaitUsage=0.000000 - order:32 cpu3irqUsage=0.000000 - order:33 cpu3niceUsage=0.000000 - order:34 cpu3softIrqUsage=0.000000 - order:35 cpu3systemUsage=13.684211 - order:36 cpu3userUsage=54.736842 + order:0 timestamp=1501839064260 + order:1 TotalcpuUsage=0.502513 + order:2 TotalcpuidleUsage=99.497487 + order:3 TotalcpuioWaitUsage=0.000000 + order:4 TotalcpuirqUsage=0.000000 + order:5 TotalcpuniceUsage=0.000000 + order:6 TotalcpusoftIrqUsage=0.000000 + order:7 TotalcpusystemUsage=0.251256 + order:8 TotalcpuuserUsage=0.251256 + order:9 cpu0Frequency=1992000 + order:10 cpu0Usage=1.000000 + order:11 cpu0idleUsage=99.000000 + order:12 cpu0ioWaitUsage=0.000000 + order:13 cpu0irqUsage=0.000000 + order:14 cpu0niceUsage=0.000000 + order:15 cpu0softIrqUsage=0.000000 + order:16 cpu0systemUsage=0.000000 + order:17 cpu0userUsage=1.000000 + order:18 cpu1Frequency=1992000 + order:19 cpu1Usage=0.000000 + order:20 cpu1idleUsage=100.000000 + order:21 cpu1ioWaitUsage=0.000000 + order:22 cpu1irqUsage=0.000000 + order:23 cpu1niceUsage=0.000000 + order:24 cpu1softIrqUsage=0.000000 + order:25 cpu1systemUsage=0.000000 + order:26 cpu1userUsage=0.000000 + order:27 cpu2Frequency=1992000 + order:28 cpu2Usage=1.000000 + order:29 cpu2idleUsage=99.000000 + order:30 cpu2ioWaitUsage=0.000000 + order:31 cpu2irqUsage=0.000000 + order:32 cpu2niceUsage=0.000000 + order:33 cpu2softIrqUsage=0.000000 + order:34 cpu2systemUsage=1.000000 + order:35 cpu2userUsage=0.000000 + order:36 cpu3Frequency=1992000 + order:37 cpu3Usage=0.000000 + order:38 cpu3idleUsage=100.000000 + order:39 cpu3ioWaitUsage=0.000000 + order:40 cpu3irqUsage=0.000000 + order:41 cpu3niceUsage=0.000000 + order:42 cpu3softIrqUsage=0.000000 + order:43 cpu3systemUsage=0.000000 + order:44 cpu3userUsage=0.000000 ... @@ -227,56 +234,62 @@ Click **Report** to access the report list. Touch a report to view its details. - Collect twice the frequency and usage of CPU cores and CPU usage and load of processes. ``` - # SP_daemon -N 2 -PKG com.ohos.settings -c - - - - order:0 timestamp=1503078694916 - order:1 ProcAppName=com.ohos.settings - order:2 ProcCpuLoad=0 - order:3 ProcCpuUsage=0 - order:4 ProcId=0 - order:5 ProcSCpuUsage=0 - order:6 ProcUCpuUsage=0 - order:7 cpu0Frequency=1992000 - order:8 cpu0Usage=31.868132 - order:9 cpu0idleUsage=68.131868 - order:10 cpu0ioWaitUsage=0.000000 - order:11 cpu0irqUsage=0.000000 - order:12 cpu0niceUsage=0.000000 - order:13 cpu0softIrqUsage=0.000000 - order:14 cpu0systemUsage=15.384615 - order:15 cpu0userUsage=16.483516 - order:16 cpu1Frequency=1992000 - order:17 cpu1Usage=44.791667 - order:18 cpu1idleUsage=55.208333 - order:19 cpu1ioWaitUsage=0.000000 - order:20 cpu1irqUsage=0.000000 - order:21 cpu1niceUsage=0.000000 - order:22 cpu1softIrqUsage=0.000000 - order:23 cpu1systemUsage=13.541667 - order:24 cpu1userUsage=31.250000 - order:25 cpu2Frequency=1992000 - order:26 cpu2Usage=37.894737 - order:27 cpu2idleUsage=62.105263 - order:28 cpu2ioWaitUsage=0.000000 - order:29 cpu2irqUsage=0.000000 - order:30 cpu2niceUsage=0.000000 - order:31 cpu2softIrqUsage=1.052632 - order:32 cpu2systemUsage=13.684211 - order:33 cpu2userUsage=23.157895 - order:34 cpu3Frequency=1992000 - order:35 cpu3Usage=81.632653 - order:36 cpu3idleUsage=18.367347 - order:37 cpu3ioWaitUsage=0.000000 - order:38 cpu3irqUsage=0.000000 - order:39 cpu3niceUsage=0.000000 - order:40 cpu3softIrqUsage=0.000000 - order:41 cpu3systemUsage=15.306122 - order:42 cpu3userUsage=66.326531 + # SP_daemon -N 2 -PKG ohos.samples.ecg -c + order:0 timestamp=1501839151499 + order:1 ProcAppName=ohos.samples.ecg + order:2 ProcCpuLoad=0.000000 + order:3 ProcCpuUsage=36.177645 + order:4 ProcId=2111 + order:5 ProcSCpuUsage=8.982036 + order:6 ProcUCpuUsage=27.195609 + order:7 TotalcpuUsage=62.500000 + order:8 TotalcpuidleUsage=37.500000 + order:9 TotalcpuioWaitUsage=0.000000 + order:10 TotalcpuirqUsage=0.000000 + order:11 TotalcpuniceUsage=0.000000 + order:12 TotalcpusoftIrqUsage=0.000000 + order:13 TotalcpusystemUsage=21.614583 + order:14 TotalcpuuserUsage=40.885417 + order:15 cpu0Frequency=1992000 + order:16 cpu0Usage=77.083333 + order:17 cpu0idleUsage=22.916667 + order:18 cpu0ioWaitUsage=0.000000 + order:19 cpu0irqUsage=0.000000 + order:20 cpu0niceUsage=0.000000 + order:21 cpu0softIrqUsage=0.000000 + order:22 cpu0systemUsage=21.875000 + order:23 cpu0userUsage=55.208333 + order:24 cpu1Frequency=1992000 + order:25 cpu1Usage=57.731959 + order:26 cpu1idleUsage=42.268041 + order:27 cpu1ioWaitUsage=0.000000 + order:28 cpu1irqUsage=0.000000 + order:29 cpu1niceUsage=0.000000 + order:30 cpu1softIrqUsage=0.000000 + order:31 cpu1systemUsage=21.649485 + order:32 cpu1userUsage=36.082474 + order:33 cpu2Frequency=1992000 + order:34 cpu2Usage=59.793814 + order:35 cpu2idleUsage=40.206186 + order:36 cpu2ioWaitUsage=0.000000 + order:37 cpu2irqUsage=0.000000 + order:38 cpu2niceUsage=0.000000 + order:39 cpu2softIrqUsage=0.000000 + order:40 cpu2systemUsage=19.587629 + order:41 cpu2userUsage=40.206186 + order:42 cpu3Frequency=1992000 + order:43 cpu3Usage=55.789474 + order:44 cpu3idleUsage=44.210526 + order:45 cpu3ioWaitUsage=0.000000 + order:46 cpu3irqUsage=0.000000 + order:47 cpu3niceUsage=0.000000 + order:48 cpu3softIrqUsage=0.000000 + order:49 cpu3systemUsage=23.157895 + order:50 cpu3userUsage=32.631579 + ... - + command exec finished! # ``` @@ -286,12 +299,10 @@ Click **Report** to access the report list. Touch a report to view its details. >- Make sure you are on the application screen when running this command. - Collect once the GPU frequency and load of the system. - + ``` # SP_daemon -N 1 -g - - - + order:0 timestamp=1503078740268 order:1 gpuFrequency=200000000 order:2 gpuLoad=38.000000 @@ -304,16 +315,15 @@ Click **Report** to access the report list. Touch a report to view its details. ``` # SP_daemon -N 2 -t - + order:0 timestamp=1502720711191 order:1 gpu-thermal=42500.000000 order:2 soc-thermal=43.125000 - - + order:0 timestamp=1502720712191 order:1 gpu-thermal=41875.000000 order:2 soc-thermal=42.500000 - + command exec finished! # ``` @@ -326,12 +336,12 @@ Click **Report** to access the report list. Touch a report to view its details. order:1 memAvailable=7339224 order:2 memFree=7164708 order:3 memTotal=11641840 - + order:0 timestamp=1705041563527 order:1 memAvailable=7339136 order:2 memFree=7164684 order:3 memTotal=11641840 - + command exec finished! # ``` @@ -340,7 +350,7 @@ Click **Report** to access the report list. Touch a report to view its details. ``` # SP_daemon -N 1 -PKG ohos.samples.ecg -r - + order:0 timestamp=1720427095197 order:1 arktsHeapPss=17555 order:2 gpuPss=7021 @@ -361,7 +371,6 @@ Click **Report** to access the report list. Touch a report to view its details. order:17 swap=122076 order:18 swapPss=122076 - command exec finished! # ``` @@ -374,41 +383,37 @@ Click **Report** to access the report list. Touch a report to view its details. ``` # SP_daemon -N 2 -snapshot + + order:0 timestamp=1501837609657 + order:1 capture=data/local/tmp/capture/screenCap_1501837609657.png - order:0 timestamp=1705041753321 - order:1 capture=data/local/tmp/capture/screenCap_1705041753321.png - - /data/local/tmp/capture created! - - order:0 timestamp=1705041754324 + order:0 timestamp=1501837610657 order:1 capture=NA - + command exec finished! # ``` >**NOTE** > - >- Screenshots are collected every 2 seconds. - > - >- + >- Screenshots are collected every 2 seconds. > >- When the collection is complete, you can view the screenshots in **data/local/tmp/capture**. > - >- To export the screenshots to drive D, open a new CLI and run the **hdc file recv data/local/tmp/capture/screenCap_1700725192774.png D:\** command. + >- To export the screenshots to drive D, open a new CLI and run the **hdc file recv data/local/tmp/capture/screenCap_1700725192774.png D:\\** command. - Collect the network speeds twice. ``` # SP_daemon -N 2 -net - + order:0 timestamp=1705041904832 order:1 networkDown=0 order:2 networkUp=0 - + order:0 timestamp=1705041905870 order:1 networkDown=22931 order:2 networkUp=2004 - + command exec finished! # ``` @@ -417,27 +422,27 @@ Click **Report** to access the report list. Touch a report to view its details. ``` # SP_daemon -N 5 -PKG ohos.samples.ecg -f - + order:0 timestamp=1705306472232 order:1 fps=43 order:2 fpsJitters=602261688;;8352083;;8267708;;8305209;;8298437;;8308854;;8313542;;8569271;;8061458;;8300521;;8308333;;8309896;;8429167;;8241667;;8258333;;8318229;;8312500;;8304167;;41760937;;16418750;;8298959;;8319270;;8308334;;8313541;;8302605;;8320312;;8298958;;8326042;;8321354;;8301042;;8310417;;8309895;;8308855;;8331250;;8286458;;8343229;;8278125;;8311458;;8306250;;8312500;;8320834;;8346875;;8283333 - order:3 refreshrate=120 - + order:3 refreshrate=69 + order:0 timestamp=1705306473234 order:1 fps=40 order:2 fpsJitters=674427313;;8191145;;8310417;;8319271;;8301562;;8318750;;8302084;;8314062;;8333334;;8283854;;8307812;;8311979;;8310417;;8307813;;8309375;;8323958;;8306250;;8308333;;8317709;;8296875;;8721875;;7895833;;8320833;;8340625;;8276563;;8409896;;8216145;;8310938;;8301042;;8362500;;8252604;;8317708;;8376042;;8256250;;8292187;;8303125;;8313542;;8310417;;8520312 - order:3 refreshrate=120 + order:3 refreshrate=69 ... - + command exec finished! # ``` >**NOTE** > >- When running this command, make sure you are on the application screen, and then swipe on the screen or switch between screens. - >- When dynamic refresh rate (DRR) is enabled, the refresh rate changes in real time (multiple changes may occur within one second). The value of **refreshrate** is collected at a timestamp. + >- When dynamic refresh rate (DRR) is enabled, the refresh rate changes in real time (multiple changes may occur within one second). The value of **refreshrate** is obtained at a timestamp. + - - Collect the frame rate of the specified view layer for 10 times. ``` @@ -445,14 +450,14 @@ Click **Report** to access the report list. Touch a report to view its details. order:0 timestamp=1705306822850 order:1 fps=15 order:2 fpsJitters=876291843;;8314062;;8308334;;8314583;;8310417;;8308333;;8326042;;8314583;;8292708;;8492709;;8143750;;8340104;;8294271;;8302604;;8297396 - order:3 refreshrate=120 - + order:3 refreshrate=69 + order:0 timestamp=1705306823852 order:1 fps=12 order:2 fpsJitters=906667363;;8279167;;8311458;;8315625;;8291146;;8313021;;8323438;;8293750;;8303125;;8313541;;8301563;;8317708 - order:3 refreshrate=120 + order:3 refreshrate=69 ... - + command exec finished! # ``` @@ -478,145 +483,162 @@ Click **Report** to access the report list. Touch a report to view its details. - Collect the full information of the system, including the CPU, GPU, temperature, memory, DDR, network speed, and screenshot information. - + ``` # SP_daemon -N 10 -c -g -t -r -d -net -snapshot - - order:0 timestamp=1502725274844 - order:1 cpu0Frequency=1992000 - order:2 cpu0Usage=37.634409 - order:3 cpu0idleUsage=62.365591 - order:4 cpu0ioWaitUsage=0.000000 - order:5 cpu0irqUsage=0.000000 - order:7 cpu0softIrqUsage=1.075269 - order:8 cpu0systemUsage=17.204301 - order:9 cpu0userUsage=19.354839 - order:10 cpu1Frequency=1992000 - order:11 cpu1Usage=87.878788 - order:12 cpu1idleUsage=12.121212 - order:13 cpu1ioWaitUsage=0.000000 - order:14 cpu1irqUsage=0.000000 - order:15 cpu1niceUsage=0.000000 - order:16 cpu1softIrqUsage=0.000000 - order:17 cpu1systemUsage=15.151515 - order:18 cpu1userUsage=72.727273 - order:19 cpu2Frequency=1992000 - order:20 cpu2Usage=45.544554 - order:21 cpu2idleUsage=54.455446 - order:22 cpu2ioWaitUsage=0.000000 - order:23 cpu2irqUsage=0.000000 - order:24 cpu2niceUsage=0.000000 - order:25 cpu2softIrqUsage=0.990099 - order:26 cpu2systemUsage=14.851485 - order:27 cpu2userUsage=29.702970 - order:28 cpu3Frequency=1992000 - order:29 cpu3Usage=39.175258 - order:30 cpu3idleUsage=60.824742 - order:31 cpu3ioWaitUsage=0.000000 - order:32 cpu3irqUsage=0.000000 - order:33 cpu3niceUsage=0.000000 - order:34 cpu3softIrqUsage=1.030928 - order:35 cpu3systemUsage=14.432990 - order:36 cpu3userUsage=23.711340 - order:37 gpuFrequency=300000000 - order:38 gpuLoad=25.000000 - order:39 gpu-thermal=43750.000000 - order:40 soc-thermal=45.555000 - order:41 memAvailable=1118792 - order:42 memFree=688032 - order:43 memTotal=1990104 - order:44 ddrFrequency=0 - order:45 networkDown=0 - order:46 networkUp=0 - order:47 capture=data/local/tmp/capture/screenCap_1502725274893.png - + + order:0 timestamp=1501837838664 + order:1 TotalcpuUsage=0.751880 + order:2 TotalcpuidleUsage=99.248120 + order:3 TotalcpuioWaitUsage=0.000000 + order:4 TotalcpuirqUsage=0.000000 + order:5 TotalcpuniceUsage=0.000000 + order:6 TotalcpusoftIrqUsage=0.000000 + order:7 TotalcpusystemUsage=0.501253 + order:8 TotalcpuuserUsage=0.250627 + order:9 cpu0Frequency=1992000 + order:10 cpu0Usage=0.000000 + order:11 cpu0idleUsage=100.000000 + order:12 cpu0ioWaitUsage=0.000000 + order:13 cpu0irqUsage=0.000000 + order:14 cpu0niceUsage=0.000000 + order:15 cpu0softIrqUsage=0.000000 + order:16 cpu0systemUsage=0.000000 + order:17 cpu0userUsage=0.000000 + order:18 cpu1Frequency=1992000 + order:19 cpu1Usage=0.000000 + order:20 cpu1idleUsage=100.000000 + order:21 cpu1ioWaitUsage=0.000000 + order:22 cpu1irqUsage=0.000000 + order:23 cpu1niceUsage=0.000000 + order:24 cpu1softIrqUsage=0.000000 + order:25 cpu1systemUsage=0.000000 + order:26 cpu1userUsage=0.000000 + order:27 cpu2Frequency=1992000 + order:28 cpu2Usage=1.000000 + order:29 cpu2idleUsage=99.000000 + order:30 cpu2ioWaitUsage=0.000000 + order:31 cpu2irqUsage=0.000000 + order:32 cpu2niceUsage=0.000000 + order:33 cpu2softIrqUsage=0.000000 + order:34 cpu2systemUsage=1.000000 + order:35 cpu2userUsage=0.000000 + order:36 cpu3Frequency=1992000 + order:37 cpu3Usage=0.000000 + order:38 cpu3idleUsage=100.000000 + order:39 cpu3ioWaitUsage=0.000000 + order:40 cpu3irqUsage=0.000000 + order:41 cpu3niceUsage=0.000000 + order:42 cpu3softIrqUsage=0.000000 + order:43 cpu3systemUsage=0.000000 + order:44 cpu3userUsage=0.000000 + order:45 gpuFrequency=200000000 + order:46 gpuLoad=0.000000 + order:47 gpu-thermal=40000.000000 + order:48 soc-thermal=40.625000 + order:49 memAvailable=1142820 + order:50 memFree=687988 + order:51 memTotal=1935948 + order:52 ddrFrequency=800000000 + order:53 networkDown=0 + order:54 networkUp=0 + order:55 capture=data/local/tmp/capture/screenCap_1501837838669.png + ... - + command exec finished! # ``` - Collect the full information of the specified application, including the CPU, GPU, temperature, frame rate, memory, DDR, network speed, and screenshot information. - + ``` # SP_daemon -N 10 -PKG ohos.samples.ecg -c -g -t -f -r -d -net -snapshot - - order:0 timestamp=1502725340425 - order:1 ProcAppName=com.ohos.settings + + order:0 timestamp=1501837949706 + order:1 ProcAppName=ohos.samples.ecg order:2 ProcCpuLoad=0.000000 - order:3 ProcCpuUsage=35.950135 - order:4 ProcId=3912 - order:5 ProcSCpuUsage=6.721698 - order:6 ProcUCpuUsage=29.228437 - order:7 cpu0Frequency=1992000 - order:8 cpu0Usage=64.539007 - order:9 cpu0idleUsage=35.460993 - order:10 cpu0ioWaitUsage=0.000000 - order:11 cpu0irqUsage=0.000000 - order:12 cpu0niceUsage=0.000000 - order:13 cpu0softIrqUsage=0.000000 - order:14 cpu0systemUsage=26.241135 - order:15 cpu0userUsage=38.297872 - order:16 cpu1Frequency=1992000 - order:17 cpu1Usage=73.758865 - order:18 cpu1idleUsage=26.241135 - order:19 cpu1ioWaitUsage=0.000000 - order:20 cpu1irqUsage=0.000000 - order:21 cpu1niceUsage=0.000000 - order:22 cpu1softIrqUsage=0.000000 - order:23 cpu1systemUsage=29.078014 - order:24 cpu1userUsage=44.680851 - order:25 cpu2Frequency=1992000 - order:26 cpu2Usage=75.172414 - order:27 cpu2idleUsage=24.827586 - order:28 cpu2ioWaitUsage=0.000000 - order:29 cpu2irqUsage=0.000000 - order:30 cpu2niceUsage=0.000000 - order:31 cpu2softIrqUsage=0.000000 - order:32 cpu2systemUsage=18.620690 - order:33 cpu2userUsage=56.551724 - order:34 cpu3Frequency=1992000 - order:35 cpu3Usage=80.419580 - order:36 cpu3idleUsage=19.580420 - order:37 cpu3ioWaitUsage=0.000000 - order:38 cpu3irqUsage=0.000000 - order:39 cpu3niceUsage=0.000000 - order:40 cpu3softIrqUsage=0.699301 - order:41 cpu3systemUsage=21.678322 - order:42 cpu3userUsage=58.041958 - order:43 gpuFrequency=800000000 - order:44 gpuLoad=45.000000 - order:45 gpu-thermal=44375.000000 - order:46 soc-thermal=46.111000 - order:47 fps=40 - order:48 fpsJitters=14482127;;28966003;;28971836;;14484751;;28952878;;28970962;;14480959;;28968337;;14476001;;28967461;;28968045;;14477751;;28966878;;28975337;;14475126;;28962795;;28967461;;14496710;;28953169;;28966003;;14483002;;28963961;;28965711;;28964836;;28966295;;14550085;;28898628;;28964544;;28975628;;14497293;;28938878;;43454546;;28966003;;28973295;;28959878;;28964252;;14476585;;28965128;;28970670;;14478626 - order:49 refreshrate=69 - order:50 arktsHeapPss=8482 - order:51 gpuPss=0 - order:52 graphicPss=10800 - order:53 heapAlloc=0 - order:54 heapFree=0 - order:55 heapSize=0 - order:56 memAvailable=1113084 - order:57 memFree=681968 - order:58 memTotal=1990104 - order:59 nativeHeapPss=24630 - order:60 privateClean=7072 - order:61 privateDirty=43304 - order:62 pss=71001 - order:63 sharedClean=93024 - order:64 sharedDirty=45060 - order:65 stackPss=1784 - order:66 swap=0 - order:67 swapPss=0 - order:68 ddrFrequency=0 - order:69 networkDown=0 - order:70 networkUp=0 - order:71 capture=data/local/tmp/capture/screenCap_1502725341222.png - + order:3 ProcCpuUsage=38.775000 + order:4 ProcId=1960 + order:5 ProcSCpuUsage=8.875000 + order:6 ProcUCpuUsage=29.900000 + order:7 TotalcpuUsage=85.416667 + order:8 TotalcpuidleUsage=14.583333 + order:9 TotalcpuioWaitUsage=0.000000 + order:10 TotalcpuirqUsage=0.000000 + order:11 TotalcpuniceUsage=0.000000 + order:12 TotalcpusoftIrqUsage=0.000000 + order:13 TotalcpusystemUsage=33.072917 + order:14 TotalcpuuserUsage=52.343750 + order:15 cpu0Frequency=1992000 + order:16 cpu0Usage=92.929293 + order:17 cpu0idleUsage=7.070707 + order:18 cpu0ioWaitUsage=0.000000 + order:19 cpu0irqUsage=0.000000 + order:20 cpu0niceUsage=0.000000 + order:21 cpu0softIrqUsage=0.000000 + order:22 cpu0systemUsage=40.404040 + order:23 cpu0userUsage=52.525253 + order:24 cpu1Frequency=1992000 + order:25 cpu1Usage=82.291667 + order:26 cpu1idleUsage=17.708333 + order:27 cpu1ioWaitUsage=0.000000 + order:28 cpu1irqUsage=0.000000 + order:29 cpu1niceUsage=0.000000 + order:30 cpu1softIrqUsage=0.000000 + order:31 cpu1systemUsage=29.166667 + order:32 cpu1userUsage=53.125000 + order:33 cpu2Frequency=1992000 + order:34 cpu2Usage=81.111111 + order:35 cpu2idleUsage=18.888889 + order:36 cpu2ioWaitUsage=0.000000 + order:37 cpu2irqUsage=0.000000 + order:38 cpu2niceUsage=0.000000 + order:39 cpu2softIrqUsage=0.000000 + order:40 cpu2systemUsage=31.111111 + order:41 cpu2userUsage=50.000000 + order:42 cpu3Frequency=1992000 + order:43 cpu3Usage=85.858586 + order:44 cpu3idleUsage=14.141414 + order:45 cpu3ioWaitUsage=0.000000 + order:46 cpu3irqUsage=0.000000 + order:47 cpu3niceUsage=0.000000 + order:48 cpu3softIrqUsage=0.000000 + order:49 cpu3systemUsage=32.323232 + order:50 cpu3userUsage=53.535354 + order:51 gpuFrequency=200000000 + order:52 gpuLoad=29.000000 + order:53 gpu-thermal=41875.000000 + order:54 soc-thermal=45.000000 + order:55 fps=40 + order:56 fpsJitters=14482127;;28966003;;28971836;;14484751;;28952878;;28970962;;14480959;;28968337;;14476001;;28967461;;28968045;;14477751;;28966878;;28975337;;14475126;;28962795;;28967461;;14496710;;28953169;;28966003;;14483002;;28963961;;28965711;;28964836;;28966295;;14550085;;28898628;;28964544;;28975628;;14497293;;28938878;;43454546;;28966003;;28973295;;28959878;;28964252;;14476585;;28965128;;28970670;;14478626 + order:57 refreshrate=69 + order:58 arktsHeapPss=10970 + order:59 gpuPss=0 + order:60 graphicPss=10800 + order:61 heapAlloc=0 + order:62 heapFree=0 + order:63 heapSize=0 + order:64 memAvailable=1137784 + order:65 memFree=682592 + order:66 memTotal=1935948 + order:67 nativeHeapPss=21398 + order:68 privateClean=24816 + order:69 privateDirty=44932 + order:70 pss=91587 + order:71 sharedClean=100512 + order:72 sharedDirty=36832 + order:73 stackPss=1444 + order:74 swap=0 + order:75 swapPss=0 + order:76 ddrFrequency=800000000 + order:77 networkDown=0 + order:78 networkUp=0 + order:79 capture=data/local/tmp/capture/screenCap_1501837950216.png + ... - + command exec finished! # ``` @@ -637,21 +659,25 @@ Run the **start** command to start collection, operate the device or application | -stop |Yes| Stops collection. A report is generated when collection is complete. | ##### Samples - - ``` + + ``` Start data collection. # SP_daemon -start -c SP_daemon Collection begins + + command exec finished! # Stop data collection. # SP_daemon -stop SP_daemon Collection ended - Output Path: data/local/tmp/smartperf/1/t_index_info_csv + Output Path: data/local/tmp/smartperf/1/t_index_info.csv + + command exec finished! # - ``` + ``` >**NOTE** > >- To start collecting the system data, run the **SP_daemon -start -c -g -t -r -d -net -snapshot** command. @@ -668,20 +694,20 @@ If the collection result is saved in a CSV file, perform the following steps to - To check the path to the test result file: - ``` + ``` C:\Users\issusser>hdc shell # cd data/local/tmp # ls data.csv # - ``` + ``` - To export the test result file: ``` C:\Users\issusser>hdc file recv data/local/tmp/data.csv D:\ [I][2023-11-08 16:16:41] HdcFile::TransferSummary success FileTransfer finish, Size:429, File count = 1, time:6ms rate:71.50kB/s - + C:\Users\issusser> ``` @@ -693,23 +719,23 @@ If the collection result is saved in a CSV file, perform the following steps to | :-----| :--------------------- |:-----| | cpuFrequency | CPU core frequency. |Unit: Hz| | cpuUasge | CPU core usage. |%| - | cpuidleUsage | CPU usage in idle state. |%| + | cpuidleUsage | CPU usage in idle state. |%| | cpuioWaitUsage | CPU usage of I/O wait. |%| - | cpuirqUsage | CPU usage of hardware interrupts. |%| + | cpuirqUsage | CPU usage of hardware interrupts. |%| | cpuniceUsage | CPU usage of user level processes with lower scheduling priority. |%| - | cpusoftIrqUsage | CPU usage of software interrupts. |%| + | cpusoftIrqUsage | CPU usage of software interrupts. |%| | cpusystemUsage | CPU usage in kernel mode. |%| - | cpuuserUsage | CPU usage in user mode. |%| - | ProcId | PID. |-| - | ProcAppName | App package name. |-| + | cpuuserUsage | CPU usage in user mode. |%| + | ProcId | Process ID. |-| + | ProcAppName | Application bundle name. |-| | ProcCpuLoad | Process CPU load. |%| - | ProcCpuUsage | CPU usage of the process. |%| + | ProcCpuUsage | CPU usage of the process. |%| | ProcUCpuUsage | CPU usage of the process in user mode. |%| - | ProcSCpuUsage | CPU usage of the process in kernel mode. |%| + | ProcSCpuUsage | CPU usage of the process in kernel mode. |%| | gpuFrequ | GPU frequency of the system. |%| | gpuLoad | GPU load of the system. |%| - | currentNow | Current value. |Unit: mA| - | voltageNow | Voltage value. |Unit: μV| + | currentNow | Current value. |Unit: mA| + | voltageNow | Voltage value. |Unit: μV| | fps | Number of frames per second. |Unit: FPS| | fpsJitters | Frame interval. |Unit: ns| | refreshrate | Screen refresh rate. |Unit: Hz| @@ -736,7 +762,7 @@ If the collection result is saved in a CSV file, perform the following steps to | arktsHeapPss | Used ArkTS memory size. |Unit: KB| | nativeHeapPss | Used native memory size. |Unit: KB| | stackPss | Used stack memory size. |Unit: KB| - | timeStamp | Timestamp. |Collection time.| + | timeStamp | Timestamp. |Collection time.| ### Scenario Collection @@ -747,17 +773,17 @@ In addition to basic collection, the response and completion delay can be collec | Command |Mandatory| Description | | :-----|:-----| :--------------------- | -| -editor|Yes| Scenario collection tag, which can be followed by parameter configuration options. | -| -responseTime|No| Response delay. | -| -completeTime|No| Completion delay. | +| -editor|Yes| Identifies scenario collection. Parameter options can be added after. | +| -responseTime|No| Collects the response latency. | +| -completeTime|No| Collects the completion delay. | | -fpsohtest|No| A validator used to collect the frame rate every second. The frame rate is collected 10 times by default. | #### Samples -- Collect the application response delay. +- Collect the application response latency. (This command supports only the RK3568 device.) ``` - # SP_daemon -editor responseTime com.ohos.settings + # SP_daemon -editor responseTime ohos.samples.ecg ohtest time:544ms command exec finished! @@ -766,10 +792,10 @@ In addition to basic collection, the response and completion delay can be collec > >- Open the application before collection, press **Enter** in the CLI, switch to the application page, and wait for the collection result to be printed. -- Collect the application completion delay. +- Collect the application completion latency. (This command supports only the RK3568 device.) ``` - # SP_daemon -editor completeTime com.ohos.settings + # SP_daemon -editor completeTime ohos.samples.ecg ohtest time:677ms command exec finished! @@ -800,7 +826,7 @@ The power collection result of the current device can be written into the **data | -deviceinfo|No| Obtains device information. | | -server|No| Starts a daemon process by starting or stopping collection. | | -clear|No| Clears all the SP_daemon processes. | -| -ohtestfps|No| Obtains the frame rate. The number of collection times can be set (collection is performed every second). | +| -ohtestfps|No| Obtains the frame rate. You can set the number of collection times (collection is performed every second). | | -editorServer|No| Starts a daemon process by using an editor. | | -recordcapacity|No| Obtains the battery level of the current device. | | -profilerfps |No| Collects the frame rate of the current page. | @@ -811,7 +837,9 @@ The power collection result of the current device can be written into the **data ``` # SP_daemon -screen - activeMode: 1260x2720, refreshrate=120 + activeMode: 720x1280, refreshrate=69 + + command exec finished! # ``` @@ -831,15 +859,16 @@ The power collection result of the current device can be written into the **data cpu_c1_max: 1992000 cpu_c1_min: 408000 cpu_cluster_name: policy0 + daemonPerfVersion: 1.0.5 deviceTypeName: rk3568 - fullname: OpenHarmony-5.0.2.43 + fullname: OpenHarmony-5.1.0.46 gpu_max_freq: 800000000 gpu_min_freq: 200000000 model: ohos name: OpenHarmony 3.2 - sn: 7001005458323933328a26dbb7bd3900 - version: OpenHarmony 5.0.2.43 - + sn: 150100424a5444345209d941bec6b900 + version: OpenHarmony 5.1.0.46 + command exec finished! # ``` @@ -852,9 +881,6 @@ The power collection result of the current device can be written into the **data # pidof SP_daemon 7024 # - - command exec finished! - # ``` >**NOTE** > @@ -864,14 +890,14 @@ The power collection result of the current device can be written into the **data ``` # pidof SP_daemon - 9923 11402 + 2725 # SP_daemon -clear + + + command exec finished! # # pidof SP_daemon # - - command exec finished! - # ``` >**NOTE** > @@ -894,9 +920,6 @@ The power collection result of the current device can be written into the **data fps:41|1501926693532 SP_daemon exec finished! # - - command exec finished! - # ``` >**NOTE** > @@ -907,11 +930,9 @@ The power collection result of the current device can be written into the **data ``` # SP_daemon -editorServer - Socket Process called! - Socket TCP Init called! - Socket Process called! - Socket Process called! - — + + + command exec finished! ``` diff --git a/en/application-dev/application-test/wukong-guidelines.md b/en/application-dev/application-test/wukong-guidelines.md index 5712a6fb1bf3830c8ef2fec416b7c2b7e5621473..5853fadca258d8bf03bd8f3c60bbfe37f68f8648 100644 --- a/en/application-dev/application-test/wukong-guidelines.md +++ b/en/application-dev/application-test/wukong-guidelines.md @@ -114,7 +114,12 @@ The following figure shows the wukong component architecture and the responsibil -r, --rotate rotate event percent -e, --allow ability the ability name of allowlist -E, --block ability the ability name of blocklist + -Y, --blockCompId the id list of block component + -y, --blockCompType the type list of block component -I, --screenshot get screenshot(only in random input) + -B, --checkBWScreen black and white screen detection + -U, --Uri set Uri pages + -x, --Uri-type set Uri-type # wukong special -help // Help menu for wukong special testing. usage: wukong special [] These are wukong special arguments list: @@ -143,12 +148,12 @@ The following figure shows the wukong component architecture and the responsibil | Command | Description | Mandatory| Description | | --------------- | ------------------------------------ | ---- | ---------------------------------------- | | -h,--help | Obtains the help information about the test. | No | - | -| -c,--count | Sets the number of execution times. This command conflicts with the **-T** command. Select either of them. | No | The default value is 10, in times. | +| -c,--count | Sets the number of execution times. This command conflicts with the **-T** command. Set either of them. | No | The default value is 10, in times. | | -i,--interval | Sets the test interval. | No | The default value is 1500, in millisecond. | | -s,--seed | Sets the random seed. | No | If the same random seed is set, the same random event sequence is generated.| -| -b,--bundle[bundlename, ......, bundlename] | Sets the allowed bundles for the test. This command conflicts with the **-p** command.| No | By default, all bundles on the device are allowed. Use commas (,) to separate bundle names. | -| -p,--prohibit[bundlename, ......, bundlename] | Sets the blocked bundles for the test. This command conflicts with the **-b** command.| No | By default, no bundle is blocked. Use commas (,) to separate bundle names. | -| -d,--page[page, ......, page] | Sets the blocked pages for the test.| No | By default, the **pages/system** pages are blocked. Use commas (,) to separate page names.| +| -b,--bundle[bundlename, ......, bundlename] | Sets allowed bundles for the test. This command conflicts with the **-p** command.| No | By default, all bundles on the device are allowed. Use commas (,) to separate bundle names. | +| -p,--prohibit[bundlename, ......, bundlename] | Sets blocked bundles for the test. This command conflicts with the **-b** command.| No | By default, no bundle is blocked. Use commas (,) to separate bundle names. | +| -d,--page[page, ......, page] | Sets blocked pages for the test.| No | By default, the **pages/system** pages are blocked. Use commas (,) to separate page names.| | -a,--appswitch | Sets the proportion of the random application startup event test. | No | The default value is 10%. | | -t,--touch | Sets the proportion of the random touch event test. | No | The default value is 10%. | | -S,--swap | Sets the proportion of the random swipe event test. | No | The default value is 3%. | @@ -244,10 +249,10 @@ The following figure shows the wukong component architecture and the responsibil | -c,--count | Sets the number of test times. This command conflicts with the **-T** command. Set either of them. | No | The default value is 10, in times. | | -i,--interval | Sets the test interval. | No | The default value is 1500, in millisecond. | | -s,--seed | Sets the random seed. | No | If the same random seed is set, the same random event sequence is generated.| -| -b,--bundle[bundlename, ......, bundlename] | Sets the bundle name of allowlist for the test. This command conflicts with the **-p** command.| No | By default, all applications on the device are allowed. (Use commas (,) to separate application names.) | -| -p,--prohibit[bundlename, ......, bundlename] | Sets the bundle name of blocklist for the test. This command conflicts with the **-b** command.| No | By default, no application is blocked. (Use commas (,) to separate application names.) | -| -d,--page[page, ......, page] | Sets the list of blocked pages for the test.| No | By default, the pages/system pages are blocked. (Use commas (,) to separate page names.)| -| -a,--appswitch | Sets the proportion of random application startup test. | No | The default value is 10%. | +| -b,--bundle[bundlename, ......, bundlename] | Sets allowed bundles for the test. This command conflicts with the **-p** command.| No | By default, all bundles on the device are allowed. Use commas (,) to separate bundle names. | +| -p,--prohibit[bundlename, ......, bundlename] | Sets blocked bundles for the test. This command conflicts with the **-b** command.| No | By default, no bundle is blocked. Use commas (,) to separate bundle names. | +| -d,--page[page, ......, page] | Sets blocked pages for the test.| No | By default, the **pages/system** pages are blocked. Use commas (,) to separate page names.| +| -a,--appswitch | Sets the proportion of the random application startup event test. | No | The default value is 10%. | | -t,--touch | Sets the proportion of the random touch event test. | No | The default value is 10%. | | -S,--swap | Sets the proportion of the random swipe event test. | No | The default value is 3%. | | -m,--mouse | Sets the proportion of the random mouse event test. | No | The default value is 1%. | @@ -272,7 +277,7 @@ The following figure shows the wukong component architecture and the responsibil The parameters in the command are described as follows. | Command | Value |Description | | -------------- | -------------- | -------------- | -| wukong exec | - | Works as the main command. | +| wukong focus | - | Works as the main command. | | -s | 10 | Sets the random seed. The seed value is **10**. | | -i | 1000 | Sets the application startup interval to **1000** ms.| | -a | 0.28 | Sets the proportion of the random application startup test to **28%**. | @@ -298,7 +303,7 @@ After the test commands are executed, the test result is automatically generated | wukong_report.csv | Stores the test report summary. | | wukong.log | Indicates the test operation history. | -### Viewing Operation Logs +### View operation logs You can run the hdc command to obtain logs to the local host and view the operation history. @@ -316,3 +321,41 @@ C:\Users\xxx>hdc file recv /data/local/tmp/wukong/report/20170805_170053/wukong. [I][2024-01-03 20:08:02] HdcFile::TransferSummary success FileTransfer finish, Size:76492, File count = 1, time:16ms rate:4780.75kB/s ``` + +## FAQs +### failed to connect to AAMS + **Symptom** + +failed to connect to AAMS. + + **Possible Cause** + +AAMS is occupied by Hypium or the UIViewer of DevEco Testing. AAMS can be connected to only one program at a time. + + **Solution** + +Stop the process that occupies AAMS or restart the device. +### Errorcode:(4005) + **Symptom** + +Errorcode:(4005). + + **Possible Cause** + +The size of the screen display area changes. As a result, the page information fails to be obtained. + + **Solution** + +This error does not affect the test process and does not need to be handled. +### Errorcode:(4007) + **Symptom** + +Errorcode:(4007). + + **Possible Cause** + +The size of the screen display area changes. As a result, the page information fails to be obtained. + + **Solution** + +This error does not affect the test process and does not need to be handled. diff --git a/en/application-dev/arkts-utils/Readme-EN.md b/en/application-dev/arkts-utils/Readme-EN.md index 4621bd12e066f2771bc85c4cff7ac2468c58d491..ed7854b2f85398954df52621c1e04fa6eabeb66b 100644 --- a/en/application-dev/arkts-utils/Readme-EN.md +++ b/en/application-dev/arkts-utils/Readme-EN.md @@ -1,85 +1,88 @@ # ArkTS - [Introduction to ArkTS](arkts-overview.md) -- ArkTS Utility - - [ArkTS Utils Overview](arkts-utils-overview.md) - - XML Generation, Parsing, and Conversion +- ArkTS Common Library + - [Overview of the ArkTS Common Library](arkts-utils-overview.md) + - XML Generation, Parsing, and Conversion - [XML Overview](xml-overview.md) - [XML Generation](xml-generation.md) - [XML Parsing](xml-parsing.md) - [XML Conversion](xml-conversion.md) - - [Buffer Introduction](buffer.md) - - ArkTS Containers - - [Container Overview](container-overview.md) + - [Buffer](buffer.md) + - ArkTS Container Library + - [Overview of the ArkTS Container Library](container-overview.md) - [Linear Containers](linear-container.md) - [Nonlinear Containers](nonlinear-container.md) -- ArkTS Concurrency - - [Concurrency Overview](concurrency-overview.md) +- ArkTS Concurrency + - [Overview of Concurrency](concurrency-overview.md) - [Asynchronous Concurrency](async-concurrency-overview.md) - - Multithreaded Concurrency - - [Multithreaded Concurrency Overview](multi-thread-concurrency-overview.md) - - [TaskPool Introduction](taskpool-introduction.md) - - [Worker Introduction](worker-introduction.md) + - Multithreaded Concurrency + - [Overview of Multithreaded Concurrency](multi-thread-concurrency-overview.md) + - [TaskPool](taskpool-introduction.md) + - [Worker](worker-introduction.md) - [Comparison Between TaskPool and Worker](taskpool-vs-worker.md) - - Inter-Thread Communication - - [ArkTS Inter-Thread Communication Overview](interthread-communication-overview.md) - - Inter-Thread Communication Objects - - [Common Object](normal-object.md) + - Inter-Thread Communication + - [Overview of ArkTS Inter-Thread Communication](interthread-communication-overview.md) + - Inter-Thread Communication Objects + - [Regular Object](normal-object.md) - [ArrayBuffer Object](arraybuffer-object.md) - [SharedArrayBuffer Object](shared-arraybuffer-object.md) - [Transferable Object (NativeBinding Object)](transferabled-object.md) - - Sendable Object - - [Sendable Object Overview](arkts-sendable.md) - - [Sendable Usage Rules and Constraints](sendable-constraints.md) + - Sendable Object + - [Overview of Sendable Objects](arkts-sendable.md) + - [Usage Rules and Constraints for Sendable](sendable-constraints.md) - [Asynchronous Lock](arkts-async-lock-introduction.md) - [ASON Parsing and Generation](ason-parsing-generation.md) - [Shared Container](arkts-collections-introduction.md) - [Shared Module](arkts-sendable-module.md) - - [Freezing a Sendable Object](sendable-freeze.md) - - [Sendable Use Scenarios](sendable-guide.md) - - Communication Between Threads + - [Freezing Sendable Objects](sendable-freeze.md) + - [Use Scenarios of Sendable](sendable-guide.md) + - Communication Between Threads - [Using TaskPool for Independent Time-Consuming Tasks](independent-time-consuming-task.md) - [Using TaskPool for Multiple Time-Consuming Tasks](multi-time-consuming-tasks.md) - [Communication Between the TaskPool Task and Host Thread](taskpool-communicates-with-mainthread.md) - - [Instant Communication Between the Worker Thread and Host Thread](worker-communicates-with-mainthread.md) - - [Worker Thread Synchronously Calling Methods of the Host Thread](worker-invoke-mainthread-interface.md) - - Multithreaded Development - - [Multithreaded Development Overview](multithread-develop-overview.md) - - Concurrent Time-Consuming Tasks - - [Concurrent Time-Consuming Task Scenarios](time-consuming-task-overview.md) + - [Real-Time Communication Between the Worker Thread and Host Thread](worker-communicates-with-mainthread.md) + - [Synchronous Calls to Host Thread Interfaces from Worker](worker-invoke-mainthread-interface.md) + - Multithreaded Development + - [Overview of Multithreaded Development](multithread-develop-overview.md) + - Concurrency in Time-Consuming Tasks + - [Overview of Concurrency in Time-Consuming Tasks](time-consuming-task-overview.md) - [CPU Intensive Task Development (TaskPool and Worker)](cpu-intensive-task-development.md) - [I/O Intensive Task Development (TaskPool)](io-intensive-task-development.md) - [Synchronous Task Development (TaskPool and Worker)](sync-task-development.md) - - Concurrent Continuous Tasks - - [Concurrent Continuous Task Scenarios](long-time-task-overview.md) + - Concurrency in Continuous Tasks + - [Overview of Concurrency in Continuous Tasks](long-time-task-overview.md) - [Continuous Task Development (TaskPool)](long-time-task-guide.md) - - Concurrent Resident Tasks - - [Concurrent Resident Task Scenarios](resident-task-overview.md) + - Concurrency in Resident Tasks + - [Overview of Concurrency in Resident Tasks](resident-task-overview.md) - [Resident Task Development (Worker)](resident-task-guide.md) - - Multithreaded Development Practice Cases - - [Batch Data Writing to the Database](batch-database-operations-guide.md) + - Multithreaded Development Practice Cases + - [Batch Database Operations](batch-database-operations-guide.md) - [Concurrent Loading of Service Modules](concurrent-loading-modules-guide.md) - - [Global Configuration Items](global-configuration-guide.md) + - [Global Configuration](global-configuration-guide.md) - [ArkUI Data Updates](makeobserved-sendable.md) - - [Data Sharing Between C++ Threads](native-interthread-shared.md) + - [C++ Inter-Thread Data Sharing](native-interthread-shared.md) + - [ArkUI Waterfall Rendering](taskpool-waterflow.md) - [ArkTS Cross-Language Interaction](arkts-cross-language-interaction.md) -- ArkTS Runtime - - [ArkTS Runtime Overview](arkts-runtime-overview.md) +- ArkTS Runtime + - [Overview of ArkTS Runtime](arkts-runtime-overview.md) - [GC](gc-introduction.md) - - ArkTS Modularization - - [Introduction to Modular Operation](module-principle.md) + - ArkTS Modularization + - [Overview of Modular Operation](module-principle.md) - [Dynamic Import](arkts-dynamic-import.md) - [Lazy Import](arkts-lazy-import.md) - - [Dynamically Loading a Native Module in Synchronous Mode](js-apis-load-native-module.md) + - [Dynamically Loading Native Modules in Synchronous Mode](js-apis-load-native-module.md) + - [Statically Loading Native Modules](arkts-import-native-module.md). - [Loading Modules Using Node-API](load-module-base-nodeapi.md) -- ArkTS Compilation Toolchain - - [ArkTS Compilation Toolchain Overview](compilation-tool-chain-overview.md) - - Ark Bytecode - - [Ark Bytecode Overview](arkts-bytecode-overview.md) + - [Side Effects and Optimization of Module Loading](arkts-module-side-effects.md) +- ArkTS Compilation Toolchain + - [Overview of the ArkTS Compilation Toolchain](compilation-tool-chain-overview.md) + - Ark Bytecode + - [Overview of Ark Bytecode](arkts-bytecode-overview.md) - [Ark Bytecode File Format](arkts-bytecode-file-format.md) - [Ark Bytecode Fundamentals](arkts-bytecode-fundamentals.md) - - [Naming Rules of Ark Bytecode Functions](arkts-bytecode-function-name.md) + - [Naming Conventions for Ark Bytecode Functions](arkts-bytecode-function-name.md) - [Customizing Ark Bytecode During Compilation](customize-bytecode-during-compilation.md) - [Disassembler](tool-disassembler.md) - - [ArkGuard](source-obfuscation.md) + - [ArkGuard for Code Obfuscation](source-obfuscation.md) - [Configuring arkOptions in build-profile.json5](arkoptions-guide.md) diff --git a/en/application-dev/arkts-utils/arkoptions-guide.md b/en/application-dev/arkts-utils/arkoptions-guide.md index b0a81a48cf12a67112c28b78146fa4edfee9f0e2..37ed4ee529df4f05542c801b0771903f9df6803f 100644 --- a/en/application-dev/arkts-utils/arkoptions-guide.md +++ b/en/application-dev/arkts-utils/arkoptions-guide.md @@ -1,18 +1,24 @@ # Configuring arkOptions in build-profile.json5 -## Configuration File Tag +## Overview - **Table 1** types field in the arkOptions tag +**arkOptions** is used to configure settings related to ArkTS compilation. This topic describes the configuration of the **types**, **maxFlowDepth**, and **transformLib** options in **arkOptions**. For more settings, see [build-profile.json5](https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V5/ide-hvigor-build-profile-V5). -| Name| Description| Data Type| Left Unspecified Allowed| +## types + +### Description + + Field **types** in **arkOptions** + +| Name| Description| Data Type| Optional| | -------- | -------- | -------- | -------- | -| types | Type declaration files to import globally. Using this field can avoid individual imports in each source file.| Array| Yes (initial value: left empty)| +| types | Specifies type declaration files to be globally imported, avoiding the need to import them individually in each source file.| Array| Optional, defaults to an empty array| -## types Field Configuration in arkOptions +### Example -Example of the Types Field in arkOptions +Below provides an example configuration of the **types** Field in **arkOptions**. -Add the **types** field to the **arkOptions** attribute of the **buildOption** tag in the **build-profile.json5** configuration file of a module. +Add the **types** field to the **arkOptions** property in the **buildOption** section of the module-level **build-profile.json5** file. ```json // In /entry/build-profile.json5 { @@ -22,14 +28,14 @@ Add the **types** field to the **arkOptions** attribute of the **buildOption** t } ``` -The **types** field can be set to a bundle name, relative path to the bundle location, or relative path to the declaration file. Only the search in the current module is supported. If files with the same name (with different file name extensions) exists in the specified directory, the files are loaded in the following order, from high to low: **.d.ets** > **.d.ts**.
- (1) Inputting package name: If a bundle name is specified, it is used to search for the declaration files in **oh_modules/@types/**, xxx.
- (2) Inputting relative path of the package: Search the defined declaration file at the relative path of **build-profile.json5**, for example, **./oh_modules/@types/mocha**.
- (3) Inputting relative path of the declaration file: Search the declaration file in the relative path, for example, **./src/main/ets/pages/global**. +The **types** field can be set to a package name, relative path to a package, or relative path to a declaration file. It supports searches only within the current module. If there are files with the same name but different extensions in a directory, the default loading order is .d.ets > .d.ts.
+(1) Package name: Searches for declaration files defined by the package name in the **oh_modules/@types/** directory, for example, "chai".
+(2) Relative path to a package: Searches for declaration files based on the relative path to **build-profile.json5**, for example, "./oh_modules/@types/mocha".
+(3) Relative path to a declaration file: Searches for declaration files in the specified relative path, for example, "./src/main/ets/pages/global". -*Note:* +### Precautions -If you input the package name or the relative path of the package location in the **types** field, **dependencies** at **project file/entry/oh-package.json5** should be set as follows: +If you specify a package name or a relative path to a package in the **types** field, configure **dependencies** in the project-level **/entry/oh-package.json5** file as follows: ```json "dependencies": { "@types/chai": "latest", @@ -37,17 +43,51 @@ If you input the package name or the relative path of the package location in th } ``` -If you input the relative path of the declaration file in the **types** field, make sure the corresponding declaration file, such as the **src/main/ets/pages/global.d.ts** file, exists in the module. The content of the declaration file is as follows: +If you specify a relative path to a declaration file in the **types** field, ensure the corresponding declaration file exists in the module. Below is the content of a declaration file named **global.d.ts** in **src/main/ets/pages**: ```typescript declare namespace Global { type ObjectType = string | number; } ``` -After **types** is set to globally import type declarations, the types declared can be used as follows: +After configuring types, you can use these global types in your code: ```typescript // In entry/src/main/ets/pages/Index.ets let a: Chai.Message; let b: Mocha.HookFunction; let c: Global.ObjectType; ``` + +## transformLib + +### Description + +Field **transformLib** in **arkOptions** + +| Name| Description| Configuration Scope| Data Type| Optional| +| -------- | -------- | -------- | -------- | -------- | +| transformLib | Specifies the bytecode instrumentation plugin configuration, allowing you to modify bytecode during compilation. This field is supported only in the stage model. The format is a relative path to the dynamic library that does the instrumentation. The dynamic library must be generated on the corresponding platform and cannot be copied or renamed across platforms.| Module-level| String| Optional, defaults to not using this feature| + +### Example + +Below provides an example configuration of the **transformLib** Field in **arkOptions**. + +Add the **transformLib** field to the **arkOptions** property in the **buildOption** section of the module-level **build-profile.json5** file. +```json +// In /entry/build-profile.json5 +{ + "buildOption": { + "arkOptions": { + "transformLib": "./dll/example.dll" + } + } +} + +``` +For details about how to modify Ark bytecode, see [Customizing Ark Bytecode During Compilation](customize-bytecode-during-compilation.md). + +### Precautions + +- If this field is not configured, the feature is not used by default. +- The configuration takes effect for HAP and HSP modules immediately. For HAR modules, only bytecode HAR configurations are effective; non-bytecode HAR configurations are ignored. +- The file format must be .dll (for Windows) or .so (for Linux/macOS). diff --git a/en/application-dev/arkts-utils/arkts-async-lock-introduction.md b/en/application-dev/arkts-utils/arkts-async-lock-introduction.md index c3bb232a9b370c576aee058244102329e960fcb7..35fef4f6c10bd433afcff21ed6dd8fead8c36a4d 100644 --- a/en/application-dev/arkts-utils/arkts-async-lock-introduction.md +++ b/en/application-dev/arkts-utils/arkts-async-lock-introduction.md @@ -1,18 +1,18 @@ # Asynchronous Lock -To solve the data contention problem between multi-thread concurrent tasks, ArkTS introduces the asynchronous lock capability. An asynchronous lock may be held by a class object. Therefore, to facilitate obtaining of the same asynchronous lock object between concurrent instances, the [AsyncLock object](../reference/apis-arkts/js-apis-arkts-utils.md#asynclock) supports cross-thread reference transfer. +To address data race issues in concurrent multithreading tasks, ArkTS introduces asynchronous locks. These locks can be held by class objects. To simplify access across concurrent instances, the [AsyncLock object](../reference/apis-arkts/js-apis-arkts-utils.md#asynclock) supports pass-by-reference across threads. -ArkTS supports asynchronous operations, and blocking locks are prone to deadlocks. Therefore, only asynchronous locks (non-blocking locks) are used in ArkTS. In addition, the asynchronous lock may be further used to ensure time sequence consistency of asynchronous tasks in a single thread, to prevent a synchronization problem caused by an uncertain time sequence of the asynchronous tasks. +Given that ArkTS supports asynchronous operations, blocking locks are prone to deadlocks. Therefore, ArkTS only supports asynchronous locks (non-blocking locks). In addition, asynchronous locks can ensure the temporal consistency of asynchronous tasks within a single thread, preventing synchronization issues caused by uncertain task timing. -For more APIs related to asynchronous locks, see [ArkTSUtils.locks](../reference/apis-arkts/js-apis-arkts-utils.md#arktsutilslocks). +For more details about asynchronous lock APIs, see [ArkTSUtils.locks](../reference/apis-arkts/js-apis-arkts-utils.md#arktsutilslocks). -> **Note** +> **NOTE** > -> The method that uses an asynchronous lock must be marked as **async**, and the caller must use **await** in the call to ensure the correct call sequence. +> Methods using asynchronous locks must be marked as **async**, and the caller must use the **await** keyword to ensure correct timing. -## Example +## Usage Example -To solve the contention problem caused by the modification of shared variables in different threads of the [@Sendable object](arkts-sendable.md), asynchronous locks can be used for data protection. Example: +To prevent data races when modifying shared variables across threads with [@Sendable objects](arkts-sendable.md), asynchronous locks can be used for data protection. The sample code is as follows: ```ts import { ArkTSUtils, taskpool } from '@kit.ArkTS'; @@ -23,14 +23,14 @@ export class A { lock_: ArkTSUtils.locks.AsyncLock = new ArkTSUtils.locks.AsyncLock(); public async getCount(): Promise { - // Add an asynchronous lock to the data to be protected. + // Add an asynchronous lock to protect the data. return this.lock_.lockAsync(() => { return this.count_; }) } public async increaseCount() { - // Add an asynchronous lock to the data to be protected. + // Add an asynchronous lock to protect the data. await this.lock_.lockAsync(() => { this.count_++; }) @@ -58,9 +58,9 @@ struct Index { middle: { anchor: '__container__', align: HorizontalAlign.Center } }) .onClick(async () => { - // Create the sendable object a. + // Create the Sendable object a. let a: A = new A(); - // Transfer instance a to the subthread. + // Pass object a to a child thread. await taskpool.execute(printCount, a); }) } diff --git a/en/application-dev/arkts-utils/arkts-bytecode-file-format.md b/en/application-dev/arkts-utils/arkts-bytecode-file-format.md index 93aee902e13ba18a763ddd22f7623c33f33c9c6a..4ba4680e17e28b331b6b3049001b3f6faa7ab6fb 100644 --- a/en/application-dev/arkts-utils/arkts-bytecode-file-format.md +++ b/en/application-dev/arkts-utils/arkts-bytecode-file-format.md @@ -1,227 +1,239 @@ # Ark Bytecode File Format -The Ark Bytecode file is a binary product compiled in ArkTS/TS/JS. This topic describes the Ark Bytecode file format in detail, aiming to introduce each part of the bytecode and guide you to analyze and modify the bytecode. +The Ark bytecode file is the binary output generated by compiling ArkTS/TS/JS code. This topic describes the Ark bytecode file format in detail, aiming to help you understand its structure and facilitate the analysis and modification of bytecode files. ## Constraints -This topic only applies to Ark Bytecode in 11.0.2.0 version. (The version number is an internal reserved field of the Ark compiler.) +This topic is applicable only to Ark bytecode of version 12.0.6.0. The version number is an internal field of the Ark compiler and does not require your attention. -## Data Types of Bytecode File +## Bytecode File Data Types ### Integer -| **Name** | **NOTE** | +| **Name** | **Description** | | -------------- | ---------------------------------- | | `uint8_t` | 8-bit unsigned integer. | | `uint16_t` | 16-bit unsigned integer in little-endian mode. | | `uint32_t` | 32-bit unsigned integer in little-endian mode. | -| `uleb128` | Leb128-encoded unsigned integer. | -| `sleb128` | Leb128-encoded signed integer. | +| `uleb128` | Unsigned integer encoded in LEB128 format. | +| `sleb128` | Signed integer encoded in LEB128 format. | ### String -- Align in single byte. + +- Alignment: single-byte aligned - Format -| **Name**| **Format**| **NOTE** | +| **Name**| **Format**| **Description** | | -------------- | -------------- | ------------------------------------------------------------ | -| `utf16_length` | `uleb128` | The value is **`len << 1 \**| **is_ascii**, where **len** indicates the size of a string encoded by UTF-16, and **is_ascii`** indicates whether the string contains only ASCII characters. The value can be **0** or **1**.| -| `data` | `uint8_t[]` | MUTF-8 encoded character sequence ending with **\0**. | +| `utf16_length` | `uleb128` | The value is **len << 1 \**| **is_ascii**, where **len** is the length of a string encoded by UTF-16, and **is_ascii** specifies whether the string contains only ASCII characters (**0** or **1**).| +| `data` | `uint8_t[]` | Null-terminated sequence of characters encoded in MUTF-8 format. | ### TaggedValue -- Align in single byte. + +- Alignment: single-byte aligned - Format -| **Name**| **Format**| **NOTE** | +| **Name**| **Format**| **Description** | | -------------- | -------------- | -------------------------------------------- | -| `tag` | `uint8_t` | Indicates the tag of a data type. | -| `data` | `uint8_t[]` | According to different tags, **data** is of different types or is empty.| +| `tag` | `uint8_t` | Marker indicating the type of data. | +| `data` | `uint8_t[]` | Data content. Its type is determined by the tag, and it may be empty.| ## TypeDescriptor -**TypeDescriptor** is the format of the [Class](#class) name. Its name **L_ClassName;** is consisted by **'L'**, **'_'**, **ClassName**, and **';'**. In this case, **ClassName** indicates the full name of the class. **'.'** in the name is replaced with **'/'**. +Represents [class](#class) names in the format of **L_ClassName;**, where **ClassName** is the fully qualified name, in which **'.'** is replaced with **'/'**. ## Bytecode File Layout -The bytecode file is compiled based on the [Header](#header) structure. All structures in the file can be accessed directly or indirectly from the **Header**. The reference modes of the structure in the bytecode file include offset and index. The offset calculated from 0 is a 32-bit value, indicating the distance between the start position of the current structure and the file header in the bytecode file. An index is a 16-bit value that indicates the position of the current structure in the index region. This mechanism is described in [IndexSection](#indexsection). +The bytecode file begins with the [Header](#header) structure, from which all other structures can be accessed directly or indirectly. References within the file use offsets (32-bit) and indexes (16-bit). Offsets indicate the position relative to the file header, starting from 0. Indexes point to specific entries within index regions. More details are provided in [IndexSection](#indexsection). -All multi-byte values in the bytecode file are in little-endian. +All multi-byte values in bytecode files are stored in little-endian format. ### Header -- Align in single byte. + +- Alignment: single-byte aligned - Format -| **Name** | **Format**| **NOTE** | +| **Name** | **Format**| **Description** | | ----------------- | -------------- | ------------------------------------------------------------ | -| `magic` | `uint8_t[8]` | Value of the magic number must be **'P' 'A' 'N' 'D' 'A' '\0' '\0' '\0'**. | -| `checksum` | `uint32_t` | **Adler32** checksum of the content in the bytecode file except the magic number and this check field.| -| `version` | `uint8_t[4]` | [Version](#version) number of the bytecode file.| -| `file_size` | `uint32_t` | Size of a bytecode file, in bytes. | -| `foreign_off` | `uint32_t` | An offset that points to an external region. The external region contains two types of elements: [ForeignClass](#foreignclass) or [ForeignMethod](#foreignmethod). **foreign_off** points to the first element in the region.| -| `foreign_size` | `uint32_t` | Size of the external region, in bytes. | -| `num_classes` | `uint32_t` | Number of elements in the [ClassIndex](#classindex) structure, that is, the number of [Class](#class) defined in the file.| +| `magic` | `uint8_t[8]` | Magic number of the file header. Its value must be **'P' 'A' 'N' 'D' 'A' '\0' '\0' '\0'**. | +| `checksum` | `uint32_t` | **Adler32** checksum of the content in the bytecode file, excluding the magic number and this checksum field.| +| `version` | `uint8_t[4]` | [Version](#version) of the bytecode file.| +| `file_size` | `uint32_t` | Size of the bytecode file, in bytes. | +| `foreign_off` | `uint32_t` | An offset that points to a foreign region, which contains only elements of the type [ForeignClass](#foreignclass) or [ForeignMethod](#foreignmethod). **foreign_off** points to the first element in the region.| +| `foreign_size` | `uint32_t` | Size of the foreign region, in bytes. | +| `num_classes` | `uint32_t` | Number of elements in the [ClassIndex](#classindex) structure, that is, the number of [classes](#class) defined in the file.| | `class_idx_off` | `uint32_t` | An offset that points to [ClassIndex](#classindex).| -| `num_lnps` | `uint32_t` | Number of elements in the [LineNumberProgramIndex](#linenumberprogramindex) structure, that is, the number of [Line number program](#line-number-program) defined in the file.| +| `num_lnps` | `uint32_t` | Number of elements in the [LineNumberProgramIndex](#linenumberprogramindex) structure, that is, the number of [line number programs](#line-number-program) defined in the file.| | `lnp_idx_off` | `uint32_t` | An offset that points to [LineNumberProgramIndex](#linenumberprogramindex).| -| `reserved` | `uint32_t` | Reserved field used internally in the Ark Bytecode file. | -| `reserved` | `uint32_t` | Reserved field used internally in the Ark Bytecode file. | -| `num_index_regions` | `uint32_t` | Number of elements in the [IndexSection](#indexsection) structure, that is, the number of [IndexHeader](#indexheader) in the file.| +| `reserved` | `uint32_t` | Reserved field for internal use by the Ark bytecode file. | +| `reserved` | `uint32_t` | Reserved field for internal use by the Ark bytecode file. | +| `num_index_regions` | `uint32_t` | Number of elements in the [IndexSection](#indexsection) structure, that is, the number of [IndexHeaders](#indexheader) in the file.| | `index_section_off` | `uint32_t` | An offset that points to [IndexSection](#indexsection).| ### Version -The bytecode version number consists of four parts in the format of **major version number.minor version number.feature version number.Build version number**. +The bytecode version number consists of four parts in the format of major.minor.feature.build. -| **Name**| **Format**| **NOTE** | +| **Name**| **Format**| **Description** | | -------------- | -------------- | ---------------------------------------------------------- | -| Major version number | `uint8_t` | Indicates the changes to the bytecode file format caused by the overall structure adjustment. | -| Minor version number | `uint8_t` | Indicates the changes to the bytecode file format caused by partial structure adjustment or major feature adjustment.| -| Feature version number | `uint8_t` | Indicates the changes to the bytecode file format caused by small- and medium-sized features. | -| Build version number | `uint8_t` | Indicates the changes to the bytecode file format caused by defect rectification. | +| Major | `uint8_t` | Indicates significant architectural changes. | +| Minor | `uint8_t` | Indicates changes in local architecture or major features.| +| Feature | `uint8_t` | Indicates changes due to minor features. | +| Build | `uint8_t` | Indicates changes due to bug fixes. | ### ForeignClass -Describes the enclosing classes in the bytecode file. They are declared in other files and referenced in the current bytecode file. -- Align in single byte. +Represents foreign classes referenced in the bytecode file but declared in other files. + +- Alignment: single-byte aligned - Format -| **Name**| **Format**| **NOTE** | +| **Name**| **Format**| **Description** | | -------------- | -------------- | ------------------------------------------------------------ | -| `name` | `String` | Enclosing class name, which follows the [TypeDescriptor](#typedescriptor) syntax.| +| `name` | `String` | Foreign class name, which follows the [TypeDescriptor](#typedescriptor) syntax.| ### ForeignMethod -Describes external methods in bytecode file. They are declared in other files and referenced in the current bytecode file. -- Align in single byte. +Represents foreign methods referenced in the bytecode file but declared in other files. + +- Alignment: single-byte aligned - Format -| **Name**| **Format**| **NOTE** | +| **Name**| **Format**| **Description** | | -------------- | -------------- | ------------------------------------------------------------ | -| `class_idx` | `uint16_t` | An index pointing to the class to which the method belongs. It points to a position in [ClassRegionIndex](#classregionindex), whose value is an offset pointing to [Class](#class) or [ForeignClass](#foreignclass).| -| `reserved` | `uint16_t` | Reserved field used internally in the Ark Bytecode file. | -| `name_off` | `uint32_t` | An offset that points to [string](#string), indicating the method name.| +| `class_idx` | `uint16_t` | An index of the class to which the method belongs. It points to a position in [ClassRegionIndex](#classregionindex), and the position value is an offset pointing to [Class](#class) or [ForeignClass](#foreignclass).| +| `reserved` | `uint16_t` | Reserved field for internal use by the Ark bytecode file. | +| `name_off` | `uint32_t` | An offset to a [string](#string) representing the method name.| | `index_data` | `uleb128` | [MethodIndexData](#methodindexdata) data of the method.| -**Note:**
-With the offset of **ForeignMethod**, an appropriate **IndexHeader** can be found to parse the **class_idx**. +> **NOTE** +> +> The offset of **ForeignMethod** can be used to locate the appropriate **IndexHeader** for parsing **class_idx**. ### ClassIndex -The **ClassIndex** structure is used to quickly locate the definition of the **Class** by name. -- Align in four bytes. +Facilitates quick lookup of class definitions by name. + +- Alignment: 4-byte aligned - Format -| **Name**| **Format**| **NOTE** | +| **Name**| **Format**| **Description** | | -------------- | -------------- | ------------------------------------------------------------ | -| `offsets` | `uint32_t[]` | An array. The value of each element in this array is an offset pointing to [Class](#class). Elements in an array are sorted by the class name which follows the [TypeDescriptor](#typedescriptor) syntax. The array length is specified by **num_classes** in [Header](#header).| +| `offsets` | `uint32_t[]` | An array of offsets pointing to [classes](#class). Elements in the array are sorted by the class name, which follows the [TypeDescriptor](#typedescriptor) syntax. The array length is specified by **num_classes** in [Header](#header).| ### Class -In a bytecode file, a class can represent a source code file of Ark Bytecode or a built-in [Annotation](#annotation). When it indicates a source code file, the method of the class corresponds to the function in the source code file, and class field corresponds to the internal information in the source file. When it indicates a built-in **Annotation**, the class does not contain the field or method. A class in the source code file is represented in the bytecode file as a method corresponding to its constructor. +Represents either a source code file or an internal [Annotation](#annotation). For a source code file, **methods** correspond to functions in the source code file, and **fields** correspond to internal information in the source file. For **Annotation**, **fields** or **methods** are not contained. A class in the source code file is represented as a constructor in the bytecode file. -- Align in single byte. +- Alignment: single-byte aligned - Format -| **Name**| **Format**| **NOTE** | +| **Name**| **Format**| **Description** | | -------------- | -------------- | ------------------------------------------------------------ | | `name` | `String` | Class name, which follows the [TypeDescriptor](#typedescriptor) syntax.| -| `reserved` | `uint32_t` | Reserved field used internally in the Ark Bytecode file. | -| `access_flags` | `uleb128` | Accessing tag of **Class**, which is a combination of [ClassAccessFlag](#classaccessflag).| -| `num_fields` | `uleb128` | Number of fields of **Class**. | -| `num_methods` | `uleb128` | Number of methods of **Class**. | +| `reserved` | `uint32_t` | Reserved field for internal use by the Ark bytecode file. | +| `access_flags` | `uleb128` | Tags to access the class, which is a combination of [ClassAccessFlags](#classaccessflag).| +| `num_fields` | `uleb128` | Number of fields in the class. | +| `num_methods` | `uleb128` | Number of methods in the class. | | `class_data` | `TaggedValue[]` | Array with variable length. Each element in the array is of the [TaggedValue](#taggedvalue) type, and the element tag is of the [ClassTag](#classtag) type. Elements in the array are sorted in ascending order based on the tag (except the **0x00** tag).| -| `fields` | `Field[]` | Array of **Class** fields. Each element in this array is of the [Field](#field) type. The array length is specified by **num_fields**.| -| `methods` | `Method[]` | Array of **Class** methods. Each element in this array is of the [Method](#method) type. The array length is specified by **num_methods**.| +| `fields` | `Field[]` | Array of fields in the class. Each element in this array is of the [Field](#field) type. The array length is specified by **num_fields**.| +| `methods` | `Method[]` | Array of methods in the class. Each element in this array is of the [Method](#method) type. The array length is specified by **num_methods**.| ### ClassAccessFlag -| **Name**| **Value**| **NOTE** | +| **Name**| **Value**| **Description** | | -------------- | ------------ | ------------------------------------------------------------ | -| `ACC_PUBLIC` | `0x0001` | Default attribute. [Class](#class) in the Ark Bytecode has this tag.| +| `ACC_PUBLIC` | `0x0001` | Default attribute. All [classes](#class) in the Ark bytecode file have this tag.| | `ACC_ANNOTATION` | `0x2000` | Declares this class as the [Annotation](#annotation) type.| ### ClassTag -- Align in single byte. + +- Alignment: single-byte aligned - Format -| **Name**| **Value**| **Quantity**| **Format**| **NOTE** | +| **Name**| **Value**| **Quantity**| **Format**| **Description** | | -------------- | ------------ | -------------- | -------------- | ------------------------------------------------------------ | -| `NOTHING` | `0x00` | `1` | `none` | The [TaggedValue](#taggedvalue) with this tag is the final item of the **class_data**.| -| `SOURCE_LANG` | `0x02` | `0-1 ` | `uint8_t` | The **data** of [TaggedValue](#taggedvalue) with this tag is **0**, indicating that the source code language is in ArkTS, TS, or JS.| -| `SOURCE_FILE` | `0x07` | `0-1` | `uint32_t`| The **data** of [TaggedValue](#taggedvalue) with this tag is an offset that points to [string](#string), indicating the name of the source file.| +| `NOTHING` | `0x00` | `1` | `none` | Marks a [TaggedValue](#taggedvalue) as the final item in **class_data**.| +| `SOURCE_LANG` | `0x02` | `0-1 ` | `uint8_t` | **data** of a [TaggedValue](#taggedvalue) with this tag is **0**, indicating that the source code language is in ArkTS, TS, or JS.| +| `SOURCE_FILE` | `0x07` | `0-1` | `uint32_t`| **data** of a [TaggedValue](#taggedvalue) with this tag is an offset that points to a [string](#string) representing the source file name.| -**Note:**
-**ClassTag** is the tag of the element ([TaggedValue](#taggedvalue)) in the **class_data**. The number in the table header refers to the number of occurrences of the element with this tag in the **class_data** of a [Class](#class). +> **NOTE** +> +> **ClassTag** is a marker of the element ([TaggedValue](#taggedvalue)) in **class_data**. **Quantity** in the table header refers to the number of occurrences of the element with this tag in **class_data** of a [class](#class). ### Field -Describes the fields in the bytecode file. +Represents fields within the bytecode file. -- Align in single byte. +- Alignment: single-byte aligned - Format -| **Name**| **Format**| **NOTE** | +| **Name**| **Format**| **Description** | | -------------- | -------------- | ------------------------------------------------------------ | -| `class_idx` | `uint16_t` | An index pointing to the class to which the field belongs. It points to a position in [ClassRegionIndex](#classregionindex). The value of the position is of the [Type](#type) type and is an offset pointing to [Class](#class).| -| `type_idx` | `uint16_t` | An index that points to the type of the field and points to a position in [ClassRegionIndex](#classregionindex). The value of the position is of the [Type](#type) type.| -| `name_off` | `uint32_t` | An offset that points to [string](#string), indicating the name of the field.| -| `reserved` | `uleb128` | Reserved field used internally in the Ark Bytecode file. | +| `class_idx` | `uint16_t` | An index of the class to which the field belongs. It points to a position in [ClassRegionIndex](#classregionindex). The value of the position is of the [Type](#type) type and is an offset pointing to [Class](#class).| +| `type_idx` | `uint16_t` | An index of the type of the field. It points to a position in [ClassRegionIndex](#classregionindex). The value of the position is of the [Type](#type) type.| +| `name_off` | `uint32_t` | An offset to a [string](#string) representing the field name.| +| `reserved` | `uleb128` | Reserved field for internal use by the Ark bytecode file. | | `field_data` | `TaggedValue[]` | Array with variable length. Each element in the array is of the [TaggedValue](#taggedvalue) type, and the element tag is of the [FieldTag](#fieldtag) type. Elements in the array are sorted in ascending order based on the tag (except the **0x00** tag).| -**Note:**
-Based on the offset of the **Field**, the appropriate **IndexHeader** can be found to parse the **class_idx** and **type_idx**. +> **NOTE** +> +> The offset of **Field** can be used to locate the appropriate **IndexHeader** for parsing **class_idx** and **type_idx**. ### FieldTag -- Align in single byte. +- Alignment: single-byte aligned - Format -| **Name**| **Value**| **Quantity**| **Format**| **NOTE** | +| **Name**| **Value**| **Quantity**| **Format**| **Description** | | -------------- | ------------ | -------------- | -------------- | ------------------------------------------------------------ | -| `NOTHING` | `0x00` | `1` | `none` | The [TaggedValue](#taggedvalue) with this tag is the final item of the **field_data**.| -| `INT_VALUE` | `0x01` | `0-1` | `sleb128` | The **data** type of the [TaggedValue](#taggedvalue) with this tag is of **boolean**, **byte**, **char**, **short**, or **int**.| -| `VALUE` | `0x02` | `0-1` | `uint32_t` | The **data** type of the [TaggedValue](#taggedvalue) with this tag is of **FLOAT** or **ID** in [Value formats](#value-formats).| +| `NOTHING` | `0x00` | `1` | `none` | Marks a [TaggedValue](#taggedvalue) as the final item in **field_data**.| +| `INT_VALUE` | `0x01` | `0-1` | `sleb128` | The **data** type of a [TaggedValue](#taggedvalue) with this tag is of **boolean**, **byte**, **char**, **short**, or **int**.| +| `VALUE` | `0x02` | `0-1` | `uint32_t` | The **data** type of a [TaggedValue](#taggedvalue) with this tag is of **FLOAT** or **ID** in [Value formats](#value-formats).| -**Note:**
-**FieldTag** is the tag of the element ([TaggedValue](#taggedvalue)) in the **field_data**. The number in the table header refers to the number of occurrences of the element with this tag in the **field_data** of a [Field](#field). +> **NOTE** +> +> **FieldTag** is a marker of the element ([TaggedValue](#taggedvalue)) in **field_data**. **Quantity** in the table header refers to the number of occurrences of the element with this tag in **field_data** of a [field](#field). ### Method -Describes methods in bytecode files. +Represents methods within the bytecode file. -- Align in single byte. +- Alignment: single-byte aligned - Format -| **Name**| **Format**| **NOTE** | +| **Name**| **Format**| **Description** | | -------------- | -------------- | ------------------------------------------------------------ | -| `class_idx` | `uint16_t` | An index pointing to the class to which the method belongs. It points to a position in [ClassRegionIndex](#classregionindex). The value of the position is of the [Type](#type) type and is an offset pointing to [Class](#class).| -| `reserved` | `uint16_t` | Reserved field used internally in the Ark Bytecode file. | -| `name_off` | `uint32_t` | An offset that points to [string](#string), indicating the method name.| +| `class_idx` | `uint16_t` | An index of the class to which the method belongs. It points to a position in [ClassRegionIndex](#classregionindex). The value of the position is of the [Type](#type) type and is an offset pointing to [Class](#class).| +| `reserved` | `uint16_t` | Reserved field for internal use by the Ark bytecode file. | +| `name_off` | `uint32_t` | An offset to a [string](#string) representing the method name.| | `index_data` | `uleb128` | [MethodIndexData](#methodindexdata) data of the method.| | `method_data` | `TaggedValue[]` | Array with variable length. Each element in the array is of the [TaggedValue](#taggedvalue) type, and the element tag is of the [MethodTag](#methodtag) type. Elements in the array are sorted in ascending order based on the tag (except the **0x00** tag).| -**Note:**
-With the offset of **Method**, an appropriate **IndexHeader** can be found to parse the **class_idx**. +> **NOTE** +> +> The offset of **Method** can be used to locate the appropriate **IndexHeader** for parsing **class_idx**. ### MethodIndexData -**MethodIndexData** is an unsigned 32-bit integer divided into three parts. +A 32-bit unsigned integer, divided into three parts. -| **Bit**| **Name**| **Format**| **NOTE** | +| **Bit**| **Name**| **Format**| **Description** | | ------------ | -------------- | -------------- | ------------------------------------------------------------ | -| 0 - 15 | `header_index` | `uint16_t` | Points to a position in [IndexSection](#indexsection). The value of this position is [IndexHeader](#indexheader). You can use **IndexHeader** to find the offsets of the method ([Method](#method)), [string](#string), or literal array ([LiteralArray](#literalarray)) referenced by this method.| -| 16 - 23 | `function_kind` | `uint8_t` | Indicates the function type ([FunctionKind](#functionkind)) of a method | -| 24 - 31 | `reserved` | `uint8_t` | Reserved field used internally in the Ark Bytecode file. | +| 0 - 15 | `header_index` | `uint16_t` | Points to a position in [IndexSection](#indexsection). The value of this position is [IndexHeader](#indexheader). You can use **IndexHeader** to find the offsets of all methods ([Method](#method)), [string](#string), or literal array ([LiteralArray](#literalarray)) referenced by this method.| +| 16 - 23 | `function_kind` | `uint8_t` | Function type ([FunctionKind](#functionkind)) of a method.| +| 24 - 31 | `reserved` | `uint8_t` | Reserved field for internal use by the Ark bytecode file. | #### FunctionKind -| **Name** | **Value**| **NOTE** | +| **Name** | **Value**| **Description** | | ------------------------ | ------------ | ---------------- | | `FUNCTION` | `0x1` | Common function. | | `NC_FUNCTION` | `0x2` | Common arrow function. | @@ -234,52 +246,53 @@ With the offset of **Method**, an appropriate **IndexHeader** can be found to pa ### MethodTag -| **Name**| **Value**| **Quantity**| **Format**| **NOTE** | +| **Name**| **Value**| **Quantity**| **Format**| **Description** | | -------------- | ------------ | -------------- | -------------- | ------------------------------------------------------------ | -| `NOTHING` | `0x00` | `1` | `none` | The [TaggedValue](#taggedvalue) with this tag is the final item of the **method_data**.| -| `CODE` | `0x01` | `0-1 ` | `uint32_t` | The **data** of [TaggedValue](#taggedvalue) with this tag is an offset pointing to [Code](#code), indicating the code segment of the method.| -| `SOURCE_LANG` | `0x02` | `0-1` | `uint8_t` | The **data** of [TaggedValue](#taggedvalue) with this tag is **0**, indicating that the source code language is in ArkTS, TS, or JS.| -| `DEBUG_INFO` | `0x05` | `0-1` | `uint32_t` | The **data** of [TaggedValue](#taggedvalue) with this tag is an offset pointing to [DebugInfo](#debuginfo), indicating the debugging information of the method.| -| `ANNOTATION` | `0x06` | `>=0` | `uint32_t` | The **data** of [TaggedValue](#taggedvalue) with this tag is an offset pointing to [Annotation](#annotation), indicating the annotation of the method.| +| `NOTHING` | `0x00` | `1` | `none` | Marks a [TaggedValue](#taggedvalue) as the final item in **method_data**.| +| `CODE` | `0x01` | `0-1 ` | `uint32_t` | **data** of a [TaggedValue](#taggedvalue) with this tag is an offset pointing to [Code](#code), indicating the code segment of the method.| +| `SOURCE_LANG` | `0x02` | `0-1` | `uint8_t` | **data** of a [TaggedValue](#taggedvalue) with this tag is **0**, indicating that the source code language is in ArkTS, TS, or JS.| +| `DEBUG_INFO` | `0x05` | `0-1` | `uint32_t` | **data** of a [TaggedValue](#taggedvalue) with this tag is an offset pointing to [DebugInfo](#debuginfo), indicating the debugging information of the method.| +| `ANNOTATION` | `0x06` | `>=0` | `uint32_t` | **data** of a [TaggedValue](#taggedvalue) with this tag is an offset pointing to [Annotation](#annotation), indicating the annotation of the method.| -**Note:**
-**MethodTag** is the tag of the element ([TaggedValue](#taggedvalue)) in the **method_data**. The number in the table header refers to the number of occurrences of the element with this tag in the **method_data** of a [Method](#method). +> **NOTE** +> +> **MethodTag** is a marker of the element ([TaggedValue](#taggedvalue)) in **method_data**. **Quantity** in the table header refers to the number of occurrences of the element with this tag in **method_data** of a [method](#method). ### Code -- Align in single byte. +- Alignment: single-byte aligned - Format -| **Name**| **Format**| **NOTE** | +| **Name**| **Format**| **Description** | | -------------- | -------------- | ------------------------------------------------------------ | | `num_vregs` | `uleb128` | Number of registers. Registers that store input and default parameters are not counted. | | `num_args` | `uleb128` | Total number of input and default parameters. | | `code_size` | `uleb128` | Total size of all instructions, in bytes. | -| `tries_size` | `uleb128` | Length of the **try_blocks** array, that is, the number of [TryBlock](#tryblock). | +| `tries_size` | `uleb128` | Length of the **try_blocks** array, that is, the number of [TryBlocks](#tryblock). | | `instructions` | `uint8_t[]` | Array of all instructions. | -| `try_blocks` | `TryBlock[]` | An array. Each element in the array is of the **TryBlock** type.| +| `try_blocks` | `TryBlock[]` | An array of **TryBlock** elements.| ### TryBlock -- Align in single byte. +- Alignment: single-byte aligned - Format -| **Name**| **Format**| **NOTE** | +| **Name**| **Format**| **Description** | | -------------- | -------------- | ------------------------------------------------------------ | | `start_pc` | `uleb128` | Offset between the first instruction of the **TryBlock** and the start position of the **instructions** in [Code](#code).| | `length` | `uleb128` | Size of the **TryBlock** object to create, in bytes. | -| `num_catches` | `uleb128` | Number of [CatchBlock](#catchblock) associated with **TryBlock**. The value is 1.| +| `num_catches` | `uleb128` | Number of [CatchBlocks](#catchblock) associated with **TryBlock**. The value is 1.| | `catch_blocks` | `CatchBlock[]` | Array of **CatchBlocks** associated with **TryBlock**. The array contains one **CatchBlock** that can capture all types of exceptions.| ### CatchBlock -- Align in single byte. +- Alignment: single-byte aligned - Format -| **Name**| **Format**| **NOTE** | +| **Name**| **Format**| **Description** | | -------------- | -------------- | ----------------------------------------------- | | `type_idx` | `uleb128` | If the value is **0**, the **CatchBlock** captures all types of exceptions.| | `handler_pc` | `uleb128` | Program counter of the first instruction for handling the exception. | @@ -287,20 +300,21 @@ With the offset of **Method**, an appropriate **IndexHeader** can be found to pa ### Annotation -Describes an annotation structure. +Represents annotations in the bytecode file. -- Align in single byte. +- Alignment: single-byte aligned - Format -| **Name**| **Format** | **NOTE** | +| **Name**| **Format** | **Description** | | -------------- | ------------------- | ------------------------------------------------------------ | -| `class_idx` | `uint16_t` | An index pointing to the class to which the **Annotation** belongs. It points to a position in [ClassRegionIndex](#classregionindex). The value of the position is of the [Type](#type) type and is an offset pointing to [Class](#class).| +| `class_idx` | `uint16_t` | An index of the class to which the **Annotation** belongs. It points to a position in [ClassRegionIndex](#classregionindex). The value of the position is of the [Type](#type) type and is an offset pointing to [Class](#class).| | `count` | `uint16_t` | Length of the **elements** array. | -| `elements` | AnnotationElement[] | An array. Each element of the array is of the [AnnotationElement](#annotationelement) type.| -| `element_types` | `uint8_t[]` | An array. Each element in the array is of the [AnnotationElementTag](#annotationelementtag) type and is used to describe an **AnnotationElement.** The position of each element in the **element_types** array is the same as that of the corresponding **AnnotationElement** in the **elements** array.| +| `elements` | AnnotationElement[] | An array of [AnnotationElement](#annotationelement) elements.| +| `element_types` | `uint8_t[]` | An array, in which each element is of the [AnnotationElementTag](#annotationelementtag) type and is used to describe an **AnnotationElement.** The position of each element in the **element_types** array is the same as that of the corresponding **AnnotationElement** in the **elements** array.| -**Note:**
-With the offset of **Annotation**, an appropriate **IndexHeader** can be found to parse the **class_idx**. +> **NOTE** +> +> The offset of **Annotation** can be used to locate the appropriate **IndexHeader** for parsing **class_idx**. ### AnnotationElementTag @@ -327,149 +341,150 @@ With the offset of **Annotation**, an appropriate **IndexHeader** can be found t ### AnnotationElement -- Align in single byte. +- Alignment: single-byte aligned - Format -| **Name**| **Format**| **NOTE** | +| **Name**| **Format**| **Description** | | -------------- | -------------- | ------------------------------------------------------------ | -| `name_off` | `uint32_t` | An offset that points to [string](#string), indicating the name of the annotation element.| -| `value` | `uint32_t` | Value of the annotation element. If the width of the value is less than 32 bits, the value itself is stored here. Otherwise, the value stored here is an offset pointing to the [Value formats](#value-formats).| +| `name_off` | `uint32_t` | An offset to a [string](#string) representing the annotation element name.| +| `value` | `uint32_t` | Value of the annotation element. If the width of the value is less than 32 bits, the value itself is stored here. Otherwise, the value stored here is an offset pointing to the [value formats](#value-formats).| ### Value formats -Different value types have different value encoding formats, including INTEGER, LONG, FLOAT, DOUBLE, and ID. +Different value types have different value encoding formats, including **INTEGER**, **LONG**, **FLOAT**, **DOUBLE**, and **ID**. -| **Name**| **Format**| **NOTE** | +| **Name**| **Format**| **Description** | | -------------- | -------------- | ------------------------------------------------------------ | -| `INTEGER` | `uint32_t` | Signed 4-byte integer value. | -| `LONG` | `uint64_t` | Signed 8-byte integer value. | -| `FLOAT` | `uint32_t` | 4-byte mode, which is extended to the right zero. The system interprets it as an IEEE754 32-bit floating-point value.| -| `DOUBLE` | `uint64_t` | 8-byte mode, which is extended to the right zero. The system interprets it as an IEEE754 64-bit floating-point value.| -| `ID` | `uint32_t` | 4-byte mode, indicating the offset of a structure in a file. | +| `INTEGER` | `uint32_t` | 4-byte signed integer. | +| `LONG` | `uint64_t` | 8-byte signed integer. | +| `FLOAT` | `uint32_t` | 4-byte pattern that is zero-extended to the right. The system interprets this pattern as a 32-bit floating-point value in IEEE754 format.| +| `DOUBLE` | `uint64_t` | 8-byte pattern that is zero-extended to the right. The system interprets this pattern as a 64-bit floating-point value in IEEE754 format.| +| `ID` | `uint32_t` | 4-byte pattern that indicates the offset to another structure in the file. | ### LineNumberProgramIndex -The **LineNumberProgramIndex** structure is an array that facilitates the use of a more compact index to access the [Line number program](#line-number-program). +An array that facilitates the use of a more compact index to access the [line number program](#line-number-program). -- Align in four bytes. +- Alignment: 4-byte aligned - Format -| **Name**| **Format**| **NOTE** | +| **Name**| **Format**| **Description** | | -------------- | -------------- | ------------------------------------------------------------ | -| `offsets` | `uint32_t[]` | An array in which the value of each element is an offset pointing to a line number program. The array length is specified by **num_lnps** in [Header](#header).| +| `offsets` | `uint32_t[]` | An array of offsets pointing to line number programs. The array length is specified by **num_lnps** in [Header](#header).| ### DebugInfo -The **DebugInfo** contains the mapping between the program counter of the method and the line and column numbers in the source code, as well as information about local variables. The format of the debugging information evolves from the contents of [DWARF 3.0 Standard](https://dwarfstd.org/dwarf3std.html) (see section 6.2). The execution model of the [State machine](#state-machine) interprets the [Line number program](#line-number-program) to obtain the mapping and local variable information code. To deduplicate programs with the same line number in different methods, all constants referenced in the programs are moved to the [Constant pool](#constant-pool). +Contains mappings between program counters of the method and the line/column numbers in the source code, as well as information about local variables. The format of the debugging information is derived from the contents in section 6.2 of [DWARF 3.0 Standard](https://dwarfstd.org/dwarf3std.html). The execution model of the [state machine](#state-machine) interprets the [line number program](#line-number-program) to obtain the mappings and local variable information code. To deduplicate programs with the same line number in different methods, all constants referenced in the programs are moved to the [constant pool](#constant-pool). -- Align in single byte. +- Alignment: single-byte aligned - Format -| **Name** | **Format**| **NOTE** | +| **Name** | **Format**| **Description** | | ----------------------- | -------------- | ------------------------------------------------------------ | | `line_start` | `uleb128` | Initial value of the line number register of the state machine. | | `num_parameters` | `uleb128` | Total number of input and default parameters. | -| `parameters` | `uleb128[]` | Array that stores the names of input parameters. The array length is **num_parameters**. The value of each element is the offset of the string or **0**. If the value is **0**, the corresponding parameter does not have a name.| +| `parameters` | `uleb128[]` | Array that stores the names of input parameters. The array length is specified by **num_parameters**. The value of each element is the offset to the string or **0**. If the value is **0**, the corresponding parameter does not have a name.| | `constant_pool_size` | `uleb128` | Size of the constant pool, in bytes. | | `constant_pool` | `uleb128[]` | Array for storing constant pool data. The array length is **constant_pool_size**. | | `line_number_program_idx` | `uleb128` | An index that points to a position in [LineNumberProgramIndex](#linenumberprogramindex). The value of this position is an offset pointing to [Line number program](#line-number-program). The length of **Line number program** is variable and ends with the **END_SEQUENCE** operation code.| -#### Constant pool -A constant pool is a structure for storing constants in **DebugInfo**. Many methods have similar line number programs, which differ only in variable names, variable types, and file names. To deduplicate such line number programs, all constants referenced in the programs are stored in the constant pool. When interpreting the program, the state machine maintains a pointer to the constant pool. When interpreting an instruction that requires constant parameters, the state machine reads the value from the position pointed by the memory constant pool pointer and then increments the pointer. +#### Constant Pool +A structure within **DebugInfo** for storing constants. Many methods have similar line number programs, differing only in variable names, variable types, and file names. To eliminate redundancy in these programs, all referenced constants are stored in the constant pool. During program interpretation, the state machine maintains a pointer to the constant pool. When interpreting an instruction that requires a constant parameter, the state machine reads the value from the position pointed to by the constant pool pointer and then increments the pointer. -#### State machine -The state machine is used to generate [DebugInfo](#debuginfo) information. It contains the following registers. +#### State Machine +Generates [DebugInfo](#debuginfo) information. It contains the following registers. -| **Name** | **Initial Value** | **NOTE** | +| **Name** | **Initial Value** | **Description** | | ----------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | -| `address` | 0 | Program counter, an instruction that points to a method, can only monotonically increase. | -| `line` | Value of the **line_start** attribute of [DebugInfo](#debuginfo)| Unsigned integer, corresponding to the line number in the source code. All lines are numbered from 1. Therefore, the register value cannot be less than **1**.| +| `address` | 0 | Program counter (points to an instruction in the method), which can only increase monotonically. | +| `line` | Value of **line_start** in [DebugInfo](#debuginfo)| Unsigned integer, corresponding to the line number in the source code. All lines are numbered from 1. Therefore, the register value cannot be less than **1**.| | `column` | 0 | Unsigned integer, corresponding to the column number in the source code. | -| `file` | Value of **SOURCE_FILE** in **class_data** (see [Class](#class)), or 0.| An offset that points to [string](#string), indicating the name of the source file. If there is no file name, that is, there is no **SOURCE_FILE** tag in [Class](#class), the register value is **0**.| -| `source_code` | 0 | An offset that points to [string](#string), indicating the source code of the source file. If there is no source code information, the register value is **0**.| -| `constant_pool_ptr` | Address of the first byte from the constant pool in [DebugInfo](#debuginfo).| Pointer that points to the current constant value. | +| `file` | Value of **SOURCE_FILE** in **class_data** (see [Class](#class)), or 0.| An offset to a [string](#string) representing the source file name. If there is no file name (no **SOURCE_FILE** tag in [Class](#class)), the register value is **0**.| +| `source_code` | 0 | An offset to a [string](#string) representing the source code of the source file. If there is no source code information, the register value is **0**.| +| `constant_pool_ptr` | Address of the first byte of the constant pool in [DebugInfo](#debuginfo).| Pointer to the current constant value. | -#### Line number program -A line number program consists of instructions. Each instruction contains a single-byte operation code and optional parameters. Because of different operation codes, a parameter value may be encoded in an instruction (called an instruction parameter) or needs to be obtained from a constant pool (called a constant pool parameter). +#### Line Number Program +Consists of instructions, each containing a single-byte operation code and optional parameters. Depending on the operation code, the parameter values may be encoded within the instruction (called instruction parameters) or retrieved from the constant pool (called constant pool parameters). -| **Operation Code** | **Value**| **Command Parameters** | **Constant Pool Parameters** | **Parameters**| **NOTE** | +| **Operation Code** | **Value**| **Instruction Parameter** | **Constant Pool Parameters** | **Parameter Description**| **Description** | | ----- | ----- | ------- | ---- | ------- | ------ | | `END_SEQUENCE` | `0x00` | | | | Marks the end of the line number program. | -| `ADVANCE_PC` | `0x01` | | `uleb128 addr_diff` | **addr_diff**: value to be added to the **address** register value. | The value in the **address** register plus **addr_diff** points to the next address without generating a location entry.| -| `ADVANCE_LINE` | `0x02` | | `sleb128 line_diff` | **line_diff**: value to be added to the **line** register value. | The value in the **line** register plus **line_diff** points to the next line position without generating a position entry.| -| `START_LOCAL` | `0x03` | `sleb128 register_num` | `uleb128 name_idx`
`uleb128 type_idx` | **register_num**: register containing local variables.
**name_idx**: an offset pointing to [string](#string), indicating the variable name.
**type_idx**: an offset pointing to [string](#string), indicating the variable type.| Introduces a local variable with a name and a type in the current address. The number of the register that will contain this variable is encoded in the instruction. If the register number is -1, it indicates that the register is an accumulator. The values of **name_idx** and **type_idx** may be **0**. If so, the corresponding information does not exist.| -| `START_LOCAL_EXTENDED` | `0x04` | `sleb128 register_num` | `uleb128 name_idx`
`uleb128 type_idx`
`uleb128 sig_idx` | **register_num**: register containing local variables.
**name_idx**: an offset pointing to [string](#string), indicating the variable name.
**type_idx**: an offset pointing to [string](#string), indicating the variable type.
**sig_idx**: an offset pointing to [string](#string), indicating the variable signature.| Introduces a local variable with a name, a type, and a signature in the current address. The number of the register that will contain this variable is encoded in the instruction. If the register number is -1, it indicates that the register is an accumulator. The values of **name_idx**, **type_idx**, and **sig_idx** may be **0**. If so, the corresponding information does not exist.| -| `END_LOCAL` | `0x05` | `sleb128 register_num` | | **register_num**: register containing local variables. | Marks a local variable in the specified register as out of range at the current address. If the register number is -1, it indicates that the register is an accumulator.| -| `SET_FILE` | `0x09` | | `uleb128 name_idx` | **name_idx**: an offset pointing to [string](#string), indicating the file name.| Sets the value of the file register. The value of **name_idx** may be **0**. If so, it indicates that the corresponding information does not exist.| -| `SET_SOURCE_CODE` | `0x0a` | | `uleb128 source_idx` | **source_idx**: an offset pointing to [string](#string), indicating the source code of the file.| Sets the value of the **source_code** register. The value of **source_idx** may be **0**. If so, it indicates that the corresponding information does not exist.| +| `ADVANCE_PC` | `0x01` | | `uleb128 addr_diff` | **addr_diff**: value to increment the **address** register. | Increments the **address** register by **addr_diff** to point to the next address, without generating a location entry.| +| `ADVANCE_LINE` | `0x02` | | `sleb128 line_diff` | **line_diff**: value to increment the **line** register. | Increments the **line** register by **line_diff** to point to the next line position, without generating a location entry.| +| `START_LOCAL` | `0x03` | `sleb128 register_num` | `uleb128 name_idx`
`uleb128 type_idx` | **register_num**: register containing the local variable.
**name_idx**: an offset to a [string](#string) representing the variable name.
**type_idx**: an offset to a [string](#string) representing the variable type.| Introduces a local variable with a name and type at the current address. The number of the register that will contain this variable is encoded in the instruction. If **register_num** is **-1**, it indicates an accumulator register. The values of **name_idx** and **type_idx** may be **0**, indicating no such information.| +| `START_LOCAL_EXTENDED` | `0x04` | `sleb128 register_num` | `uleb128 name_idx`
`uleb128 type_idx`
`uleb128 sig_idx` | **register_num**: register containing the local variable.
**name_idx**: an offset to a [string](#string) representing the variable name.
**type_idx**: an offset to a [string](#string) representing the variable type.
**sig_idx**: an offset to a [string](#string) representing the variable signature.| Introduces a local variable with a name, type, and signature at the current address. The number of the register that will contain this variable is encoded in the instruction. If **register_num** is **-1**, it indicates an accumulator register. The values of **name_idx**, **type_idx**, and **sig_idx** may be **0**, indicating no such information.| +| `END_LOCAL` | `0x05` | `sleb128 register_num` | | **register_num**: register containing the local variable. | Marks the local variable in the specified register as out of scope at the current address. If **register_num** is **-1**, it indicates an accumulator register.| +| `SET_FILE` | `0x09` | | `uleb128 name_idx` | **name_idx**: an offset to a [string](#string) representing the file name.| Sets the value of the file register. The value of **name_idx** may be **0**, indicating no such information.| +| `SET_SOURCE_CODE` | `0x0a` | | `uleb128 source_idx` | **source_idx**: an offset to a [string](#string) representing the source code of the file.| Sets the value of the **source_code** register. The value of **source_idx** may be **0**, indicating no such information.| | `SET_COLUMN` | `0x0b` | | `uleb128 column_num` | **column_num**: column number to be set. | Sets the value of the **column** register and generates a location entry. | -| Special operation code | `0x0c..0xff` | | | | Makes the **line** and **address** registers point to the next address and generate a location entry. For details, see the following description.| +| Special operation code | `0x0c..0xff` | | | | Adjusts the **line** and **address** registers to the next address and generate a location entry. Details are described below.| -For special operation codes whose values are between **0x0c** and **0xff** (included), the state machine moves the **line** and **address** registers by a small part and then generates a new location entry. For details, see section 6.2.5.1 "Special Opcodes" in [DWARF 3.0 Standard](https://dwarfstd.org/dwarf3std.html). +For special operation codes in the range **0x0c** to **0xff** (included), the state machine performs the following steps to adjust the **line** and **address** registers and then generates a new location entry. For details, see section 6.2.5.1 "Special Opcodes" in [DWARF 3.0 Standard](https://dwarfstd.org/dwarf3std.html). -| **No.**| **Operation** | **NOTE** | +| **Step**| **Operation** | **Description** | | ----- | -------------------------------------------------- | ------------------------------------------------------------ | | 1 | `adjusted_opcode = opcode - OPCODE_BASE` | Calculates the adjusted operation code. The value of **OPCODE_BASE** is **0x0c**, which is the first special operation code.| -| 2 | `address += adjusted_opcode / LINE_RANGE` | Increases the value of the **address** register. The value of LINE_RANGE is 15, which is used to calculate the change of the line number information.| -| 3 | `line += LINE_BASE + (adjusted_opcode % LINE_RANGE)` | Increase the value of the **line** register. The value of **LINE_BASE** is **-4**, which is the minimum line number increment. The maximum row number increment is **LINE_BASE + LINE_RANGE - 1**.| +| 2 | `address += adjusted_opcode / LINE_RANGE` | Increments the **address** register. The value of **LINE_RANGE** is 15, which is used to calculate changes in the line number information.| +| 3 | `line += LINE_BASE + (adjusted_opcode % LINE_RANGE)` | Increments the **line** register. The value of **LINE_BASE** is **-4**, which is the minimum line number increment. The maximum increment is **LINE_BASE + LINE_RANGE - 1**.| | 4 | | Generates a new location entry. | -**Note:**
-The special operation code is calculated by using the following formula: **(line_increment - LINE_BASE) + (address_increment * LINE_RANGE) + OPCODE_BASE**. +> **NOTE** +> +> Special operation codes are calculated by using the following formula: (line_increment - LINE_BASE) + (address_increment * LINE_RANGE) + OPCODE_BASE. ### IndexSection -Generally, each structure of a bytecode file is referenced by using a 32-bit offset. When a structure references another structure, the 32-bit offset of the referenced structure needs to be recorded in the current structure. To reduce a file size, a bytecode file is divided into multiple index regions, and a structure in each index region uses a 16-bit index. The **IndexSection** structure describes a collection of index areas. +Generally, bytecode files use 32-bit offsets for referencing structures. When a structure references another structure, the current structure records a 32-bit offset of the referenced structure. To optimize file size, the bytecode file is segmented into index regions that use 16-bit indices instead of 32-bit offsets. The **IndexSection** structure provides an overview of these regions. -- Align in four bytes. +- Alignment: 4-byte aligned - Format -| **Name**| **Format**| **NOTE** | +| **Name**| **Format**| **Description** | | -------------- | -------------- | --------- | -| `headers` | `IndexHeader[]` | An array. Each element in the array is of the [IndexHeader](#indexheader) type. Elements in the array are sorted based on the start offset of the region. The array length is specified by **num_index_regions** in [Header](#header).| +| `headers` | `IndexHeader[]` | An array of [IndexHeader](#indexheader) elements. Elements in the array are sorted based on the start offset of the region. The array length is specified by **num_index_regions** in [Header](#header).| ### IndexHeader -Each **IndexHeader** structure describes an index region. Each index region has two types of indexes: indexes pointing to [Type](#type) and indexes pointing to methods, strings, or literal arrays. +Represents an index region. Each index region has two types of indexes: indexes pointing to [Type](#type) and indexes pointing to methods, strings, or literal arrays. -- Align in four bytes. +- Alignment: 4-byte aligned - Format -| **Name** | **Format**| **NOTE** | +| **Name** | **Format**| **Description** | | -------------- | -------------- | ---------- | | `start_off` | `uint32_t` | Start offset of the region. | | `end_off` | `uint32_t` | End offset of the region. | | `class_region_idx_size` | `uint32_t` | Number of elements in [ClassRegionIndex](#classregionindex) of the region. The maximum value is **65536**.| -| `class_region_idx_off` | `uint32_t` | An offset that points to [ClassRegionIndex](#classregionindex).| -| `method_string_literal_region_idx_size` | `uint32_t` | Number of elements in the [MethodStringLiteralRegionIndex](#methodstringliteralregionindex) of the region. The maximum value is **65536**.| -| `method_string_literal_region_idx_off` | `uint32_t` | An offset that points to [MethodStringLiteralRegionIndex](#methodstringliteralregionindex).| -| `reserved` | `uint32_t` | Reserved field used internally in the Ark Bytecode file. | -| `reserved` | `uint32_t` | Reserved field used internally in the Ark Bytecode file. | -| `reserved` | `uint32_t` | Reserved field used internally in the Ark Bytecode file. | -| `reserved` | `uint32_t` | Reserved field used internally in the Ark Bytecode file. | +| `class_region_idx_off` | `uint32_t` | An offset to [ClassRegionIndex](#classregionindex).| +| `method_string_literal_region_idx_size` | `uint32_t` | Number of elements in [MethodStringLiteralRegionIndex](#methodstringliteralregionindex) of the region. The maximum value is **65536**.| +| `method_string_literal_region_idx_off` | `uint32_t` | An offset to [MethodStringLiteralRegionIndex](#methodstringliteralregionindex).| +| `reserved` | `uint32_t` | Reserved field for internal use by the Ark bytecode file. | +| `reserved` | `uint32_t` | Reserved field for internal use by the Ark bytecode file. | +| `reserved` | `uint32_t` | Reserved field for internal use by the Ark bytecode file. | +| `reserved` | `uint32_t` | Reserved field for internal use by the Ark bytecode file. | ### ClassRegionIndex -The **ClassRegionIndex** structure is used to find the corresponding [Type](#type) through a more compact index. +Provides compact indexing for locating [Type](#type) entries. -- Align in four bytes. +- Alignment: 4-byte aligned - Format -| **Name**| **Format**| **NOTE** | +| **Name**| **Format**| **Description** | | -------------- | -------------- | ------------------------------------------------------------ | -| `types` | `Type[]` | An array. Each element in the array is of the [Type](#type) type. The array length is specified by **class_region_idx_size** in [IndexHeader](#indexheader).| +| `types` | `Type[]` | An array of [Type](#type) elements. The array length is specified by **class_region_idx_size** in [IndexHeader](#indexheader).| ### Type -Indicates a basic type code or an offset pointing to [Class](#class). It is a 32-bit value. +A 32-bit value representing either a basic type encoding or an offset to a [class](#class). -Basic types are encoded in the following ways. +Basic type encodings are listed below. -| **Type** | **Code** | +| **Type** | **Encoding** | | -------------- | -------------- | | `u1` | `0x00` | | `i8` | `0x01` | @@ -486,32 +501,32 @@ Basic types are encoded in the following ways. ### MethodStringLiteralRegionIndex -The **MethodStringLiteralRegionIndex** structure is used to find the corresponding methods, strings, or literal arrays through a more compact index. +Provides compact indexing for methods, strings, or literal arrays. -- Align in four bytes. +- Alignment: 4-byte aligned - Format -| **Name**| **Format**| **NOTE** | +| **Name**| **Format**| **Description** | | -------------- | -------------- | ------------------------------------------------------------ | -| `offsets` | `uint32_t[]` | An array. The value of each element is an offset pointing to a method, a string, or a literal array. The array length is specified by **method_string_literal_region_idx_size** in [IndexHeader](#indexheader).| +| `offsets` | `uint32_t[]` | An array of offsets to methods, strings, or literal arrays. The array length is specified by **method_string_literal_region_idx_size** in [IndexHeader](#indexheader).| ### LiteralArray -Describes the literal array in the bytecode file. +Describes a literal array in the bytecode file. -- Align in single byte. +- Alignment: single-byte aligned - Format -| **Name**| **Format**| **NOTE** | +| **Name**| **Format**| **Description** | | -------------- | -------------- | ------------------------------------------------------------ | | `num_literals` | `uint32_t` | Length of the **literals** array. | -| `literals` | `Literal[]` | An array. Each element of the array is of the [Literal](#literal) type.| +| `literals` | `Literal[]` | An array of [Literal](#literal) elements.| ### Literal -Describes the literals in a bytecode file. There are four encoding formats based on the number of bytes of the literals. +Describes literals in the bytecode file. There are four encoding formats based on the number of bytes of the literals. -| **Name**| **Format**| **Alignment Type**| **NOTE**| +| **Name**| **Format**| **Alignment**| **Description**| | -------------- | -------------- | ------------------ | -------------- | | ByteOne | `uint8_t` | 1 byte | Single-byte value. | | ByteTwo | `uint16_t` | 2 bytes | Double-byte value. | diff --git a/en/application-dev/arkts-utils/arkts-bytecode-function-name.md b/en/application-dev/arkts-utils/arkts-bytecode-function-name.md index b752b550e74b142ad253c2b92eee51a19a3d7db1..023e3ecc4986c5565c81b10f52318fbf9e681e05 100644 --- a/en/application-dev/arkts-utils/arkts-bytecode-function-name.md +++ b/en/application-dev/arkts-utils/arkts-bytecode-function-name.md @@ -1,48 +1,48 @@ -# Naming Rules of Ark Bytecode Functions +# Naming Conventions for Ark Bytecode Functions -## Abstract -This topic describes the naming rules of the string pointed by the **name_off** field of [Method](arkts-bytecode-file-format.md#method) in the bytecode file. These rules take effect since the Ark Bytecode in version **12.0.4.0**. -## Entry Point Function -Function that is executed when the module is loaded. The function name is fixed to **func_main_0**. -## Non-entry Point Function -The name structure of other functions in the bytecode file is as follows: +## Overview +This topic describes the naming conventions for the strings pointed to by the **name_off** field in [methods](arkts-bytecode-file-format.md#method) of bytecode files. These conventions apply to Ark bytecode files of version 12.0.4.0 or later. +## Entry Function +Function executed during module loading. The function name is fixed at **func_main_0**. +## Non-Entry Function +The naming structure for other functions in the bytecode file is as follows: ```ts -##Prefix#Original function name +##prefix#original_function_name ``` -The following sections will describe the prefix and original function name in detail. +The following sections describe the prefix and original function name in detail. ### Prefix -The prefix contains the scope information when the function is defined. It consists of the following parts: -* Scope Label -* Scope Name -* Duplicate Sequence Number +The prefix includes information about the scope where the function is defined. It consists of the following parts: +* Scope tag +* Scope name +* Renaming index (if applicable) The prefix structure is as follows: ```ts -[]<[Duplicate Sequence Number]>...[] +[]<[Renaming index]>...[] ``` -In this case, angle brackets (< >) are separators for easy reading and are excluded from the actual prefix; square brackets ([ ]) indicate that the value can be empty. [\] is required only when duplicate scopes exist, which indicates that [\] can be empty. The last scope label is the one corresponding to the function. -#### Scope Label -The scope label indicates the scope type. The following table lists the scopes and corresponding labels. Other scopes are not recorded in the function name. -| Scope| Scope Label| Description| +Here, angle brackets (< >) are delimiters for readability and are not part of the actual prefix, and square brackets ([ ]) indicates optional elements. [\] is only included if there are duplicate scope names and can be empty otherwise. The last scope tag corresponds to the function itself. +#### Scope Tag +Scope tags indicate the type of scope. The table below lists the scopes and their corresponding tags. Other scopes are not included in function names. +| Scope| Scope Tag| Description| | --- | --- | --- | | Class| `~` | Scope defined by the **class** keywords.| -| Instance function| `>` | Scope defined by the instance functions of a class| -| Static function| `<` | Scope defined by the static functions of a class| -| Constructor used to create a worker object.| `=` | Scope defined by the constructors of a class| -| Common function| `*` | Scopes defined by all functions except the preceding types| -| namespace/module | `&` | Scope defined by the **namespace** or **module** keywords| -| enum | `%` | Scope defined by the **enum** keywords| +| Instance function| `>` | Scope defined by the instance member functions in a class.| +| Static function| `<` | Scope defined by the static functions in a class.| +| Constructor function| `=` | Scope defined by the constructors in a class.| +| Ordinary function| `*` | Scope defined by all functions except the preceding types.| +| namespace/module | `&` | Scope defined by the **namespace** or **module** keywords.| +| enum | `%` | Scope defined by the **enum** keywords.| #### Scope Name -The name used to define the scope in the source code. If the value is anonymous, the value is an empty string. To reduce the bytecode size, the ArkCompiler optimizes long scope names. In this case, the scope names are displayed in the format of **@hexadecimal number**. This number indicates the index of the scope name in a string array. In the bytecode file, there is a [field](arkts-bytecode-file-format.md#field) named **ScopeNames** in the [Class](arkts-bytecode-file-format.md#class) corresponding to the source code. This **field** value points to an offset of [LiteralArray](arkts-bytecode-file-format.md#literalarray) which stores a string array. The hexadecimal number is the index of the scope name in this array. The original function name is not converted to an index. +Scope names indicate the name used to define the scope in the source code. If the scope is anonymous, it is an empty string. To reduce the bytecode size, the Ark compiler optimizes longer scope names, representing them as @ followed by a hexadecimal number. This hexadecimal number is the index of the scope name in a string array. In the bytecode file, there is a [field](arkts-bytecode-file-format.md#field) named **scopeNames** in the [class](arkts-bytecode-file-format.md#class) corresponding to the source code. This **field** value points to an offset of a [LiteralArray](arkts-bytecode-file-format.md#literalarray) storing the string array. The hexadecimal number is the index of the scope name in this array. The original function name is not converted to an index. Example: ```ts -function longFuncName() { // The function name of longFuncName is "#*#longFuncName", in which "longFuncName" is the original function name and will not be converted to an index. +function longFuncName() { // The function name of longFuncName is "#*#longFuncName", where "longFuncName" is the original function name and will not be converted to an index. function A() { } // The function name of A is "#*@0*#A", where "@0" indicates the string whose index is 0 in the corresponding LiteralArray. In this case, the string is "longFuncName", which means that the original name of this function is "#*longFuncName*#A". function B() { } // The function name of B is "#*@0*#B". } ``` -#### Duplicate Sequence Number -If an entity with the same name exists in the same scope within the source code, the entity name is suffixed with a duplicate sequence number. This number is written in the format of **^ hexadecimal number**. If duplicate names exist, the first one is not numbered, that is, the duplicate sequence number is empty. And the entities are numbered from the second one, starting from **1**. +#### Renaming Index +If the source code contains entities with the same name in the same scope, a renaming index is appended to the duplicate names. The renaming index is represented as ^ followed by a hexadecimal number. For the first occurrence, no index is added (the renaming index is empty), and subsequent occurrences start from 1. Example: ```ts @@ -51,11 +51,11 @@ namespace A { } namespace A { - function foo() { } // The function name of foo is "#&A^1*#foo", where "^1" indicates the duplicate sequence number. + function foo() { } // The function name of foo is "#&A^1*#foo", where "^1" indicates the renaming index. } ``` ### Original Function Name -It indicates function name in the source code. For an anonymous function, the value is an empty string. Similarly, if a function with the same name exists in the same scope within the source code, the function name is followed by a duplicate sequence number, so does an anonymous function. +The original function name represents the name of the function in the source code. For anonymous functions, it is an empty string. Similarly, if there are duplicate function names in the same scope, a renaming index is appended to the duplicate names, including anonymous functions. ```ts function foo() {} // The original function name is "foo". @@ -63,19 +63,19 @@ function foo() {} // The original function name is "fo () => { } // The original function name is "^1". ``` -#### Special Situations -1. If an anonymous function is stored in a variable when the function is defined, the original function name is the variable name. An example is as follows: +#### Special Cases +1. If an anonymous function is assigned to a variable, the original function name is the variable name. An example is as follows: ```ts let a = () => {} // The original function name is "a". ``` -2. If an anonymous function is defined in an object literal and stored in a literal attribute: -* If the attribute name does not contain a **slash (\)** or a **period (.)**, the original function name is the attribute name. +2. If an anonymous function is defined in an object literal and assigned to a literal property, the following cases are possible: +* If the property name does not contain a slash (/\) or a period (.), the original function name is the property name. ```ts let B = { b : () => {} // The original function name is "b". } ``` -* If the attribute name contains a **slash (\)** or a **period (.)**, the original function is named as an anonymous function to prevent ambiguity. +* If the property name contains a slash (/\) or a period (.), the original function name follows the naming convention for anonymous functions to avoid ambiguity. ```ts let a = { "a.b#c^2": () => {} // The original function name is "". @@ -83,28 +83,28 @@ function foo() {} // The original function name is "fo } ``` -**You should avoid using characters other than letters, digits, and underscores (_) to name functions to avoid ambiguity.** -## Example +**You should avoid using characters other than letters, digits, and underscores (_) in function names to avoid ambiguity.** +## Examples ```ts -namespace A { // The function name of namespace in bytecode is "#&#A". +namespace A { // The function name of the namespace in bytecode is "#&#A". class B { // The function name of the constructor in bytecode is "#&A~B=#B". - m() { // The function name of m in bytecode is "#&A~B>#m". + m() { // The function name of the function m in bytecode is "#&A~B>#m". return () => {} // The function name of the anonymous function in bytecode is "#&A~B>m*#". } - static s() {} // The function name of static function s in bytecode is "#&A~B<#s". + static s() {} // The function name of the static function s in bytecode is "#&A~B<#s". } - enum E { // The function name of enum in bytecode is "#&A %#E". + enum E { // The function name of the enum in bytecode is "#&A %#E". } } ``` ```ts -namespace LongNamespaceName { // The function name of namespace in bytecode is "#&#LongNamespaceName". - class LongClassName { // The function name of the constructor in bytecode is "#&@1~@0=#LongClassName". - longFunctionName() { // The function name of the instance function in the bytecode is "#&@1~@0>#longFunctionName". +namespace LongNamespaceName { // The function name of the namespace in bytecode is "#&#LongNamespaceName". + class LongClassName { // The function name of the constructor function in bytecode is "#&@1~@0=#LongClassName". + longFunctionName() { // The function name of the instance function in bytecode is "#&@1~@0>#longFunctionName". } - longFunctionName() { // The function name in bytecode is "#&@1~@0>#longFunctionName^1". - function inSecondFunction() {} // The function name in bytecode is "#&@1~@0>@2^1*#inSecondFunction". + longFunctionName() { // The function name of the function in bytecode is "#&@1~@0>#longFunctionName^1". + function inSecondFunction() {} // The function name of the function in bytecode is "#&@1~@0>@2^1*#inSecondFunction". } } } diff --git a/en/application-dev/arkts-utils/arkts-bytecode-fundamentals.md b/en/application-dev/arkts-utils/arkts-bytecode-fundamentals.md index 8436954e5e9d16b24ca0436e70a5f273322098a1..c9c60d6c8e379fcd709f82926582e0f683575c0c 100644 --- a/en/application-dev/arkts-utils/arkts-bytecode-fundamentals.md +++ b/en/application-dev/arkts-utils/arkts-bytecode-fundamentals.md @@ -1,48 +1,48 @@ # Ark Bytecode Fundamentals -## Overall design -### Abstract -Ark Bytecode is a binary file generated by the ArkCompiler in ArkTS, TS or JS and provided for Ark to interpret and execute. Bytecode mainly contains Ark Bytecode instructions.
-This topic describes the design of Ark Bytecode instructions. The following sections describe the important concepts, formats, and meanings of Ark Bytecode instructions, helping you understand these instructions and develop instruction-related features.
-An Ark Bytecode instruction consists of an operation code (instruction name) and an instruction input parameter list. An operation code can be a code without a prefix or with a prefix. Registers, immediates, string id, method id, and literal id can be used as input parameters of instructions. In addition, accumulators are used as default parameters in some instructions.
-In Ark Bytecode, in addition to register and accumulator, there are four value storage modes: **global variable**, **[module](https://262.ecma-international.org/12.0/#sec-ecmascript-language-scripts-and-modules) namespace and variable**, **lexical environment and variable**, and **patch variable**. The instruction can use the values stored by these four modes as input parameters. +## Overall Design +### Overview +Ark bytecode is a binary file generated by the ArkCompiler from ArkTS/TS/JS code and provided for Ark Runtime to interpret and execute. Bytecode mainly contains Ark bytecode instructions.
+This topic introduces the design of these instructions, covering key concepts, specific formats, and meanings to help you understand and work with Ark bytecode instructions effectively.
+An Ark bytecode instruction consists of an operation code (instruction name) and a list of parameters. An operation code can be prefix-free or prefixed. Registers, immediate values, string id, method id, and literal id can be used as parameters. In addition, the accumulator can be used as a default parameter in some instructions.
+In addition to registers and accumulator, Ark bytecode supports four value storage mechanisms: global variables, [module](https://262.ecma-international.org/12.0/#sec-ecmascript-language-scripts-and-modules) namespaces and variables, lexical environments and variables, and patch variables. Instructions can reference values from these storage locations as parameters. ### Terms and Constraints -#### Terminology -The following table lists the terms involved in this topic. +#### Terms +The following table lists the terms used in this topic. | Term | Description | | ---------- | ---------- | -| acc | Accumulator, a special register in the Ark Bytecode. | -| bit | Used as a unit in this topic. | -| hole | Objects or variables that have not been initialized. | -| id | Index, which is a general name of string id, method id, or literal id. | -| string id | String index, which is a 16-bit number used to link to the corresponding string. | -| method id | Method index, which is a 16-bit number and is used to link to the corresponding method. | -| literal id | Literal index, which is a 16-bit number and is used to link to the corresponding literal array. | -| lexical environment | Lexical environment, which is used to store the semantic environment of closure variables. | -| lexical variable | Lexical variable, a closure variable stored in the lexical environment. | - -#### Constraint -* All content described in code in this topic follows the ArkTS Language Specifications. For details, see [Introduction](../quick-start/introduction-to-arkts.md). -* This topic applies only to Ark Bytecode whose version number is 11.0.2.0. (The version number is an internal reserved field of the ArkCompiler.) +| acc | Accumulator, a special register in the Ark bytecode. | +| bit | A binary digit, represented as a bit in this topic. | +| hole | An uninitialized object or variable. | +| id | Index, a general term for string id, method id, or literal id. | +| string id | A 16-bit number indexing a string. | +| method id | A 16-bit number indexing a method. | +| literal id | A 16-bit number indexing a literal array. | +| lexical environment | A semantic environment storing closure variables. | +| lexical variable | A closure variable stored in the lexical environment. | + +#### Constraints +* All code examples provided in this topic adhere to the [ArkTS language specifications](../quick-start/introduction-to-arkts.md). +* This topic is applicable only to Ark bytecode of version 12.0.6.0. The version number is an internal field of the ArkCompiler and does not require your attention. ### Bytecode Composition -#### Operation Code and Prefix -The operation code in the Ark Bytecode is usually encoded as an 8-bit value, so there can be a maximum of 256 operation codes. With the runtime features of the ArkCompiler are getting evolved, the number of bytecode is increasing and has exceeded 256. Therefore, the Ark Bytecode introduces a prefix to extend the maximum width of the operation code from 8 bits to 16 bits. An 8-bit operation code (without a prefix) is used to indicate an instruction that appears frequently, and a 16-bit operation code (with a prefix) is used to indicate an instruction that appears occasionally
-An operation code with a prefix is a 16-bit value stored in little-endian mode. It consists of an 8-bit operation code and an 8-bit prefix. You can shift the operation code leftwards by 8 bits and run the **OR** logic with the code and the prefix to encode. -| Prefix Operation Code | Mnemonic | Description. | +#### Operation Codes and Prefixes +Operation codes in Ark bytecode are typically 8-bit values, allowing for up to 256 unique opcodes. However, as the ArkCompiler's functionality has expanded, the number of operation codes has exceeded 256. To accommodate this, the Ark bytecode introduces prefixes, expanding the maximum operation code width from 8 bits to 16 bits. 8-bit operation codes (prefix-free) are used for common instructions, whereas 16-bit operation codes (prefixed) are used for less frequent ones.
+Prefixed operation codes are stored in little-endian format, composed of an 8-bit operation code and an 8-bit prefix. During encoding, the operation code is shifted left by 8 bits and then ORed with the prefix. +| Prefix | Mnemonic | Description | | ---------- | ---------- | ---------- | | 0xfe | throw | Conditional/Unconditional **throw** instruction.| -| 0xfd | wide | An instruction that contains an immediate, id, or register index with a wider encoding width. | -| 0xfc | deprecated | Instructions that are no longer generated by the ArkCompiler are used only to maintain runtime compatibility.
Following sections will no longer describe such instructions.| +| 0xfd | wide | Instructions with wider encoding widths for immediate values, IDs, or register indexes. | +| 0xfc | deprecated | Instructions no longer generated by the ArkCompiler. They are used only for runtime compatibility.
These instructions are not described in the following sections.| | 0xfb | callruntime | Instructions for calling runtime methods. | -The mnemonic of a prefix operation code is in the form of **prefix mnemonic.operation code mnemonic**, for example, **wide.stlexvar**. If the operation code of the **stlexvar** instruction is **0x0d** and the prefix **wide** is **0xfd**, the operation code of **wide.stlexvar** is **0x0dfd**. +The mnemonic form of a prefixed operation code is **prefix mnemonic.operation code mnemonic**. For example, **wide.stlexvar** combines the prefix **wide** (**0xfd**) with the operation code **stlexvar** (**0x0d**), resulting in the prefixed operation code **0x0dfd**. -#### Register and Accumulator -The Ark VM model is built based on registers. All registers are virtual registers. When the value of the original type is stored in the register, the width of the register is 64 bits. When the value of the object type is stored in the register, the width of the register is adapted to be wide enough to store the reference to the object.
-In Ark Bytecode, there is an invisible register called accumulator (also referred to as **acc** for short). **acc** is the default destination register of many instructions and the default parameter of many instructions. It does not occupy the encoding width, which helps generate more compact bytecode.
+#### Registers and Accumulator +The Ark Virtual Machine (VM) uses a register-based model with virtual registers. When a register holds a primitive value, it is 64 bits wide; when it holds an object reference, its width adjusts accordingly.
+A special invisible register called the accumulator (acc) is used in the Ark bytecode. The acc serves as the default target for many instructions and as a default parameter for others, helping to produce more compact bytecode without consuming additional encoding width.
Example: ```ts @@ -57,18 +57,18 @@ Related instructions in the bytecode: return } ``` -*ldai 0x1*: loads integer literal 1 to **acc**.
-*return*: returns the value in **acc**. +*ldai 0x1*: loads integer literal 1 to the acc.
+*return*: returns the value in the acc. -#### Immediate -Some instructions in Ark Bytecode use constants to represent data such as integer values, double-precision floating-point values, and jump offsets. Such constants are called immediate, which can be 8 bits, 16 bits, 32 bits, or 64 bits. +#### immediate values +Some instructions use constants to represent integer values, double-precision floating-point values, or jump offsets. These constants, known as immediate values, can be 8-bit, 16-bit, 32-bit, or 64-bit. -#### Method Index, String Index, and Literal Index -The Ark Bytecode stores the offsets of all methods, strings, and literal arrays used in the source file. The literal array stores various literal data, such as an integer number, a string offset, and a method offset. In the Ark Bytecode instruction, indexes of these methods, strings, and literal arrays are 16 bits, which are respectively referred to as a method index (method id), a string index (string id), and a literal index (literal id). These indexes are encoded in instructions to reference methods, strings, and literal arrays. +#### Method, String, and Literal Indexes +The Ark bytecode stores offsets for all methods, strings, and literal arrays used in the source file. Literal arrays contain various literals, such as integer numbers, string offsets, and method offsets. In Ark bytecode instructions, these indexes are 16-bit values, referred to as method indexes (method id), string indexes (string id), and literal indexes (literal id). These indexes are encoded in instructions to reference methods, strings, and literal arrays. -### Value Storage Mode -#### Global variables -In [Script](https://262.ecma-international.org/12.0/#sec-ecmascript-language-scripts-and-modules) build mode, a global variable is a variable stored in a globally unique mapping. Its key is the name of the global variable, and its value is that of the global variable. Global variables can be accessed through global-related instructions.
+### Value Storage Mechanisms +#### Global Variables +In [Script](https://262.ecma-international.org/12.0/#sec-ecmascript-language-scripts-and-modules) build mode, global variables are stored in a globally unique mapping, with the variable name as the key and its value as the value. Global variables can be accessed using global-related instructions.
Example: ```ts @@ -90,23 +90,26 @@ Related instructions in the bytecode: ... } ``` -*tryldglobalbyname 0x0, a*: loads the global variable named **a** to **acc**. If this variable does not exist, an exception is thrown.
-*trystglobalbyname 0x2, a*: stores the value of **acc** to the global variable named **a**. If this variable does not exist, an exception is thrown.
-*trystglobalbyname 0x3, b*: stores the value of **acc** to the global variable named **b**. If this variable does not exist, an exception is thrown.
-**Note:**
-**0x0**, **0x2**, and **0x3** in the preceding instructions are reserved for internal use in Ark runtime. - -#### Module Namespace and Module Variable -All [module namespaces](https://262.ecma-international.org/12.0/#module-namespace-exotic-object) used in the source file are compiled into an array. An index is used in the instruction to reference a module namespace. For example, *getmodulenamespace 0x1* references the module namespace at the *0x1* index.
-All module variables used in the source file are compiled into an array. In the instruction, an index is used to reference a module variable. For example, *stmodulevar 0x1* references a module variable at *0x1* index.
-In a function, if the declaration of a module variable is in the same source file as the function, the variable is called a local module variable. Otherwise, it is called an external module variable. For example, *ldlocalmodulevar* and *ldexternalmodulevar* are used respectively to load local module variables and external module variables.
-The scenarios for generating module instructions include [import](https://262.ecma-international.org/12.0/#sec-imports) and [export](https://262.ecma-international.org/12.0/#sec-exports). The main scenarios are as follows: +*tryldglobalbyname 0x0, a*: loads a global variable named **a** to the acc. If this variable does not exist, an exception is thrown.
+*trystglobalbyname 0x2, a*: stores the value of the acc to a global variable named **a**. If this variable does not exist, an exception is thrown.
+*trystglobalbyname 0x3, b*: stores the value of the acc to a global variable named **b**. If this variable does not exist, an exception is thrown.
+ +> **NOTE** +> +> **0x0**, **0x2**, and **0x3** in the preceding instructions are reserved for internal use in the Ark Runtime. + +#### Module Namespaces and Variables +All [module namespaces](https://262.ecma-international.org/12.0/#module-namespace-exotic-object) used in the source file are compiled into arrays, referenced by instructions using indexes. For example, *getmodulenamespace 0x1* references the module namespace at index *0x1*.
+All module variables used in the source file are compiled into arrays, referenced by instructions using indexes. For example, *stmodulevar 0x1* references a module variable at index *0x1*.
+In a function, if the declaration of a module variable is in the same source file as the function, the variable is called a local module variable. Otherwise, it is called an external module variable. For example, *ldlocalmodulevar* and *ldexternalmodulevar* are used to load local module variables and external module variables, respectively.
+Scenarios for generating module instructions include [import](https://262.ecma-international.org/12.0/#sec-imports) and [export](https://262.ecma-international.org/12.0/#sec-exports). The main scenarios are as follows: * **import * as**: module namespace * **import { }**: module variable * **export**: local export -**Note:**
-The logic related to the module is implemented within the compiler. With the evolution of the ArkCompiler, new scenarios involving module instructions may occur. On the other hand, existing scenarios related to module namespaces and module variable instructions may no longer generate module-related instructions as requirements evolve and code is reconstructed.
+> **NOTE** +> +> Module-related logic is an internal implementation detail of the compiler. As the ArkCompiler evolves, new scenarios involving module instructions may emerge, and existing ones may change due to evolving requirements or code refactoring.
Example: ```ts @@ -140,21 +143,21 @@ Related instructions in the bytecode: ... } ``` -*getmodulenamespace 0x1*: obtains the module namespace (c) of slot 1 and store it in **acc**.
-*stmodulevar 0x0*: stores the values in **acc** to slot 0 of the current module.
-*ldexternalmodulevar 0x0*: loads the value (a) of slot 0 of the external module and stores it in **acc**.
-*ldlocalmodulevar 0x0*: loads the value (d) of slot 0 of the current local module and stores it in **acc**. +*getmodulenamespace 0x1*: obtains the module namespace (c) of slot 1 and stores it in the acc.
+*stmodulevar 0x0*: stores the values in the acc into slot 0 of the current module.
+*ldexternalmodulevar 0x0*: loads the value (a) of slot 0 of the external module and stores it in the acc.
+*ldlocalmodulevar 0x0*: loads the value (d) of slot 0 of the current local module and stores it in the acc. -#### Lexical Environment and Lexical Variable -In Ark Bytecode, a lexical environment may be considered as an array with multiple slots, and each slot corresponds to one lexical variable. Multiple lexical environments may exist in one method. The relative level number and slot index of the lexical environment are used in the instruction to represent a lexical variable. For example, *ldlexvar 0x1, 0x2* is used to store the value of slot 2 in the lexical environment beyond one level to **acc**. +#### Lexical Environments and Lexical Variables +In Ark bytecode, a lexical environment may be considered as an array with multiple slots, and each slot corresponds to one lexical variable. A method may contain multiple lexical environments. Instructions reference lexical variables using the relative nesting level and slot index of the lexical environment. For example, *ldlexvar 0x1, 0x2* loads the value from slot 0x2 of the lexical environment one level outside the current lexical environment into the acc. ``` -|xxx|xxx|xxx|xxx| <-- First lexical environment beyond the current lexical environment. +|xxx|xxx|xxx|xxx| <-- Lexical environment one level outside the current lexical environment. ^ |------------ ldlexvar 0x1, 0x2 |xxx|xxx|xxx|xxx| <-- Current lexical environment. ``` -**Note:**
+**NOTE**
The logic related to **lexical** is used in the compiler. With subsequent evolution of the ArkCompiler, new scenarios involving lexical instructions may emerge. On the other hand, existing **lexical** instruction-related scenarios may no longer generates **lexical** instructions as requirements evolve and code is reconstructed. Example: ```ts @@ -184,12 +187,12 @@ Related instructions in the bytecode: ... } ``` -*newlexenv 0x1*: creates a lexical environment whose slot number is 1, stores it in **acc**, and enters this environment.
-*stlexvar 0x0, 0x0*: stores the value in **acc** to slot 0 of the lexical environment beyond 0 level.
-*ldlexvar 0x0, 0x0*: stores the value of slot 0 in the lexical environment beyond 0 level to **acc**. +*newlexenv 0x1*: creates a lexical environment with one slot, stores it in the acc, and enters this environment.
+*stlexvar 0x0, 0x0*: stores the value in the acc into slot 0 of the lexical environment 0 level outside the current lexical environment.
+*ldlexvar 0x0, 0x0*: stores the value from slot 0 of the lexical environment 0 level outside the current lexical environment into the acc. -#### Shared lexical environment -The shared lexical environment is a special type of lexical environment. Different from the general lexical environment, each lexical variable in the shared lexical environment is a [sendable object](arkts-sendable.md). Ark Compiler shares lexical variables among multiple threads through the shared lexical environment. +#### Shared Lexical Environments +Shared lexical environments are a special type of lexical environment Unlike regular lexical environments, each lexical variable in a shared lexical environment is a [Sendable object](arkts-sendable.md). The ArkCompiler uses shared lexical environments to enable sharing of lexical variables across multiple threads. Example: ```ets @@ -224,19 +227,19 @@ label_0: label_2: } ``` -an instruction callruntime.newsendableenv 0x1: creating a shared lexical environment whose slot quantity is 1, and entering the lexical environment;
-*callruntime.stsendablevar 0x0, 0x0*: stores the value in **acc** to slot 0 of the lexical environment beyond 0 level.
-*callruntime.ldsendablevar 0x0, 0x0*: stores the value of slot 0 in the lexical environment beyond 0 level to **acc**. +an instruction callruntime.newsendableenv 0x1: creates a shared lexical environment with one slot and enters this lexical environment.
+*callruntime.stsendablevar 0x0, 0x0*: stores the value in the acc into slot 0 of the lexical environment outside level 0.
+*callruntime.ldsendablevar 0x0, 0x0*: stores the value from slot 0 of the lexical environment 0 level outside the current lexical environment into the acc. -#### Patch Variable -The ArkCompiler supports patch mode. When a source file is modified, you can compile it in the patch mode and generate a patch bytecode. The patch bytecode works with the original bytecode to update features. When the ArkCompiler compiles in patch mode, the generated patch variables are stored in a special patch lexical environment. The Ark Bytecode uses the slot number in the patch lexical environment to reference the patch variable. For example, *ldpatchvar 0x1* is used to load the patch variable of slot 1.
+#### Patch Variables +The ArkCompiler supports patch mode compilation. When a source file is modified, patch mode compilation generates a patch bytecode that, together with the original bytecode, completes the functional update. During patch mode compilation, patch variables generated by the ArkCompiler are stored in a special patch lexical environment. Instructions in the Ark bytecode use slot numbers from the patch lexical environment to reference patch variables. For example, the instruction *ldpatchvar 0x1* is used to load the patch variable from slot 1.
Example: ```ts -function bar(): void {} // Add a statement to compile the patch. +function bar(): void {} // Add a statement and compile the patch. function foo(): void { - bar(); // Add a statement to compile the patch. + bar(); // Add a statement and compile the patch. } ``` Related instructions in the bytecode: @@ -257,11 +260,11 @@ Related instructions in the bytecode: ... } ``` -*wide.stpatchvar 0x0*: stores the **bar** function to slot 0 in the patch lexical environment.
-*wide.ldpatchvar 0x0*: stores the value of slot 0 in the patch lexical environment to **acc**. +*wide.stpatchvar 0x0*: stores the **bar** function into slot 0 of the patch lexical environment.
+*wide.ldpatchvar 0x0*: stores the value from slot 0 in the patch lexical environment into the acc. -### Function Calling Specifications -For a method that contains N pieces of formal parameters, the last N+3 registers used by the method are used to pass parameters. In this case, the first three registers represent the function (FunctionObject) itself, [new.target](https://262.ecma-international.org/12.0/#sec-function-environment-records) (NewTarget), and **this** in the lexical environment. The subsequent N registers correspond to these N pieces of formal parameters.
+### Function Call Specifications +For a method with N formal parameters, the last N+3 registers are used to pass parameters. The first three registers are fixed to represent the function object (FunctionObject), [new.target](https://262.ecma-international.org/12.0/#sec-function-environment-records) (NewTarget), and **this** from the lexical environment where the function resides. The subsequent N registers correspond to the N formal parameters.
Example: ```ts @@ -282,356 +285,356 @@ Related instructions in the bytecode: | Mnemonic | Semantic Description | | ---------- | ---------- | | ID16 | 8-bit operation code and 16-bit id | -| IMM16 | 8-bit operation code and 16-bit immediate | -| IMM16_ID16 | 8-bit operation code, 16-bit immediate, and 16-bit id | -| IMM16_ID16_ID16_IMM16_V8 | 8-bit operation code, 16-bit immediate, two 16-bit id, 16-bit immediate, and 8-bit register | -| IMM16_ID16_IMM8 | 8-bit operation code, 16-bit immediate, 16-bit id, and 8-bit immediate | -| IMM16_ID16_V8 | 8-bit operation code, 16-bit immediate, 16-bit id, and 8-bit register | -| IMM16_IMM16 | 8-bit operation code and two 16-bit immediates | -| IMM16_IMM8_V8 | 8-bit operation code, 16-bit immediate, 8-bit immediate, and 8-bit register | -| IMM16_V8 | 8-bit operation code, 16-bit immediate, and 8-bit register | -| IMM16_V8_IMM16 | 8-bit operation code, 16-bit immediate, 8-bit register, and 16-bit immediate | -| IMM16_V8_V8 | 8-bit operation code, 16-bit immediate, and two 8-bit registers | -| IMM32 | 8-bit operation code and 32-bit immediate | -| IMM4_IMM4 | 8-bit operation code, two 4-bit immediates | -| IMM64 | 8-bit operation code and 64-bit immediate | -| IMM8 | 8-bit operation code and 8-bit immediate | -| IMM8_ID16 | 8-bit operation code, 8-bit immediate, and 16-bit id | -| IMM8_ID16_ID16_IMM16_V8 | 8-bit operation code, 8-bit immediate, two 16-bit id, 16-bit immediate, and 8-bit register | -| IMM8_ID16_IMM8 | 8-bit operation code, 8-bit immediate, 16-bit id, 8-bit immediate | -| IMM8_ID16_V8 | 8-bit operation code, 8-bit immediate, 16-bit id, and 8-bit register | -| IMM8_IMM16 | 8-bit operation code, 8-bit immediate, and 16-bit immediate | -| IMM8_IMM8 | 8-bit operation code, two 8-bit immediates | -| IMM8_IMM8_V8 | 8-bit operation code, two 8-bit immediates, and 8-bit register | -| IMM8_V8 | 8-bit operation code, 8-bit immediate, and 8-bit register | -| IMM8_V8_IMM16 | 8-bit operation code, 8-bit immediate, 8-bit register, and 16-bit immediate | -| IMM8_V8_V8 | 8-bit operation code, 8-bit immediate, and two 8-bit registers | -| IMM8_V8_V8_V8 | 8-bit operation code, 8-bit immediate, and three 8-bit registers | -| IMM8_V8_V8_V8_V8 | 8-bit operation code, 8-bit immediate, and four 8-bit registers | +| IMM16 | 8-bit operation code and 16-bit immediate value | +| IMM16_ID16 | 8-bit operation code, 16-bit immediate value, and 16-bit id | +| IMM16_ID16_ID16_IMM16_V8 | 8-bit operation code, 16-bit immediate value, two 16-bit id, 16-bit immediate value, and 8-bit register | +| IMM16_ID16_IMM8 | 8-bit operation code, 16-bit immediate value, 16-bit id, and 8-bit immediate value | +| IMM16_ID16_V8 | 8-bit operation code, 16-bit immediate value, 16-bit id, and 8-bit register | +| IMM16_IMM16 | 8-bit operation code and two 16-bit immediate values | +| IMM16_IMM8_V8 | 8-bit operation code, 16-bit immediate value, 8-bit immediate value, and 8-bit register | +| IMM16_V8 | 8-bit operation code, 16-bit immediate value, and 8-bit register | +| IMM16_V8_IMM16 | 8-bit operation code, 16-bit immediate value, 8-bit register, and 16-bit immediate value | +| IMM16_V8_V8 | 8-bit operation code, 16-bit immediate value, and two 8-bit registers | +| IMM32 | 8-bit operation code and 32-bit immediate value | +| IMM4_IMM4 | 8-bit operation code and two 4-bit immediate values | +| IMM64 | 8-bit operation code and 64-bit immediate value | +| IMM8 | 8-bit operation code and 8-bit immediate value | +| IMM8_ID16 | 8-bit operation code, 8-bit immediate value, and 16-bit id | +| IMM8_ID16_ID16_IMM16_V8 | 8-bit operation code, 8-bit immediate value, two 16-bit id, 16-bit immediate value, and 8-bit register | +| IMM8_ID16_IMM8 | 8-bit operation code, 8-bit immediate value, 16-bit id, 8-bit immediate value | +| IMM8_ID16_V8 | 8-bit operation code, 8-bit immediate value, 16-bit id, and 8-bit register | +| IMM8_IMM16 | 8-bit operation code, 8-bit immediate value, and 16-bit immediate value | +| IMM8_IMM8 | 8-bit operation code and two 8-bit immediate values | +| IMM8_IMM8_V8 | 8-bit operation code, two 8-bit immediate values, and 8-bit register | +| IMM8_V8 | 8-bit operation code, 8-bit immediate value, and 8-bit register | +| IMM8_V8_IMM16 | 8-bit operation code, 8-bit immediate value, 8-bit register, and 16-bit immediate value | +| IMM8_V8_V8 | 8-bit operation code, 8-bit immediate value, and two 8-bit registers | +| IMM8_V8_V8_V8 | 8-bit operation code, 8-bit immediate value, and three 8-bit registers | +| IMM8_V8_V8_V8_V8 | 8-bit operation code, 8-bit immediate value, and four 8-bit registers | | NONE | 8-bit operation code | -| PREF_IMM16 | 16-bit prefix operation code, 16-bit immediate | -| PREF_IMM16_ID16 | 16-bit prefix operation code, 16-bit immediate, and 16-bit id | -| PREF_IMM16_V8 | 16-bit prefix operation code, 16-bit immediate, and 8-bit register | -| PREF_IMM16_V8_V8 | 16-bit prefix operation code, 16-bit immediate, and two 8-bit registers | -| PREF_IMM8 | 16-bit prefix operation code and 8-bit immediate | -| PREF_NONE | 16-bit prefix operation code | -| PREF_V8 | 16-bit prefix operation code and 8-bit register | -| PREF_V8_ID16 | 16-bit prefix operation code, 8-bit register, and16-bit id | -| PREF_V8_IMM32 | 16-bit prefix operation code, 8-bit register, and 32-bit immediate | +| PREF_IMM16 | 16-bit prefixed operation code, 16-bit immediate value | +| PREF_IMM16_ID16 | 16-bit prefixed operation code, 16-bit immediate value, and 16-bit id | +| PREF_IMM16_V8 | 16-bit prefixed operation code, 16-bit immediate value, and 8-bit register | +| PREF_IMM16_V8_V8 | 16-bit prefixed operation code, 16-bit immediate value, and two 8-bit registers | +| PREF_IMM8 | 16-bit prefixed operation code and 8-bit immediate value | +| PREF_NONE | 16-bit prefixed operation code | +| PREF_V8 | 16-bit prefixed operation code and 8-bit register | +| PREF_V8_ID16 | 16-bit prefixed operation code, 8-bit register, and 16-bit id | +| PREF_V8_IMM32 | 16-bit prefixed operation code, 8-bit register, and 32-bit immediate value | | V16_V16 | 8-bit operation code and two 16-bit registers | | V4_V4 | 8-bit operation code and two 4-bit registers | | V8 | 8-bit operation code and 8-bit register | -| V8_IMM16 | 8-bit operation code, 8-bit register, and 16-bit immediate | -| V8_IMM8 | 8-bit operation code, 8-bit register, and 8-bit immediate | +| V8_IMM16 | 8-bit operation code, 8-bit register, and 16-bit immediate value | +| V8_IMM8 | 8-bit operation code, 8-bit register, and 8-bit immediate value | | V8_V8 | 8-bit operation code and two 8-bit registers | | V8_V8_V8 | 8-bit operation code and three 8-bit registers | | V8_V8_V8_V8 | 8-bit operation code and four 8-bit registers | ## Bytecode Summary -The table below summarizes all Ark Bytecodes in the current version. The register index, immediate, and id are described in the form of one character for every four-bit width.
-Take the *defineclasswithbuffer RR, @AAAA, @BBBB, +CCCC, vDD* instruction as an example:
-* *defineclasswithbuffer*: indicates the operation code mnemonic. -* *RR*: 8-bit reserved number used internally during Ark runtime. The number mentioned here is just an example showing a complete instruction format. +The table below summarizes all Ark bytecode instructions in the current version. The register index, immediate value, and id are described using a character to represent each four-bit width.
+For example, consider the instruction *defineclasswithbuffer RR, @AAAA, @BBBB, +CCCC, vDD*:
+* *defineclasswithbuffer*: mnemonic for the operation code. +* *RR*: 8-bit reserved number used internally during the Ark runtime. The number mentioned here is just an example showing a complete instruction format. * *@AAAA, @BBBB*: 16-bit id -* *+CCCC*: 16-bit immediate +* *+CCCC*: 16-bit immediate value * *vDD*: 8-bit register index | Operation Code | Format | Mnemonic/Syntax | Parameters | Description | | ------- | ------- | ---------- | ---------- | -------- | -| 0x00 | NONE | ldundefined | | Load **undefined** to **acc**. | -| 0x01 | NONE | ldnull | | Load **null** to **acc**. | -| 0x02 | NONE | ldtrue | | Load **true** to **acc**. | -| 0x03 | NONE | ldfalse | | Load **false** to **acc**. | -| 0x04 | NONE | createemptyobject | | Create an empty object and store it in **acc**. | -| 0x05 | IMM8| createemptyarray RR | R: 8-bit reserved number used in Ark runtime| Create an empty array and store it in **acc**. | -| 0x06 | IMM8_ID16 | createarraywithbuffer RR, @AAAA | R: 8-bit reserved number used in Ark runtime
A: 16-bit literal id| Use the literal array corresponding to index A to create an array object and store it in **acc**. | -| 0x07 | IMM8_ID16 | createobjectwithbuffer RR, @AAAA | R: 8-bit reserved number used in Ark runtime
A: 16-bit literal id| Use the literal array corresponding to index A to create an object and store it in **acc**. | -| 0x08 | IMM8_IMM8_V8 | newobjrange RR, +AA, vBB | R: 8-bit reserved number used in Ark runtime
A: number of parameters
B: class object
B + 1, ..., B + A - 1: parameter passed to the constructor| Use **B + 1, ..., B + A - 1** as a parameter to create an instance of class B and store it in **acc**. | -| 0x09 | IMM8 | newlexenv +AA | A: number of slots in the lexical environment| Create a lexical environment with slot A, store it in **acc**, and enter the lexical environment. | -| 0x0a | IMM8_V8 | add2 RR, vAA | Default input parameter: acc: operand
R: 8-bit reserved number used in Ark runtime
A: operand| Calculate **A + acc** and store the result in **acc**. | -| 0x0b | IMM8_V8 | sub2 RR, vAA | Default input parameter: acc: operand
R: 8-bit reserved number used in Ark runtime
A: operand| Calculate **A - acc** and store the result in **acc**. | -| 0x0c | IMM8_V8 | mul2 RR, vAA | Default input parameter: acc: operand
R: 8-bit reserved number used in Ark runtime
A: operand| Calculate **A * acc** and store the result in **acc**. | -| 0x0d | IMM8_V8 | div2 RR, vAA | Default input parameter: acc: operand
R: 8-bit reserved number used in Ark runtime
A: operand| Calculate **A / acc** and store the result in **acc**. | -| 0x0e | IMM8_V8 | mod2 RR, vAA | Default input parameter: acc: operand
R: 8-bit reserved number used in Ark runtime
A: operand| Calculate **A % acc** and store the result in **acc**. | -| 0x0f | IMM8_V8 | eq RR, vAA | Default input parameter: acc: operand
R: 8-bit reserved number used in Ark runtime
A: operand| Calculate **A == acc** and store the result in **acc**. | -| 0x10 | IMM8_V8 | noteq RR, vAA | Default input parameter: acc: operand
R: 8-bit reserved number used in Ark runtime
A: operand| Calculate **A != acc** and store the result in **acc**. | -| 0x11 | IMM8_V8 | less RR, vAA | Default input parameter: acc: operand
R: 8-bit reserved number used in Ark runtime
A: operand| Calculate **A < acc** and store the result in **acc**. | -| 0x12 | IMM8_V8 | lesseq RR, vAA | Default input parameter: acc: operand
R: 8-bit reserved number used in Ark runtime
A: operand| Calculate **A <= acc** and store the result in **acc**. | -| 0x13 | IMM8_V8 | greater RR, vAA | Default input parameter: acc: operand
R: 8-bit reserved number used in Ark runtime
A: operand| Calculate **A > acc** and store the result in **acc**. | -| 0x14 | IMM8_V8 | greatereq RR, vAA | Default input parameter: acc: operand
R: 8-bit reserved number used in Ark runtime
A: operand| Calculate **A >= acc** and store the result in **acc**. | -| 0x15 | IMM8_V8 | shl2 RR, vAA | Default input parameter: acc: operand
R: 8-bit reserved number used in Ark runtime
A: operand| Calculate **A << acc** and store the result in **acc**. | -| 0x16 | IMM8_V8 | shr2 RR, vAA | Default input parameter: acc: operand
R: 8-bit reserved number used in Ark runtime
A: operand| Calculate **A >>> acc** and store the result in **acc**. | -| 0x17 | IMM8_V8 | ashr2 RR, vAA | Default input parameter: acc: operand
R: 8-bit reserved number used in Ark runtime
A: operand| Calculate **A >> acc** and store the result in **acc**. | -| 0x18 | IMM8_V8 | and2 RR, vAA | Default input parameter: acc: operand
R: 8-bit reserved number used in Ark runtime
A: operand| Calculate **A & acc** and store the result in **acc**. | -| 0x19 | IMM8_V8 | or2 RR, vAA | Default input parameter: acc: operand
R: 8-bit reserved number used in Ark runtime
A: operand| Calculate'A\| **acc`** and store the result in **acc**. | -| 0x1a | IMM8_V8 | xor2 RR, vAA | Default input parameter: acc: operand
R: 8-bit reserved number used in Ark runtime
A: operand| Calculate **A ^ acc** and store the result in **acc**. -| 0x1b | IMM8_V8 | exp RR, vAA | Default input parameter: acc: operand
R: 8-bit reserved number used in Ark runtime
A: operand| Calculate **A ** acc** and store the result in **acc**. | -| 0x1c | IMM8 | typeof RR | Default input parameter: acc: object
R: 8-bit reserved number used in Ark runtime| Calculate **typeof acc** and store the result in **acc**. | -| 0x1d | IMM8 | tonumber RR | Default input parameter: acc: object
R: 8-bit reserved number used in Ark runtime| Use **acc** as a parameter, execute [ToNumber](https://262.ecma-international.org/12.0/#sec-tonumber), and store the result in **acc**. | -| 0x1e | IMM8 | tonumeric RR | Default input parameter: acc: object
R: 8-bit reserved number used in Ark runtime| Use **acc** as a parameter, execute [ToNumeric](https://262.ecma-international.org/12.0/#sec-tonumeric), and store the result in **acc**. | -| 0x1f | IMM8 | neg RR | Default input parameter: acc: operand
R: 8-bit reserved number used in Ark runtime| Calculate **-acc** and store the result in **acc**. | -| 0x20 | IMM8 | not RR | Default input parameter: acc: operand
R: 8-bit reserved number used in Ark runtime| Calculate **~acc** and store the result in **acc**. | -| 0x21 | IMM8 | inc RR | Default input parameter: acc: operand
R: 8-bit reserved number used in Ark runtime| Calculate **acc + 1** and store the result in **acc**. | -| 0x22 | IMM8 | dec RR | Default input parameter: acc: operand
R: 8-bit reserved number used in Ark runtime| Calculate **acc - 1** and store the result in **acc**. | -| 0x23 | NONE | istrue | Default input parameter: acc: object| Calculate **acc == true** and store the result in **acc**. | -| 0x24 | NONE | isfalse | Default input parameter: acc: object| Calculate **acc == false** and store the result in **acc**. | -| 0x25 | IMM8_V8 | isin RR, vAA | Default input parameter: acc: object
R: 8-bit reserved number used in Ark runtime
A: Object| Calculate **A in acc** and store the result in **acc**. | -| 0x26 | IMM8_V8 | instanceof RR, vAA | Default input parameter: acc: object
R: 8-bit reserved number used in Ark runtime
A: Object| Calculate **A instanceof acc** and store the result in **acc**. | -| 0x27 | IMM8_V8 | strictnoteq RR, vAA | Default input parameter: acc: object
R: 8-bit reserved number used in Ark runtime
A: Object| Calculate **acc !== A** and store the result in **acc**. | -| 0x28 | IMM8_V8 | stricteq RR, vAA | Default input parameter: acc: object
R: 8-bit reserved number used in Ark runtime
A: Object| Calculate **acc === A** and store the result in **acc**. | -| 0x29 | IMM8 | callarg0 RR | Default input parameter: acc: function object
R: 8-bit reserved number used in Ark runtime| Directly call the function object stored in **acc** without passing parameters and store the result in **acc**. | -| 0x2a | IMM8_V8 | callarg1 RR, vAA | Default input parameter: acc: function object
R: 8-bit reserved number used in Ark runtime
A: Parameter| Use **A** as a parameter to call the function object stored in **acc** and store the result in **acc**. | -| 0x2b | IMM8_V8_V8 | callargs2 RR, vAA, vBB | Default input parameter: acc: function object
R: 8-bit reserved number used in Ark runtime
A and B: parameters| Use **A** and **B** as parameters to call the function object stored in **acc** and store the result in **acc**. | -| 0x2c | IMM8_V8_V8_V8 | callargs3 RR, vAA, vBB, vCC | Default input parameter: acc: function object
R: 8-bit reserved number used in Ark runtime
A, B, C: parameter| Use **A**, **B**, and **C** as parameters to call the function object stored in **acc** and store the result in **acc**. | -| 0x2d | IMM8_V8 | callthis0 RR, vAA | Default input parameter: acc: function object
R: 8-bit reserved number used in Ark runtime
A: Object| Set **this** to **A**, call the function object stored in **acc** without passing parameters, and store the result in **acc**. | -| 0x2e | IMM8_V8_V8 | callthis1 RR, vAA, vBB | Default input parameter: acc: function object
R: 8-bit reserved number used in Ark runtime
A: Object
B: parameter| Set **this** to **A**, call the function object stored in **acc** by setting **B** as the parameter, and store the result in **acc**. | -| 0x2f | IMM8_V8_V8_V8 | callthis2 RR, vAA, vBB, vCC | Default input parameter: acc: function object
R: 8-bit reserved number used in Ark runtime
A: Object
B, C: parameter | Set **this** to **A**, call the function object stored in **acc** by setting **B** and **C** as parameters, and store the result in **acc**. | -| 0x30 | IMM8_V8_V8_V8_V8 | callthis3 RR, vAA, vBB, vCC, vDD | Default input parameter: acc: function object
R: 8-bit reserved number used in Ark runtime
A: Object
B, C, D: parameter | Set **this** to **A**, call the function object stored in **acc** by setting **B**, **C**, and **D** as parameters, and store the result in **acc**. | -| 0x31 | IMM8_IMM8_V8 | callthisrange RR, +AA, vBB | Default input parameter: acc: function object
R: 8-bit reserved number used in Ark runtime
A: number of parameters
B: object
B + 1, ..., B + A: parameter| Set **this** to **B**, call the function object stored in **acc** by setting **B + 1, ..., B + A** as the parameter, and store the result in **acc**. | -| 0x32 | IMM8_IMM8_V8 | supercallthisrange RR, +AA, vBB | R: 8-bit reserved number used in Ark runtime
A: number of parameters
B, ..., B + A - 1: parameter| Use **B, ..., B + A - 1** as the parameter to call the **super** function and store the result in **acc**.
When the value of **A** is **0**, the value of **B** is **undefined**.
This instruction appears only in non-arrow functions. | -| 0x33 | IMM8_ID16_IMM8 | definefunc RR, @AAAA, +BB | R: 8-bit reserved number used in Ark runtime
A: method id
B: number of formal parameters of method A| Create the function object of method A and store it in **acc**. | -| 0x34 | IMM8_ID16_IMM8 | definemethod RR, @AAAA, +BB | Default input parameter: acc: class object or its prototype. When the static method is used, the parameter is a class object in **acc**.
R: 8-bit reserved number used in Ark runtime
A: method id
B: number of formal parameters of method A | Create the function object of method A, set the object of **acc** to the [HomeObject](https://262.ecma-international.org/12.0/#sec-ecmascript-function-objects) attribute of the function object, and store this function object in **acc**. | -| 0x35 | IMM8_ID16_ID16_IMM16_V8 | defineclasswithbuffer RR, @AAAA, @BBBB, +CCCC, vDD | R: 8-bit reserved number used in Ark runtime
A: **method id** of the constructor of a class
B: literal id
C: number of formal parameters of method A
D: parent class| Use the literal array corresponding to index B and parent class D to create a class object of A and store it in **acc**. | -| 0x36 | V8 | getnextpropname vAA | A: iterator| Execute the [next](https://262.ecma-international.org/12.0/#sec-%25foriniteratorprototype%25.next) method of [for-in iterator](https://262.ecma-international.org/12.0/#sec-createiterresultobject) A and store the result in **acc**. | -| 0x37 | IMM8_V8 | ldobjbyvalue RR, vAA | Default input parameter: acc: attribute key
R: 8-bit reserved number used in Ark runtime
A: Object| Load the attribute whose key is **acc** of object A and store the result in **acc**. -| 0x38 | IMM8_V8_V8 | stobjbyvalue RR, vAA, vBB | Default input parameter: acc: value
R: 8-bit reserved number used in Ark runtime
A: Object
B: attribute key| Store the value in **acc** to the attribute whose key is B of object A. | -| 0x39 | IMM8_V8 | ldsuperbyvalue RR, vAA | Default input parameter: acc: attribute key
R: 8-bit reserved number used in Ark runtime
A: Object| In the current function, obtain the attribute whose key of **super** is **acc** and store the attribute in **acc**. If the attribute is of an accessor, the object in A is used as the **this** parameter when the **getter** function of the attribute is called. | -| 0x3a | IMM8_IMM16 | ldobjbyindex RR, +AAAA | Default input parameter: acc: object
R: 8-bit reserved number used in Ark runtime
A: attribute key| Load the attribute whose key is A of the object stored in **acc** and store the attribute in **acc**. | -| 0x3b | IMM8_V8_IMM16 | stobjbyindex RR, vAA, +BBBB | Default input parameter: acc: value
R: 8-bit reserved number used in Ark runtime
A: Object
B: attribute key| Store the value in **acc** to the attribute whose key is B of object A. | -| 0x3c | IMM4_IMM4 | ldlexvar +A, +B | A: lexical environment level
B: slot number| Store the value of slot B in the lexical environment beyond A levels in **acc**. | -| 0x3d | IMM4_IMM4 | stlexvar +A, +B | Default input parameter: acc: value
A: lexical environment level
B: slot number| Store the value in **acc** to slot B in the lexical environment beyond A levels. | -| 0x3e | ID16 | lda.str @AAAA | A: string id| Store the string corresponding to index A to **acc**. | -| 0x3f | IMM8_ID16 | tryldglobalbyname RR, @AAAA | R: 8-bit reserved number used in Ark runtime
A: string id| Store the global variable whose name is the string corresponding to index A in **acc**. If the global variable named A does not exist, an exception is thrown. | -| 0x40 | IMM8_ID16 | trystglobalbyname RR, @AAAA | Default input parameter: acc: value
R: 8-bit reserved number used in Ark runtime
A: string id| Store the value in **acc** to the global variable whose name is the string corresponding to index A. If the global variable named A does not exist, an exception is thrown. | -| 0x41 | IMM16_ID16 | ldglobalvar RRRR, @AAAA | R: 16-bit reserved number used in Ark runtime
A: string id| Store the value of the global variable whose name is the string corresponding to index A in **acc**. The variable must exist. | -| 0x42 | IMM8_ID16 | ldobjbyname RR, @AAAA | Default input parameter: acc: object
R: 8-bit reserved number used in Ark runtime
A: string id| Load the attribute whose key of the object stored in **acc** is the string corresponding to index A and store the attribute in **acc**. | -| 0x43 | IMM8_ID16_V8 | stobjbyname RR, @AAAA, vBB | Default input parameter: acc: value
R: 8-bit reserved number used in Ark runtime
A: string id
B: object| Store the value of **acc** to the attribute whose key of object B is the string corresponding to index A. | -| 0x44 | V4_V4 | mov vA, vB | A, B: register index| Copy the contents in register B to register A. | -| 0x45 | V8_V8 | mov vAA, vBB | A, B: register index| Copy the contents in register B to register A. | -| 0x46 | IMM8_ID16 | ldsuperbyname RR, @AAAA | Default input parameter: acc: object
R: 8-bit reserved number used in Ark runtime
A: string id| In the current function, obtain the attribute whose key of **super** is the string corresponding to index A and store the attribute in **acc**. If the attribute is of an accessor, the object in **acc** is used as the **this** parameter when the **getter** function of the attribute is called. | -| 0x47 | IMM16_ID16 | stconsttoglobalrecord RRRR, @AAAA | Default input parameter: acc: value
R: 16-bit reserved number used in Ark runtime
A: string id| Store the value of **acc** to the constant of the string corresponding to index A defined by **const** in the global variable. | -| 0x48 | IMM16_ID16 | sttoglobalrecord RRRR, @AAAA | Default input parameter: acc: value
R: 16-bit reserved number used in Ark runtime
A: string id| Store the value of **acc** to the variable of the string corresponding to index A defined by **let** in the global variable. | -| 0x49 | IMM8_ID16 | ldthisbyname RR, @AAAA | R: 8-bit reserved number used in Ark runtime
A: string id| Load the attribute whose key of **this** is the string corresponding to index A and store the result in **acc**. | -| 0x4a | IMM8_ID16 | stthisbyname RR, @AAAA | Default input parameter: acc: value
R: 8-bit reserved number used in Ark runtime
A: string id| Store the value of **acc** to the attribute whose key of **this** is the string corresponding to index A. | -| 0x4b | IMM8 | ldthisbyvalue RR | Default input parameter: acc: attribute key
R: 8-bit reserved number used in Ark runtime| Load the attribute whose key of **this** is **acc** and store the result in **acc**. | -| 0x4c | IMM8_V8 | stthisbyvalue RR, vAA | Default input parameter: acc: value
R: 8-bit reserved number used in Ark runtime
A: attribute key| Store the value of **acc** to the attribute whose key of **this** is A. | -| 0x4d | IMM8 | jmp +AA | A: signed branch offset| Jump to branch A unconditionally. | -| 0x4e | IMM16 | jmp +AAAA | A: signed branch offset| Jump to branch A unconditionally. | -| 0x4f | IMM8 | jeqz +AA | Default input parameter: acc: value
A: signed branch offset| Calculate **acc == 0** and jump to branch A if it is true. | -| 0x50 | IMM16 | jeqz +AAAA | Default input parameter: acc: value
A: signed branch offset| Calculate **acc == 0** and jump to branch A if it is true. | -| 0x51 | IMM8 | jnez +AA | Default input parameter: acc: value
A: signed branch offset| Calculate **acc != 0** and jump to branch A if it is true. | -| 0x52 | IMM8 | jstricteqz +AA | Default input parameter: acc: value
A: signed branch offset| Calculate **acc === 0** and jump to branch A if it is true.
The instruction feature is disabled and is unavailable currently. | -| 0x53 | IMM8 | jnstricteqz +AA | Default input parameter: acc: value
A: signed branch offset| Calculate **acc !== 0** and jump to branch A if it is true.
The instruction feature is disabled and is unavailable currently. | -| 0x54 | IMM8 | jeqnull +AA | Default input parameter: acc: value
A: signed branch offset| Calculate **acc == null** and jump to branch A if it is true.
The instruction feature is disabled and is unavailable currently. | -| 0x55 | IMM8 | jnenull +AA | Default input parameter: acc: value
A: signed branch offset| Calculate **acc != null** and jump to branch A if it is true.
The instruction feature is disabled and is unavailable currently. | -| 0x56 | IMM8 | jstricteqnull +AA | Default input parameter: acc: value
A: signed branch offset| Calculate **acc === null** and jump to branch A if it is true.
The instruction feature is disabled and is unavailable currently. | -| 0x57 | IMM8 | jnstricteqnull +AA | Default input parameter: acc: value
A: signed branch offset| Calculate **acc !== null** and jump to branch A if it is true.
The instruction feature is disabled and is unavailable currently. | -| 0x58 | IMM8 | jequndefined +AA | Default input parameter: acc: value
A: signed branch offset| Calculate **acc == undefined** and jump to branch A if it is true.
The instruction feature is disabled and is unavailable currently. | -| 0x59 | IMM8 | jneundefined +AA | Default input parameter: acc: value
A: signed branch offset| Calculate **acc != undefined** and jump to branch A if it is true.
The instruction feature is disabled and is unavailable currently. | -| 0x5a | IMM8 | jstrictequndefined +AA | Default input parameter: acc: value
A: signed branch offset| Calculate **acc === undefined** and jump to branch A if it is true.
The instruction feature is disabled and is unavailable currently. | -| 0x5b | IMM8 | jnstrictequndefined +AA | Default input parameter: acc: value
A: signed branch offset| Calculate **acc !== undefined** and jump to branch A if it is true.
The instruction feature is disabled and is unavailable currently. | -| 0x5c | V8_IMM8 | jeq vAA, +BB | Default input parameter: acc: value
A: value
B: signed branch offset| Calculate **acc == A** and jump to branch B if it is true.
The instruction feature is disabled and is unavailable currently. | -| 0x5d | V8_IMM8 | jne vAA, +BB | Default input parameter: acc: value
A: value
B: signed branch offset| Calculate **acc != A** and jump to branch B if it is true.
The instruction feature is disabled and is unavailable currently. | -| 0x5e | V8_IMM8 | jstricteq vAA, +BB | Default input parameter: acc: object
A: Object
B: signed branch offset| Calculate **acc === A** and jump to branch B if it is true.
The instruction feature is disabled and is unavailable currently. | -| 0x5f | V8_IMM8 | jnstricteq vAA, +BB | Default input parameter: acc: object
A: Object
B: signed branch offset| Calculate **acc !== A** and jump to branch B if it is true.
The instruction feature is disabled and is unavailable currently. | -| 0x60 | V8 | lda vAA | A: register index| Store the contents of register A in **acc**. | -| 0x61 | V8 | sta vAA | Default input parameter: acc
A: register index| Store the contents of acc in register A. | -| 0x62 | IMM32 | ldai +AAAAAAAA | A: constant literal| Store the integer literal A in **acc**. | -| 0x63 | IMM64 | fldai +AAAAAAAAAAAAAAAA | A: constant literal| Store the double-precision floating-point literal A in **acc**. | -| 0x64 | NONE | return | Default input parameter: acc: value| Returns the value in **acc**. | -| 0x65 | NONE | returnundefined | | **undefined** is returned. | -| 0x66 | NONE | getpropiterator | Default input parameter: acc: object| Stores the [for-in iterator](https://262.ecma-international.org/12.0/#sec-createiterresultobject) of the object in **acc**. | -| 0x67 | IMM8 | getiterator RR | Default input parameter: acc: object
R: 8-bit reserved number used in Ark runtime| Execute the [GetIterator](https://262.ecma-international.org/12.0/#sec-getiterator) (acc, sync) method and store the result in **acc**. | -| 0x68 | IMM8_V8 | closeiterator RR, vAA | R: 8-bit reserved number used in Ark runtime
A: Object| Use A of the *[iteratorRecord](https://262.ecma-international.org/12.0/#sec-iterator-records)* type as a parameter to execute [IteratorClose](https://262.ecma-international.org/12.0/#sec-iteratorclose) and store the result in **acc**. | -| 0x69 | NONE | poplexenv | | Jump out of the current lexical environment and enter the outer lexical environment. | -| 0x6a | NONE | ldnan | | Store the **nan** value in **acc**. | -| 0x6b | NONE | ldinfinity | | Store the **infinity** value in **acc**. | -| 0x6c | NONE | getunmappedargs | | Store the **arguments** of the current function in **acc**. | -| 0x6d | NONE | ldglobal | | Store the **global** object in **acc**.| -| 0x6e | NONE | ldnewtarget | | Store the **NewTarget** implicit parameter of the current function in **acc**.
The instruction feature is disabled and is unavailable currently. | -| 0x6f | NONE | ldthis | | Store the this value in **acc**. | -| 0x70 | NONE | ldhole | | Store the **hole** in **acc**. | -| 0x71 | IMM8_ID16_IMM8 | createregexpwithliteral RR, @AAAA, +BB | R: 8-bit reserved number used in Ark runtime
A: string id
B: regular expression modifier| Use the string corresponding to index A and the modifier corresponding to index B to create a regular expression and store it in **acc**.
The correspondence between B and a specified modifier is: 0 (default value with no modifier), 1 (g), 2 (i), 4 (m), 8 (s), 16 (u), 32 (y); B may also refer to a combination of modifiers that comply with syntax specifications, for example, **3** and its modifier is **gi**. | -| 0x72 | IMM16_ID16_IMM8 | createregexpwithliteral RRRR, @AAAA, +BB | R: 16-bit reserved number used in Ark runtime
A: string id
B: regular expression modifier| Use the string corresponding to index A and the modifier corresponding to index B to create a regular expression and store it in **acc**.
The correspondence between B and a specified modifier is: 0 (default value with no modifier), 1 (g), 2 (i), 4 (m), 8 (s), 16 (u), 32 (y); B may also refer to a combination of modifiers that comply with syntax specifications, for example, **3** and its modifier is **gi**. | -| 0x73 | IMM8_IMM8_V8 | callrange RR, +AA, vBB | Default input parameter: acc: function object
R: 8-bit reserved number used in Ark runtime
A: number of parameters
B, ..., B + A - 1: parameter| Use **B, ..., B + A - 1** as a parameter to call the function object stored in **acc** and store the result in **acc**. | -| 0x74 | IMM16_ID16_IMM8 | definefunc RRRR, @AAAA, +BB | R: 16-bit reserved number used in Ark runtime
A: method id
B: number of formal parameters of method A| Create the function object of method A and store it in **acc**. | -| 0x75 | IMM16_ID16_ID16_IMM16_V8 | defineclasswithbuffer RRRR, @AAAA, @BBBB, +CCCC, vDD | R: 16-bit reserved number used in Ark runtime
A: **method id** of the constructor of a class
B: literal id
C: number of formal parameters of method A
D: parent class| Use the literal array corresponding to index B and parent class D to create a class object of A and store it in **acc**. | -| 0x76 | IMM8 | gettemplateobject RR | Default input parameter: acc: object
R: 8-bit reserved number used in Ark runtime| Execute [GetTemplateObject](https://262.ecma-international.org/12.0/#sec-gettemplateobject) (acc) and store the result in **acc**. | -| 0x77 | IMM8_V8 | setobjectwithproto RR, vAA | Default input parameter: acc: object
R: 8-bit reserved number used in Ark runtime
A: value| Set the **\_\_proto\_\_** attribute of the object stored in **acc** to A. | -| 0x78 | IMM8_V8_V8 | stownbyvalue RR, vAA, vBB | Default input parameter: acc: value
R: 8-bit reserved number used in Ark runtime
A: Object
B: attribute key| Store the value in **acc** to the attribute whose key is B of object A. | -| 0x79 | IMM8_V8_IMM16 | stownbyindex RR, vAA, +BBBB | Default input parameter: acc: value
R: 8-bit reserved number used in Ark runtime
A: Object
B: attribute key| Store the value in **acc** to the attribute whose key is B of object A. | -| 0x7a | IMM8_ID16_V8 | stownbyname RR, @AAAA, vBB | Default input parameter: acc: value
R: 8-bit reserved number used in Ark runtime
A: string id
B: object| Store the value of **acc** to the attribute whose key of object B is the string corresponding to index A. | -| 0x7b | IMM8 | getmodulenamespace +AA | A: module index| Execute the [GetModuleNamespace](https://262.ecma-international.org/12.0/#sec-getmodulenamespace) instruction for module A and store the result in **acc**. | -| 0x7c | IMM8 | stmodulevar +AA | Default input parameter: acc: value
A: slot number| Store the value of **acc** to the module variable of slot A. | -| 0x7d | IMM8 | ldlocalmodulevar +AA | A: slot number| Store the local module variables of slot A in **acc**. | -| 0x7e | IMM8 | ldexternalmodulevar +AA | A: slot number| Store the external module variable of slot A in **acc**. | -| 0x7f | IMM16_ID16 | stglobalvar RRRR, @AAAA | Default input parameter: acc: value
R: 16-bit reserved number used in Ark runtime
A: string id| Store the value in **acc** to the global variable whose name is the string corresponding to index A. This variable must exist. | -| 0x80 | IMM16 | createemptyarray RRRR | R: 16-bit reserved number used in Ark runtime| Create an empty array and store it in **acc**. | -| 0x81 | IMM16_ID16 | createarraywithbuffer RRRR, @AAAA | R: 16-bit reserved number used in Ark runtime
A: literal id| Use the literal array corresponding to index A to create an array object and store it in **acc**. | -| 0x82 | IMM16_ID16 | createobjectwithbuffer RRRR, @AAAA | R: 16-bit reserved number used in Ark runtime
A: literal id| Use the literal array corresponding to index A to create an object and store it in **acc**. | -| 0x83 | IMM16_IMM8_V8 | newobjrange RRRR, +AA, vBB | R: 16-bit reserved number used in Ark runtime
A: number of parameters
B: class object
B + 1, ..., B + A - 1: parameter passed to the constructor| Use **B + 1, ..., B + A - 1** as a parameter to create an instance of class B and store it in **acc**. | -| 0x84 | IMM16 | typeof RRRR | Default input parameter: acc: object
R: 16-bit reserved number used in Ark runtime| Calculate **typeof acc** and store the result in **acc**. | -| 0x85 | IMM16_V8 | ldobjbyvalue RRRR, vAA | Default input parameter: acc: attribute key
R: 16-bit reserved number used in Ark runtime
A: Object| Load the attribute whose key is **acc** of object A and store the result in **acc**. | -| 0x86 | IMM16_V8_V8 | stobjbyvalue RRRR, vAA, vBB | Default input parameter: acc: value
R: 16-bit reserved number used in Ark runtime
A: Object
B: attribute key| Store the value in **acc** to the attribute whose key is B of object A. | -| 0x87 | IMM16_V8 | ldsuperbyvalue RRRR, vAA | Default input parameter: acc: attribute key
R: 16-bit reserved number used in Ark runtime
A: Object| In the current function, obtain the attribute whose key of **super** is **acc** and store the attribute in **acc**. If the attribute is of an accessor, the object in A is used as the **this** parameter when the **getter** function of the attribute is called. | -| 0x88 | IMM16_IMM16 | ldobjbyindex RRRR, +AAAA | Default input parameter: acc: object
R: 16-bit reserved number used in Ark runtime
A: attribute key| Load the attribute whose key is A of the object stored in **acc** and store the attribute in **acc**. | -| 0x89 | IMM16_V8_IMM16 | stobjbyindex RRRR, vAA, +BBBB | Default input parameter: acc: value
R: 16-bit reserved number used in Ark runtime
A: Object
B: attribute key| Store the value in **acc** to the attribute whose key is B of object A. | -| 0x8a | IMM8_IMM8 | ldlexvar +AA, +BB | A: lexical environment level
B: slot number| Store the value of slot B in the lexical environment beyond A levels in **acc**. | -| 0x8b | IMM8_IMM8 | stlexvar +AA, +BB | Default input parameter: acc: value
A: lexical environment level
B: slot number| Store the value in **acc** to slot B in the lexical environment beyond A levels. | -| 0x8c | IMM16_ID16 | tryldglobalbyname RRRR, @AAAA | R: 16-bit reserved number used in Ark runtime
A: string id| Store the global variable whose name is the string corresponding to index A in **acc**. If the global variable named A does not exist, an exception is thrown. | -| 0x8d | IMM16_ID16 | trystglobalbyname RRRR, @AAAA | Default input parameter: acc: value
R: 16-bit reserved number used in Ark runtime
A: string id| Store the value in **acc** to the global variable whose name is the string corresponding to index A. If the global variable named A does not exist, an exception is thrown. | -| 0x8e | IMM8_ID16_V8 | stownbynamewithnameset RR, @AAAA, vBB | Default input parameter: acc: function object
R: 8-bit reserved number used in Ark runtime
A: string id
B: object| Store the function object in **acc** to the attribute whose key of object B is the string corresponding to index A and set the function name to the string corresponding to index A. | -| 0x8f | V16_V16 | mov vAAAA, vBBBB | A, B: register index| Copy the contents in register B to register A. | -| 0x90 | IMM16_ID16 | ldobjbyname RRRR, @AAAA | Default input parameter: acc: object
R: 16-bit reserved number used in Ark runtime
A: string id| Load the attribute whose key of the object stored in **acc** is the string corresponding to index A and store the attribute in **acc**. | -| 0x91 | IMM16_ID16_V8 | stobjbyname RRRR, @AAAA, vBB | Default input parameter: acc: value
R: 16-bit reserved number used in Ark runtime
A: string id
B: object| Store the value of **acc** to the attribute whose key of object B is the string corresponding to index A. | -| 0x92 | IMM16_ID16 | ldsuperbyname RRRR, @AAAA | Default input parameter: acc: object
R: 16-bit reserved number used in Ark runtime
A: string id| In the current function, obtain the attribute whose key of **super** is the string corresponding to index A and store the attribute in **acc**. If the attribute is of an accessor, the object in **acc** is used as the **this** parameter when the **getter** function of the attribute is called. | -| 0x93 | IMM16_ID16 | ldthisbyname RRRR, @AAAA | R: 16-bit reserved number used in Ark runtime
A: string id| Load the attribute whose key of **this** is the string corresponding to index A and store the result in **acc**. | -| 0x94 | IMM16_ID16 | stthisbyname RRRR, @AAAA | Default input parameter: acc: value
R: 16-bit reserved number used in Ark runtime
A: string id| Store the value of **acc** to the attribute whose key of **this** is the string corresponding to index A. | -| 0x95 | IMM16 | ldthisbyvalue RRRR | Default input parameter: acc: attribute key
R: 16-bit reserved number used in Ark runtime| Load the attribute whose key of **this** is **acc** and store the result in **acc**. | -| 0x96 | IMM16_V8 | stthisbyvalue RRRR, vAA | Default input parameter: acc: value
R: 16-bit reserved number used in Ark runtime
A: attribute key| Store the value of **acc** to the attribute whose key of **this** is A. | -| 0x97 | V8 | asyncgeneratorreject vAA | Default input parameter: acc: exception
A: generator| Use the exception stored in *[generator](https://262.ecma-international.org/12.0/#sec-generator-objects)* A and **acc**, execute [AsyncGeneratorReject](https://262.ecma-international.org/12.0/#sec-asyncgeneratorreject), and store the result in **acc**. | -| 0x98 | IMM32 | jmp +AAAAAAAA | A: signed branch offset| Jump to branch A unconditionally. | -| 0x99 | IMM8_V8_V8 | stownbyvaluewithnameset RR, vAA, vBB | Default input parameter: acc: function object
R: 8-bit reserved number used in Ark runtime
A: Object
B: attribute key| Store the value of **acc** to the attribute whose key of object A is B and set the function name to B. | -| 0x9a | IMM32 | jeqz +AAAAAAAA | Default input parameter: acc: value
A: signed branch offset| Calculate **acc == 0** and jump to branch A if it is true. | -| 0x9b | IMM16 | jnez +AAAA | Default input parameter: acc: value
A: signed branch offset| Calculate **acc != 0** and jump to branch A if it is true. | -| 0x9c | IMM32 | jnez +AAAAAAAA | Default input parameter: acc: value
A: signed branch offset| Calculate **acc != 0** and jump to branch A if it is true. | -| 0x9d | IMM16 | jstricteqz +AAAA | Default input parameter: acc: value
A: signed branch offset| Calculate **acc === 0** and jump to branch A if it is true.
The instruction feature is disabled and is unavailable currently. | -| 0x9e | IMM16 | jnstricteqz +AAAA | Default input parameter: acc: value
A: signed branch offset| Calculate **acc !== 0** and jump to branch A if it is true.
The instruction feature is disabled and is unavailable currently. | -| 0x9f | IMM16 | jeqnull +AAAA | Default input parameter: acc: value
A: signed branch offset| Calculate **acc == null** and jump to branch A if it is true.
The instruction feature is disabled and is unavailable currently. | -| 0xa0 | IMM16 | jnenull +AAAA | Default input parameter: acc: value
A: signed branch offset| Calculate **acc != null** and jump to branch A if it is true.
The instruction feature is disabled and is unavailable currently. | -| 0xa1 | IMM16 | jstricteqnull +AAAA | Default input parameter: acc: value
A: signed branch offset| Calculate **acc === null** and jump to branch A if it is true.
The instruction feature is disabled and is unavailable currently. | -| 0xa2 | IMM16 | jnstricteqnull +AAAA | Default input parameter: acc: value
A: signed branch offset| Calculate **acc !== null** and jump to branch A if it is true.
The instruction feature is disabled and is unavailable currently. | -| 0xa3 | IMM16 | jequndefined +AAAA | Default input parameter: acc: value
A: signed branch offset| Calculate **acc == undefined** and jump to branch A if it is true.
The instruction feature is disabled and is unavailable currently. | -| 0xa4 | IMM16 | jneundefined +AAAA | Default input parameter: acc: value
A: signed branch offset| Calculate **acc != undefined** and jump to branch A if it is true.
The instruction feature is disabled and is unavailable currently. | -| 0xa5 | IMM16 | jstrictequndefined +AAAA | Default input parameter: acc: value
A: signed branch offset| Calculate **acc === undefined** and jump to branch A if it is true.
The instruction feature is disabled and is unavailable currently. | -| 0xa6 | IMM16 | jnstrictequndefined +AAAA | Default input parameter: acc: value
A: signed branch offset| Calculate **acc !== undefined** and jump to branch A if it is true.
The instruction feature is disabled and is unavailable currently. | -| 0xa7 | V8_IMM16 | jeq vAA, +BBBB | Default input parameter: acc: value
A: value
B: signed branch offset| Calculate **acc == A** and jump to branch B if it is true.
The instruction feature is disabled and is unavailable currently. | -| 0xa8 | V8_IMM16 | jne vAA, +BBBB | Default input parameter: acc: value
A: value
B: signed branch offset| Calculate **acc != A** and jump to branch B if it is true.
The instruction feature is disabled and is unavailable currently. | -| 0xa9 | V8_IMM16 | jstricteq vAA, +BBBB | Default input parameter: acc: value
A: value
B: signed branch offset| Calculate **acc === A** and jump to branch B if it is true.
The instruction feature is disabled and is unavailable currently. | -| 0xaa | V8_IMM16 | jnstricteq vAA, +BBBB | Default input parameter: acc: value
A: value
B: signed branch offset| Calculate **acc !== A** and jump to branch B if it is true.
The instruction feature is disabled and is unavailable currently. | -| 0xab | IMM16 | getiterator RRRR | Default input parameter: acc: object
R: 16-bit reserved number used in Ark runtime| Execute the [GetIterator](https://262.ecma-international.org/12.0/#sec-getiterator) (acc, sync) method and store the result in **acc**. | -| 0xac | IMM16_V8 | closeiterator RRRR, vAA | R: 16-bit reserved number used in Ark runtime
A: Object| Use A of the *[iteratorRecord](https://262.ecma-international.org/12.0/#sec-iterator-records)* type as a parameter to execute [IteratorClose](https://262.ecma-international.org/12.0/#sec-iteratorclose) and store the result in **acc**. | +| 0x00 | NONE | ldundefined | | Loads **undefined** to the acc. | +| 0x01 | NONE | ldnull | | Loads **null** to the acc. | +| 0x02 | NONE | ldtrue | | Loads **true** to the acc. | +| 0x03 | NONE | ldfalse | | Loads **false** to the acc. | +| 0x04 | NONE | createemptyobject | | Creates an empty object and stores it in the acc. | +| 0x05 | IMM8| createemptyarray RR | R: 8-bit reserved number used in Ark runtime| Creates an empty array and stores it in the acc. | +| 0x06 | IMM8_ID16 | createarraywithbuffer RR, @AAAA | R: 8-bit reserved number used in Ark runtime
A: 16-bit literal id| Uses the literal array corresponding to index A to create an array object and stores it in the acc. | +| 0x07 | IMM8_ID16 | createobjectwithbuffer RR, @AAAA | R: 8-bit reserved number used in Ark runtime
A: 16-bit literal id| Uses the literal array corresponding to index A to create an object and stores it in the acc. | +| 0x08 | IMM8_IMM8_V8 | newobjrange RR, +AA, vBB | R: 8-bit reserved number used in Ark runtime
A: number of parameters
B: class object
B + 1, ..., B + A - 1: parameter passed to the constructor| Uses **B + 1, ..., B + A - 1** as a parameter to create an instance of class B and stores it in the acc. | +| 0x09 | IMM8 | newlexenv +AA | A: number of slots in the lexical environment| Creates a lexical environment with slot A, stores it in the acc, and enters the lexical environment. | +| 0x0a | IMM8_V8 | add2 RR, vAA | Default input parameter: acc: operand
R: 8-bit reserved number used in Ark runtime
A: operand| Calculates `A + acc` and stores the result in the acc. | +| 0x0b | IMM8_V8 | sub2 RR, vAA | Default input parameter: acc: operand
R: 8-bit reserved number used in Ark runtime
A: operand| Calculates `A - acc` and stores the result in the acc. | +| 0x0c | IMM8_V8 | mul2 RR, vAA | Default input parameter: acc: operand
R: 8-bit reserved number used in Ark runtime
A: operand| Calculates `A * acc` and stores the result in the acc. | +| 0x0d | IMM8_V8 | div2 RR, vAA | Default input parameter: acc: operand
R: 8-bit reserved number used in Ark runtime
A: operand| Calculates `A / acc` and stores the result in the acc. | +| 0x0e | IMM8_V8 | mod2 RR, vAA | Default input parameter: acc: operand
R: 8-bit reserved number used in Ark runtime
A: operand| Calculates `A % acc` and stores the result in the acc. | +| 0x0f | IMM8_V8 | eq RR, vAA | Default input parameter: acc: operand
R: 8-bit reserved number used in Ark runtime
A: operand| Calculates `A == acc` and stores the result in the acc. | +| 0x10 | IMM8_V8 | noteq RR, vAA | Default input parameter: acc: operand
R: 8-bit reserved number used in Ark runtime
A: operand| Calculates `A != acc` and stores the result in the acc. | +| 0x11 | IMM8_V8 | less RR, vAA | Default input parameter: acc: operand
R: 8-bit reserved number used in Ark runtime
A: operand| Calculates `A < acc` and stores the result in the acc. | +| 0x12 | IMM8_V8 | lesseq RR, vAA | Default input parameter: acc: operand
R: 8-bit reserved number used in Ark runtime
A: operand| Calculates `A <= acc` and stores the result in the acc. | +| 0x13 | IMM8_V8 | greater RR, vAA | Default input parameter: acc: operand
R: 8-bit reserved number used in Ark runtime
A: operand| Calculates `A > acc` and stores the result in the acc. | +| 0x14 | IMM8_V8 | greatereq RR, vAA | Default input parameter: acc: operand
R: 8-bit reserved number used in Ark runtime
A: operand| Calculates `A >= acc` and stores the result in the acc. | +| 0x15 | IMM8_V8 | shl2 RR, vAA | Default input parameter: acc: operand
R: 8-bit reserved number used in Ark runtime
A: operand| Calculates `A << acc` and stores the result in the acc. | +| 0x16 | IMM8_V8 | shr2 RR, vAA | Default input parameter: acc: operand
R: 8-bit reserved number used in Ark runtime
A: operand| Calculates `A >>> acc` and stores the result in the acc. | +| 0x17 | IMM8_V8 | ashr2 RR, vAA | Default input parameter: acc: operand
R: 8-bit reserved number used in Ark runtime
A: operand| Calculates `A >> acc` and stores the result in the acc. | +| 0x18 | IMM8_V8 | and2 RR, vAA | Default input parameter: acc: operand
R: 8-bit reserved number used in Ark runtime
A: operand| Calculates `A & acc` and stores the result in the acc. | +| 0x19 | IMM8_V8 | or2 RR, vAA | Default input parameter: acc: operand
R: 8-bit reserved number used in Ark runtime
A: operand| Calculates `A \| acc` and stores the result in the acc. | +| 0x1a | IMM8_V8 | xor2 RR, vAA | Default input parameter: acc: operand
R: 8-bit reserved number used in Ark runtime
A: operand| Calculates `A ^ acc` and stores the result in the acc. +| 0x1b | IMM8_V8 | exp RR, vAA | Default input parameter: acc: operand
R: 8-bit reserved number used in Ark runtime
A: operand| Calculates `A ** acc` and stores the result in the acc. | +| 0x1c | IMM8 | typeof RR | Default input parameter: acc: object
R: 8-bit reserved number used in Ark runtime| Calculates `typeof acc` and stores the result in the acc. | +| 0x1d | IMM8 | tonumber RR | Default input parameter: acc: object
R: 8-bit reserved number used in Ark runtime| Uses the acc as a parameter, executes [ToNumber](https://262.ecma-international.org/12.0/#sec-tonumber), and stores the result in the acc. | +| 0x1e | IMM8 | tonumeric RR | Default input parameter: acc: object
R: 8-bit reserved number used in Ark runtime| Uses the acc as a parameter, executes [ToNumeric](https://262.ecma-international.org/12.0/#sec-tonumeric), and stores the result in the acc. | +| 0x1f | IMM8 | neg RR | Default input parameter: acc: operand
R: 8-bit reserved number used in Ark runtime| Calculates `-acc` and stores the result in the acc. | +| 0x20 | IMM8 | not RR | Default input parameter: acc: operand
R: 8-bit reserved number used in Ark runtime| Calculates `~acc` and stores the result in the acc. | +| 0x21 | IMM8 | inc RR | Default input parameter: acc: operand
R: 8-bit reserved number used in Ark runtime| Calculates `acc + 1` and stores the result in the acc. | +| 0x22 | IMM8 | dec RR | Default input parameter: acc: operand
R: 8-bit reserved number used in Ark runtime| Calculates `acc - 1` and stores the result in the acc. | +| 0x23 | NONE | istrue | Default input parameter: acc: object| Calculates `acc == true` and stores the result in the acc. | +| 0x24 | NONE | isfalse | Default input parameter: acc: object| Calculates `acc == false` and stores the result in the acc. | +| 0x25 | IMM8_V8 | isin RR, vAA | Default input parameter: acc: object
R: 8-bit reserved number used in Ark runtime
A: Object| Calculates `A in acc` and stores the result in the acc. | +| 0x26 | IMM8_V8 | instanceof RR, vAA | Default input parameter: acc: object
R: 8-bit reserved number used in Ark runtime
A: Object| Calculates `A instanceof acc` and stores the result in the acc. | +| 0x27 | IMM8_V8 | strictnoteq RR, vAA | Default input parameter: acc: object
R: 8-bit reserved number used in Ark runtime
A: Object| Calculates `acc !== A` and stores the result in the acc. | +| 0x28 | IMM8_V8 | stricteq RR, vAA | Default input parameter: acc: object
R: 8-bit reserved number used in Ark runtime
A: Object| Calculates `acc === A` and stores the result in the acc. | +| 0x29 | IMM8 | callarg0 RR | Default input parameter: acc: function object
R: 8-bit reserved number used in Ark runtime| Directly calls the function object stored in the acc without passing parameters and stores the result in the acc. | +| 0x2a | IMM8_V8 | callarg1 RR, vAA | Default input parameter: acc: function object
R: 8-bit reserved number used in Ark runtime
A: Parameter| Uses **A** as a parameter to call the function object stored in the acc and stores the result in the acc. | +| 0x2b | IMM8_V8_V8 | callargs2 RR, vAA, vBB | Default input parameter: acc: function object
R: 8-bit reserved number used in Ark runtime
A and B: parameters| Uses **A** and **B** as parameters to call the function object stored in the acc and stores the result in the acc. | +| 0x2c | IMM8_V8_V8_V8 | callargs3 RR, vAA, vBB, vCC | Default input parameter: acc: function object
R: 8-bit reserved number used in Ark runtime
A, B, C: parameter| Uses **A**, **B**, and **C** as parameters to call the function object stored in the acc and stores the result in the acc. | +| 0x2d | IMM8_V8 | callthis0 RR, vAA | Default input parameter: acc: function object
R: 8-bit reserved number used in Ark runtime
A: Object| Sets **this** to **A**, calls the function object stored in the acc without passing parameters, and stores the result in the acc. | +| 0x2e | IMM8_V8_V8 | callthis1 RR, vAA, vBB | Default input parameter: acc: function object
R: 8-bit reserved number used in Ark runtime
A: Object
B: parameter| Sets **this** to **A**, calls the function object stored in the acc by setting **B** as a parameter, and stores the result in the acc. | +| 0x2f | IMM8_V8_V8_V8 | callthis2 RR, vAA, vBB, vCC | Default input parameter: acc: function object
R: 8-bit reserved number used in Ark runtime
A: Object
B, C: parameter | Sets **this** to **A**, calls the function object stored in the acc by setting **B** and **C** as parameters, and stores the result in the acc. | +| 0x30 | IMM8_V8_V8_V8_V8 | callthis3 RR, vAA, vBB, vCC, vDD | Default input parameter: acc: function object
R: 8-bit reserved number used in Ark runtime
A: Object
B, C, D: parameter | Sets **this** to **A**, calls the function object stored in the acc by setting **B**, **C**, and **D** as parameters, and stores the result in the acc. | +| 0x31 | IMM8_IMM8_V8 | callthisrange RR, +AA, vBB | Default input parameter: acc: function object
R: 8-bit reserved number used in Ark runtime
A: number of parameters
B: object
B + 1, ..., B + A: parameter| Sets **this** to **B**, calls the function object stored in the acc by setting **B + 1, ..., B + A** as a parameter, and stores the result in the acc. | +| 0x32 | IMM8_IMM8_V8 | supercallthisrange RR, +AA, vBB | R: 8-bit reserved number used in Ark runtime
A: number of parameters
B, ..., B + A - 1: parameter| Uses **B, ..., B + A - 1** as a parameter to call the **super** function and stores the result in the acc.
When the value of **A** is **0**, the value of **B** is **undefined**.
This instruction appears only in non-arrow functions. | +| 0x33 | IMM8_ID16_IMM8 | definefunc RR, @AAAA, +BB | R: 8-bit reserved number used in Ark runtime
A: method id
B: number of formal parameters of method A| Creates the function object of method A and stores it in the acc. | +| 0x34 | IMM8_ID16_IMM8 | definemethod RR, @AAAA, +BB | Default input parameter: acc: class object or its prototype. When the static method is used, the parameter is a class object in the acc.
R: 8-bit reserved number used in Ark runtime
A: method id
B: number of formal parameters of method A | Creates the function object of method A, sets the object in the acc to the [HomeObject](https://262.ecma-international.org/12.0/#sec-ecmascript-function-objects) property of the function object, and stores this function object in the acc. | +| 0x35 | IMM8_ID16_ID16_IMM16_V8 | defineclasswithbuffer RR, @AAAA, @BBBB, +CCCC, vDD | R: 8-bit reserved number used in Ark runtime
A: method id of the constructor of a class
B: literal id
C: number of formal parameters of method A
D: parent class| Uses the literal array corresponding to index B and parent class D to create a class object of A and stores it in the acc. | +| 0x36 | V8 | getnextpropname vAA | A: iterator| Executes the [next](https://262.ecma-international.org/12.0/#sec-%25foriniteratorprototype%25.next) method of [for-in iterator](https://262.ecma-international.org/12.0/#sec-createiterresultobject) A and stores the result in the acc. | +| 0x37 | IMM8_V8 | ldobjbyvalue RR, vAA | Default input parameter: acc: property key
R: 8-bit reserved number used in Ark runtime
A: Object| Loads the property whose key is **acc** of object A and stores the result in the acc. +| 0x38 | IMM8_V8_V8 | stobjbyvalue RR, vAA, vBB | Default input parameter: acc: value
R: 8-bit reserved number used in Ark runtime
A: Object
B: property key| Stores the value in the acc to the property whose key is B of object A. | +| 0x39 | IMM8_V8 | ldsuperbyvalue RR, vAA | Default input parameter: acc: property key
R: 8-bit reserved number used in Ark runtime
A: Object| In the current function, obtains the property whose key of **super** is **acc** and stores the property in the acc. If the property is of an accessor, the object in A is used as the **this** parameter when the **getter** function of the property is called. | +| 0x3a | IMM8_IMM16 | ldobjbyindex RR, +AAAA | Default input parameter: acc: object
R: 8-bit reserved number used in Ark runtime
A: property key| Loads the property whose key is A of the object stored in the acc and stores the property in the **acc**. | +| 0x3b | IMM8_V8_IMM16 | stobjbyindex RR, vAA, +BBBB | Default input parameter: acc: value
R: 8-bit reserved number used in Ark runtime
A: Object
B: property key| Stores the value in the **acc** to the property whose key is B of object A. | +| 0x3c | IMM4_IMM4 | ldlexvar +A, +B | A: lexical environment level
B: slot number| Stores the value of slot B in the lexical environment beyond A levels in the acc. | +| 0x3d | IMM4_IMM4 | stlexvar +A, +B | Default input parameter: acc: value
A: lexical environment level
B: slot number| Stores the value in the acc to slot B in the lexical environment beyond A levels. | +| 0x3e | ID16 | lda.str @AAAA | A: string id| Stores the string corresponding to index A to **acc**. | +| 0x3f | IMM8_ID16 | tryldglobalbyname RR, @AAAA | R: 8-bit reserved number used in Ark runtime
A: string id| Stores the global variable whose name is the string corresponding to index A in the acc. If the global variable named A does not exist, an exception is thrown. | +| 0x40 | IMM8_ID16 | trystglobalbyname RR, @AAAA | Default input parameter: acc: value
R: 8-bit reserved number used in Ark runtime
A: string id| Stores the value in the acc to the global variable whose name is the string corresponding to index A. If the global variable named A does not exist, an exception is thrown. | +| 0x41 | IMM16_ID16 | ldglobalvar RRRR, @AAAA | R: 16-bit reserved number used in Ark runtime
A: string id| Stores the value of the global variable whose name is the string corresponding to index A in the acc. The variable must exist. | +| 0x42 | IMM8_ID16 | ldobjbyname RR, @AAAA | Default input parameter: acc: object
R: 8-bit reserved number used in Ark runtime
A: string id| Loads the property whose key of the object stored in the acc is the string corresponding to index A and stores the property in the acc. | +| 0x43 | IMM8_ID16_V8 | stobjbyname RR, @AAAA, vBB | Default input parameter: acc: value
R: 8-bit reserved number used in Ark runtime
A: string id
B: object| Stores the value in the acc to the property whose key of object B is the string corresponding to index A. | +| 0x44 | V4_V4 | mov vA, vB | A, B: register index| Copies the contents in register B to register A. | +| 0x45 | V8_V8 | mov vAA, vBB | A, B: register index| Copies the contents in register B to register A. | +| 0x46 | IMM8_ID16 | ldsuperbyname RR, @AAAA | Default input parameter: acc: object
R: 8-bit reserved number used in Ark runtime
A: string id| In the current function, obtains the property whose key of **super** is the string corresponding to index A and stores the property in the acc. If the property is of an accessor, the object in the acc is used as the **this** parameter when the **getter** function of the property is called. | +| 0x47 | IMM16_ID16 | stconsttoglobalrecord RRRR, @AAAA | Default input parameter: acc: value
R: 16-bit reserved number used in Ark runtime
A: string id| Stores the value in the acc to the constant of the string corresponding to index A defined by **const** in the global variable. | +| 0x48 | IMM16_ID16 | sttoglobalrecord RRRR, @AAAA | Default input parameter: acc: value
R: 16-bit reserved number used in Ark runtime
A: string id| Stores the value in the acc to the variable of the string corresponding to index A defined by **let** in the global variable. | +| 0x49 | IMM8_ID16 | ldthisbyname RR, @AAAA | R: 8-bit reserved number used in Ark runtime
A: string id| Loads the property whose key of **this** is the string corresponding to index A and stores the result in the acc. | +| 0x4a | IMM8_ID16 | stthisbyname RR, @AAAA | Default input parameter: acc: value
R: 8-bit reserved number used in Ark runtime
A: string id| Stores the value in the acc to the property whose key of **this** is the string corresponding to index A. | +| 0x4b | IMM8 | ldthisbyvalue RR | Default input parameter: acc: property key
R: 8-bit reserved number used in Ark runtime| Loads the property whose key of **this** is **acc** and stores the result in the acc. | +| 0x4c | IMM8_V8 | stthisbyvalue RR, vAA | Default input parameter: acc: value
R: 8-bit reserved number used in Ark runtime
A: property key| Stores the value in the acc to the property whose key of **this** is A. | +| 0x4d | IMM8 | jmp +AA | A: signed branch offset| Jumps to branch A unconditionally. | +| 0x4e | IMM16 | jmp +AAAA | A: signed branch offset| Jumps to branch A unconditionally. | +| 0x4f | IMM8 | jeqz +AA | Default input parameter: acc: value
A: signed branch offset| Calculates `acc == 0` and jumps to branch A if it is true. | +| 0x50 | IMM16 | jeqz +AAAA | Default input parameter: acc: value
A: signed branch offset| Calculates `acc == 0` and jumps to branch A if it is true. | +| 0x51 | IMM8 | jnez +AA | Default input parameter: acc: value
A: signed branch offset| Calculates `acc != 0` and jumps to branch A if it is true. | +| 0x52 | IMM8 | jstricteqz +AA | Default input parameter: acc: value
A: signed branch offset| Calculates `acc === 0` and jumps to branch A if it is true.
The instruction feature is disabled and is unavailable currently. | +| 0x53 | IMM8 | jnstricteqz +AA | Default input parameter: acc: value
A: signed branch offset| Calculates `acc !== 0` and jumps to branch A if it is true.
The instruction feature is disabled and is unavailable currently. | +| 0x54 | IMM8 | jeqnull +AA | Default input parameter: acc: value
A: signed branch offset| Calculates `acc == null` and jumps to branch A if it is true.
The instruction feature is disabled and is unavailable currently. | +| 0x55 | IMM8 | jnenull +AA | Default input parameter: acc: value
A: signed branch offset| Calculates `acc != null` and jumps to branch A if it is true.
The instruction feature is disabled and is unavailable currently. | +| 0x56 | IMM8 | jstricteqnull +AA | Default input parameter: acc: value
A: signed branch offset| Calculates `acc === null` and jumps to branch A if it is true.
The instruction feature is disabled and is unavailable currently. | +| 0x57 | IMM8 | jnstricteqnull +AA | Default input parameter: acc: value
A: signed branch offset| Calculates `acc !== null` and jumps to branch A if it is true.
The instruction feature is disabled and is unavailable currently. | +| 0x58 | IMM8 | jequndefined +AA | Default input parameter: acc: value
A: signed branch offset| Calculates `acc == undefined` and jumps to branch A if it is true.
The instruction feature is disabled and is unavailable currently. | +| 0x59 | IMM8 | jneundefined +AA | Default input parameter: acc: value
A: signed branch offset| Calculates `acc != undefined` and jumps to branch A if it is true.
The instruction feature is disabled and is unavailable currently. | +| 0x5a | IMM8 | jstrictequndefined +AA | Default input parameter: acc: value
A: signed branch offset| Calculates `acc === undefined` and jumps to branch A if it is true.
The instruction feature is disabled and is unavailable currently. | +| 0x5b | IMM8 | jnstrictequndefined +AA | Default input parameter: acc: value
A: signed branch offset| Calculates `acc !== undefined` and jumps to branch A if it is true.
The instruction feature is disabled and is unavailable currently. | +| 0x5c | V8_IMM8 | jeq vAA, +BB | Default input parameter: acc: value
A: value
B: signed branch offset| Calculates `acc == A` and jumps to branch B if it is true.
The instruction feature is disabled and is unavailable currently. | +| 0x5d | V8_IMM8 | jne vAA, +BB | Default input parameter: acc: value
A: value
B: signed branch offset| Calculates `acc != A` and jumps to branch B if it is true.
The instruction feature is disabled and is unavailable currently. | +| 0x5e | V8_IMM8 | jstricteq vAA, +BB | Default input parameter: acc: object
A: Object
B: signed branch offset| Calculates `acc === A` and jumps to branch B if it is true.
The instruction feature is disabled and is unavailable currently. | +| 0x5f | V8_IMM8 | jnstricteq vAA, +BB | Default input parameter: acc: object
A: Object
B: signed branch offset| Calculates `acc !== A` and jumps to branch B if it is true.
The instruction feature is disabled and is unavailable currently. | +| 0x60 | V8 | lda vAA | A: register index| Stores the contents of register A in the acc. | +| 0x61 | V8 | sta vAA | Default input parameter: acc
A: register index| Stores the contents of acc in register A. | +| 0x62 | IMM32 | ldai +AAAAAAAA | A: constant literal| Stores the integer literal A in the acc. | +| 0x63 | IMM64 | fldai +AAAAAAAAAAAAAAAA | A: constant literal| Stores the double-precision floating-point literal A in the acc. | +| 0x64 | NONE | return | Default input parameter: acc: value| Returns the value in the acc. | +| 0x65 | NONE | returnundefined | | Returns **undefined**. | +| 0x66 | NONE | getpropiterator | Default input parameter: acc: object| Stores the [for-in iterator](https://262.ecma-international.org/12.0/#sec-createiterresultobject) of the object in the acc. | +| 0x67 | IMM8 | getiterator RR | Default input parameter: acc: object
R: 8-bit reserved number used in Ark runtime| Executes the [GetIterator](https://262.ecma-international.org/12.0/#sec-getiterator) (acc, sync) method and stores the result in the acc. | +| 0x68 | IMM8_V8 | closeiterator RR, vAA | R: 8-bit reserved number used in Ark runtime
A: Object| Uses A of the *[iteratorRecord](https://262.ecma-international.org/12.0/#sec-iterator-records)* type as a parameter to execute [IteratorClose](https://262.ecma-international.org/12.0/#sec-iteratorclose) and stores the result in the acc. | +| 0x69 | NONE | poplexenv | | Jumps out of the current lexical environment and enters the outer lexical environment. | +| 0x6a | NONE | ldnan | | Stores the **nan** value in the acc. | +| 0x6b | NONE | ldinfinity | | Stores the **infinity** value in the acc. | +| 0x6c | NONE | getunmappedargs | | Stores the **arguments** of the current function in the acc. | +| 0x6d | NONE | ldglobal | | Stores the **global** object in the acc.| +| 0x6e | NONE | ldnewtarget | | Stores the **NewTarget** implicit parameter of the current function in the acc.
The instruction feature is disabled and is unavailable currently. | +| 0x6f | NONE | ldthis | | Stores the **this** value in the acc. | +| 0x70 | NONE | ldhole | | Stores the **hole** value in the acc. | +| 0x71 | IMM8_ID16_IMM8 | createregexpwithliteral RR, @AAAA, +BB | R: 8-bit reserved number used in Ark runtime
A: string id
B: regular expression modifier| Uses the string corresponding to index A and the modifier corresponding to index B to create a regular expression and stores it in the acc.
The correspondence between B and a specified modifier is: 0 (default value with no modifier), 1 (g), 2 (i), 4 (m), 8 (s), 16 (u), 32 (y); B may also refer to a combination of modifiers that comply with syntax specifications, for example, **3** and its modifier is **gi**. | +| 0x72 | IMM16_ID16_IMM8 | createregexpwithliteral RRRR, @AAAA, +BB | R: 16-bit reserved number used in Ark runtime
A: string id
B: regular expression modifier| Uses the string corresponding to index A and the modifier corresponding to index B to create a regular expression and stores it in the acc.
The correspondence between B and a specified modifier is: 0 (default value with no modifier), 1 (g), 2 (i), 4 (m), 8 (s), 16 (u), 32 (y); B may also refer to a combination of modifiers that comply with syntax specifications, for example, **3** and its modifier is **gi**. | +| 0x73 | IMM8_IMM8_V8 | callrange RR, +AA, vBB | Default input parameter: acc: function object
R: 8-bit reserved number used in Ark runtime
A: number of parameters
B, ..., B + A - 1: parameter| Uses **B, ..., B + A - 1** as a parameter to call the function object stored in the acc and stores the result in the acc. | +| 0x74 | IMM16_ID16_IMM8 | definefunc RRRR, @AAAA, +BB | R: 16-bit reserved number used in Ark runtime
A: method id
B: number of formal parameters of method A| Creates the function object of method A and stores it in the acc. | +| 0x75 | IMM16_ID16_ID16_IMM16_V8 | defineclasswithbuffer RRRR, @AAAA, @BBBB, +CCCC, vDD | R: 16-bit reserved number used in Ark runtime
A: **method id** of the constructor of a class
B: literal id
C: number of formal parameters of method A
D: parent class| Uses the literal array corresponding to index B and parent class D to create a class object of A and stores it in the acc. | +| 0x76 | IMM8 | gettemplateobject RR | Default input parameter: acc: object
R: 8-bit reserved number used in Ark runtime| Executes [GetTemplateObject](https://262.ecma-international.org/12.0/#sec-gettemplateobject) (acc) and stores the result in the acc. | +| 0x77 | IMM8_V8 | setobjectwithproto RR, vAA | Default input parameter: acc: object
R: 8-bit reserved number used in Ark runtime
A: value| Sets the **\_\_proto\_\_** property of the object stored in the acc to A. | +| 0x78 | IMM8_V8_V8 | stownbyvalue RR, vAA, vBB | Default input parameter: acc: value
R: 8-bit reserved number used in Ark runtime
A: Object
B: property key| Stores the value in the acc to the property whose key is B of object A. | +| 0x79 | IMM8_V8_IMM16 | stownbyindex RR, vAA, +BBBB | Default input parameter: acc: value
R: 8-bit reserved number used in Ark runtime
A: Object
B: property key| Stores the value in the acc to the property whose key is B of object A. | +| 0x7a | IMM8_ID16_V8 | stownbyname RR, @AAAA, vBB | Default input parameter: acc: value
R: 8-bit reserved number used in Ark runtime
A: string id
B: object| Stores the value in the acc to the property whose key of object B is the string corresponding to index A. | +| 0x7b | IMM8 | getmodulenamespace +AA | A: module index| Executes the [GetModuleNamespace](https://262.ecma-international.org/12.0/#sec-getmodulenamespace) instruction for module A and stores the result in the acc. | +| 0x7c | IMM8 | stmodulevar +AA | Default input parameter: acc: value
A: slot number| Stores the value in the acc to the module variable of slot A. | +| 0x7d | IMM8 | ldlocalmodulevar +AA | A: slot number| Stores the local module variables of slot A in the acc. | +| 0x7e | IMM8 | ldexternalmodulevar +AA | A: slot number| Stores the external module variable of slot A in the acc. | +| 0x7f | IMM16_ID16 | stglobalvar RRRR, @AAAA | Default input parameter: acc: value
R: 16-bit reserved number used in Ark runtime
A: string id| Stores the value in the acc to the global variable whose name is the string corresponding to index A. This variable must exist. | +| 0x80 | IMM16 | createemptyarray RRRR | R: 16-bit reserved number used in Ark runtime| Creates an empty array and stores it in the acc. | +| 0x81 | IMM16_ID16 | createarraywithbuffer RRRR, @AAAA | R: 16-bit reserved number used in Ark runtime
A: literal id| Uses the literal array corresponding to index A to create an array object and stores it in the acc. | +| 0x82 | IMM16_ID16 | createobjectwithbuffer RRRR, @AAAA | R: 16-bit reserved number used in Ark runtime
A: literal id| Uses the literal array corresponding to index A to create an object and stores it in the acc. | +| 0x83 | IMM16_IMM8_V8 | newobjrange RRRR, +AA, vBB | R: 16-bit reserved number used in Ark runtime
A: number of parameters
B: class object
B + 1, ..., B + A - 1: parameter passed to the constructor| Uses **B + 1, ..., B + A - 1** as a parameter to create an instance of class B and stores it in the acc. | +| 0x84 | IMM16 | typeof RRRR | Default input parameter: acc: object
R: 16-bit reserved number used in Ark runtime| Calculates `typeof acc` and stores the result in the acc. | +| 0x85 | IMM16_V8 | ldobjbyvalue RRRR, vAA | Default input parameter: acc: property key
R: 16-bit reserved number used in Ark runtime
A: Object| Loads the property whose key is **acc** of object A and stores the result in the acc. | +| 0x86 | IMM16_V8_V8 | stobjbyvalue RRRR, vAA, vBB | Default input parameter: acc: value
R: 16-bit reserved number used in Ark runtime
A: Object
B: property key| Stores the value in the acc to the property whose key is B of object A. | +| 0x87 | IMM16_V8 | ldsuperbyvalue RRRR, vAA | Default input parameter: acc: property key
R: 16-bit reserved number used in Ark runtime
A: Object| In the current function, obtains the property whose key of **super** is **acc** and stores the property in the acc. If the property is of an accessor, the object in A is used as the **this** parameter when the **getter** function of the property is called. | +| 0x88 | IMM16_IMM16 | ldobjbyindex RRRR, +AAAA | Default input parameter: acc: object
R: 16-bit reserved number used in Ark runtime
A: property key| Loads the property whose key is A of the object stored in the acc and stores the property in the acc. | +| 0x89 | IMM16_V8_IMM16 | stobjbyindex RRRR, vAA, +BBBB | Default input parameter: acc: value
R: 16-bit reserved number used in Ark runtime
A: Object
B: property key| Stores the value in the acc to the property whose key is B of object A. | +| 0x8a | IMM8_IMM8 | ldlexvar +AA, +BB | A: lexical environment level
B: slot number| Stores the value of slot B in the lexical environment beyond A levels in the acc. | +| 0x8b | IMM8_IMM8 | stlexvar +AA, +BB | Default input parameter: acc: value
A: lexical environment level
B: slot number| Stores the value in the acc to slot B in the lexical environment beyond A levels. | +| 0x8c | IMM16_ID16 | tryldglobalbyname RRRR, @AAAA | R: 16-bit reserved number used in Ark runtime
A: string id| Stores the global variable whose name is the string corresponding to index A in the acc. If the global variable named A does not exist, an exception is thrown. | +| 0x8d | IMM16_ID16 | trystglobalbyname RRRR, @AAAA | Default input parameter: acc: value
R: 16-bit reserved number used in Ark runtime
A: string id| Stores the value in the acc to the global variable whose name is the string corresponding to index A. If the global variable named A does not exist, an exception is thrown. | +| 0x8e | IMM8_ID16_V8 | stownbynamewithnameset RR, @AAAA, vBB | Default input parameter: acc: function object
R: 8-bit reserved number used in Ark runtime
A: string id
B: object| Stores the function object in the acc to the property whose key of object B is the string corresponding to index A and sets the function name to the string corresponding to index A. | +| 0x8f | V16_V16 | mov vAAAA, vBBBB | A, B: register index| Copies the contents in register B to register A. | +| 0x90 | IMM16_ID16 | ldobjbyname RRRR, @AAAA | Default input parameter: acc: object
R: 16-bit reserved number used in Ark runtime
A: string id| Loads the property whose key of the object stored in the acc is the string corresponding to index A and stores the property in the acc. | +| 0x91 | IMM16_ID16_V8 | stobjbyname RRRR, @AAAA, vBB | Default input parameter: acc: value
R: 16-bit reserved number used in Ark runtime
A: string id
B: object| Stores the value in the acc to the property whose key of object B is the string corresponding to index A. | +| 0x92 | IMM16_ID16 | ldsuperbyname RRRR, @AAAA | Default input parameter: acc: object
R: 16-bit reserved number used in Ark runtime
A: string id| In the current function, obtains the property whose key of **super** is the string corresponding to index A and stores the property in the acc. If the property is of an accessor, the object in the acc is used as the **this** parameter when the **getter** function of the property is called. | +| 0x93 | IMM16_ID16 | ldthisbyname RRRR, @AAAA | R: 16-bit reserved number used in Ark runtime
A: string id| Loads the property whose key of **this** is the string corresponding to index A and stores the result in the acc. | +| 0x94 | IMM16_ID16 | stthisbyname RRRR, @AAAA | Default input parameter: acc: value
R: 16-bit reserved number used in Ark runtime
A: string id| Stores the value in the acc to the property whose key of **this** is the string corresponding to index A. | +| 0x95 | IMM16 | ldthisbyvalue RRRR | Default input parameter: acc: property key
R: 16-bit reserved number used in Ark runtime| Loads the property whose key of **this** is **acc** and stores the result in the acc. | +| 0x96 | IMM16_V8 | stthisbyvalue RRRR, vAA | Default input parameter: acc: value
R: 16-bit reserved number used in Ark runtime
A: property key| Stores the value in the acc to the property whose key of **this** is A. | +| 0x97 | V8 | asyncgeneratorreject vAA | Default input parameter: acc: exception
A: generator| Uses the exception stored in [generator](https://262.ecma-international.org/12.0/#sec-generator-objects) A and the acc, executes [AsyncGeneratorReject](https://262.ecma-international.org/12.0/#sec-asyncgeneratorreject), and stores the result in the acc. | +| 0x98 | IMM32 | jmp +AAAAAAAA | A: signed branch offset| Jumps to branch A unconditionally. | +| 0x99 | IMM8_V8_V8 | stownbyvaluewithnameset RR, vAA, vBB | Default input parameter: acc: function object
R: 8-bit reserved number used in Ark runtime
A: Object
B: property key| Stores the value in the acc to the property whose key of object A is B and set the function name to B. | +| 0x9a | IMM32 | jeqz +AAAAAAAA | Default input parameter: acc: value
A: signed branch offset| Calculates `acc == 0` and jumps to branch A if it is true. | +| 0x9b | IMM16 | jnez +AAAA | Default input parameter: acc: value
A: signed branch offset| Calculates `acc != 0` and jumps to branch A if it is true. | +| 0x9c | IMM32 | jnez +AAAAAAAA | Default input parameter: acc: value
A: signed branch offset| Calculates `acc != 0` and jumps to branch A if it is true. | +| 0x9d | IMM16 | jstricteqz +AAAA | Default input parameter: acc: value
A: signed branch offset| Calculates `acc === 0` and jumps to branch A if it is true.
The instruction feature is disabled and is unavailable currently. | +| 0x9e | IMM16 | jnstricteqz +AAAA | Default input parameter: acc: value
A: signed branch offset| Calculates `acc !== 0` and jumps to branch A if it is true.
The instruction feature is disabled and is unavailable currently. | +| 0x9f | IMM16 | jeqnull +AAAA | Default input parameter: acc: value
A: signed branch offset| Calculates `acc == null` and jumps to branch A if it is true.
The instruction feature is disabled and is unavailable currently. | +| 0xa0 | IMM16 | jnenull +AAAA | Default input parameter: acc: value
A: signed branch offset| Calculates `acc != null` and jumps to branch A if it is true.
The instruction feature is disabled and is unavailable currently. | +| 0xa1 | IMM16 | jstricteqnull +AAAA | Default input parameter: acc: value
A: signed branch offset| Calculates `acc === null` and jumps to branch A if it is true.
The instruction feature is disabled and is unavailable currently. | +| 0xa2 | IMM16 | jnstricteqnull +AAAA | Default input parameter: acc: value
A: signed branch offset| Calculates `acc !== null` and jumps to branch A if it is true.
The instruction feature is disabled and is unavailable currently. | +| 0xa3 | IMM16 | jequndefined +AAAA | Default input parameter: acc: value
A: signed branch offset| Calculates `acc == undefined` and jumps to branch A if it is true.
The instruction feature is disabled and is unavailable currently. | +| 0xa4 | IMM16 | jneundefined +AAAA | Default input parameter: acc: value
A: signed branch offset| Calculates `acc != undefined` and jumps to branch A if it is true.
The instruction feature is disabled and is unavailable currently. | +| 0xa5 | IMM16 | jstrictequndefined +AAAA | Default input parameter: acc: value
A: signed branch offset| Calculates `acc === undefined` and jumps to branch A if it is true.
The instruction feature is disabled and is unavailable currently. | +| 0xa6 | IMM16 | jnstrictequndefined +AAAA | Default input parameter: acc: value
A: signed branch offset| Calculates `acc !== undefined` and jumps to branch A if it is true.
The instruction feature is disabled and is unavailable currently. | +| 0xa7 | V8_IMM16 | jeq vAA, +BBBB | Default input parameter: acc: value
A: value
B: signed branch offset| Calculates `acc == A` and jumps to branch B if it is true.
The instruction feature is disabled and is unavailable currently. | +| 0xa8 | V8_IMM16 | jne vAA, +BBBB | Default input parameter: acc: value
A: value
B: signed branch offset| Calculates `acc != A` and jumps to branch B if it is true.
The instruction feature is disabled and is unavailable currently. | +| 0xa9 | V8_IMM16 | jstricteq vAA, +BBBB | Default input parameter: acc: value
A: value
B: signed branch offset| Calculates `acc === A` and jumps to branch B if it is true.
The instruction feature is disabled and is unavailable currently. | +| 0xaa | V8_IMM16 | jnstricteq vAA, +BBBB | Default input parameter: acc: value
A: value
B: signed branch offset| Calculates `acc !== A` and jumps to branch B if it is true.
The instruction feature is disabled and is unavailable currently. | +| 0xab | IMM16 | getiterator RRRR | Default input parameter: acc: object
R: 16-bit reserved number used in Ark runtime| Executes the [GetIterator](https://262.ecma-international.org/12.0/#sec-getiterator) (acc, sync) method and stores the result in the acc. | +| 0xac | IMM16_V8 | closeiterator RRRR, vAA | R: 16-bit reserved number used in Ark runtime
A: Object| Uses A of the *[iteratorRecord](https://262.ecma-international.org/12.0/#sec-iterator-records)* type as a parameter to execute [IteratorClose](https://262.ecma-international.org/12.0/#sec-iteratorclose) and stores the result in the acc. | | 0xad | NONE | ldsymbol | | Load the **Symbol** object in **acc**. | -| 0xae | NONE | asyncfunctionenter | | Create an asynchronous function object and store the object in **acc**. | -| 0xaf | NONE | ldfunction | | Load the current function object in **acc**. | -| 0xb0 | NONE | debugger | | This command is used to pause execution during debugging. | -| 0xb1 | V8 | creategeneratorobj vAA | A: function object| Use function object A to create a *generator* and store it in **acc**. | -| 0xb2 | V8_V8 | createiterresultobj vAA, vBB | A: Object
B: Boolean value| Set *value* A and *done* B as parameters to execute [CreateIterResultObject](https://262.ecma-international.org/12.0/#sec-createiterresultobject) instruction and store the result in **acc**. | -| 0xb3 | IMM8_V8_V8 | createobjectwithexcludedkeys +AA, vBB, vCC | A: number of range registers
B: object
C, ..., C + A: attribute key value.| Based on object B, create an object excluding the key **C, ..., C + A** and store it in **acc**.
This instruction supports object creation by using destructor and extension syntax. | -| 0xb4 | IMM8_V8 | newobjapply RR, vAA | Default input parameter: acc: parameter list
R: 8-bit reserved number used in Ark runtime
A: class object| Use the parameter list stored in **acc** to create an instance of class A and store it in **acc**. | -| 0xb5 | IMM16_V8 | newobjapply RRRR, vAA | Default input parameter: acc: parameter list
R: 16-bit reserved number used in Ark runtime
A: class object| Use the parameter list stored in **acc** to create an instance of class A and store it in **acc**. | -| 0xb6 | IMM8_ID16 | newlexenvwithname +AA, @BBBB | A: number of slots in the lexical environment
B: literal id| Use the lexical variable name stored in the literal array corresponding to index B to create a lexical environment with A slots, store this lexical environment in **acc**, and enter. | -| 0xb7 | V8 | createasyncgeneratorobj vAA | A: function object| Create an asynchronous *generator* based on function object A and store it in **acc**. | -| 0xb8 | V8_V8_V8 | asyncgeneratorresolve vAA, vBB, vCC | A: generator
B: object
C: boolean value| Use *generator* A, *value* B, and *done* C as parameters to execute [AsyncGeneratorResolve](https://262.ecma-international.org/12.0/#sec-asyncgeneratorresolve) and store the result in **acc**. | -| 0xb9 | IMM8_V8 | supercallspread RR, vAA | Default input parameter: acc: class object
R: 8-bit reserved number used in Ark runtime
A: parameter list| Use parameter list A as a parameter, call the parent class constructor of the class stored in **acc**, and store the result in **acc**. | -| 0xba | IMM8_V8_V8 | apply RR, vAA, vBB | Default input parameter: acc: function object
R: 8-bit reserved number used in Ark runtime
A: Object
B: parameter list| Set **this** to A, use parameter list B as the parameter, call the function object stored in **acc**, and store the return value in **acc**. | -| 0xbb | IMM8_IMM8_V8 | supercallarrowrange RR, +AA, vBB | Default input parameter: acc: class object
R: 8-bit reserved number used in Ark runtime
A: number of parameters
B, ..., B + A - 1: parameter| Use **B, ..., B + A - 1** as a parameter to call the constructor function of the parent class of the class stored in **acc** and store the result in **acc**.
If the value of A is **0**, B is **undefined**.
This instruction appears only in arrow functions. | -| 0xbc | V8_V8_V8_V8 | definegettersetterbyvalue vAA, vBB, vCC, vDD | Default input parameter: acc: boolean value, indicating whether to set a name for the accessor.
A: Object
B: attribute key
C: **getter** function object
D: **setter** function object| Use **getter** method C and **setter** method D as parameters to define the accessor of the attribute whose key of object A is B and store the result object in **acc**.
If C is **undefined** and D is **undefined**, **getter** and **setter** are not set respectively. | -| 0xbd | NONE | dynamicimport | Default input parameter: acc: value| Use the value of **acc** as a parameter to execute [ImportCalls](https://262.ecma-international.org/12.0/#sec-import-calls) and store the result in **acc**. | -| 0xbe | IMM16_ID16_IMM8 | definemethod RRRR, @AAAA, +BB | Default input parameter: acc: class object or its prototype. When the static method is used, the parameter is a class object in **acc**.
R: 16-bit reserved number used in Ark runtime
A: method id
B: number of formal parameters of method A| Create the function object of method A, set the object of **acc** to the [[[HomeObject]]](https://262.ecma-international.org/12.0/#sec-ecmascript-function-objects) attribute of the function object, and store this function object in **acc**. | -| 0xbf | NONE | resumegenerator | Default input parameter: acc: generator| Execute [GeneratorResume](https://262.ecma-international.org/12.0/#sec-generatorresume) based on the generator stored in **acc** and store the result in **acc**. | -| 0xc0 | NONE | getresumemode | Default input parameter: acc: generator| After the generator finishes executing, obtain the restored value and store it in **acc**. | -| 0xc1 | IMM16 | gettemplateobject RRRR | Default input parameter: acc: object
R: 16-bit reserved number used in Ark runtime| Execute [GetTemplateObject](https://262.ecma-international.org/12.0/#sec-gettemplateobject) (acc) and store the result in **acc**. | -| 0xc2 | V8 | delobjprop vAA | Default input parameter: acc: attribute key
A: Object| Delete the attribute whose key is **acc** of object A. | -| 0xc3 | V8 | suspendgenerator vAA | Default input parameter: acc: value
A: generator| Use the value stored in **acc** to suspend *generator* A and store the result in **acc**. | -| 0xc4 | V8 | asyncfunctionawaituncaught vAA | Default input parameter: acc: value
A: function object| Use the function object A and the value of **acc** to execute [AwaitExpression](https://262.ecma-international.org/12.0/#prod-AwaitExpression) and store the result in **acc**. | -| 0xc5 | V8 | copydataproperties vAA | Default input parameter: acc: object
A: target object| Copy all attributes of the object stored in **acc** to A and store A in **acc**. | -| 0xc6 | V8_V8 | starrayspread vAA, vBB | Default input parameter: acc: value
A: array
B: array index| Store the value in **acc** to the position starting with index B of array A in the format of [SpreadElement](https://262.ecma-international.org/12.0/#prod-SpreadElement), and store the length of the result array in **acc**. | -| 0xc7 | IMM16_V8 | setobjectwithproto RRRR, vAA | Default input parameter: acc: object
R: 16-bit reserved number used in Ark runtime
A: value| Set the **\_\_proto\_\_** attribute of the object stored in **acc** to A. | -| 0xc8 | IMM16_V8_V8 | stownbyvalue RRRR, vAA, vBB | Default input parameter: acc: value
R: 16-bit reserved number used in Ark runtime
A: Object
B: attribute key| Store the value in **acc** to the attribute whose key is B of object A. | -| 0xc9 | IMM8_V8_V8 | stsuperbyvalue RR, vAA, vBB | Default input parameter: acc: value
R: 8-bit reserved number used in Ark runtime
A: Object
B: attribute key| In the current function, the value of **acc** is stored to the attribute whose key of **super** is B. If the attribute is of an accessor, the object in A is used as the **this** parameter when the **setter** function of the attribute is called. | -| 0xca | IMM16_V8_V8 | stsuperbyvalue RRRR, vAA, vBB | Default input parameter: acc: value
R: 16-bit reserved number used in Ark runtime
A: Object
B: attribute key| In the current function, the value of **acc** is stored to the attribute whose key of **super** is B. If the attribute is of an accessor, the object in A is used as the **this** parameter when the **setter** function of the attribute is called. | -| 0xcb | IMM16_V8_IMM16 | stownbyindex RRRR, vAA, +BBBB | Default input parameter: acc: value
R: 16-bit reserved number used in Ark runtime
A: Object
B: attribute key| Store the value in **acc** to the attribute whose key is B of object A. | -| 0xcc | IMM16_ID16_V8 | stownbyname RRRR, @AAAA, vBB | Default input parameter: acc: value
R: 16-bit reserved number used in Ark runtime
A: string id
B: object| Store the value of **acc** to the attribute whose key of object B is the string corresponding to index A. | -| 0xcd | V8 | asyncfunctionresolve vAA | Default input parameter: acc: value
A: asynchronous function object| Use the value in **acc** to parse the **Promise** object of object A and store the result in **acc**. | -| 0xce | V8 | asyncfunctionreject vAA | Default input parameter: acc: value
A: asynchronous function object| Use the value in **acc** to reject the **Promise** object of object A and store the result in **acc**. | -| 0xcf | IMM8 | copyrestargs +AA | A: position of the [rest parameter](https://262.ecma-international.org/12.0/#prod-FunctionRestParameter) in the formal parameter list| Copy the rest parameters and store the parameter array copy in **acc**. | -| 0xd0 | IMM8_ID16_V8 | stsuperbyname RR, @AAAA, vBB | Default input parameter: acc: value
R: 8-bit reserved number used in Ark runtime
A: string id
B: object| In the current function, store the value of **acc** to the attribute whose key of **super** is the string corresponding to index A.
If the attribute is of an accessor, the object in B is used as the **this** parameter when the **setter** function of the attribute is called. | -| 0xd1 | IMM16_ID16_V8 | stsuperbyname RRRR, @AAAA, vBB | Default input parameter: acc: value
R: 16-bit reserved number used in Ark runtime
A: string id
B: object| In the current function, store the value of **acc** to the attribute whose key of **super** is the string corresponding to index A.
If the attribute is of an accessor, the object in B is used as the **this** parameter when the **setter** function of the attribute is called. | -| 0xd2 | IMM16_V8_V8 | stownbyvaluewithnameset RRRR, vAA, vBB | Default input parameter: acc: function object
R: 8-bit reserved number used in Ark runtime
A: Object
B: attribute key| Store the value of **acc** to the attribute whose key of object A is B and set the function name to B. | -| 0xd3 | ID16 | ldbigint @AAAA | A: string id| Create a value of the **BigInt** type based on the string corresponding to index A and store the value in **acc**. | -| 0xd4 | IMM16_ID16_V8 | stownbynamewithnameset RRRR, @AAAA, vBB | Default input parameter: acc: function object
R: 16-bit reserved number used in Ark runtime
A: string id
B: object| Store the function object in **acc** to the attribute whose key of object B is the string corresponding to index A and set the function name to the string corresponding to index A. | +| 0xae | NONE | asyncfunctionenter | | Creates an asynchronous function object and store the object in the acc. | +| 0xaf | NONE | ldfunction | | Loads the current function object in the acc. | +| 0xb0 | NONE | debugger | | Pauses execution during debugging. | +| 0xb1 | V8 | creategeneratorobj vAA | A: function object| Uses function object A to create a generator and stores it in the acc. | +| 0xb2 | V8_V8 | createiterresultobj vAA, vBB | A: Object
B: Boolean value| Sets *value* A and *done* B as parameters to execute [CreateIterResultObject](https://262.ecma-international.org/12.0/#sec-createiterresultobject) instruction and stores the result in the acc. | +| 0xb3 | IMM8_V8_V8 | createobjectwithexcludedkeys +AA, vBB, vCC | A: number of range registers
B: object
C, ..., C + A: property key value.| Based on object B, creates an object excluding the key **C, ..., C + A** and stores it in the acc.
This instruction supports object creation by using destructor and extension syntax. | +| 0xb4 | IMM8_V8 | newobjapply RR, vAA | Default input parameter: acc: parameter list
R: 8-bit reserved number used in Ark runtime
A: class object| Uses the parameter list stored in the acc to create an instance of class A and stores it in the acc. | +| 0xb5 | IMM16_V8 | newobjapply RRRR, vAA | Default input parameter: acc: parameter list
R: 16-bit reserved number used in Ark runtime
A: class object| Uses the parameter list stored in the acc to create an instance of class A and stores it in the acc. | +| 0xb6 | IMM8_ID16 | newlexenvwithname +AA, @BBBB | A: number of slots in the lexical environment
B: literal id| Uses the lexical variable name stored in the literal array corresponding to index B to create a lexical environment with A slots, stores this lexical environment in the acc, and enters the lexical environment. | +| 0xb7 | V8 | createasyncgeneratorobj vAA | A: function object| Creates an asynchronous generator based on function object A and stores it in the acc. | +| 0xb8 | V8_V8_V8 | asyncgeneratorresolve vAA, vBB, vCC | A: generator
B: object
C: boolean value| Uses *generator* A, *value* B, and *done* C as parameters to execute [AsyncGeneratorResolve](https://262.ecma-international.org/12.0/#sec-asyncgeneratorresolve) and stores the result in the acc. | +| 0xb9 | IMM8_V8 | supercallspread RR, vAA | Default input parameter: acc: class object
R: 8-bit reserved number used in Ark runtime
A: parameter list| Uses parameter list A as a parameter, calls the parent class constructor of the class stored in the acc, and stores the result in the acc. | +| 0xba | IMM8_V8_V8 | apply RR, vAA, vBB | Default input parameter: acc: function object
R: 8-bit reserved number used in Ark runtime
A: Object
B: parameter list| Sets **this** to A, use parameter list B as a parameter, calls the function object stored in the acc, and stores the return value in the acc. | +| 0xbb | IMM8_IMM8_V8 | supercallarrowrange RR, +AA, vBB | Default input parameter: acc: class object
R: 8-bit reserved number used in Ark runtime
A: number of parameters
B, ..., B + A - 1: parameter| Uses **B, ..., B + A - 1** as a parameter to call the constructor function of the parent class of the class stored in the acc and stores the result in the acc.
If the value of A is **0**, B is **undefined**.
This instruction appears only in arrow functions. | +| 0xbc | V8_V8_V8_V8 | definegettersetterbyvalue vAA, vBB, vCC, vDD | Default input parameter: acc: boolean value, indicating whether to set a name for the accessor.
A: Object
B: property key
C: **getter** function object
D: **setter** function object| Uses **getter** method C and **setter** method D as parameters to define the accessor of the property whose key of object A is B and stores the result object in the acc.
If C is **undefined** and D is **undefined**, **getter** and **setter** are not set respectively. | +| 0xbd | NONE | dynamicimport | Default input parameter: acc: value| Uses the value in the acc as a parameter, executes [ImportCalls](https://262.ecma-international.org/12.0/#sec-import-calls), and stores the result in the acc. | +| 0xbe | IMM16_ID16_IMM8 | definemethod RRRR, @AAAA, +BB | Default input parameter: acc: class object or its prototype. When the static method is used, the parameter is a class object in the acc.
R: 16-bit reserved number used in Ark runtime
A: method id
B: number of formal parameters of method A| Creates the function object of method A, sets the object in the acc to the [HomeObject](https://262.ecma-international.org/12.0/#sec-ecmascript-function-objects) property of the function object, and stores this function object in the acc. | +| 0xbf | NONE | resumegenerator | Default input parameter: acc: generator| Executes [GeneratorResume](https://262.ecma-international.org/12.0/#sec-generatorresume) based on the generator stored in the acc and stores the result in the acc. | +| 0xc0 | NONE | getresumemode | Default input parameter: acc: generator| After the generator finishes executing, obtains the restored value and stores it in the acc. | +| 0xc1 | IMM16 | gettemplateobject RRRR | Default input parameter: acc: object
R: 16-bit reserved number used in Ark runtime| Executes [GetTemplateObject](https://262.ecma-international.org/12.0/#sec-gettemplateobject) (acc) and stores the result in the acc. | +| 0xc2 | V8 | delobjprop vAA | Default input parameter: acc: property key
A: Object| Deletes the property whose key is **acc** of object A. | +| 0xc3 | V8 | suspendgenerator vAA | Default input parameter: acc: value
A: generator| Uses the value stored in the acc to suspend *generator* A and stores the result in the acc. | +| 0xc4 | V8 | asyncfunctionawaituncaught vAA | Default input parameter: acc: value
A: function object| Uses the function object A and the value in the acc to execute [AwaitExpression](https://262.ecma-international.org/12.0/#prod-AwaitExpression) and stores the result in the acc. | +| 0xc5 | V8 | copydataproperties vAA | Default input parameter: acc: object
A: target object| Copies all properties of the object stored in the acc to A and stores A in the acc. | +| 0xc6 | V8_V8 | starrayspread vAA, vBB | Default input parameter: acc: value
A: array
B: array index| Stores the value in the acc to the position starting with index B of array A in the format of [SpreadElement](https://262.ecma-international.org/12.0/#prod-SpreadElement), and stores the length of the result array in the acc. | +| 0xc7 | IMM16_V8 | setobjectwithproto RRRR, vAA | Default input parameter: acc: object
R: 16-bit reserved number used in Ark runtime
A: value| Sets the **\_\_proto\_\_** property of the object stored in the acc to A. | +| 0xc8 | IMM16_V8_V8 | stownbyvalue RRRR, vAA, vBB | Default input parameter: acc: value
R: 16-bit reserved number used in Ark runtime
A: Object
B: property key| Stores the value in the acc to the property whose key is B of object A. | +| 0xc9 | IMM8_V8_V8 | stsuperbyvalue RR, vAA, vBB | Default input parameter: acc: value
R: 8-bit reserved number used in Ark runtime
A: Object
B: property key| In the current function, stores the value in the acc to the property whose key of **super** is B. If the property is of an accessor, the object in A is used as the **this** parameter when the **setter** function of the property is called. | +| 0xca | IMM16_V8_V8 | stsuperbyvalue RRRR, vAA, vBB | Default input parameter: acc: value
R: 16-bit reserved number used in Ark runtime
A: Object
B: property key| In the current function, stores the value in the acc to the property whose key of **super** is B. If the property is of an accessor, the object in A is used as the **this** parameter when the **setter** function of the property is called. | +| 0xcb | IMM16_V8_IMM16 | stownbyindex RRRR, vAA, +BBBB | Default input parameter: acc: value
R: 16-bit reserved number used in Ark runtime
A: Object
B: property key| Stores the value in the acc to the property whose key is B of object A. | +| 0xcc | IMM16_ID16_V8 | stownbyname RRRR, @AAAA, vBB | Default input parameter: acc: value
R: 16-bit reserved number used in Ark runtime
A: string id
B: object| Stores the value in the acc to the property whose key of object B is the string corresponding to index A. | +| 0xcd | V8 | asyncfunctionresolve vAA | Default input parameter: acc: value
A: asynchronous function object| Uses the value in the acc to parse the **Promise** object of object A and stores the result in the acc. | +| 0xce | V8 | asyncfunctionreject vAA | Default input parameter: acc: value
A: asynchronous function object| Uses the value in the acc to reject the **Promise** object of object A and stores the result in the acc. | +| 0xcf | IMM8 | copyrestargs +AA | A: position of the [rest parameter](https://262.ecma-international.org/12.0/#prod-FunctionRestParameter) in the formal parameter list| Copies the rest parameters and stores the parameter array copy in the acc. | +| 0xd0 | IMM8_ID16_V8 | stsuperbyname RR, @AAAA, vBB | Default input parameter: acc: value
R: 8-bit reserved number used in Ark runtime
A: string id
B: object| In the current function, stores the value in the acc to the property whose key of **super** is the string corresponding to index A.
If the property is of an accessor, the object in B is used as the **this** parameter when the **setter** function of the property is called. | +| 0xd1 | IMM16_ID16_V8 | stsuperbyname RRRR, @AAAA, vBB | Default input parameter: acc: value
R: 16-bit reserved number used in Ark runtime
A: string id
B: object| In the current function, stores the value in the acc to the property whose key of **super** is the string corresponding to index A.
If the property is of an accessor, the object in B is used as the **this** parameter when the **setter** function of the property is called. | +| 0xd2 | IMM16_V8_V8 | stownbyvaluewithnameset RRRR, vAA, vBB | Default input parameter: acc: function object
R: 8-bit reserved number used in Ark runtime
A: Object
B: property key| Stores the value in the acc to the property whose key of object A is B and set the function name to B. | +| 0xd3 | ID16 | ldbigint @AAAA | A: string id| Creates a value of the **BigInt** type based on the string corresponding to index A and stores the value in the acc. | +| 0xd4 | IMM16_ID16_V8 | stownbynamewithnameset RRRR, @AAAA, vBB | Default input parameter: acc: function object
R: 16-bit reserved number used in Ark runtime
A: string id
B: object| Stores the function object in the acc to the property whose key of object B is the string corresponding to index A and sets the function name to the string corresponding to index A. | | 0xd5 | NONE | nop | | No operation. | -| 0xd6 | IMM8 | setgeneratorstate +AA | Default input parameter: acc: generator object
A: generator state| Set the generator state stored in **acc** to A. For details, see [GeneratorState](https://262.ecma-international.org/12.0/#sec-properties-of-generator-instances) and [AsyncGeneratorState](https://262.ecma-international.org/12.0/#sec-properties-of-asyncgenerator-intances).
A may have the following values: undefined(0x0), suspendedStart(0x1), suspendedYield(0x2), executing(0x3), completed (0x4), and awaitingReturn (0x5). | -| 0xd7 | IMM8 | getasynciterator RR | Default input parameter: acc: object
R: 8-bit reserved number used in Ark runtime| Execute the [GetIterator](https://262.ecma-international.org/12.0/#sec-getiterator) (acc, async) and store the result in **acc**. | -| 0xd8 | IMM8_IMM16_IMM16 | ldprivateproperty RR, +AAAA, +BBBB | Default input parameter: acc: object
A: lexical environment level
B: slot number| Load and set the value of slot B in the lexical environment beyond A levels as the attribute key, and store the value corresponding to the key of the object in **acc**. | -| 0xd9 | IMM8_IMM16_IMM16_V8 | stprivateproperty RR, +AAAA, +BBBB, vCC | A: lexical environment level
B: slot number
C: object| Load the value of slot B in the lexical environment beyond A levels as the attribute key and store the value in **acc** to the key of the object C stored in **acc**. | -| 0xda | IMM8_IMM16_IMM16 | testin RR, +AAAA, +BBBB | Default input parameter: acc: object
A: lexical environment level
B: slot number| Load the value of slot B in the lexical environment beyond A levels, calculate whether the value is **in acc**, and store the result in **acc**. | -| 0xdb | IMM8_ID16_V8 | definefieldbyname RR, @AAAA, vBB | Default input parameter: acc: value
A: string id
B: object| Define an attribute whose key is A for object B and store the value of **acc** to the attribute. | -| 0xdc | IMM8_ID16_V8 | definepropertybyname RR, @AAAA, vBB | Default input parameter: acc: value
A: string id
B: object| Define an attribute whose key is A for object B and store the value of **acc** to the attribute. | -| 0xfb | PREF_NONE | callruntime.notifyconcurrentresult | Default input parameter: acc: return value of the concurrent function| Notify the runtime of the return value of the concurrent function.
This instruction is used only in concurrent functions. | +| 0xd6 | IMM8 | setgeneratorstate +AA | Default input parameter: acc: generator object
A: generator state| Sets the generator state stored in the acc to A. For details, see [GeneratorState](https://262.ecma-international.org/12.0/#sec-properties-of-generator-instances) and [AsyncGeneratorState](https://262.ecma-international.org/12.0/#sec-properties-of-asyncgenerator-intances).
A may have the following values: undefined(0x0), suspendedStart(0x1), suspendedYield(0x2), executing(0x3), completed (0x4), and awaitingReturn (0x5). | +| 0xd7 | IMM8 | getasynciterator RR | Default input parameter: acc: object
R: 8-bit reserved number used in Ark runtime| Executes the [GetIterator](https://262.ecma-international.org/12.0/#sec-getiterator) (acc, async) and stores the result in the acc. | +| 0xd8 | IMM8_IMM16_IMM16 | ldprivateproperty RR, +AAAA, +BBBB | Default input parameter: acc: object
A: lexical environment level
B: slot number| Loads and sets the value of slot B in the lexical environment beyond A levels as the property key, and stores the value corresponding to the key of the object in the acc. | +| 0xd9 | IMM8_IMM16_IMM16_V8 | stprivateproperty RR, +AAAA, +BBBB, vCC | A: lexical environment level
B: slot number
C: object| Loads the value of slot B in the lexical environment beyond A levels as the property key and stores the value in the acc to the key of the object C stored in the acc. | +| 0xda | IMM8_IMM16_IMM16 | testin RR, +AAAA, +BBBB | Default input parameter: acc: object
A: lexical environment level
B: slot number| Loads the value of slot B in the lexical environment beyond A levels, calculates whether the value is **in acc**, and stores the result in the acc. | +| 0xdb | IMM8_ID16_V8 | definefieldbyname RR, @AAAA, vBB | Default input parameter: acc: value
A: string id
B: object| Defines a property whose key is A for object B and store the value in the acc to the property. | +| 0xdc | IMM8_ID16_V8 | definepropertybyname RR, @AAAA, vBB | Default input parameter: acc: value
A: string id
B: object| Defines a property whose key is A for object B and store the value in the acc to the property. | +| 0xfb | PREF_NONE | callruntime.notifyconcurrentresult | Default input parameter: acc: return value of the concurrent function| Notifies the runtime of the return value of the concurrent function.
This instruction appears only in concurrent functions. | | 0xfc | (deprecated) | | | Deprecated operation code.| -| 0xfd | PREF_IMM16_V8_V8 | wide.createobjectwithexcludedkeys +AAAA, vBB, vCC | A: number of range registers
B: object
C, ..., C + A: attribute key value.| Based on object B, create an object excluding the key **C, ..., C + A** and store it in **acc**.
This instruction supports object creation by using destructor and extension syntax. | +| 0xfd | PREF_IMM16_V8_V8 | wide.createobjectwithexcludedkeys +AAAA, vBB, vCC | A: number of range registers
B: object
C, ..., C + A: property key value.| Based on object B, creates an object excluding the key **C, ..., C + A** and stores it in the acc.
This instruction supports object creation by using destructor and extension syntax. | | 0xfe | PREF_NONE | throw | Default input parameter: acc: exception| Throws the exception stored in acc. | -| 0x01fb | PREF_IMM8_V8_V8 | callruntime.definefieldbyvalue RR, vAA, vBB | Default input parameter: acc: value
A: attribute key
B: object| Define an attribute whose key is A for object B and store the value of **acc** to the attribute. | +| 0x01fb | PREF_IMM8_V8_V8 | callruntime.definefieldbyvalue RR, vAA, vBB | Default input parameter: acc: value
A: property key
B: object| Defines a property whose key is A for object B and store the value in the acc to the property. | | 0x01fc | (deprecated) | | | Deprecated operation code.| -| 0x01fd | PREF_IMM16_V8 | wide.newobjrange +AAAA, vBB | A: number of parameters
B: class object
B + 1, ..., B + A - 1: parameter passed to the constructor| Use **B + 1, ..., B + A - 1** as a parameter to create an instance of class B and store it in **acc**. | +| 0x01fd | PREF_IMM16_V8 | wide.newobjrange +AAAA, vBB | A: number of parameters
B: class object
B + 1, ..., B + A - 1: parameter passed to the constructor| Uses **B + 1, ..., B + A - 1** as a parameter to create an instance of class B and stores it in the acc. | | 0x01fe | PREF_NONE | throw.notexists | | Exception thrown: undefined method. | -| 0x02fb | PREF_IMM8_IMM32_V8 | callruntime.definefieldbyindex RR, +AAAAAAAA, vBB | Default input parameter: acc: value
A: attribute key
B: object| Define an attribute whose key is A for object B and store the value of **acc** to the attribute. | +| 0x02fb | PREF_IMM8_IMM32_V8 | callruntime.definefieldbyindex RR, +AAAAAAAA, vBB | Default input parameter: acc: value
A: property key
B: object| Defines a property whose key is A for object B and store the value in the acc to the property. | | 0x02fc | (deprecated) | | | Deprecated operation code.| -| 0x02fd | PREF_IMM16 | wide.newlexenv +AAAA | A: number of slots in the lexical environment| Create a lexical environment with slot A, store it in **acc**, and enter the lexical environment. | -| 0x02fe | PREF_NONE | throw.patternnoncoercible | | Exception thrown: This object cannot be forcibly executed. | -| 0x03fb | PREF_NONE | callruntime.topropertykey | Default input parameter: acc: value| Convert the value in **acc** to the attribute value. If the conversion fails, an error is thrown. | +| 0x02fd | PREF_IMM16 | wide.newlexenv +AAAA | A: number of slots in the lexical environment| Creates a lexical environment with slot A, stores it in the acc, and enters the lexical environment. | +| 0x02fe | PREF_NONE | throw.patternnoncoercible | | Throws an exception indicating that this object cannot be forcibly executed. | +| 0x03fb | PREF_NONE | callruntime.topropertykey | Default input parameter: acc: value| Converts the value in the acc to the property value. If the conversion fails, an error is thrown. | | 0x03fc | (deprecated) | | | Deprecated operation code.| -| 0x03fd | PREF_IMM16_ID16 | wide.newlexenvwithname +AAAA, @BBBB | A: number of slots in the lexical environment
B: literal id| Use the lexical variable name stored in the literal array corresponding to index B to create a lexical environment with A slots, store this lexical environment in **acc**, and enter. | -| 0x03fe | PREF_NONE | throw.deletesuperproperty | | Exception thrown: Delete the attribute of the parent class. | -| 0x04fb | PREF_IMM_16_ID16 | callruntime.createprivateproperty +AAAA, @BBBB | A: number of symbols to be created
B: literal id| Create A symbols. Obtain the stored private method from the literal array corresponding to index B. If a private instance method exists, an additional symbol ("method") will be created. Based on the creation sequence, place the created symbols at the end of the lexical environment where the current class is located.
This instruction appears only when a class is defined. | +| 0x03fd | PREF_IMM16_ID16 | wide.newlexenvwithname +AAAA, @BBBB | A: number of slots in the lexical environment
B: literal id| Uses the lexical variable name stored in the literal array corresponding to index B to create a lexical environment with A slots, stores this lexical environment in the acc, and enters the lexical environment. | +| 0x03fe | PREF_NONE | throw.deletesuperproperty | | Throws an exception indicating an attempt to delete the property of the parent class. | +| 0x04fb | PREF_IMM_16_ID16 | callruntime.createprivateproperty +AAAA, @BBBB | A: number of symbols to be created
B: literal id| Creates A symbols. Obtain the stored private method from the literal array corresponding to index B. If a private instance method exists, an additional symbol ("method") will be created. Based on the creation sequence, place the created symbols at the end of the lexical environment where the current class is located.
This instruction appears only when a class is defined. | | 0x04fc | (deprecated) | | | Deprecated operation code.| -| 0x04fd | PREF_IMM16_V8 | wide.callrange +AAAA, vBB | Default input parameter: acc: function object
A: number of parameters
B, ..., B + A - 1: parameter| Use **B, ..., B + A - 1** as a parameter to call the function object stored in **acc** and store the result in **acc**. | -| 0x04fe | PREF_V8 | throw.constassignment vAA | A: constant variable name| Exception thrown: Assign a value to a constant variable. | -| 0x05fb | PREF_IMM8_IMM_16_IMM_16_V8 | callruntime.defineprivateproperty RR, +AAAA, +BBBB, vCC | Default input parameter: acc: value
A: lexical environment level
B: slot number
C: object| Load the value of slot B in the lexical environment beyond A levels, change value to **acc**, and add it to object C as a private attribute. | +| 0x04fd | PREF_IMM16_V8 | wide.callrange +AAAA, vBB | Default input parameter: acc: function object
A: number of parameters
B, ..., B + A - 1: parameter| Uses **B, ..., B + A - 1** as a parameter to call the function object stored in the acc and stores the result in the acc. | +| 0x04fe | PREF_V8 | throw.constassignment vAA | A: constant variable name| Throws an exception indicating a value is assigned to a constant variable. | +| 0x05fb | PREF_IMM8_IMM_16_IMM_16_V8 | callruntime.defineprivateproperty RR, +AAAA, +BBBB, vCC | Default input parameter: acc: value
A: lexical environment level
B: slot number
C: object| Loads the value of slot B in the lexical environment beyond A levels, changes the value to **acc**, and adds it to object C as a private property. | | 0x05fc | (deprecated) | | | Deprecated operation code.| -| 0x05fd | PREF_IMM16_V8 | wide.callthisrange +AAAA, vBB | Default input parameter: acc: function object
A: number of parameters
B: object
B + 1, ..., B + A: parameter| Set **this** to **B**, call the function object stored in **acc** by setting **B + 1, ..., B + A** as the parameter, and store the result in **acc**. | -| 0x05fe | PREF_V8 | throw.ifnotobject vAA | A: Object| If A is not an object, an exception is thrown. | -| 0x06fb | PREF_IMM8_V8 | callruntime.callinit +RR, vAA | acc: function object
R: 8-bit reserved number used in Ark runtime
A: Object| Set **this** to **A**, call the function object stored in **acc** without passing parameters, and store the result in **acc**. | +| 0x05fd | PREF_IMM16_V8 | wide.callthisrange +AAAA, vBB | Default input parameter: acc: function object
A: number of parameters
B: object
B + 1, ..., B + A: parameter| Sets **this** to **B**, calls the function object stored in the acc by setting **B + 1, ..., B + A** as a parameter, and stores the result in the acc. | +| 0x05fe | PREF_V8 | throw.ifnotobject vAA | A: Object| Throws an exception if A is not an object. | +| 0x06fb | PREF_IMM8_V8 | callruntime.callinit +RR, vAA | acc: function object
R: 8-bit reserved number used in Ark runtime
A: Object| Sets **this** to **A**, calls the function object stored in the acc without passing parameters, and stores the result in the acc. | | 0x06fc | (deprecated) | | | Deprecated operation code.| -| 0x06fd | PREF_IMM16_V8 | wide.supercallthisrange +AAAA, vBB | A: number of parameters
B, ..., B + A - 1: parameter| Use **B, ..., B + A - 1** as the parameter to call the **super** function and store the result in **acc**.
When the value of **A** is **0**, the value of **B** is **undefined**.
This instruction appears only in non-arrow functions. | -| 0x06fe | PREF_V8_V8 | throw.undefinedifhole vAA, vBB | A: Object
B: object name| If the value of A is **hole**, the following exception is thrown: The value of B is **undefined**. | -| 0x07fb | PREF_IMM16_ID16_ID16_IMM16_V8 | callruntime.definesendableclass RRRR, @AAAA, @BBBB, +CCCC, vDD | R: 16-bit reserved number used in Ark runtime
A: method id of the constructor of [sendable class](arkts-sendable.md#sendable-class)
B: literal id
C: number of formal parameters of method A
D: parent class| Use the literal array corresponding to index B and parent class D to create a class object of A and store it in **acc**. | +| 0x06fd | PREF_IMM16_V8 | wide.supercallthisrange +AAAA, vBB | A: number of parameters
B, ..., B + A - 1: parameter| Uses **B, ..., B + A - 1** as a parameter to call the **super** function and stores the result in the acc.
When the value of **A** is **0**, the value of **B** is **undefined**.
This instruction appears only in non-arrow functions. | +| 0x06fe | PREF_V8_V8 | throw.undefinedifhole vAA, vBB | A: Object
B: object name| If the value of A is **hole**, throws an exception indicating that the value of B is **undefined**. | +| 0x07fb | PREF_IMM16_ID16_ID16_IMM16_V8 | callruntime.definesendableclass RRRR, @AAAA, @BBBB, +CCCC, vDD | R: 16-bit reserved number used in Ark runtime
A: method id of the constructor of [sendable class](arkts-sendable.md#sendable-class)
B: literal id
C: number of formal parameters of method A
D: parent class| Uses the literal array corresponding to index B and parent class D to create a class object of A and stores it in the acc. | | 0x07fc | (deprecated) | | | Deprecated operation code.| -| 0x07fd | PREF_IMM16_V8 | wide.supercallarrowrange +AAAA, vBB | Default input parameter: acc: class object
A: number of parameters
B, ..., B + A - 1: parameter| Use **B, ..., B + A - 1** as a parameter to call the constructor function of the parent class of the class stored in **acc** and store the result in **acc**.
If the value of A is **0**, B is **undefined**.
This instruction appears only in arrow functions. | -| 0x07fe | PREF_IMM8 | throw.ifsupernotcorrectcall +AA | Default input parameter: acc: object
A: error type| If **super** is not called properly, an error is thrown. | -| 0x08fb | PREF_IMM16 | callruntime.ldsendableclass +AAAA | A: lexical environment level| Store the [sendable class](arkts-sendable.md#sendable-class) of the lexical environment beyond A levels in **acc**. | +| 0x07fd | PREF_IMM16_V8 | wide.supercallarrowrange +AAAA, vBB | Default input parameter: acc: class object
A: number of parameters
B, ..., B + A - 1: parameter| Uses **B, ..., B + A - 1** as a parameter to call the constructor function of the parent class of the class stored in the acc and stores the result in the acc.
If the value of A is **0**, B is **undefined**.
This instruction appears only in arrow functions. | +| 0x07fe | PREF_IMM8 | throw.ifsupernotcorrectcall +AA | Default input parameter: acc: object
A: error type| Throws an exception if **super** is not called properly. | +| 0x08fb | PREF_IMM16 | callruntime.ldsendableclass +AAAA | A: lexical environment level| Stores the [Sendable class](arkts-sendable.md#sendable-class) of the lexical environment beyond A levels in the acc. | | 0x08fc | (deprecated) | | | Deprecated operation code.| -| 0x08fd | PREF_IMM32 | wide.ldobjbyindex +AAAAAAAA | Default input parameter: acc: object
A: attribute key| Load the attribute whose key is A of the object stored in **acc** and store the attribute in **acc**. | -| 0x08fe | PREF_IMM16 | throw.ifsupernotcorrectcall +AAAA | Default input parameter: acc: object
A: error type| If **super** is not called properly, an error is thrown. | -| 0x09fb | PREF_IMM8 | callruntime.ldsendableexternalmodulevar +AA | A: slot number| Store the external module variable of slot A in **acc**. This instruction is used only in the sendable class and [sendable function](arkts-sendable.md#sendable-function). | +| 0x08fd | PREF_IMM32 | wide.ldobjbyindex +AAAAAAAA | Default input parameter: acc: object
A: property key| Loads the property whose key is A of the object stored in the acc and stores the property in the acc. | +| 0x08fe | PREF_IMM16 | throw.ifsupernotcorrectcall +AAAA | Default input parameter: acc: object
A: error type| Throws an exception if **super** is not called properly. | +| 0x09fb | PREF_IMM8 | callruntime.ldsendableexternalmodulevar +AA | A: slot number| Stores the external module variable of slot A in the acc. This instruction is used only in Sendable classes and [Sendable functions](arkts-sendable.md#sendable-function). | | 0x09fc | (deprecated) | | | Deprecated operation code.| -| 0x09fd | PREF_V8_IMM32 | wide.stobjbyindex vAA, +BBBBBBBB | Default input parameter: acc: value
A: Object
B: attribute key| Store the value in **acc** to the attribute whose key is B of object A. | -| 0x09fe | PREF_ID16 | throw.undefinedifholewithname @AAAA | Default input parameter: acc: object
A: string id| If the value of **acc** is **hole**, the following exception is thrown: The value of A is **undefined**. | -| 0x0afb | PREF_IMM16 | callruntime.wideldsendableexternalmodulevar +AAAA | A: slot number| Store the external module variable of slot A in **acc**. This command is used only in the sendable class and sendable function. | +| 0x09fd | PREF_V8_IMM32 | wide.stobjbyindex vAA, +BBBBBBBB | Default input parameter: acc: value
A: Object
B: property key| Stores the value in the acc to the property whose key is B of object A. | +| 0x09fe | PREF_ID16 | throw.undefinedifholewithname @AAAA | Default input parameter: acc: object
A: string id| If the value in the acc is **hole**, throws an exception indicating that the value of A is **undefined**. | +| 0x0afb | PREF_IMM16 | callruntime.wideldsendableexternalmodulevar +AAAA | A: slot number| Stores the external module variable of slot A in the acc. This instruction is used only in Sendable classes and Sendable functions. | | 0x0afc | (deprecated) | | | Deprecated operation code.| -| 0x0afd | PREF_V8_IMM32 | wide.stownbyindex vAA, +BBBBBBBB | Default input parameter: acc: value
A: Object
B: attribute key| Store the value in **acc** to the attribute whose key is B of object A. | -| 0x0bfb | PREF_IMM8 | callruntime.newsendableenv +AA | A: number of slots in a shared lexical environment| Create a shared lexical environment with slot A and enter the lexical environment. | +| 0x0afd | PREF_V8_IMM32 | wide.stownbyindex vAA, +BBBBBBBB | Default input parameter: acc: value
A: Object
B: property key| Stores the value in the acc to the property whose key is B of object A. | +| 0x0bfb | PREF_IMM8 | callruntime.newsendableenv +AA | A: number of slots in a shared lexical environment| Creates a shared lexical environment with slot A and enters the lexical environment. | | 0x0bfc | (deprecated) | | | Deprecated operation code.| -| 0x0bfd | PREF_IMM16 | wide.copyrestargs +AAAA | A: start position of the rest parameters in the formal parameter list| Copy the rest parameters and store the parameter array copy in **acc**. | -| 0x0cfb | PREF_IMM16 | callruntime.widenewsendableenv +AAAA | A: number of slots in a shared lexical environment| Create a shared lexical environment with slot A and enter the lexical environment. | +| 0x0bfd | PREF_IMM16 | wide.copyrestargs +AAAA | A: start position of the rest parameters in the formal parameter list| Copies the rest parameters and stores the parameter array copy in the acc. | +| 0x0cfb | PREF_IMM16 | callruntime.widenewsendableenv +AAAA | A: number of slots in a shared lexical environment| Creates a shared lexical environment with slot A and enters the lexical environment. | | 0x0cfc | (deprecated) | | | Deprecated operation code.| -| 0x0cfd | PREF_IMM16_IMM16 | wide.ldlexvar +AAAA, +BBBB | A: lexical environment level
B: slot number| Store the value of slot B in the lexical environment beyond A levels in **acc**. | -| 0x0dfb | PREF_IMM4_IMM4 | callruntime.stsendablevar +A +B | Default input parameter: acc: value
A: Shared lexical environment level
B: slot number| Store the value in **acc** to slot B in the lexical environment beyond A levels. | +| 0x0cfd | PREF_IMM16_IMM16 | wide.ldlexvar +AAAA, +BBBB | A: lexical environment level
B: slot number| Stores the value of slot B in the lexical environment beyond A levels in the acc. | +| 0x0dfb | PREF_IMM4_IMM4 | callruntime.stsendablevar +A +B | Default input parameter: acc: value
A: shared lexical environment level
B: slot number| Stores the value in the acc to slot B in the shared lexical environment beyond A levels. | | 0x0dfc | (deprecated) | | | Deprecated operation code.| -| 0x0dfd | PREF_IMM16_IMM16 | wide.stlexvar +AAAA, +BBBB | Default input parameter: acc: value
A: lexical environment level
B: slot number| Store the value in **acc** to slot B in the lexical environment beyond A levels. | -| 0x0efb | PREF_IMM8_IMM8 | callruntime.stsendablevar +AA +BB | Default input parameter: acc: value
A: Shared lexical environment level
B: slot number | Store the value in **acc** to slot B in the lexical environment beyond A levels. | +| 0x0dfd | PREF_IMM16_IMM16 | wide.stlexvar +AAAA, +BBBB | Default input parameter: acc: value
A: lexical environment level
B: slot number| Stores the value in the acc to slot B in the lexical environment beyond A levels. | +| 0x0efb | PREF_IMM8_IMM8 | callruntime.stsendablevar +AA +BB | Default input parameter: acc: value
A: shared lexical environment level
B: slot number | Stores the value in the acc to slot B in the shared lexical environment beyond A levels. | | 0x0efc | (deprecated) | | | Deprecated operation code.| -| 0x0efd | PREF_IMM16 | wide.getmodulenamespace +AAAA | A: module index| Execute the [GetModuleNamespace](https://262.ecma-international.org/12.0/#sec-getmodulenamespace) instruction for module A and store the result in **acc**. | -| 0x0ffb | PREF_IMM16_IMM16 | callruntime.widestsendablevar +AAAA +BBBB | Default input parameter: acc: value
A: Shared lexical environment level
B: slot number| Store the value in **acc** to slot B in the lexical environment beyond A levels. | +| 0x0efd | PREF_IMM16 | wide.getmodulenamespace +AAAA | A: module index| Executes the [GetModuleNamespace](https://262.ecma-international.org/12.0/#sec-getmodulenamespace) instruction for module A and stores the result in the acc. | +| 0x0ffb | PREF_IMM16_IMM16 | callruntime.widestsendablevar +AAAA +BBBB | Default input parameter: acc: value
A: shared lexical environment level
B: slot number| Stores the value in the acc to slot B in the shared lexical environment beyond A levels. | | 0x0ffc | (deprecated) | | | Deprecated operation code.| -| 0x0ffd | PREF_IMM16 | wide.stmodulevar +AAAA | Default input parameter: acc: value
A: slot number| Store the value of **acc** to the module variable of slot A. | -| 0x10fb | PREF_IMM4_IMM4 | callruntime.ldsendablevar +A +B | A: Shared lexical environment level
B: slot number | Store the value of slot B in the lexical environment beyond A levels in **acc**. | +| 0x0ffd | PREF_IMM16 | wide.stmodulevar +AAAA | Default input parameter: acc: value
A: slot number| Stores the value in the acc to the module variable of slot A. | +| 0x10fb | PREF_IMM4_IMM4 | callruntime.ldsendablevar +A +B | A: shared lexical environment level
B: slot number | Stores the value of slot B in the shared lexical environment beyond A levels in the acc. | | 0x10fc | (deprecated) | | | Deprecated operation code.| -| 0x10fd | PREF_IMM16 | wide.ldlocalmodulevar +AAAA | A: slot number| Store the local module variables of slot A in **acc**.| -| 0x11fb | PREF_IMM8_IMM8 | callruntime.ldsendablevar +AA + BB | A: Shared lexical environment level
B: slot number | Store the value of slot B in the lexical environment beyond A levels in **acc**. | +| 0x10fd | PREF_IMM16 | wide.ldlocalmodulevar +AAAA | A: slot number| Stores the local module variables of slot A in the acc.| +| 0x11fb | PREF_IMM8_IMM8 | callruntime.ldsendablevar +AA + BB | A: shared lexical environment level
B: slot number | Stores the value of slot B in the shared lexical environment beyond A levels in the acc. | | 0x11fc | (deprecated) | | | Deprecated operation code.| -| 0x11fd | PREF_IMM16 | wide.ldexternalmodulevar +AAAA | A: slot number| Store the external module variable of slot A in **acc**.| -| 0x12fb | PREF_IMM16_IMM16 | callruntime.wideldsendablevar +AAAA +BBBB | A: Shared lexical environment level
B: slot number| Store the value of slot B in the lexical environment beyond A levels in **acc**. | +| 0x11fd | PREF_IMM16 | wide.ldexternalmodulevar +AAAA | A: slot number| Stores the external module variable of slot A in the acc.| +| 0x12fb | PREF_IMM16_IMM16 | callruntime.wideldsendablevar +AAAA +BBBB | A: shared lexical environment level
B: slot number| Stores the value of slot B in the shared lexical environment beyond A levels in the acc. | | 0x12fc | (deprecated) | | | Deprecated operation code.| -| 0x12fd | PREF_IMM16 | wide.ldpatchvar +AAAA | A: slot number of the patch variable| Load the patch variable of slot A to **acc**.
This instruction is used only build scenarios under the patch mode.| -| 0x13fb | PREF_IMM8 | callruntime.istrue +RR | Default input parameter: acc: operand
R: 8-bit reserved number used in Ark runtime| Calculate **acc == true** and store the result in **acc**. | +| 0x12fd | PREF_IMM16 | wide.ldpatchvar +AAAA | A: slot number of the patch variable| Loads the patch variable of slot A to the acc.
This instruction is used only build scenarios under the patch mode.| +| 0x13fb | PREF_IMM8 | callruntime.istrue +RR | Default input parameter: acc: operand
R: 8-bit reserved number used in Ark runtime| Calculates `acc == true` and stores the result in the acc. | | 0x13fc | (deprecated) | | | Deprecated operation code.| -| 0x13fd | PREF_IMM16 | wide.stpatchvar +AAAA | Default input parameter: acc: value
A: slot number of the patch variable| Store the value of **acc** to the patch variable of slot A.
This instruction is used only build scenarios under the patch mode.| -| 0x14fb | PREF_IMM8 | callruntime.isfalse +RR | Default input parameter: acc: operand
R: 8-bit reserved number used in Ark runtime| Calculate **acc == false** and store the result in **acc**. | -| 0x15fb | PREF_IMM8 | callruntime.ldlazymodulevar +AA | A: slot number| Store the external module variable of slot A in **acc**. This directive applies only to module variables imported using [lazy import](arkts-lazy-import.md). | -| 0x16fb | PREF_IMM16 | callruntime.wideldlazymodulevar +AAAA | A: slot number| Store the external module variable of slot A in **acc**. This directive applies only to module variables imported using lazy import. | -| 0x17fb | PREF_IMM8 | callruntime.ldlazysendablemodulevar +AA | A: slot number| Store the external module variable of slot A in **acc**. This directive applies only to module variables imported through lazy import and appears only in sendable classes and sendable functions. | -| 0x18fb | PREF_IMM16 | callruntime.wideldlazysendablemodulevar +AAAA | A: slot number| Store the external module variable of slot A in **acc**. This directive applies only to module variables imported through lazy import and appears only in sendable classes and sendable functions. | +| 0x13fd | PREF_IMM16 | wide.stpatchvar +AAAA | Default input parameter: acc: value
A: slot number of the patch variable| Stores the value in the acc to the patch variable of slot A.
This instruction is used only build scenarios under the patch mode.| +| 0x14fb | PREF_IMM8 | callruntime.isfalse +RR | Default input parameter: acc: operand
R: 8-bit reserved number used in Ark runtime| Calculates `acc == false` and stores the result in the acc. | +| 0x15fb | PREF_IMM8 | callruntime.ldlazymodulevar +AA | A: slot number| Stores the external module variable of slot A in the acc. This instruction applies only to module variables imported using [lazy import](arkts-lazy-import.md). | +| 0x16fb | PREF_IMM16 | callruntime.wideldlazymodulevar +AAAA | A: slot number| Stores the external module variable of slot A in the acc. This instruction applies only to module variables imported using lazy import. | +| 0x17fb | PREF_IMM8 | callruntime.ldlazysendablemodulevar +AA | A: slot number| Stores the external module variable of slot A in the acc. This instruction applies only to module variables imported through lazy import and appears only in Sendable classes and Sendable functions. | +| 0x18fb | PREF_IMM16 | callruntime.wideldlazysendablemodulevar +AAAA | A: slot number| Stores the external module variable of slot A in the acc. This instruction applies only to module variables imported through lazy import and appears only in Sendable classes and Sendable functions. | | 0x14fc
0x15fc
...
0x2efc | (deprecated) | | | Deprecated operation code.| diff --git a/en/application-dev/arkts-utils/arkts-bytecode-overview.md b/en/application-dev/arkts-utils/arkts-bytecode-overview.md index 1939f7ee64994fc88e4d143c76a4fe90f3f9311e..d7d77d9a600e7057f83c29b04ea5084ae85b367c 100644 --- a/en/application-dev/arkts-utils/arkts-bytecode-overview.md +++ b/en/application-dev/arkts-utils/arkts-bytecode-overview.md @@ -1,11 +1,11 @@ -# Ark Bytecode Overview +# Overview of Ark Bytecode -The ARK bytecode file is a binary product generated after ArkTS/TS/JS compilation. This section describes each part of the ARK bytecode file to help you understand the content of the bytecode file and analyze and modify the bytecode. +The Ark bytecode file is a binary output generated from compiling ArkTS/TS/JS code. The following content is provided, helping you understand the structure and content of Ark bytecode files, thereby effectively analyzing and modifying bytecode. -- ARK bytecode file format: describes the structure information of each part in the bytecode file, and the storage mode and dependency of each structure. +- Ark bytecode file format: describes the composition of Ark bytecode files, including information about data structures within the file, how they are stored, and their interdependencies. -- Basic principles of Ark bytecode: describes the important concepts, formats, and meanings of instructions in bytecode, helping developers understand Ark bytecode instructions and develop instruction-related features. +- Basic principles of Ark bytecode: describes the fundamental concepts, formats, and meanings of bytecode instructions, helping you understand these instructions and develop features related to bytecode manipulation. -- Ark bytecode function naming rules: describes the naming rules of function names in bytecode files. +- Naming conventions for Ark bytecode functions: describes the naming conversions for functions within bytecode files. -- Customizing Ark Bytecode During Compilation: describes how to modify the content of a bytecode file. +- Customizing Ark bytecode during compilation: describes how to modify the content of a bytecode file at compile time. diff --git a/en/application-dev/arkts-utils/arkts-collections-introduction.md b/en/application-dev/arkts-utils/arkts-collections-introduction.md index f69552cb1795a51bdc12f06ccefbde6c288358b9..0fdf2c6cb46ae2727fdd5fa57140bd6b6437cab8 100644 --- a/en/application-dev/arkts-utils/arkts-collections-introduction.md +++ b/en/application-dev/arkts-utils/arkts-collections-introduction.md @@ -2,22 +2,22 @@ ## ArkTS Collections -The ArkTS shared container ([@arkts.collections (ArkTS Collections)](../reference/apis-arkts/js-apis-arkts-collections.md)) is a container class for shared transmission between concurrent tasks and can be used for high-performance data transmission in concurrent scenarios. The functions of the container are similar to those of the container defined in the Ecmascript262 specification, but there are still some differences. For details, see [Behavior Differences Between Shared Container APIs and Native APIs](#behavior-differences-between-shared-container-apis-and-native-apis). +ArkTS shared containers ([@arkts.collections (ArkTS Collections)](../reference/apis-arkts/js-apis-arkts-collections.md)) are designed for high-performance data transmission between concurrent tasks. They offer similar functionality to the containers defined in the ECMAScript 262 specification but with some key differences, which are outlined in the [Behavior Differences Between Shared Container APIs and Native APIs](#behavior-differences-between-shared-container-apis-and-native-apis). -When an ArkTS shared container is transferred between multiple concurrent tasks, the default behavior is reference transfer. Multiple concurrent tasks can operate the same container instance. Pass-by-copy is also supported. In this mode, each concurrent instance holds an ArkTS container instance. +By default, ArkTS shared containers are passed by reference, allowing multiple concurrent tasks to manipulate the same container instance. They also support pass-by-copy, where each concurrent task holds an ArkTS container instance. -ArkTS containers are not thread-safe. They adopt the fail-fast approach. An exception is thrown if multiple concurrent instances make structural changes to a container instance at the same time. Therefore, when modifying attributes in a container, you need to use the asynchronous lock (arkts-async-lock-introduction.md) mechanism provided by ArkTS to ensure secure access to the ArkTS container. +ArkTS shared containers are not thread-safe and employ a fail-fast mechanism to prevent concurrent structural modifications, which would otherwise trigger exceptions. When modifying container properties, you must use the [asynchronous lock](arkts-async-lock-introduction.md) mechanism to ensure safe access. -ArkTS shared containers include [Array](../reference/apis-arkts/js-apis-arkts-collections.md#collectionsarray), [Map](../reference/apis-arkts/js-apis-arkts-collections.md#collectionsmap), [Set](../reference/apis-arkts/js-apis-arkts-collections.md#collectionsset), [TypedArray](../reference/apis-arkts/js-apis-arkts-collections.md#collectionstypedarray) (Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, Uint8ClampedArray and Float32Array), and [ArrayBuffer](../reference/apis-arkts/js-apis-arkts-collections.md#collectionsarraybuffer). For details, see [@arkts.collections (ArkTS Collections)](../reference/apis-arkts/js-apis-arkts-collections.md). +The ArkTS shared containers include the following types: [Array](../reference/apis-arkts/js-apis-arkts-collections.md#collectionsarray), [Map](../reference/apis-arkts/js-apis-arkts-collections.md#collectionsmap), [Set](../reference/apis-arkts/js-apis-arkts-collections.md#collectionsset), [TypedArray](../reference/apis-arkts/js-apis-arkts-collections.md#collectionstypedarray) (Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, Uint8ClampedArray, and Float32Array), and [ArrayBuffer](../reference/apis-arkts/js-apis-arkts-collections.md#collectionsarraybuffer). For details, see [@arkts.collections (ArkTS Collections)](../reference/apis-arkts/js-apis-arkts-collections.md). -The following is an example of using a container set: +The following is an example of using the collection: ```ts import { ArkTSUtils, collections, taskpool } from '@kit.ArkTS'; @Concurrent async function add(arr: collections.Array, lock: ArkTSUtils.locks.AsyncLock) { - await lock.lockAsync (() => { // If no asynchronous lock is added, the task will fail due to data contention conflicts. + await lock.lockAsync(() => { // Without the asynchronous lock, the task will fail due to data race conflicts. arr[0]++; }) } @@ -60,41 +60,41 @@ struct Index { ## Behavior Differences Between Shared Container APIs and Native APIs -ArkTS provides a shared container set related to Sendable data. The API behavior is different from that of the native API. For details, see the following comparison. +ArkTS provides shared containers for Sendable data, with some behavior differences when compared with native APIs. These differences are detailed below. -> **Note** +> **NOTE** > -> The type of the ArkTS shared container is different from that of the native container defined in the Ecmascript262 specification. Therefore, when the isArray () method of the native container array is used to determine the collections.Array instance object, false is returned. +> ArkTS shared containers have different types from native ECMAScript containers. Therefore, if the native **isArray()** method is used on a **collections.Array instance** object, **false** is returned. ### Array -A native container array can be converted into an ArkTS array using the [collections.Array.from](../reference/apis-arkts/js-apis-arkts-collections.md#from) method. An ArkTS array can be converted into a native container array using the from method of the native container array. +Native Array containers can be converted into ArkTS Array containers using the [collections.Array.from](../reference/apis-arkts/js-apis-arkts-collections.md#from) method, and ArkTS Array containers can be converted into native Array containers using the native **from** method. | Native API| ArkTS Collections API| Behavior Difference Exists| Different Behavior in ArkTS Collections| | -------- | -------- | -------- | -------- | -| length: number | readonly length: number | Supported| To prevent the spread of undefined, it is not allowed to set **length**.| -| new(arrayLength ?: number): any[] | static create(arrayLength: number, initialValue: T): Array | Supported| To prevent the spread of undefined, a constructor must be provided with an initial value.| +| length: number | readonly length: number | Yes| To prevent the spread of **undefined**, it is not allowed to set **length**.| +| new(arrayLength ?: number): any[] | static create(arrayLength: number, initialValue: T): Array | Yes| To prevent the spread of **undefined**, a constructor must be provided with an initial value.| | new <T>(arrayLength: number): T[] | constructor() | No| / | -| new <T>(...items: T[]): T[] | constructor(first: T, ...left: T[]) | Supported| To prevent the spread of undefined, a constructor must be provided with an initial value. In inheritance scenarios, this constructor cannot be called to construct an object.| +| new <T>(...items: T[]): T[] | constructor(first: T, ...left: T[]) | Yes| To prevent the spread of **undefined**, a constructor must be provided with an initial value. In inheritance scenarios, this constructor cannot be called to construct an object.| | from<T>(arrayLike: ArrayLike<T>): T[] | static from<T>(arrayLike: ArrayLike<T>): Array<T> | No| / | -| pop(): T \| undefined | pop(): T \| undefined | Supported| It is not allowed to add, delete, or modify elements during traversal or access. Otherwise, an exception is thrown.| -| push(...items: T[]): number | push(...items: T[]): number | Supported| It is not allowed to add, delete, or modify elements during traversal or access. Otherwise, an exception is thrown.| -| concat(...items: ConcatArray<T>[]): T[] | concat(...items: ConcatArray<T>[]): Array<T> | Supported| It is not allowed to add, delete, or modify elements during traversal or access. Otherwise, an exception is thrown.| -| concat(...items: (T \| ConcatArray<T>)[]): T[] | concat(...items: ConcatArray<T>[]): Array<T> | Supported| It is not allowed to add, delete, or modify elements during traversal or access. Otherwise, an exception is thrown.| +| pop(): T \| undefined | pop(): T \| undefined | Yes| It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown.| +| push(...items: T[]): number | push(...items: T[]): number | Yes| It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown.| +| concat(...items: ConcatArray<T>[]): T[] | concat(...items: ConcatArray<T>[]): Array<T> | Yes| It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown.| +| concat(...items: (T \| ConcatArray<T>)[]): T[] | concat(...items: ConcatArray<T>[]): Array<T> | Yes| It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown.| | join(separator?: string): string | join(separator?: string): string | No| / | -| shift(): T \| undefined | shift(): T \| undefined | Supported| It is not allowed to add, delete, or modify elements during traversal or access. Otherwise, an exception is thrown.| +| shift(): T \| undefined | shift(): T \| undefined | Yes| It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown.| | slice(start?: number, end?: number): T[] | slice(start?: number, end?: number): Array<T> | No| / | -| sort(compareFn?: (a: T, b: T) => number): this | sort(compareFn?: (a: T, b: T) => number): Array<T> | Supported| 1. It is not allowed to add, delete, or modify elements during traversal or access. Otherwise, an exception is thrown.
2. In inheritance scenarios, the actual return value type cannot be obtained.| -| unshift(...items: T[]): number | unshift(...items: T[]): number | Supported| It is not allowed to add, delete, or modify elements during traversal or access. Otherwise, an exception is thrown.| +| sort(compareFn?: (a: T, b: T) => number): this | sort(compareFn?: (a: T, b: T) => number): Array<T> | Yes| 1. It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown.
2. In inheritance scenarios, the actual type of the return value cannot be obtained.| +| unshift(...items: T[]): number | unshift(...items: T[]): number | Yes| It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown.| | indexOf(searchElement: T, fromIndex?: number): number | indexOf(searchElement: T, fromIndex?: number): number | No| / | -| forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void | forEach(callbackFn: (value: T, index: number, array: Array<T>) => void): void | Supported| ArkTS does not support **this**. As a result, **thisArg** is not supported.| -| map<U>(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[] | map<U>(callbackFn: (value: T, index: number, array: Array<T>) => U): Array<U> | Supported| ArkTS does not support **this**. As a result, **thisArg** is not supported.| -| filter(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): T[] | filter(predicate: (value: T, index: number, array: Array<T>) => boolean): Array<T> | Supported| ArkTS does not support **this**. As a result, **thisArg** is not supported.| +| forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void | forEach(callbackFn: (value: T, index: number, array: Array<T>) => void): void | Yes| ArkTS does not support **this**. As a result, the **thisArg** parameter is not supported.| +| map<U>(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[] | map<U>(callbackFn: (value: T, index: number, array: Array<T>) => U): Array<U> | Yes| ArkTS does not support **this**. As a result, the **thisArg** parameter is not supported.| +| filter(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): T[] | filter(predicate: (value: T, index: number, array: Array<T>) => boolean): Array<T> | Yes| ArkTS does not support **this**. As a result, the **thisArg** parameter is not supported.| | reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T | reduce(callbackFn: (previousValue: T, currentValue: T, currentIndex: number, array: Array<T>) => T): T | No| / | | reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U | reduce<U>(callbackFn: (previousValue: U, currentValue: T, currentIndex: number, array: Array<T>) => U, initialValue: U): U | No| / | -| [n: number]: T | [index: number]: T | Supported| It is not allowed to add, delete, or modify elements during traversal or access. Otherwise, an exception is thrown.| -| findIndex(predicate: (value: T, index: number, obj: T[]) => unknown, thisArg?: any): number | findIndex(predicate: (value: T, index: number, obj: Array<T>) => boolean): number | Yes| ArkTS does not support **this**. As a result, **thisArg** is not supported.| -| fill(value: T, start?: number, end?: number): this | fill(value: T, start?: number, end?: number): Array<T> | Supported| 1. It is not allowed to add, delete, or modify elements during traversal or access. Otherwise, an exception is thrown.
2. In inheritance scenarios, the actual return value type cannot be obtained.| +| [n: number]: T | [index: number]: T | Yes| It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown.| +| findIndex(predicate: (value: T, index: number, obj: T[]) => unknown, thisArg?: any): number | findIndex(predicate: (value: T, index: number, obj: Array<T>) => boolean): number | Yes| ArkTS does not support **this**. As a result, the **thisArg** parameter is not supported.| +| fill(value: T, start?: number, end?: number): this | fill(value: T, start?: number, end?: number): Array<T> | Yes| 1. It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown.
2. In inheritance scenarios, the actual type of the return value cannot be obtained.| | entries(): IterableIterator<[number, T]> | entries(): IterableIterator<[number, T]> | No| / | | keys(): IterableIterator<number> | keys(): IterableIterator<number> | No| / | | values(): IterableIterator<T> | values(): IterableIterator<T> | No| / | @@ -111,7 +111,7 @@ A native container array can be converted into an ArkTS array using the [collect ### TypedArray (Int8Array Used as an Example) -The native container TypedArray can be converted to the ArkTS TypedArray container using the [collections.TypedArray.from](../reference/apis-arkts/js-apis-arkts-collections.md#from-1) method. The ArkTS TypedArray container can be converted to the native container TypedArray using the from method of the native container TypedArray. +Native TypedArray containers can be converted into ArkTS TypedArray containers using the [collections.TypedArray.from](../reference/apis-arkts/js-apis-arkts-collections.md#from-1) method, and ArkTS TypedArray containers can be converted into native TypedArray containers using the native **from** method. | Native API| ArkTS Collections API| Behavior Difference Exists| Different Behavior in ArkTS Collections| | -------- | -------- | -------- | -------- | @@ -120,26 +120,26 @@ The native container TypedArray can be converted to the ArkTS TypedArray contain | readonly byteOffset: number | readonly byteOffset: number | No| / | | readonly length: number | readonly length: number | No| / | | readonly BYTES_PER_ELEMENT: number | static readonly BYTES_PER_ELEMENT: number | No| / | -| copyWithin(target: number, start: number, end?: number): this | copyWithin(target: number, start: number, end?: number): Int8Array | Supported| It is not allowed to add, delete, or modify elements during traversal or access. Otherwise, an exception is thrown.| -| every(predicate: (value: number, index: number, array: Int8Array) => unknown, thisArg?: any): boolean | every(predicate: TypedArrayPredicateFn<number, Int8Array>): boolean | Supported| 1. It is not allowed to add, delete, or modify elements during traversal or access. Otherwise, an exception is thrown.
2. ArkTS does not support **this**. As a result, **thisArg** is not supported.| -| fill(value: number, start?: number, end?: number): this | fill(value: number, start?: number, end?: number): Int8Array | Supported| It is not allowed to add, delete, or modify elements during traversal or access. Otherwise, an exception is thrown.| -| filter(predicate: (value: number, index: number, array: Int8Array) => any, thisArg?: any): Int8Array | filter(predicate: TypedArrayPredicateFn<number, Int8Array>): Int8Array | Supported| 1. It is not allowed to add, delete, or modify elements during traversal or access. Otherwise, an exception is thrown.
2. ArkTS does not support **this**. As a result, **thisArg** is not supported.| -| find(predicate: (value: number, index: number, obj: Int8Array) => boolean, thisArg?: any): number \| undefined | find(predicate: TypedArrayPredicateFn<number, Int8Array>): number \| undefined | Supported| 1. It is not allowed to add, delete, or modify elements during traversal or access. Otherwise, an exception is thrown.
2. ArkTS does not support **this**. As a result, **thisArg** is not supported.| -| findIndex(predicate: (value: number, index: number, obj: Int8Array) => boolean, thisArg?: any): number | findIndex(predicate: TypedArrayPredicateFn<number, Int8Array>): number | Supported| ArkTS does not support **this**. As a result, **thisArg** is not supported.| -| forEach(callbackfn: (value: number, index: number, array: Int8Array) => void, thisArg?: any): void | forEach(callbackFn: (value: number, index: number, array: Int8Array) => void): void | Supported| 1. It is not allowed to add, delete, or modify elements during traversal or access. Otherwise, an exception is thrown.
2. ArkTS does not support **this**. As a result, **thisArg** is not supported.| +| copyWithin(target: number, start: number, end?: number): this | copyWithin(target: number, start: number, end?: number): Int8Array | Yes| It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown.| +| every(predicate: (value: number, index: number, array: Int8Array) => unknown, thisArg?: any): boolean | every(predicate: TypedArrayPredicateFn<number, Int8Array>): boolean | Yes| 1. It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown.
2. ArkTS does not support **this**. As a result, the **thisArg** parameter is not supported.| +| fill(value: number, start?: number, end?: number): this | fill(value: number, start?: number, end?: number): Int8Array | Yes| It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown.| +| filter(predicate: (value: number, index: number, array: Int8Array) => any, thisArg?: any): Int8Array | filter(predicate: TypedArrayPredicateFn<number, Int8Array>): Int8Array | Yes| 1. It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown.
2. ArkTS does not support **this**. As a result, the **thisArg** parameter is not supported.| +| find(predicate: (value: number, index: number, obj: Int8Array) => boolean, thisArg?: any): number \| undefined | find(predicate: TypedArrayPredicateFn<number, Int8Array>): number \| undefined | Yes| 1. It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown.
2. ArkTS does not support **this**. As a result, the **thisArg** parameter is not supported.| +| findIndex(predicate: (value: number, index: number, obj: Int8Array) => boolean, thisArg?: any): number | findIndex(predicate: TypedArrayPredicateFn<number, Int8Array>): number | Yes| ArkTS does not support **this**. As a result, the **thisArg** parameter is not supported.| +| forEach(callbackfn: (value: number, index: number, array: Int8Array) => void, thisArg?: any): void | forEach(callbackFn: (value: number, index: number, array: Int8Array) => void): void | Yes| 1. It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown.
2. ArkTS does not support **this**. As a result, the **thisArg** parameter is not supported.| | indexOf(searchElement: number, fromIndex?: number): number | indexOf(searchElement: number, fromIndex?: number): number | No| / | | join(separator?: string): string | join(separator?: string): string | No| / | -| map(callbackfn: (value: number, index: number, array: Int8Array) => number, thisArg?: any): Int8Array | map(callbackFn: TypedArrayForEachCallback<number, Int8Array>): Int8Array | Supported| 1. It is not allowed to add, delete, or modify elements during traversal or access. Otherwise, an exception is thrown.
2. ArkTS does not support **this**. As a result, **thisArg** is not supported.| +| map(callbackfn: (value: number, index: number, array: Int8Array) => number, thisArg?: any): Int8Array | map(callbackFn: TypedArrayForEachCallback<number, Int8Array>): Int8Array | Yes| 1. It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown.
2. ArkTS does not support **this**. As a result, the **thisArg** parameter is not supported.| | reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int8Array) => number): number | reduce(callbackFn: TypedArrayReduceCallback<number, number, Int8Array>): number | No| / | | reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int8Array) => number, initialValue: number): number | reduce(callbackFn: TypedArrayReduceCallback<number, number, Int8Array>, initialValue: number): number | No| / | | reduce<U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Int8Array) => U, initialValue: U): U | reduce<U>(callbackFn: TypedArrayReduceCallback<U, number, Int8Array>, initialValue: U): U | No| / | | reverse(): Int8Array | reverse(): Int8Array | No| / | -| set(array: ArrayLike<number>, offset?: number): void | set(array: ArrayLike<number>, offset?: number): void | Supported| It is not allowed to add, delete, or modify elements during traversal or access. Otherwise, an exception is thrown.| +| set(array: ArrayLike<number>, offset?: number): void | set(array: ArrayLike<number>, offset?: number): void | Yes| It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown.| | slice(start?: number, end?: number): Int8Array | slice(start?: number, end?: number): Int8Array | No| / | -| some(predicate: (value: number, index: number, array: Int8Array) => unknown, thisArg?: any): boolean | some(predicate: TypedArrayPredicateFn<number, Int8Array>): boolean | Supported| ArkTS does not support **this**. As a result, **thisArg** is not supported.| -| sort(compareFn?: (a: number, b: number) => number): this | sort(compareFn?: TypedArrayCompareFn<number>): Int8Array | Supported| 1. It is not allowed to add, delete, or modify elements during traversal or access. Otherwise, an exception is thrown.
2. In inheritance scenarios, the actual return value type cannot be obtained.| -| subarray(begin?: number, end?: number): Int8Array | subarray(begin?: number, end?: number): Int8Array | Supported| It is not allowed to add, delete, or modify elements during traversal or access. Otherwise, an exception is thrown.| -| [index: number]: number | [index: number]: number | Supported| It is not allowed to add, delete, or modify elements during traversal or access. Otherwise, an exception is thrown.| +| some(predicate: (value: number, index: number, array: Int8Array) => unknown, thisArg?: any): boolean | some(predicate: TypedArrayPredicateFn<number, Int8Array>): boolean | Yes| ArkTS does not support **this**. As a result, the **thisArg** parameter is not supported.| +| sort(compareFn?: (a: number, b: number) => number): this | sort(compareFn?: TypedArrayCompareFn<number>): Int8Array | Yes| 1. It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown.
2. In inheritance scenarios, the actual type of the return value cannot be obtained.| +| subarray(begin?: number, end?: number): Int8Array | subarray(begin?: number, end?: number): Int8Array | Yes| It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown.| +| [index: number]: number | [index: number]: number | Yes| It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown.| | entries(): IterableIterator<[number, number]> | entries(): IterableIterator<[number, number]> | No| / | | keys(): IterableIterator<number> | keys(): IterableIterator<number> | No| / | | values(): IterableIterator<number> | values(): IterableIterator<number> | No| / | @@ -149,36 +149,36 @@ The native container TypedArray can be converted to the ArkTS TypedArray contain | new(array: ArrayLike<number> \| ArrayBufferLike): Int8Array | constructor(array: ArrayLike<number> \| ArrayBuffer) | No| / | | new(buffer: ArrayBufferLike, byteOffset?: number, length?: number): Int8Array | constructor(buffer: ArrayBuffer, byteOffset?: number, length?: number) | No| / | | from(arrayLike: ArrayLike<number>): Int8Array | static from(arrayLike: ArrayLike<number>): Int8Array | No| / | -| from<T>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => number, thisArg?: any): Int8Array | static from<T>(arrayLike: ArrayLike<T>, mapFn: TypedArrayFromMapFn<T, number>): Int8Array | Supported| ArkTS does not support **this**. As a result, **thisArg** is not supported.| -| from(arrayLike: Iterable<number>, mapfn?: (v: number, k: number) => number, thisArg?: any): Int8Array | static from(arrayLike: Iterable<number>, mapFn?: TypedArrayFromMapFn<number, number>): Int8Array | Supported| ArkTS does not support **this**. As a result, **thisArg** is not supported.| +| from<T>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => number, thisArg?: any): Int8Array | static from<T>(arrayLike: ArrayLike<T>, mapFn: TypedArrayFromMapFn<T, number>): Int8Array | Yes| ArkTS does not support **this**. As a result, the **thisArg** parameter is not supported.| +| from(arrayLike: Iterable<number>, mapfn?: (v: number, k: number) => number, thisArg?: any): Int8Array | static from(arrayLike: Iterable<number>, mapFn?: TypedArrayFromMapFn<number, number>): Int8Array | Yes| ArkTS does not support **this**. As a result, the **thisArg** parameter is not supported.| ### Map | Native API| ArkTS Collections API| Behavior Difference Exists| Different Behavior in ArkTS Collections| | -------- | -------- | -------- | -------- | -| readonly size: number | readonly size: number | Supported| It is not allowed to add, delete, or modify elements during traversal or access. Otherwise, an exception is thrown.| -| clear(): void | clear(): void | Supported| It is not allowed to add, delete, or modify elements during traversal or access. Otherwise, an exception is thrown.| -| delete(key: K): boolean | delete(key: K): boolean | Supported| It is not allowed to add, delete, or modify elements during traversal or access. Otherwise, an exception is thrown.| -| forEach(callbackfn: (value: V, key: K, map: Map<K, V>) => void, thisArg?: any): void | forEach(callbackFn: (value: V, key: K, map: Map<K, V>) => void): void | Supported| 1. It is not allowed to add, delete, or modify elements during traversal or access. Otherwise, an exception is thrown.
2. ArkTS does not support **this**. As a result, **thisArg** is not supported.| -| get(key: K): V \| undefined | get(key: K): V \| undefined | Supported| It is not allowed to add, delete, or modify elements during traversal or access. Otherwise, an exception is thrown.| -| has(key: K): boolean | has(key: K): boolean | Supported| It is not allowed to add, delete, or modify elements during traversal or access. Otherwise, an exception is thrown.| -| set(key: K, value: V): this | set(key: K, value: V): Map<K, V> | Supported| It is not allowed to add, delete, or modify elements during traversal or access. Otherwise, an exception is thrown.| +| readonly size: number | readonly size: number | Yes| It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown.| +| clear(): void | clear(): void | Yes| It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown.| +| delete(key: K): boolean | delete(key: K): boolean | Yes| It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown.| +| forEach(callbackfn: (value: V, key: K, map: Map<K, V>) => void, thisArg?: any): void | forEach(callbackFn: (value: V, key: K, map: Map<K, V>) => void): void | Yes| 1. It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown.
2. ArkTS does not support **this**. As a result, the **thisArg** parameter is not supported.| +| get(key: K): V \| undefined | get(key: K): V \| undefined | Yes| It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown.| +| has(key: K): boolean | has(key: K): boolean | Yes| It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown.| +| set(key: K, value: V): this | set(key: K, value: V): Map<K, V> | Yes| It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown.| | entries(): IterableIterator<[K, V]> | entries(): IterableIterator<[K, V]> | No| / | | keys(): IterableIterator<K> | keys(): IterableIterator<K> | No| / | | values(): IterableIterator<V> | values(): IterableIterator<V> | No| / | -| new <K, V>(entries?: readonly (readonly [K, V])[] \| null): Map<K, V> | constructor(entries?: readonly (readonly [K, V])[] \| null) | Supported| The passed-in values of **k** and **v** during construction cannot be non-sendable data. Otherwise, an error is reported during compilation.| +| new <K, V>(entries?: readonly (readonly [K, V])[] \| null): Map<K, V> | constructor(entries?: readonly (readonly [K, V])[] \| null) | Yes| The passed-in values of **k** and **v** during construction cannot be non-Sendable data. Otherwise, an error is reported during compilation.| ### Set | Native API| ArkTS Collections API| Behavior Difference Exists| Different Behavior in ArkTS Collections| | -------- | -------- | -------- | -------- | -| readonly size: number | readonly size: number | Supported| The **arkts-sendable-compated-prop-name** cannot be used in the Sendable class and APIs.| -| add(value: T): this | add(value: T): Set<T> | Supported| It is not allowed to add, delete, or modify elements during traversal or access. Otherwise, an exception is thrown.| -| clear(): void | clear(): void | Supported| It is not allowed to add, delete, or modify elements during traversal or access. Otherwise, an exception is thrown.| -| delete(value: T): boolean | delete(value: T): boolean | Supported| It is not allowed to add, delete, or modify elements during traversal or access. Otherwise, an exception is thrown.| -| forEach(callbackfn: (value: T, value2: T, set: Set<T>) => void, thisArg?: any): void | forEach(callbackFn: (value: T, value2: T, set: Set<T>) => void): void | Supported| 1. It is not allowed to add, delete, or modify elements during traversal or access. Otherwise, an exception is thrown.
2. ArkTS does not support **this**. As a result, **thisArg** is not supported.| -| has(value: T): boolean | has(value: T): boolean | Supported| It is not allowed to add, delete, or modify elements during traversal or access. Otherwise, an exception is thrown.| +| readonly size: number | readonly size: number | Yes| Computed property names (arkts-sendable-compated-prop-name) cannot be used in Sendable classes and interfaces.| +| add(value: T): this | add(value: T): Set<T> | Yes| It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown.| +| clear(): void | clear(): void | Yes| It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown.| +| delete(value: T): boolean | delete(value: T): boolean | Yes| It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown.| +| forEach(callbackfn: (value: T, value2: T, set: Set<T>) => void, thisArg?: any): void | forEach(callbackFn: (value: T, value2: T, set: Set<T>) => void): void | Yes| 1. It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown.
2. ArkTS does not support **this**. As a result, the **thisArg** parameter is not supported.| +| has(value: T): boolean | has(value: T): boolean | Yes| It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown.| | entries(): IterableIterator<[T, T]> | entries(): IterableIterator<[T, T]> | No| / | | keys(): IterableIterator<T> | keys(): IterableIterator<T> | No| / | -| values(): IterableIterator<T> | values(): IterableIterator<T> | Supported| The **arkts-sendable-compated-prop-name** cannot be used in the Sendable class and APIs.| -| new <T = any>(values?: readonly T[] \| null): Set<T> | constructor(values?: readonly T[] \| null) | Supported| The passed-in values during construction cannot be non-sendable data. Otherwise, an error is reported during compilation.| +| values(): IterableIterator<T> | values(): IterableIterator<T> | Yes| Computed property names (arkts-sendable-compated-prop-name) cannot be used in Sendable classes and interfaces.| +| new <T = any>(values?: readonly T[] \| null): Set<T> | constructor(values?: readonly T[] \| null) | Yes| The passed-in values during construction cannot be non-Sendable data. Otherwise, an error is reported during compilation.| diff --git a/en/application-dev/arkts-utils/arkts-cross-language-interaction.md b/en/application-dev/arkts-utils/arkts-cross-language-interaction.md index b4387b36118e36ab9c395fbdee194f85a78e13cb..5bd6539665a7a5502e116e75a60ab0bbc8aa675c 100644 --- a/en/application-dev/arkts-utils/arkts-cross-language-interaction.md +++ b/en/application-dev/arkts-utils/arkts-cross-language-interaction.md @@ -1,9 +1,9 @@ -# ArkTS Cross-language Interaction +# ArkTS Cross-Language Interaction -In addition to using ArkTS for development, you can also use Node-APIs to implement cross-language interaction between ArkTS and C/C++ (Native). +In addition to supporting development with ArkTS, you can use Node-API to implement cross-language interaction between ArkTS and C/C++ (native). -The Node-APIs of OpenHarmony are extended versions of the Node.js community and are not fully compatible with the Node APIs of the Node.js community. +OpenHarmony Node-API is an extended version of Node API in the Node.js community but does not fully align with it. -In the [Node-API Development Process](../napi/use-napi-process.md), you can use [Node-API data types](../napi/napi-data-types-interfaces.md#data-types) and [APIs](../reference/native-lib/napi.md#node-api) Develop and encapsulate native capabilities. After the native module is imported to ArkTS, cross-language interaction can be implemented. +In the [Node-API development process](../napi/use-napi-process.md), you can use the [data types supported by Node-API](../napi/napi-data-types-interfaces.md#data-types) and [available APIs](../reference/native-lib/napi.md#node-api) to develop and encapsulate native capabilities. By importing the native module in ArkTS, cross-language interaction can be achieved. -[Node-API extension APIs](../napi/use-napi-about-extension.md) further extends the functions of NAPI and provides some additional interfaces for more flexible interaction and customization with ArkTS in the NAPI module. These interfaces can be used in scenarios such as creating custom ArkTS objects. For details, see [Node-API Development Specifications](../napi/napi-guidelines.md) and [Node-API FAQs](../napi/use-napi-faqs.md). Efficiently develop cross-language functions. +[Node-API extension APIs](../napi/use-napi-about-extension.md) further extends the functionalities of Node-API by providing additional interfaces for more flexible interactions and customizations with ArkTS within the Node-API module. These interfaces can be used in scenarios such as creating custom ArkTS objects. You can also refer to [Node-API Development Specifications](../napi/napi-guidelines.md) and [Node-API FAQs](../napi/use-napi-faqs.md) to efficiently develop cross-language features. diff --git a/en/application-dev/arkts-utils/arkts-dynamic-import.md b/en/application-dev/arkts-utils/arkts-dynamic-import.md index 46ca9377611a5620fc87815d02602fb5eed655f3..9418a3410a53393bc88d05eac443eaad242420ba 100644 --- a/en/application-dev/arkts-utils/arkts-dynamic-import.md +++ b/en/application-dev/arkts-utils/arkts-dynamic-import.md @@ -1,18 +1,18 @@ # Dynamic Import -Dynamic import is a powerful feature that allows for conditional loading and partial reflection, which improves the page load time. You can use it to dynamically load HSP modules, HAR, ohpm packages, and native libraries. Better yet, HAR modules can be decoupled when only variables are dynamically imported between the modules. +Dynamic imports support conditional loading and partial reflection, enhancing page load speed. It allows loading HSP modules, HAR modules, ohpm packages, and native libraries. It also enables module decoupling when only variables are dynamically imported between HAR modules. ## When to Use -Unlike [static import]](../quick-start/introduction-to-arkts.md#static-import), dynamic import allows you to load a module conditionally or on demand. The following are some cases where you might want to use dynamic import: +Dynamic imports can be used in application development when you need to import modules conditionally or on-demand, as an alternative to [static import](../quick-start/introduction-to-arkts.md#static-import). The following are some cases where you might want to use dynamic import: -* The statically imported module significantly slows the loading of your code, and there is a low likelihood that you will need the module, or you will not need it until a later time. -* The statically imported modules occupy a large amount of system memory and are unlikely to be used. -* The module being imported does not exist at load time. -* The import specifier string needs to be constructed dynamically. (Static import only supports static specifiers.) -* The module being imported has side effects (which can be understood as code that runs directly in the module), and you do not want those side effects unless some condition is true. +* Statically imported modules significantly slow the loading of your code and are rarely used or not immediately needed. +* Statically imported modules consume a large amount of system memory and are rarely used. +* The imported module does not exist at load time and needs to be fetched asynchronously. +* The import specifier string needs to be constructed dynamically. Static imports only support static specifiers. +* The imported module has side effects (which can be understood as code that runs directly in the module) that are only needed when certain conditions are triggered. -## Bonus -As aforementioned, in addition to conditional loading, dynamic import can also implement partial reflection. In the following example, the HAP dynamically imports **harlibrary** and calls the static member function **staticAdd()**, member function **instanceAdd()**, and global method **addHarlibrary()**. +## Service Expansion Scenarios +As aforementioned, in addition to conditional loading, dynamic imports can implement partial reflection. In the following example, an HAP dynamically imports a HAR package (**harlibrary**) and calls its static member function **staticAdd()**, instance member function **instanceAdd()**, and global function **addHarlibrary()**. ```typescript // harlibrary's src/main/ets/utils/Calc.ets export class Calc { @@ -53,54 +53,54 @@ export { Calc, addHarlibrary } from './src/main/ets/utils/Calc' import('harlibrary').then((ns:ESObject) => { ns.Calc.staticAdd(8, 9); // Call the static member function staticAdd(). let calc:ESObject = new ns.Calc(); // Instantiate the class Calc. - calc.instanceAdd(10, 11); // Call the member function instanceAdd(). - ns.addHarlibrary(6, 7); // Call the global method addHarlibrary(). + calc.instanceAdd(10, 11); // Call the instance member function instanceAdd(). + ns.addHarlibrary(6, 7); // Call the global function addHarlibrary(). - // Call classes, member functions, and methods by name using reflection. + // Reflection using class, member function, and method names as strings. let className = 'Calc'; let methodName = 'instanceAdd'; let staticMethod = 'staticAdd'; let functionName = 'addHarlibrary'; ns[className][staticMethod](12, 13); // Call the static member function staticAdd(). let calc1:ESObject = new ns[className](); // Instantiate the class Calc. - calc1[methodName](14, 15); // Call the member function instanceAdd(). - ns[functionName](16, 17); // Call the global method addHarlibrary(). + calc1[methodName](14, 15); // Call the instance member function instanceAdd(). + ns[functionName](16, 17); // Call the global function addHarlibrary(). }); ``` -## Implementation -A dynamic import expression accepts a constant or variable as its argument. +## Implementation of Dynamic Import +A dynamic import expression accepts a constant or variable as its argument. The following table lists the specifications of dynamic import. | Scenario| Module Specifier | Description | | :------------- | :----------------------------- | :------------------------------------------------------- | | Local module | File path | The path must start with **./** or **../**. | | Local module | HSP module name | - | -| Local module | HSP module file path | Currently, dynamic import expressions with constants are supported, but not ones with variables.| +| Local module | HSP module file path | Currently, dynamic imports with constants are supported, but not ones with variables.| | Local module | HAR module name | - | -| Local module | HAR module file path | Currently, dynamic import expressions with constants are supported, but not ones with variables.| -| Remote module | HAR module name | - | +| Local module | HAR module file path | Currently, dynamic imports with constants are supported, but not ones with variables.| +| Remote module | Remote HAR module name | - | | Remote module | ohpm package name | - | | API | @system.* | - | | API | @ohos.* | - | | API | @arkui-x.* | - | | Native library module | libNativeLibrary.so| - | -Notes: +>**NOTE** +> +> 1. Module names used in all imports are the aliases defined under **dependencies** in the **oh-package.json5** file. +> 2. It is recommended that the alias configured under **dependencies** be the same as the values of **moduleName** and **packageName**, both of which indicate the name of the module to import. **moduleName** is set in the **module.json5** file of the module, and **packageName** is set in the **oh-package.json5** file. +> 3. Importing a module by name is importing the module's entry file, generally **index.ets/ts**. -1. The module names used in imports are the aliases under **dependencies** in the **oh-package.json5** file. -2. It is recommended that the alias under **dependencies** be the same as the values of **moduleName** and **packageName**, both of which indicate the name of the module to import. **moduleName** is set in the **module.json5** file of the module, and **packageName** is set in the **oh-package.json5** file. -3. Importing a module by name is importing the module's entry point file, generally **index.ets/ts**. +## Key Points in Dynamic Import Implementation -## Implementation Key Points +### Dynamic Imports with Constant Expressions -### Dynamic Import Constant Expression - -A dynamic import constant expression is a dynamic import expression that takes in a constant as its argument. The following examples show how to use this type of dynamic import expression to import a module or API into a HAP module. +Dynamic imports with constant expressions refer to scenarios where the input to **import** is a constant. The following examples show how to use this type of dynamic import to import a module or API into a HAP module. Note: In the examples, the paths, such as the path to **Index.ets**, are set based on the current DevEco Studio module configuration and are subject to change. -- **Dynamically importing a HAR module based on the HAR module name** +- **HAP dynamically imports a HAR module using a constant module name** ```typescript // HAR's Index.ets @@ -125,7 +125,7 @@ Note: In the examples, the paths, such as the path to **Index.ets**, are set bas } ``` -- **Dynamically importing a HAR module based on the HAR module file path** +- **HAP dynamically imports a HAR module using a constant file path** ```typescript // HAR's Index.ets @@ -150,7 +150,7 @@ Note: In the examples, the paths, such as the path to **Index.ets**, are set bas } ``` -- **Dynamically importing an HSP module based on the HSP module name** +- **HAP dynamically imports an HSP module using a constant module name** ```typescript // HSP's Index.ets @@ -175,7 +175,7 @@ Note: In the examples, the paths, such as the path to **Index.ets**, are set bas } ``` -- **Dynamically importing an HSP module based on the HSP module file path** +- **HAP dynamically imports an HSP module using a constant file path** ```typescript // HSP's Index.ets @@ -200,7 +200,7 @@ Note: In the examples, the paths, such as the path to **Index.ets**, are set bas } ``` -- **Dynamically importing a remote HAR module based on the HAR module name** +- **HAP dynamically imports a remote HAR module using a constant module name** ```typescript // HAP's src/main/ets/pages/Index.ets @@ -216,7 +216,7 @@ Note: In the examples, the paths, such as the path to **Index.ets**, are set bas } ``` -- **Dynamically importing an ohpm package** +- **HAP dynamically imports an ohpm package using a constant** ```typescript // HAP's src/main/ets/pages/Index.ets @@ -232,7 +232,7 @@ Note: In the examples, the paths, such as the path to **Index.ets**, are set bas } ``` -- **Dynamically importing a file of the HAP module itself** +- **HAP dynamically imports its own single file using a constant** ```typescript // HAP's src/main/ets/Calc.ets @@ -250,7 +250,7 @@ Note: In the examples, the paths, such as the path to **Index.ets**, are set bas }); ``` -- **Dynamically importing a native library of the HAP module itself** +- **HAP dynamically imports its own native library using a constant** ```typescript // libnativeapi.so's index.d.ts @@ -271,7 +271,7 @@ Note: In the examples, the paths, such as the path to **Index.ets**, are set bas } ``` -- **Dynamically importing APIs** +- **HAP dynamically imports APIs using a constant** ```typescript // HAP's src/main/ets/pages/Index.ets @@ -282,15 +282,14 @@ Note: In the examples, the paths, such as the path to **Index.ets**, are set bas import('@ohos.hilog').then((ns:ESObject) => { ns.default.info(0x0000, 'testTag', '%{public}s', 'DynamicImport @ohos.hilog.'); }); ``` -### Dynamic Import Variable Expression +### Dynamic Imports with Variable Expressions -In DevEco Studio, the dependencies between modules are configured through **dependencies** in the **oh-package.json5** file. By default, all modules listed under **dependencies** are installed (local modules) or downloaded (remote modules), but are not built. During a HAP/HSP build, the dependency relationship is searched from the entry point file (generally **Index.ets/ts**), and only the dependencies found are added to the build. -At compile time, static imports and dynamic import constant expressions can be identified and parsed by the packaging tool rollup and its plug-ins. This means that the related dependencies can be added to the dependency tree, participate in the build process, and finally generate Ark bytecode. As for dynamic import variable expressions, since the variable value may need to be calculated or obtained from an external source, it cannot be determined at compile time; as a result, the related dependencies cannot participate in the build process. To add these dependencies to the build process, add **runtimeOnly** under **buildOption** and set it to the actual module name or file path pertaining to the variable. +In DevEco Studio, module dependencies are configured through **dependencies** in the **oh-package.json5** file. By default, all modules listed under **dependencies** are installed (for local modules) or downloaded (for remote modules), but are not built. During a HAP/HSP build, the dependency relationship is searched from the entry file (generally **Index.ets/ts**), and only the dependencies found are added to the build. +During compilation, static imports and dynamic imports with constant expressions can be identified and parsed by the packaging tool rollup and its plug-ins. This means that the related dependencies can be added to the dependency tree, participate in the build process, and finally generate Ark bytecode. However, dynamic imports with variable expressions cannot be resolved at compile-time because their values may depend on runtime calculations or external inputs. To add these dependencies to the build process, add **runtimeOnly** under **buildOption** and set it to the actual module name or file path pertaining to the variable. -**1. Schema configuration format of the runtimeOnly field** +**Schema configuration format of the runtimeOnly field** -If you are using a dynamic import variable expression to import modules or files, but not APIs, you need to add the **runtimeOnly** field under **buildOption** in the **build-profile.json5** file of the HAP/HSP/HAR module. -The following are some examples. +If you are using dynamic imports with variable expressions to import modules or files, but not APIs, you need to add the **runtimeOnly** field under **buildOption** in the **build-profile.json5** file of the HAP/HSP/HAR module. The following are some examples. ```typescript // Dynamically import a module based on the module name myHar. @@ -318,9 +317,9 @@ The corresponding **runtimeOnly** configuration is as follows: **packages** of **runtimeOnly**: name of the module to dynamically import. It must be the same as the one specified under **dependencies**. **sources** of **runtimeOnly**: path of the file to dynamically import. The path is relative to the **build-profile.json5** file of the module. -**2. Examples** +**Usage Examples** -- **Dynamically importing a HAR module based on the HAR module name** +- **HAP dynamically imports a HAR module using a variable module name** ```typescript // HAR's Index.ets @@ -356,7 +355,7 @@ The corresponding **runtimeOnly** configuration is as follows: } ``` -- **Dynamically importing an HSP module based on the HSP module name** +- **HAP dynamically imports an HSP module using a variable module name** ```typescript // HSP's Index.ets @@ -392,7 +391,7 @@ The corresponding **runtimeOnly** configuration is as follows: } ``` -- **Dynamically importing a remote HAR module based on the HAR module name** +- **HAP dynamically imports a remote HAR module using a variable module name** ```typescript // HAP's src/main/ets/pages/Index.ets @@ -420,7 +419,7 @@ The corresponding **runtimeOnly** configuration is as follows: } ``` -- **Dynamically importing an ohpm package** +- **HAP dynamically imports an ohpm package using a variable** ```typescript // HAP's src/main/ets/pages/Index.ets @@ -448,7 +447,7 @@ The corresponding **runtimeOnly** configuration is as follows: } ``` -- **Dynamically importing a file of the HAP module itself** +- **HAP dynamically imports its own single file using a variable** ```typescript // HAP's src/main/ets/Calc.ets @@ -478,7 +477,7 @@ The corresponding **runtimeOnly** configuration is as follows: } ``` -- **Dynamically importing a native library of the HAP module itself** +- **HAP dynamically imports its own native library using a variable** ```typescript // libnativeapi.so's index.d.ts @@ -510,7 +509,7 @@ The corresponding **runtimeOnly** configuration is as follows: } ``` -- **Dynamically importing APIs** +- **HAP dynamically imports APIs using a variable** ```typescript // HAP's src/main/ets/pages/Index.ets @@ -527,29 +526,29 @@ The corresponding **runtimeOnly** configuration is as follows: ``` You do not need to set **runtimeOnly** when dynamically importing APIs with variables. -### Decoupling Between HAR modules with Dynamic Import -When an application contains multiple HAR modules, and the dependency between the modules are complex, configuring their dependencies in DevEco Studio can be challenging and, if not handled carefully, can lead to cyclic dependencies. To simplify dependency management, if only variables are dynamically imported between HAR modules, you can convert dependency between HAR modules into dependency between HAR modules and HAP/HSP modules. In this way, the HAR modules are decoupled. The figure shows the dependency graph before dependency conversion. +### Decoupling Dynamic Imports Between HAR Modules +When an application contains multiple HAR packages with complex dependency relationships, circular dependencies may occur when configuring dependencies in DevEco Studio. If the dependencies between HAR packages are only through dynamic imports with variable expressions, the direct dependency relationships between HAR packages can be transferred to the HAP/HSP configuration. This decouples the dependencies between HAR packages, as shown in the figure below. -![Cyclic dependency between HAR modules before dependency conversion](figures/dynamicimport1.png) +![Circular dependency between HAR packages](figures/dynamicimport1.png) The figure shows the dependency graph after dependency conversion. -![Dependency between HAR modules and a HAP after dependency conversion](figures/dynamicimport2.png) +![Dependency between HAR and HAP](figures/dynamicimport2.png) -**1. Constraints** -- Dependency conversion is applicable only when cyclic dependency is formed between local HAR modules. -- In HAR modules for which you want to convert dependency, only dynamic import variable expressions are allowed, but not static import or dynamic import constant expressions. -- When converting dependencies, you must transfer both **dependencies** and **runtimeOnly**. -- Dependency conversion does not work for HSP modules. For example, in the case of HAP -> HSP1 -> HSP2 -> HSP3, dependency between HSP2 and HSP3 cannot be converted into dependency with the HAP. -- Only HAR modules are allowed throughout the dependency conversion chain. In other words, no HSP module is allowed between HAR modules. An incorrect use is as follows: HAP -> HAR1 -> HAR2 -> HSP -> HAR3 -> HAR4. +**Constraints** +- This workaround is only applicable when circular dependencies occur between local HAR packages. +- The transferred dependencies between HAR packages can only be through dynamic imports with variable expressions, not static imports or dynamic imports with constant expressions. +- When transferring dependencies, both **dependencies** and **runtimeOnly** configurations must be transferred simultaneously. +- HSP does not support transferring dependencies. For example, in the chain HAP -> HSP1 -> HSP2 -> HSP3, dependency between HSP2 and HSP3 cannot be transferred to HAP. +- The entire chain of transferred dependencies must consist only of HAR packages. Dependencies cannot be transferred across HSP packages. An incorrect use is as follows: HAP -> HAR1 -> HAR2 -> HSP -> HAR3 -> HAR4. - The dependency of HAR 1 on HAR 2 can be transferred to a HAP, and the dependency of HAR 3 on HAR 4 can be transferred to an HSP. However, HAR3 or HAR4 cannot be transferred to the HAP. + The dependency of HAR1 on HAR2 can be transferred to a HAP, and the dependency of HAR3 on HAR4 can be transferred to an HSP. However, HAR3 or HAR4 cannot be transferred to the HAP. -**2. Examples** +**Usage Examples** -In the following example, the HAP dynamically imports HAR module har1 based on the module name variable, and har1 dynamically imports another HAR module har2 based on the module name variable. +In the following example, HAP dynamically imports HAR package har1, and har1 dynamically imports another HAR package har2 using variables. ```json5 // HAP's oh-package.json5 diff --git a/en/application-dev/arkts-utils/arkts-import-native-module.md b/en/application-dev/arkts-utils/arkts-import-native-module.md index 3483e595fa3d396f57bd56e368ebcfb85c97b726..26ec65049fe972889d4c654b21b2992f24f21a13 100644 --- a/en/application-dev/arkts-utils/arkts-import-native-module.md +++ b/en/application-dev/arkts-utils/arkts-import-native-module.md @@ -1,10 +1,11 @@ -# Importing a Native Module +# Statically Loading Native Modules -In ECMAScript 6.0 (ES6) module design, the community uses the **import** syntax to load the content exported from other files (the ECMA specification defines the syntax specifications). -To help you easily use this feature to import the content exported from the native module (.so), ArkTS performs adaptation and provides several import methods. +In ECMAScript 6.0 (ES6) module design, the **import** syntax is used to load content exported by other files, as defined by the ECMAScript specification. + +To help you easily import content exported from native modules (.so), ArkTS has adapted and supports the following methods: ## Direct Import -Export the content from the **index.d.ts** file of a native module, and then import the content to the file. +Export content from the **index.d.ts** file of a native module, and then import the content to the file. ### Named Import ```ts @@ -41,7 +42,7 @@ add.add(2, 3); ## Indirect Import -### Converting to Named Variables Before Export and Import +### Export as Named Variables and Import ```ts // test1.ets import hilog from '@ohos.hilog' @@ -53,7 +54,7 @@ import { hilog } from './test1' hilog.info(0x000, 'testTag', '%{public}s', 'test'); ``` -### Converting to Namespaces Before Export and Import +### Export as Namespaces and Import ```ts // index.d.ts corresponding to libentry.so export const add: (a: number, b: number) => number; @@ -67,8 +68,11 @@ export * from 'libentry.so' import { add } from './test1' add(2, 3); ``` -Note: Namespaces cannot be used simultaneously during the export and import of native modules. -**Negative example:** +> **NOTE** +> +> Native modules do not support both export and import using namespaces simultaneously. + +**Anti-example:** ```ts // test1.ets export * from 'libentry.so' @@ -104,8 +108,11 @@ import('./test1').then((ns:ESObject) => { }) ``` -**Note**: When dynamic loading is not supported, a file must be exported using the namespace. -**Negative example:** +> **NOTE** +> +> Dynamic imports do not support exporting files using namespace exports. + +**Anti-example:** ```ts // test1.ets export * from 'libentry.so' diff --git a/en/application-dev/arkts-utils/arkts-lazy-import.md b/en/application-dev/arkts-utils/arkts-lazy-import.md index 5404e02020330be68226b62631567fd1f9e26cfe..58dd1b29e58f7b6df4f1e83409ff0387ae6cc56b 100644 --- a/en/application-dev/arkts-utils/arkts-lazy-import.md +++ b/en/application-dev/arkts-utils/arkts-lazy-import.md @@ -1,29 +1,29 @@ # Lazy Import -With the continuous expansion of application features, the time required for cold start increases significantly. The main reason is that a large number of modules are loaded at the early stage of startup, and a large number of redundant files that are not actually executed exist. In this case, not only an initialization process of the application is delayed, but also invalid resource occupation is caused. Therefore, measures urgently need to be taken to simplify a loading process and eliminate unnecessary file execution, to optimize cold start performance and ensure smooth user experience. +As applications evolve with more features, the time required for cold start increases significantly. The main reason is that a large number of modules are loaded at the early stage of startup, and many of them are redundant and not actually executed. This not only prolongs application initialization but also leads to invalid resource utilization. To address this, it is crucial to streamline the loading process by eliminating non-essential file executions to optimize cold start performance and ensure a smooth user experience. -> **Note** +> **NOTE** > -> - The lazy import is supported since API version 12. +> - The lazy import feature is supported since API version 12. > -> - To use the lazy import syntax on API version 12, you need to configure **"compatibleSdkVersionStage": "beta3"** in the project. Otherwise, the compilation fails. For details, see [DevEco Studio build-profile.json5 File Description](https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V5/ide-hvigor-build-profile-V5#section511142752919). +> - To use the lazy import syntax on API version 12, you must configure **"compatibleSdkVersionStage": "beta3"** in the project. Otherwise, the compilation fails. For details, see [Project-level build-profile.json5 File](https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V5/ide-hvigor-build-profile-V5#section511142752919). -## **Functions and Features** +## Features -With the lazy import, unnecessary files are not loaded in the cold start phase until these files are required during application running, shortening the time required for cold start. +The lazy import feature allows files that are pending loading to remain unloaded during the cold start phase. Instead, these files are loaded synchronously on-demand only when the application actually needs them during runtime, thereby reducing the time required for application cold start. -## Storage mode +## Usage -You can use[Trace](../performance/common-trace-using-instructions.md) tools or logs to identify files that are not actually called during cold start. By analyzing the data, you can accurately locate the files that do not need to be pre-loaded in the startup phase, and add the **lazy** identifier for the invoking points of these files. Notice that subsequent synchronous loading may block the task execution. (If a task is clicked and lazy import is triggered, the files that are not loaded will be executed in cold start, which increases the time consumption. Therefore, you need to evaluate whether to use the **lazy** identifier. +You can use [Trace](../performance/common-trace-using-instructions.md) or logs to identify files that are not actually called during cold start. For details about the analysis method, see [Lazy Import](../performance/Lazy-Import-Instructions.md). By analyzing the data, you can accurately identify the files that do not need to be pre-loaded in the startup phase, and add the **lazy** flag for the call points of these files. Note that the subsequent loading is synchronous and may block task execution. (For example, if a click task triggers a lazy import, the runtime will execute the files not loaded during the cold start, thereby increasing latency.) Therefore, you need to evaluate whether to use the **lazy** flag. > **NOTE** > -> You are not advised to blindly add **lazy** identifiers, which also increases the identification overhead during building and running. - +> You are not advised to blindly add **lazy** flags, as this can also increase the overhead of identification during compilation and runtime. + ## Scenario Behavior Analysis -- Use lazy import. +- Use lazy-import for deferred loading. ```typescript // main.ets @@ -54,13 +54,13 @@ You can use[Trace](../performance/common-trace- main executed ``` -- Reference lazy import and native import for the same module at the same time. +- Use both lazy-import and native import for the same module. ```typescript // main.ets import lazy { a } from "./mod1"; // "mod1" is not executed. import { c } from "./mod2"; // "mod2" is executed. - import { c } from "./mod2"; // "mod1" is executed. + import { b } from "./mod1"; // "mod1" is executed. // ... @@ -91,7 +91,7 @@ You can use[Trace](../performance/common-trace- main executed ``` - If the keyword **lazy** is deleted from **main.ets** file, the execution sequence is as follows: + If the keyword **lazy** is deleted from the **main.ets** file, the execution sequence is as follows: ```typescript mod1 a executed @@ -100,21 +100,21 @@ You can use[Trace](../performance/common-trace- main executed ``` -## Specifications +## Syntax Specifications and Supported Versions -- Lazy import supports the following instructions: +- The lazy import feature supports the following syntax: -| Syntax | ModuleRequest | ImportName | LocalName | Supported by API Version 12 | +| Syntax | ModuleRequest | ImportName | LocalName | Supported by API Version 12| | :--------------------------------- | :------------ | :---------- | :---------- | :------------------- | -| import lazy { x } from "mod"; | "mod" | "x" | "x" | Yes | -| import lazy { x as v } from "mod"; | "mod" | "x" | "v" | Yes. | +| import lazy { x } from "mod"; | "mod" | "x" | "x" | Yes | +| import lazy { x as v } from "mod"; | "mod" | "x" | "v" | Yes | -- The shared module is lazy imported or the dependency path contains the shared module. - Lazy import still takes effect for the shared module. For details about the constraints, see [Shared Module Development](../arkts-utils/arkts-sendable-module.md). +- Lazy importing of shared modules or modules within a dependency path that includes shared modules + Lazy import remains effective for shared modules. For details about the constraints, see [Shared Module](../arkts-utils/arkts-sendable-module.md). -### [Incorrect Example] +### Incorrect Example -Build error is reported if use the following syntax: +The following syntax will cause compilation errors: ```typescript export lazy var v; // The compiler reports an application compilation error. @@ -142,37 +142,37 @@ If the **type** keyword is added to the syntax, an error is reported. ### Syntax Not Recommended -- In the same ets file, not all the dependency modules that require the lazy import are added lazy identifiers. - - Incomplete labeling will cause lazy loading to fail and increase the overhead of identifying lazy loading. +- Incomplete **lazy** flags within the same .ets file + + Incomplete marking will cause lazy imports to fail and increase the overhead of identifying lazy-imported modules. ```typescript // main.ets - import lazy { a } from "./mod1"; // Obtain the object a from "mod1" and add a lazy identifier. + import lazy { a } from "./mod1"; // Obtain the object a from "mod1" and add the lazy flag. import { c } from "./mod2"; - import { b } from "./mod1"; // Obtain the attributes in "mod1". This syntax is not added a lazy identifier, so "mod1" is executed by default. + import { b } from "./mod1"; // Obtain the attributes in "mod1". This syntax is not added with the lazy flag, so "mod1" is executed by default. // ... ``` -- In the same ETS file, lazy loading variables are not used and exported again. Lazy loading variables cannot be exported by re-export. - - The variable c exported in this mode is not used in B.ets, and the B.ets file is not executed. When variable a is used in the A.ets file, the variable is not initialized and a JS exception is thrown. +- Re-exporting lazy-imported variables within the same .ets file without using them + + The variable **c** is not used in **B.ets**, so **B.ets** does not trigger execution. When **c** is used in **A.ets**, it is not initialized, resulting in a JS exception. ```typescript // A.ets import { c } from "./B"; console.info(c); // B.ets - import lazy { a } from "./mod1"; // Obtain the object a from "mod1" and add a lazy identifier. + import lazy { c } from "./C"; // Obtain the object c from "C" and add the lazy flag. export { c } // C.ets - function c(){}; + let c = "c"; export { c } ``` - The execution result is as follows: + Result: ```typescript - ReferenceError: a is not initaliized - at func_main_0 (A.ets:2:1) + ReferenceError: c is not initaliized + at func_main_0 (A.ets:2:13) ``` ```typescript @@ -181,22 +181,24 @@ If the **type** keyword is added to the syntax, an error is reported. console.info(ns.c); // B.ets - import lazy { a } from "./mod1"; // Obtain the object a from "mod1" and add a lazy identifier. + import lazy { c } from "./C"; // Obtain the object c from "C" and add the lazy flag. export { c } // C.ets - function c(){}; + let c = "c"; export { c } ``` - The execution result is as follows: + Result: ```typescript ReferenceError: module environment is undefined - at func_main_0 (A_ns.js:2:1) + at func_main_0 (A_ns.js:2:13) ``` - Currently, lazy import cannot be executed in kit. -- Developers need to evaluate the impact of lazy loading. - * Side-effects that do not depend on the module (such as initializing global variables and mounting globalThis) - * When objects are exported, time required for the lazy import deteriorates corresponding features. - * Bugs occur when the **lazy** identifier is used but the module is not executed. +- You need to evaluate the impact of lazy imports. + * Side effects that are independent of the module's execution (such as initializing global variables and mounting **globalThis**). For details, see [Side Effects and Optimization of Module Loading](./arkts-module-side-effects.md). + * Negative impact on the functionality of features due to the delay caused by triggering lazy imports when using exported objects. + * Bugs caused by modules not being executed due to the use of the lazy import feature. + + \ No newline at end of file diff --git a/en/application-dev/arkts-utils/arkts-module-side-effects.md b/en/application-dev/arkts-utils/arkts-module-side-effects.md new file mode 100644 index 0000000000000000000000000000000000000000..3fd8647727e0ad813c93f37c462f95be6cf3dccf --- /dev/null +++ b/en/application-dev/arkts-utils/arkts-module-side-effects.md @@ -0,0 +1,315 @@ +# Side Effects and Optimization of Module Loading +## Overview +When using [ArkTS modularization](module-principle.md), the process of loading and executing modules may introduce side effects. These side effects refer to additional behavior or state changes that occur when importing a module, beyond simply exporting functions or objects. Such behavior might affect other parts of the program, leading to unintended consequences such as unexpected top-level code execution, global state changes, prototype chain modifications, and undefined imported content. + +## Scenarios and Optimization Methods for Side Effects +### Top-Level Code Execution in Modules +**Scenario of Side Effects** + +When a module is imported, all top-level code within the module file is executed immediately, not just the exported parts. This means that even if only specific exports are needed, any code in the top-level scope will run, potentially causing side effects. +```typescript +// module.ets +console.log("Module loaded!"); // The code is executed immediately upon import, which may cause side effects. +export const data = 1; + +// main.ets +import { data } from './module' // When data is imported, the console.log file in module.ets is executed and output is generated. +console.log(data); +``` +The output is as follows: +```typescript +Module loaded! +1 +``` +**Side effects produced** + +Even though only **data** is required, **console.log("Module loaded!")** still runs, causing the unexpected output of "Module loaded!" in addition to the value of **data**. + +**Optimized methods** + +Optimization method 1: Remove the top-level code and export only the required content to avoid unnecessary code execution. +```typescript +// module.ets +export const data = 1; + +// main.ets +import { data } from './module' +console.log(data); +``` +The output is as follows: +```typescript +1 +``` +Optimization method 2: Encapsulate code that may cause side effects within functions or methods, and execute the code only when needed, rather than upon module loading. +```typescript +// module.ets +export function initialize() { + console.log("Module loaded!"); +} +export const data = 1; + +// main.ets +import { data } from './module' +console.log(data); +``` +The output is as follows: +```typescript +1 +``` +### Modifying Global Objects +**Scenario of side effects** + +The top-level code or imported modules may directly manipulate global variables, thereby changing the global state and causing side effects. +```typescript +// module.ets +export let data1 = "data from module" +globalThis.someGlobalVar = 100; // The global state is changed. + +// sideEffectModule.ets +export let data2 = "data from side effect module" +globalThis.someGlobalVar = 200; // The global state is changed. + +// moduleUseGlobalVar.ets +import { data1 } from './module' // The expected value of the global variable someGlobalVar is 100. +export function useGlobalVar() { + console.log(data1); + console.log(globalThis.someGlobalVar); // The value of someGlobalVar is changed to 200 because the sideEffectModule module is loaded to main.ets. +} + +// main.ets (entry point) +import { data1 } from "./module" // The value of the global variable someGlobalVar is changed to 100. +import { data2 } from "./sideEffectModule" // The value of the global variable someGlobalVar is changed to 200. +import { useGlobalVar } from './moduleUseGlobalVar' + +useGlobalVar(); +function maybeNotCalledAtAll() { + console.log(data1); + console.log(data2); +} +``` +The output is as follows: +``` +data from module +200 +``` +**Side effects produced** + +Modules directly change the value of the **global variable globalThis.someGlobalVar**, affecting other modules or code that use this variable. + +**Optimized methods** + +Encapsulate code that may cause side effects within functions or methods, and execute the code only when needed, rather than upon module loading. +```typescript +// module.ets +export let data1 = "data from module" +export function changeGlobalVar() { + globalThis.someGlobalVar = 100; +} + +// sideEffectModule.ets +export let data2 = "data from side effect module" +export function changeGlobalVar() { + globalThis.someGlobalVar = 200; +} + +// moduleUseGlobalVar.ets +import { data1, changeGlobalVar } from './module' +export function useGlobalVar() { + console.log(data1); + changeGlobalVar(); // Execute the code when needed, not upon module loading. + console.log(globalThis.someGlobalVar); +} + +// main.ets (entry point) +import { data1 } from "./module" +import { data2 } from "./sideEffectModule" +import { useGlobalVar } from './moduleUseGlobalVar' + +useGlobalVar(); +function maybeNotCalledAtAll() { + console.log(data1); + console.log(data2); +} +``` +The output is as follows: +``` +data from module +100 +``` +### Modifying State Variables of Application-level ArkUI Components +**Scenario of side effects** + +The top-level code or imported modules may directly modify the state variables of application-level ArkUI components, thereby changing the global state and causing side effects. +```typescript +// module.ets +export let data = "data from module" +AppStorage.setOrCreate("SomeAppStorageVar", 200); // The global UI state of the application is changed. + +// Index.ets +import { data } from "./module" // SomeAppStorageVar in AppStorage is changed to 200. + +@Entry +@Component +struct Index { + // The expected value is 100. However, the value has been changed to 200 due to module import. + @StorageLink("SomeAppStorageVar") message: number = 100; + build() { + Row() { + Column() { + Text("test" + this.message) + .fontSize(50) + } + .width("100%") + } + .height("100%") + } +} +function maybeNotCalledAtAll() { + console.log(data); +} +``` +The following content is displayed: +``` +test200 +``` +**Side effects produced** + +Modules directly change the value of **SomeAppStorageVar** in AppStorage, affecting other modules or code that use this variable. + +For more information on modifying ArkUI component state variables, see [State Management Overview](../quick-start/arkts-state-management-overview.md). + +**Optimized methods** + +Encapsulate code that may cause side effects within functions or methods, and execute the code only when needed, rather than upon module loading. +```typescript +// module.ets +export let data = "data from module" +export function initialize() { + AppStorage.setOrCreate("SomeAppStorageVar", 200); +} + +// Index.ets +import { data } from "./module" + +@Entry +@Component +struct Index { + @StorageLink("SomeAppStorageVar") message: number = 100; + build() { + Row() { + Column() { + Text("test" + this.message) + .fontSize(50) + } + .width("100%") + } + .height("100%") + } +} +function maybeNotCalledAtAll() { + console.log(data); +} +``` +The following content is displayed: +``` +test100 +``` +### Modifying Built-in Global Variables or Prototype Chains (Modifying Object Prototypes or Built-in Methods Is Forbidden in ArkTS) +**Scenario of side effects** + +Some third-party libraries or frameworks may modify built-in global objects or prototype chains to support modern JavaScript features in older browsers or runtime environments. This may affect the execution of other code. +```typescript +// modifyPrototype.ts +export let data = "data from modifyPrototype" +Array.prototype.includes = function (value) { + return this.indexOf(value) !== -1; +}; + +// main.ets +import { data } from "./modifyPrototype" // The prototype chain of the array is modified. +let arr = [1, 2, 3, 4]; +console.log("arr.includes(1) = " + arr.includes(1)); // The Array.prototype.includes method in modifyPrototype.ts is called. +function maybeNotCalledAtAll() { + console.log(data); +} +``` +**Side effects produced** + +Modifying built-in global objects or prototype chains affects the execution of other code. + +**Optimized methods** + +When importing third-party libraries that may modify built-in global objects or prototype chains, ensure that the behavior of the third-party library is as expected. +### Circular Dependencies + +**Scenario of side effects** + +ArkTS modularization supports circular dependencies, where module A depends on module B, and module B depends on module A. In such cases, some imported modules may not be fully loaded, leading to abnormal behavior and unintended side effects during execution. +```typescript +// a.ets +import { b } from "./b" +console.log('Module A: ', b); +export const a = 'A'; + +// b.ets +import { a } from "./a" +console.log('Module B: ', a); +export const b = 'B'; +``` +The output is as follows: +``` +Error message: a is not initialized +Stacktrace: + at func_main_0 (b.ets:2:27) +``` +**Side effects produced** + +Due to mutual dependencies between modules, the execution order of modules may result in undefined exports, affecting the logic flow of the code. + +**Optimized methods** + +Avoid circular dependencies between modules whenever possible, and ensure that the loading order of modules is clear and controllable to prevent unexpected side effects. You can use [@security/no-cycle](https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V5/ide_no-cycle-V5) when detecting circular dependencies. +### Lazy Import Changing the Module Execution Sequence and Leading to Undefined Global Variables +**Scenario of side effects** + +The [Lazy Import](arkts-lazy-import.md) feature allows modules to be loaded on-demand during the application runtime, rather than during the cold start phase, thereby reducing the cold start time. However, this also changes the execution sequence of modules. +```typescript +// module.ets +export let data = "data from module" +globalThis.someGlobalVar = 100; + +// moduleUseGlobalVar.ets +import lazy { data } from "./module" +console.log(globalThis.someGlobalVar); // The module is not executed due to lazy import. The value of someGlobalVar is undefined. +console.log(data); // During the value of the variable, the module is executed and the value of someGlobalVar changes to 100. +``` +The output is as follows: +``` +undefined +data from module +``` +**Side effects produced** + +Using the lazy import feature delays the execution of modules until they are needed. Modifications to global variables within these modules are also delayed, potentially leading to unexpected results. + +**Optimized methods** + +Encapsulate code that may cause side effects within functions or methods, and execute the code only when needed, rather than upon module loading. +```typescript +// module.ets +export let data = "data from module" +export function initialize() { + globalThis.someGlobalVar = 100; // Delay the execution until the function is called. +} + +// moduleUseGlobalVar.ets +import lazy { data, initialize } from "./module" +initialize(); // Execute the initialization function to initialize someGlobalVar. +console.log(globalThis.someGlobalVar); // someGlobalVar will have the expected value. +console.log(data); +``` +The output is as follows: +``` +100 +data from module +``` diff --git a/en/application-dev/arkts-utils/arkts-overview.md b/en/application-dev/arkts-utils/arkts-overview.md index d21bb5207cc6dfe16c1dbdb970f84cea94f04c7d..f6e75377ca87b61f986ca0237bb5445292fef1b3 100644 --- a/en/application-dev/arkts-utils/arkts-overview.md +++ b/en/application-dev/arkts-utils/arkts-overview.md @@ -2,14 +2,14 @@ ArkTS is the official high-level language for OpenHarmony application development. -ArkTS provides capabilities such as [declarative UI paradigm](../quick-start/arkts-declarative-ui-description.md), [state management](../quick-start/arkts-state-management-overview.md), and [rendering control](../quick-start/arkts-rendering-control-overview.md), enabling developers to develop applications in a simpler and more natural manner. +ArkTS provides capabilities such as [declarative UI paradigm](../quick-start/arkts-declarative-ui-description.md), [state management](../quick-start/arkts-state-management-overview.md), and [rendering control](../quick-start/arkts-rendering-control-overview.md), helping you create applications in a more concise and natural manner. -ArkTS is further extended based on the [TypeScript](https://www.typescriptlang.org/) (TS) ecosystem to maintain the basic style of TS. In addition, ArkTS enhances static check and analysis in the development phase through standard definitions, improving code robustness and program execution stability and performance. For details about the differences between TypeScript and ArkTS, see [TypeScript to ArkTS Cookbook](../quick-start/typescript-to-arkts-migration-guide.md). ArkTS also supports efficient interoperability with TS/JavaScript (JS). +Built on the [TypeScript](https://www.typescriptlang.org/) (TS) ecosystem, ArkTS extends its functionality while maintaining the basic style of TS. It enhances static check and analysis during development through standardized definitions, improving code robustness and achieving better program execution stability and performance. For details about the differences compared with standard TS, see [TypeScript to ArkTS Cookbook](../quick-start/typescript-to-arkts-migration-guide.md). ArkTS also supports efficient interoperability with TS/JavaScript (JS). -The ArkTS basic class library and container class library enhance basic language functions and provide capabilities such as [high-precision floating-point operation](../reference/apis-arkts/js-apis-arkts-decimal.md), [binary buffer](buffer.md), [XML generation, parsing, and conversion](xml-overview.md), and multiple container libraries, helps developers simplify development and improve development efficiency. +The ArkTS common and container libraries enhance the language's basic functionalities, offering capabilities such as [high-precision floating-point operations](../reference/apis-arkts/js-apis-arkts-decimal.md), [binary buffers](buffer.md), and [XML generation, parsing, and conversion](xml-overview.md), as well as various container libraries. These features help you simplify your work and improve development efficiency. -To address the limited support for TS/JS concurrency, ArkTS enhances the concurrent programming APIs and capabilities by providing [TaskPool](taskpool-introduction.md) and [Worker](worker-introduction.md). Two concurrent APIs are provided for developers to choose. In addition, ArkTS further proposes the concept of Sendable to support the reference transfer of objects between concurrent instances, improving the communication performance of ArkTS objects between concurrent instances. +To address the limited concurrency support in TS/JS, ArkTS enhances concurrency programming APIs and capabilities. It provides two concurrency APIs, [TaskPool](taskpool-introduction.md) and [Worker](worker-introduction.md). In addition, ArkTS introduces the concept of Sendable to support object reference passing between concurrent instances, improving communication performance of ArkTS objects in concurrent environments. -ArkCompiler supports the compilation and running of ArkTS, TS, and JS. Currently, ArkCompiler consists of the ArkTS compilation toolchain and ArkTS runtime. The ArkTS compiler is responsible for compiling the high-level language into an ARK bytecode file (\*.abc) on the development side, and the ArkTS runtime is responsible for running the bytecode file on the device side to execute the program logic. +ArkCompiler supports the compilation and execution of ArkTS, TS, and JS. Currently, it is divided into two main parts: the ArkTS compilation toolchain and the ArkTS runtime. The ArkTS compilation toolchain is responsible for compiling high-level languages into Ark bytecode files (\*.abc) on the development side, whereas the ArkTS runtime runs the bytecode files on the device side to execute the program logic. -ArkTS will continue to accommodate ever-changing app development and running requirements, and gradually provides more features, such as enhanced concurrency, improved system, and distributed development paradigm. +In the future, ArkTS will continue to evolve based on application development and runtime requirements, gradually introducing more features such as enhanced concurrency capabilities, enhanced system types, and distributed development paradigms. diff --git a/en/application-dev/arkts-utils/arkts-runtime-overview.md b/en/application-dev/arkts-utils/arkts-runtime-overview.md index 002b062bac7e5ceb6cb145f590971f0071d60726..b241d05af08f7b79e9ce812264c8237c89f1f3f8 100644 --- a/en/application-dev/arkts-utils/arkts-runtime-overview.md +++ b/en/application-dev/arkts-utils/arkts-runtime-overview.md @@ -1,23 +1,23 @@ -# ArkTS Runtime Overview +# Overview of ArkTS Runtime -The ArkTS runtime is the default language runtime of applications on OpenHarmony. It runs the bytecode and related standard libraries of ArkTS, TS, and JS, and supports the interpreter, AOT, and JIT for efficient execution, in addition, it provides a complete cross-language API implementation [Node-API](../napi/napi-introduction.md) and supports multi-language development. +ArkTS Runtime is the default language runtime for applications on OpenHarmony. It executes bytecode and standard libraries for ArkTS, TS, and JS languages, and supports the interpreter, Ahead-of-Time (AOT), and Just-In-Time (JIT) for efficient execution. It also provides [Node-API](../napi/napi-introduction.md) to enable multi-language hybrid development. -ArkCompiler JS Runtime consists of four subsystems: +ArkTS Runtime is primarily composed of four subsystems: -- The core subsystem consists of basic language-irrelevant runtime libraries, including File, Tooling, and Base. File provides bytecode. Tooling supports Debugger. Base implements system calls. +- **Core subsystem**: consists of the foundational runtime libraries that are language-agnostic, including the File component that carries bytecode, the Tooling component that supports Debugger functionality, and the Base library component responsible for adapting system calls. -- Execution Subsystem: contains the interpreter for executing Ark bytecode, fast path inline cache, and [modular file management and running](module-principle.md). +- **Execution subsystem**: includes the interpreter for executing Ark bytecode, fast-path inline caches, and [file-based modular management for runtime execution](module-principle.md). -- Compiler subsystem: includes the stub compiler, IR-based compilation optimization framework, AOT static compiler, and JIT dynamic compiler (in the experiment). +- **Compiler subsystem**: includes the stub compiler, an IR-based compilation optimization framework, an AOT static compiler, and an experimental JIT dynamic compiler. -- Runtime subsystem: includes the following modules related to the running of ArkTS, TS, and JS: +- **Runtime subsystem**: includes the following modules related to the execution of ArkTS/TS/JS: - Memory management: object allocator and [garbage collector](gc-introduction.md) (CMS-GC and Partial-Compressing-GC for concurrent marking and partial memory compression) - - Analysis tools: DFX tool and CPU and heap profiling tool + - Analysis tools: DFX, and profiling tools for CPU and heap analysis - - Concurrency management: abc file manager in the actor concurrency model + - Concurrency management: .abc file manager in the actor model - - Standard library: standard library defined by ECMAScript, efficient container library, and object model + - Standard libraries: standard libraries defined by ECMAScript, efficient container libraries, and object models - - Others: asynchronous work queues and Node-APIs that interact with C++. + - Other: asynchronous work queues, and Node-API that interact with C++ diff --git a/en/application-dev/arkts-utils/arkts-sendable-module.md b/en/application-dev/arkts-utils/arkts-sendable-module.md index 24fedad088c18a15374330e7aa23657921351458..c4705e2121ad98d11e64f3877cb34eede90a4f73 100644 --- a/en/application-dev/arkts-utils/arkts-sendable-module.md +++ b/en/application-dev/arkts-utils/arkts-sendable-module.md @@ -2,30 +2,34 @@ A shared module, marked with **use shared**, is loaded only once in a process. -A non-shared module is loaded only once in the same thread and multiple times in different threads. New module objects are generated in all these threads. Therefore, a shared module can be used to implement a singleton of a process. +A non-shared module is loaded once in the same thread and multiple times in different threads, creating a new module object in each thread. Shared modules, however, can be used to implement process-wide singletons. ## Constraints -- Similar to **use strict**, **use shared** must be written at the top of the file after the **import** statement but before other statements. +- Similar to **use strict**, **use shared** must be placed at the top level of ArkTS files and should appear after **import** statements but before any other code. - The shared attribute cannot be passed on. That is, importing a shared module does not make a non-shared module shared. + The shared property cannot be passed on. That is, importing a shared module does not make a non-shared module shared. -- A shared module supports only .ets files. +- Shared modules are only supported in .ets files. -- **side-effects-import** is not allowed within a shared module. +- **side-effects-import** is not allowed in shared modules. - After a module is shared between threads, functions are lazy loaded to dependent non-shared modules. This type of import does not involve variable export and therefore is not loaded. + A shared module is loaded only once within a single process and can be used across multiple threads. + + When a shared module is loaded, non-shared modules that it imports are not loaded immediately. Instead, these non-shared modules are lazy-imported within the current thread when their exported variables are accessed. This lazy loading ensures that non-shared modules remain isolated between threads, with each thread potentially loading the module once if needed. + + side-effects-import, which does not involve exported variables, is never loaded and therefore is not supported. ```ts // side-effects-import is not allowed. import "./sharedModule" ``` -- Variables exported by a shared module must be sendable objects. +- All variables exported by shared modules must be Sendable objects. - Shared modules can be shared among concurrent instances. Therefore, all objects exported by a module must be shareable. For details about shareable objects, see [Sendable Usage Rules and Constraints](sendable-constraints.md). + Since shared modules are shared across concurrent instances, all exported objects must be Sendable. For details, see [Usage Rules and Constraints for Sendable](sendable-constraints.md). - Modules cannot be directly exported from a shared module. @@ -42,20 +46,20 @@ A non-shared module is loaded only once in the same thread and multiple times in ``` -- A shared module can reference a shared module or a non-shared module. The reference and reference scenarios of shared modules are not restricted. +- Shared modules can import or be imported by both shared and non-shared modules. There are no restrictions on importing or being imported by shared modules. -- napi_load_module, napi_load_module_with_info, and dynamic loading do not support the loading of shared modules. +- **napi_load_module**, **napi_load_module_with_info**, and dynamic loading do not support loading of shared modules. -## Example +## Usage Example -1. Export the sendable object in a shared module. +1. Export a Sendable object from a shared module. ```ts // Shared module sharedModule.ets import { ArkTSUtils } from '@kit.ArkTS'; - // Declare the current module as a shared module. Only sendable data can be exported. + // Declare the current module as shared. Only Sendable data can be exported. "use shared" // Shared module. SingletonA is globally unique. @@ -80,30 +84,12 @@ A non-shared module is loaded only once in the same thread and multiple times in export let singletonA = new SingletonA(); ``` -2. Operate the object exported from the shared module in multiple threads. +2. Operate an object exported from the shared module across multiple threads. ```ts - import { ArkTSUtils, taskpool } from '@kit.ArkTS'; + import { taskpool } from '@kit.ArkTS'; import { singletonA } from './sharedModule'; - @Sendable - export class A { - private count_: number = 0; - lock_: ArkTSUtils.locks.AsyncLock = new ArkTSUtils.locks.AsyncLock(); - - public async getCount(): Promise { - return this.lock_.lockAsync(() => { - return this.count_; - }) - } - - public async increaseCount() { - await this.lock_.lockAsync(() => { - this.count_++; - }) - } - } - @Concurrent async function increaseCount() { await singletonA.increaseCount(); diff --git a/en/application-dev/arkts-utils/arkts-sendable.md b/en/application-dev/arkts-utils/arkts-sendable.md index 1d7035c9da4174710b2b6524545436fcff3bc817..2e3042cfc35e105cfd67daba68e0c5dfd593ae43 100644 --- a/en/application-dev/arkts-utils/arkts-sendable.md +++ b/en/application-dev/arkts-utils/arkts-sendable.md @@ -1,125 +1,124 @@ -# Sendable Object Overview +# Overview of Sendable Objects -On the traditional JS engine, there is only one way to optimize the concurrent communication overhead of objects. That is, the implementation is moved to the Native side, and the concurrent communication overhead is reduced through the transferable object (transferabled-object.md) transfer or sharing mode. However, developers still have the requirement for concurrent communication of a large number of objects. This problem has not been solved in the JS engine implementation in the industry. +In traditional JS engines, there is only one way to optimize the overhead of concurrent object communication: moving the implementation to the native side and reducing costs through the transfer or sharing of [Transferable objects](transferabled-object.md). However, this solution falls short of addressing the extensive demand for concurrent object communication. The issue remains unresolved in current JS engine implementations. -ArkTS provides the Sendable object type to solve the preceding problem through reference transfer during concurrent communication. +ArkTS introduces the concept of Sendable objects, which support pass-by-reference during concurrent communication. -The Sendable object can be shared. It points to the same JS object across threads. If the Sendable object contains JS or Native content, it can be directly shared. If the bottom layer is implemented by Native, thread security must be considered. The following figure shows the communication process. +Sendable objects are designed to be shareable across threads, maintaining a consistent reference to the same JS object before and after crossing thread boundaries. If a Sendable object contains JS or native content, it can be directly shared. However, if the underlying implementation is native, thread safety must be carefully considered. The following figure shows the communication process. ![sendable](figures/sendable.png) -Unlike other ArkTS objects, data objects that comply with the Sendable protocol must be of a fixed type at run time. +Unlike other ArkTS objects, Sendable objects must have a fixed type at runtime. -When multiple concurrent instances attempt to update Sendable data at the same time, data contention occurs, for example, multi-thread operations of [ArkTS shared container](arkts-collections-introduction.md). Therefore, ArkTS provides the asynchronous lock (arkts-async-lock-introduction.md) mechanism to avoid data competition between different concurrent instances. In addition, you can use the object freezing interface (sendable-freeze.md) to freeze an object and change it to a read-only object. In this way, you do not need to consider data competition. +When multiple concurrent instances attempt to update Sendable data at the same time, data races occurs, such as multithreaded operations on [ArkTS shared container](arkts-collections-introduction.md). To address data race issues between concurrent instances and manage the timing of multithreaded data processing, ArkTS introduces the mechanism of [asynchronous lock](arkts-async-lock-introduction.md). Additionally, objects can be frozen using the [object freezing interface](sendable-freeze.md), making them read-only and thereby eliminating the risk of data races. -The Sendable object provides efficient communication between concurrent instances, that is, the reference transfer capability. It is applicable to scenarios where developers customize large objects that require inter-thread communication. For example, a sub-thread reads data from the database and returns the data to the host thread. +Sendable objects offer efficient communication between concurrent instances by means of pass by reference. They are generally suitable for scenarios where large custom objects need to be transferred between threads, such as when a child thread reads data from a database and returns it to the main thread. ## Basic Concepts ### Sendable Protocol -The Sendable protocol defines the sendable object system and its specifications of ArkTS. Data that complies with the Sendable protocol (hereinafter referred to as Sendable objects) can be transferred between ArkTS concurrent instances. +The Sendable protocol defines the Sendable object system and its specifications in ArkTS. Data that complies with the Sendable protocol (referred to as Sendable objects) can be passed between concurrent instances in ArkTS. -By default, sendable data is passed by reference between ArkTS concurrent instances (including the main thread and the worker thread of TaskPool or Worker). Pass-by-copy is also supported. +By default, Sendable data is passed by reference between concurrent instances (including the UI main thread, TaskPool thread, and Worker thread). Pass-by-copy is also supported. ### ISendable -The interface **ISendable {}** is introduced to the ArkTS common library [@arkts.lang](../reference/apis-arkts/js-apis-arkts-lang.md) without any necessary method or property. **ISendable** is the parent type of all sendable types except null and undefined. **ISendable** is mainly used when you want to customize the sendable data struct. The class decorator [@Sendable decorator](#sendable-decorator) is the syntax sugar for implementing ISendable. +The interface **ISendable** is introduced to the ArkTS common library [@arkts.lang](../reference/apis-arkts/js-apis-arkts-lang.md). It has no required methods or properties. ISendable is the parent type of all Sendable types except for null and undefined. ISendable is mainly used when you want to customize Sendable data structures. The class decorator [@Sendable decorator](#sendable-decorator) is the syntax sugar for implementing ISendable. ### Sendable Class > **NOTE** > -> Since API version 11, the @Sendable decorator can be used to verify the sendable class. +> Since API version 11, the \@Sendable decorator can be used to verify Sendable classes. -A sendable class must meet the following requirements: +A Sendable class must meet the following requirements: -1. This function is available only when the [@Sendable decorator](#sendable-decorator) is marked. +1. It must be decorated by [@Sendable](#sendable-decorator). -2. The Sendable constraints must be met. For details, see [Sendable Usage Rules](sendable-constraints.md). +2. It must meet the Sendable constraints. For details, see [Usage Rules and Constraints for Sendable](sendable-constraints.md). ### Sendable Function > **NOTE** > -> - Since API version 12, the @Sendable decorator can be used to verify the sendable function. -> -> - To use a sendable function in API version 12, you must configure "compatibleSdkVersionStage": "beta3" in the project. Otherwise, the function does not take effect. For details, see [build-profile.json5](https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V5/ide-hvigor-build-profile-V5). +> - Since API version 12, the \@Sendable decorator can be used to verify Sendable functions. -A sendable function must meet the following requirements: +A Sendable function must meet the following requirements: -1. This function is available only when the [@Sendable decorator](#sendable-decorator) is marked. +1. It must be decorated by [@Sendable](#sendable-decorator). -2. The Sendable constraints must be met. For details, see [Sendable Usage Rules](sendable-constraints.md). +2. It must meet the Sendable constraints. For details, see [Usage Rules and Constraints for Sendable](sendable-constraints.md). ### Sendable Interface -A sendable interface must meet the following requirements: +A Sendable interface must meet the following requirements: -1. Be [ISendable](#isendable) or inherit from [ISendable](#isendable). +1. It must be [ISendable](#isendable) or inherit from [ISendable](#isendable). -2. The Sendable constraints must be met. For details, see [Sendable Usage Rules](sendable-constraints.md). +2. It must meet the Sendable constraints. For details, see [Usage Rules and Constraints for Sendable](sendable-constraints.md). ### Sendable Data Types -- All basic ArkTS data types: boolean, number, string, bigint, null, and undefined. +- All ArkTS basic data types: boolean, number, string, bigint, null, and undefined. -- [Container type data](arkts-collections-introduction.md) defined in the ArkTS language standard library ([@arkts.collections](../reference/apis-arkts/js-apis-arkts-collections.md) must be explicitly introduced). +- [Container types](arkts-collections-introduction.md) defined in ArkTS ([@arkts.collections](../reference/apis-arkts/js-apis-arkts-collections.md) must be explicitly introduced). -- [Asynchronous lock object](arkts-async-lock-introduction.md) defined in the ArkTS language standard library ([@arkts.utils](../reference/apis-arkts/js-apis-arkts-utils.md) must be explicitly introduced). +- [Asynchronous lock objects](arkts-async-lock-introduction.md) defined in ArkTS ([@arkts.utils](../reference/apis-arkts/js-apis-arkts-utils.md) must be explicitly introduced). -- Interfaces that inherit [ISendable](#isendable). +- Interfaces that inherit from [ISendable](#isendable). -- Class labeled with the [@Sendable decorator](#sendable-decorator). +- Classes decorated by [@Sendable](#sendable-decorator). -- Function labeled with the [@Sendable decorator](#sendable-decorator). +- Functions decorated by [@Sendable](#sendable-decorator). -- Sendable System Objects +- System objects that integrate Sendable, which are as follows: - [Sendable User Preferences](../reference/apis-arkdata/js-apis-data-sendablePreferences.md) - [Sendable Color Space Management](../reference/apis-arkgraphics2d/js-apis-sendableColorSpaceManager.md) - [Sendable Object-based Image Processing](../reference/apis-image-kit/js-apis-sendableImage.md) - [Resource Management](../reference/apis-localization-kit/js-apis-sendable-resource-manager.md) - [SendableContext Object Management](../reference/apis-ability-kit/js-apis-app-ability-sendableContextManager.md) -- Elements whose union type data is of the sendable type. +- Elements whose union type data is of the Sendable type. > **NOTE** > -> - The transfer of JS built-in objects between concurrent instances complies with the structured clone algorithm. The cross-thread behavior is copy transfer. Therefore, the instance of a JS built-in object is not of the sendable type. +> - Built-in JS objects are passed between concurrent instances following the structured clone algorithm, and their cross-thread behavior is pass-by-copy. Therefore, instances of JS built-in objects are not of the Sendable type. > -> - Object literals and array literals are passed between concurrent instances in compliance with the structured clone algorithm, and the semantics is passed by copy. Therefore, object literals and array literals are not of the sendable type. +> - Object literals and array literals are also passed between concurrent instances following the structured cloning algorithm, and their cross-thread behavior is pass-by-copy. Therefore, object literals and array literals are not of the Sendable type. + +## Implementation Principle of Sendable -## Implementation Principle of the Sendable Function +To implement pass-by-reference of [Sendable data](#sendable-data-types) between different concurrent instances, Sendable objects are allocated in a shared heap to achieve memory sharing across concurrent instances. -To implement reference transfer of [Sendable data](#sendable-data-types) between different concurrent instances, the Sendable shared object is allocated in the shared heap to implement memory sharing across concurrent instances. -The shared heap is a process-level heap space. Different from the local heap of a VM, the local heap can be accessed only by a single concurrent instance, while the shared heap can be accessed by all threads. The cross-thread behavior of a Sendable shared object is reference passing. Therefore, the Sendable may be referenced by multiple concurrent instances. Whether the Sendable shared object is alive depends on whether the objects of all concurrent instances have references to the Sendable shared object. +The shared heap is a process-level heap space. Unlike the local heap of a virtual machine, which can only be accessed by a single concurrent instance, the shared heap can be accessed by all threads. The cross-thread behavior of a Sendable object is pass-by-reference. Therefore, a Sendable object may be referenced by multiple concurrent instances, and its liveness depends on whether any concurrent instance holds a reference to it. -Relationship between SharedHeap and LocalHeap +Relationship between the shared heap and local heap ![image_0000002001521153](figures/image_0000002001521153.png) -The LocalHeap of each concurrent instance is isolated. The SharedHeap is a process-level heap and can be referenced by all concurrent instances. However, SharedHeap cannot reference objects in LocalHeap. +The local heap of each concurrent instance is isolated, whereas the shared heap is a process-level heap that can be referenced by all concurrent instances. However, the shared heap cannot reference objects in the local heap. -## @Sendable Decorator +## \@Sendable Decorator -Declare and verify the Sendable class and Sendable function. +The \@Sendable decorator declares and verifies Sendable classes and functions. -| @Sendable decorator| Description| +| \@Sendable Decorator| Description| | -------- | -------- | -| Decorator parameters| None.| -| Use scenario restrictions| The decorator can be used only in projects of the stage model. It can be used only in .ets files.| -| Restrictions for decorated function types| Only common functions and async functions can be decorated by @Sendable.| -| Inheritance relationship restrictions for decorated classes| A sendable class can inherit only from another sendable class. A common class cannot inherit from a sendable class.| -| Property type restrictions for decorated objects| 1. The following types are supported: string, number, boolean, bigint, null, undefined, Sendable class, collections.Array, collections.Map, and collections.Set.
2. Closure variables are not allowed.
3. Private attributes cannot be defined using \#. Use private instead.
4. Computed properties are not supported.| -| Other property restrictions for decorated objects| Member properties must be initialized explicitly. They cannot be followed by exclamation marks (!).| -| Restrictions on method parameters in decorated functions or class objects| Local variables, input parameters, and variables imported through **import** are supported. Do not use closure variables, except the sendable class and sendable function defined at the top layer.| -| Restrictions on the Sendable Class and Sendable Function| Properties cannot be added or deleted, but can be modified. The property types before and after the modification must be the same. Methods cannot be modified.| -| Use scenario| 1. Use the class method or Sendable function in TaskPool or Worker.
2. The sendable type is used when a large amount of data needs to be transmitted.| - -The following is an example of using a decorator to modify a class: +| Parameters| None.| +| Usage restrictions| It can be used only in projects of the stage model and only in .ets files.| +| Supported function types| Only regular functions and async functions can be decorated by @Sendable.| +| Class inheritance restrictions| Sendable classes can only inherit from other Sendable classes. Regular classes cannot inherit from Sendable classes.| +| Property type restrictions| 1. The following types are supported: string, number, boolean, bigint, null, undefined, Sendable class, collections.Array, collections.Map, collections.Set, and ArkTSUtils.locks.AsyncLock.
2. Closure variables are not allowed.
3. Private properties defined with \# are not supported; use **private** instead.
4. Computed properties are not supported.| +| Other property restrictions| Member properties must be initialized explicitly. They cannot be followed by exclamation marks (!).| +| Parameter restrictions for decorated functions or class methods| Local variables, parameters, and variables imported through **import** are allowed. Closure variables are not allowed, except for top-level Sendable classes and functions.| +| Restrictions for Sendable classes and functions| Adding or deleting properties is not allowed. Modifying properties is allowed, but the type must remain consistent before and after modification. Modifying methods is not supported.| +| Use scenario| 1. Scenarios where class methods or Sendable functions are used in TaskPool or Worker.
2. Scenarios involving large amounts of object data transmission. The time required for serialization increases with the data volume. After transforming data with Sendable, the efficiency of transmitting 100 KB of data is approximately 20 times higher, and for 1 MB of data, it is about 100 times higher.| + +The following is an example of using the decorator on a class: ```ts @Sendable @@ -135,7 +134,7 @@ class SendableTestClass { } ``` -The following is an example of using the decorator to decorate a function: +The following is an example of using the decorator on a function: ```ts @Sendable @@ -156,9 +155,9 @@ function TopLevelSendableFunction() { @Sendable function SendableTestFunction() { - const topClass = new TopLevelSendableClass (); // Top-level sendable class. + const topClass = new TopLevelSendableClass(); // Top-level Sendable class. topClass.PrintNum(); - TopLevelSendableFunction (); // Top-level sendable function. + TopLevelSendableFunction(); // Top-level Sendable function. console.info("Sendable test function"); } @@ -167,10 +166,10 @@ class SendableTestClass { constructor(func: SendableFuncType) { this.callback = func; } - callback: SendableFuncType; // Top-level sendable function. + callback: SendableFuncType; // Top-level Sendable function. CallSendableFunc() { - SendableTestFunction (); // Top-level sendable function. + SendableTestFunction(); // Top-level Sendable function. } } diff --git a/en/application-dev/arkts-utils/arkts-utils-overview.md b/en/application-dev/arkts-utils/arkts-utils-overview.md index a8e6c5766f3892d117e4d5a6cef861f6ad4d06ee..d3fae1fe583779196a1435897b49af7c71e98bc2 100644 --- a/en/application-dev/arkts-utils/arkts-utils-overview.md +++ b/en/application-dev/arkts-utils/arkts-utils-overview.md @@ -1,5 +1,5 @@ -# ArkTS Utils Overview +# Overview of the ArkTS Common Library -The ArkTS base class library is a collection of APIs with comprehensive functions and a series of key and practical functional modules. +The ArkTS common library is a rich set of APIs designed to provide a series of essential and practical functional modules. -The ArkTS basic class library mainly provides [XML generation, parsing, and conversion](xml-overview.md), [binary buffer](buffer.md), [multiple container class libraries](container-overview.md), and [URL string parsing](../reference/apis-arkts/js-apis-url.md), and [high-precision floating-point computing](../reference/apis-arkts/js-apis-arkts-decimal.md) to help developers simplify development and improve development efficiency. +The ArkTS common library mainly provides [XML generation, parsing, and conversion](xml-overview.md), [binary buffers](buffer.md), [multiple container libraries](container-overview.md), and [URL string parsing](../reference/apis-arkts/js-apis-url.md), and [high-precision floating-point operating](../reference/apis-arkts/js-apis-arkts-decimal.md) to help you streamline your work and boost your efficiency. diff --git a/en/application-dev/arkts-utils/arraybuffer-object.md b/en/application-dev/arkts-utils/arraybuffer-object.md index a9eefbb75eb47045e416c082480e9256738a5607..e4d525dea88b5c75010a7d23e5a64a64e4ec59cc 100644 --- a/en/application-dev/arkts-utils/arraybuffer-object.md +++ b/en/application-dev/arkts-utils/arraybuffer-object.md @@ -1,28 +1,28 @@ # ArrayBuffer Object -The ArrayBuffer contains a native memory. Similar to common objects, JS object shells need to be copied and transferred through serialization and deserialization. However, the native memory has two transmission modes: copy and transfer. +An ArrayBuffer object contains a block of native memory, and its JS object wrapper is allocated in the local heap of the virtual machine. Similar to a regular object, an ArrayBuffer object requires serialization and deserialization. However, the native memory can be passed in two ways: pass-by-copy and pass-by-transfer. -If copy is used during transmission, deep copy (recursive traversal) is required. After transmission, the two threads can independently access the ArrayBuffer. The following figure shows the communication process. +When pass-by-copy is used, a deep copy (recursive traversal) is required, and both threads can independently access the ArrayBuffer object after the transmission. The following figure shows the communication process. ![copy_transfer](figures/copy_transfer.png) -If the transfer mode is used, the original thread cannot use the ArrayBuffer object. In cross-thread scenarios, only the JS shell needs to be rebuilt, and the native memory does not need to be copied, improving efficiency. The following figure shows the communication process. +If pass-by-transfer is used, the original thread can no longer use the ArrayBuffer object. During inter-thread communication, only the JS shell needs to be reconstructed, and the native memory does not need to be copied, resulting in higher efficiency. The following figure shows the communication process. ![transfer](figures/transfer.png) -ArrayBuffer can be used to represent resources such as images. During application development, image processing is required (for example, the brightness, saturation, and size of an image need to be adjusted). To avoid blocking the UI main thread, you can transfer the image to a subthread to perform these operations. The transfer mode has higher performance. However, the original thread cannot access the ArrayBuffer object. If both threads need to access the ArrayBuffer object, the copy mode must be used. Otherwise, the transfer mode is recommended to improve performance. +ArrayBuffer objects can be used to represent resources such as images. In application development, scenarios requiring image processing (such as adjusting an image's brightness, saturation, or size) are common. To avoid blocking the UI main thread, images can be passed to child threads to perform these operations. Pass-by-transfer is more performant, but the original thread can no longer access the ArrayBuffer object. If both threads need access, pass-by-copy should be used; otherwise, pass-by-transfer is recommended to enhance performance. -The following describes how to transfer an image to a subthread by copying and transferring the image. +The following describes how to pass an image to a child thread using both methods. -## ArrayBuffer copy transfer mode +## Pass-by-Copy -In ArkTS, when the TaskPool transfers ArrayBuffer data, the transfer mode is used by default. You can call the setTransferList () API to specify the transfer mode as the transfer mode for some data and switch the copy mode for other data. +In ArkTS, TaskPool defaults to passing ArrayBuffer data by transfer. By calling the **setTransferList()** interface, you can specify which parts of the data should be passed by transfer, while the rest can be switched to pass-by-copy. -First, implement an interface that needs to be executed in a task to process ArrayBuffer. +First, implement an interface for processing the ArrayBuffer that will be executed in the Task. -Then, the ArrayBuffer data is transferred to the task in copy mode, and the ArrayBuffer is processed in the task. +Then, pass the ArrayBuffer data to the Task by copy and process it within the Task. -Finally, the UI main thread receives the ArrayBuffer data returned after the task is executed and combines the data for display. +Finally, the UI main thread receives the ArrayBuffer data returned after the Task execution and concatenates the data for display. ```ts // Index.ets @@ -31,14 +31,14 @@ import { BusinessError } from '@kit.BasicServicesKit'; @Concurrent function adjustImageValue(arrayBuffer: ArrayBuffer): ArrayBuffer { - // Perform operations on arrayBuffer. - return arrayBuffer; // The return value is transferred by default. + // Perform operations on the ArrayBuffer. + return arrayBuffer; // The return value is passed by transfer by default. } function createImageTask(arrayBuffer: ArrayBuffer, isParamsByTransfer: boolean): taskpool.Task { let task: taskpool.Task = new taskpool.Task(adjustImageValue, arrayBuffer); - if (!isParamsByTransfer) {// Whether to use the transfer mode - // Transfer an empty array []. All arrayBuffer parameters are transferred in copy mode. + if (!isParamsByTransfer) { // Whether to use pass-by-transfer. + // Pass an empty array [] to indicate that all ArrayBuffer parameters should be passed by copy. task.setTransferList([]); } return task; @@ -63,15 +63,15 @@ struct Index { let taskNum = 4; let arrayBuffer = new ArrayBuffer(1024 * 1024); let taskPoolGroup = new taskpool.TaskGroup(); - // Create a certain number of tasks based on the input taskNum. + // Create taskNum tasks. for (let i: number = 0; i < taskNum; i++) { let arrayBufferSlice: ArrayBuffer = arrayBuffer.slice(arrayBuffer.byteLength / taskNum * i, arrayBuffer.byteLength / taskNum * (i + 1)); - // Use the copy method to transmit the ArrayBuffer object. Therefore, isParamsByTransfer is false. + // To pass the ArrayBuffer object by copy, set isParamsByTransfer to false. taskPoolGroup.addTask(createImageTask(arrayBufferSlice, false)); } - // Execute the task. + // Execute the tasks. taskpool.execute(taskPoolGroup).then((data) => { - // Return the result. Combine the arrays to obtain the final result. + // Concatenate the results to obtain the final result. }).catch((e: BusinessError) => { console.error(e.message); }) @@ -83,6 +83,6 @@ struct Index { } ``` -## ArrayBuffer transfer mode +## Pass-by-Transfer -In the TaskPool, the transfer mode is used by default when the ArrayBuffer data is transferred. The original thread cannot use the ArrayBuffer data transferred to the subthread. Therefore, based on the preceding example, you can remove the task.setTransferList interface, that is, set the second parameter of createImageTask to true. +TaskPool defaults to passing ArrayBuffer data by transfer, and the original thread can no longer use the ArrayBuffer passed to the child thread. To achieve this, simply remove the **task.setTransferList** interface call in the preceding code, meaning the second parameter of **createImageTask** should be **true**. diff --git a/en/application-dev/arkts-utils/ason-parsing-generation.md b/en/application-dev/arkts-utils/ason-parsing-generation.md index 0335d45c22a41a82abb083b8bee2d4931f5250f4..c19c730347c7a1e1951f6ce4d4712e2472cdbdcc 100644 --- a/en/application-dev/arkts-utils/ason-parsing-generation.md +++ b/en/application-dev/arkts-utils/ason-parsing-generation.md @@ -1,14 +1,14 @@ # ASON Parsing and Generation -The [ASON tool](../reference/apis-arkts/js-apis-arkts-utils.md#arktsutilsason) is similar to the JSON tool provided by JavaScript. JSON is used to stringify and parse JavaScript objects. ASON provides the serialization and deserialization capabilities of the [Sendable object](arkts-sendable.md). You can use the ASON.stringify method to convert an object into a string or use the ASON.parse method to convert a string into a Sendable object so that the object can be referenced and transferred between concurrent tasks with high performance. +The [ASON utility](../reference/apis-arkts/js-apis-arkts-utils.md#arktsutilsason) is similar to the JSON utility provided by JavaScript. While JSON is used to serialize (via **stringify**) and deserialize (via **parse**) JavaScript objects, ASON provides serialization and deserialization capabilities specifically for [Sendable objects](arkts-sendable.md). You can convert Sendable objects to strings using the **ASON.stringify** method and convert strings back to Sendable objects using the **ASON.parse** method. This enables high-performance pass-by-reference of these objects between concurrent tasks. -> **Note** +> **NOTE** > -> By default, the object generated by ASON.parse is a Sendable object. The layout cannot be changed, and attributes cannot be added or deleted. If the layout of the returned object needs to be variable, you can specify the return type as MAP. In this case, all [collections.Map](../reference/apis-arkts/js-apis-arkts-collections.md#collectionsmap) objects are returned. Attributes can be added or deleted. +> By default, objects generated by **ASON.parse** are immutable Sendable objects that do not support adding or deleting properties. If you need to return objects with mutable layouts, you can specify the return type as MAP. In this case, all objects will be returned as [collections.Map](../reference/apis-arkts/js-apis-arkts-collections.md#collectionsmap) objects, which support adding and deleting properties. -## Samples +## Usage Example -The interface provided by ASON is used to serialize and deserialize the [Sendable object](arkts-sendable.md). +Use ASON interfaces to serialize and deserialize [Sendable objects](arkts-sendable.md). ```ts import { ArkTSUtils, collections } from '@kit.ArkTS'; diff --git a/en/application-dev/arkts-utils/async-concurrency-overview.md b/en/application-dev/arkts-utils/async-concurrency-overview.md index 58597fc5d14e4611dea694b8e2a7ad23e0326e1e..be2630531979ea3d71e5830c8c256b37ff4c46cc 100644 --- a/en/application-dev/arkts-utils/async-concurrency-overview.md +++ b/en/application-dev/arkts-utils/async-concurrency-overview.md @@ -1,17 +1,17 @@ -# Asynchronous Concurrency Overview (Promise and Async/Await) +# Asynchronous Concurrency (Promise and Async/Await) -Promise and async/await are standard JavaScript syntax that provides asynchronous concurrency. Asynchronous code ensures that actions initiated now finish later. It allows the execution of only one segment of code at a time and is therefore applicable to the development of a single I/O task, for example, a network request or a file read/write operation. You do not need to start another thread. +Promise and async/await are standard JavaScript asynchronous syntax that provides asynchronous concurrency capabilities. Asynchronous code can be suspended and resumed later, ensuring that only one piece of code is executed at any given moment. This approach is suitable for single I/O tasks, such as a single network request or file read/write operation, without the need to start additional threads. -Promise and async/await allow an application to perform other operations without waiting for the completion of certain actions. +Asynchronous syntax is a feature of programming languages that allows programs to continue executing other operations without waiting for certain operations to complete. ## Promise -Promise is an object used to process asynchronous operations. It converts asynchronous operations into a style similar to synchronous operations for easier code writing and maintenance. Promise provides a state mechanism to manage different phases of asynchronous operations. It also provides methods to register callback functions to handle the success or failure of these operations. +A Promise is an object used to process asynchronous operations. It converts asynchronous operations into a style similar to synchronous operations for easier code writing and maintenance. Promises provide a state mechanism to manage different phases of asynchronous operations. It also provides methods to register callback functions to handle the success or failure of these operations. -Promise has three states: pending, fulfilled, and rejected. A Promise object is in the pending state after being created and changes to the fulfilled or rejected state when the asynchronous operation is complete. +Promises have three states: pending, fulfilled, and rejected. A Promise object starts in the pending state and transitions to either fulfilled or rejected upon completion of the asynchronous operation. -The most common usage for Promise is to instantiate a Promise object through a constructor and pass in a function (usually named **executor**) with two parameters. The two parameters are **resolve** and **reject**, which represent the callback functions that should be called when the asynchronous operation succeeds and fails, respectively. The code snippet below creates a Promise object and simulates an asynchronous operation: +The most basic usage involves instantiating a Promise object through its constructor, passing in a function (usually named **executor**) with two parameters. The two parameters are **resolve** and **reject**, which represent the callback functions for the success and failure of the asynchronous operation, respectively. For example, the code snippet below creates a Promise object and simulates an asynchronous operation: ```ts const promise: Promise = new Promise((resolve: Function, reject: Function) => { @@ -26,9 +26,9 @@ setTimeout(() => { }) ``` -In the preceding code, the **setTimeout** function simulates an asynchronous operation that generates a random number one second later. If the random number is greater than 0.5, the **resolve** callback function is executed and the random number is passed in as a parameter. Otherwise, the **reject** callback function is executed and an error object is passed in. +In this code, the **setTimeout** function simulates an asynchronous operation that generates a random number one second later. If the random number is greater than 0.5, the **resolve** callback function is executed, with the random number passed as a parameter. Otherwise, the **reject** callback function is executed, with an error object passed as a parameter. -After the Promise object is created, you can use the **then** and **catch** methods to register the callback functions for the fulfilled and rejected states. The **then** method can receive two parameters: one for processing the fulfilled state and the other for processing the rejected state. If only one parameter is passed in, the **then** method automatically calls the callback function when the Promise state changes to **fulfilled** and passes in the result of the Promise object in the callback function. The **catch** method receives a callback function to process the failure result, that is, capture the exception thrown when the Promise state changes to **rejected** or the operation fails. The code snippet below shows the use of the **then** and **catch** methods: +After a Promise object is created, you can use the **then** and **catch** methods to specify callback functions for the fulfilled and rejected states. The **then** method can accept two parameters: one for handling the fulfilled state and the other for handling the rejected state. If only one parameter is passed in, the **then** method automatically calls the callback function when the Promise object state changes to **fulfilled**, with the result of the Promise object passed as a parameter. The **catch** method receives a callback function to handle failures, that is, capturing the Promise's transition to the rejected state or any exceptions thrown during the operation. The code snippet below shows the use of the **then** and **catch** methods. ```ts import { BusinessError } from '@kit.BasicServicesKit'; @@ -40,15 +40,19 @@ promise.then((result: number) => { }); ``` -In the preceding code, the callback function of the **then** method receives the success result of the Promise object as a parameter and outputs it to the console. If the Promise object enters the rejected state, the callback function of the **catch** method receives the error object as a parameter and outputs it to the console. +In this example, the callback function of the **then** method receives the successful result of the Promise object as a parameter and outputs it to the console. If the Promise object enters the rejected state, the callback function of the **catch** method receives the error object as a parameter and outputs it to the console. + +> **NOTE** +> +> When a Promise object is rejected and not handled by the **catch** method, it triggers the **unhandledRejection** event. You can use the [errorManager.on('error')](../reference/apis-ability-kit/js-apis-app-ability-errorManager.md#errormanageronerror) interface to listen for this event and globally capture unhandled Promise rejects. ## Async/Await -Async/Await is a Promise syntax sugar used to process asynchronous operations, making it easier to read and write asynchronous code. The async keyword is used to declare an asynchronous function, and the await keyword is used to wait for Promise parsing (fulfilled or rejected). In this way, the asynchronous operation logic is coded as a synchronous operation. +Async/Await is syntactic sugar for handling asynchronous operations with Promises, making it easier and more readable to write asynchronous code. By declaring a function as asynchronous with the async keyword and using the await keyword to wait for the resolution of a Promise (fulfilled or rejected), you can write asynchronous operations in a synchronous style. -The **async** function returns a Promise object to represent an asynchronous operation. Inside the **async** function, you can use the await keyword to wait for the parsing of the Promise object and return its parsed value. If an **async** function throws an exception, the Promise object returned by the function is rejected, and the exception information is passed in to the **onRejected()** method of the Promise object. +An async function returns a Promise object to represent an asynchronous operation. Inside the async function, you can use the await keyword to wait for the resolution of the Promise object and return its resolved value. If an async function throws an exception, the Promise object returned by the function is rejected, and the exception information is passed to the **onRejected()** method of the Promise object. -The code snippet below uses async/await to simulate the scenario where a synchronous API is called to execute an asynchronous operation that returns a string three seconds later. +The code snippet below uses async/await to simulate an asynchronous operation that returns a string after 3 seconds. ```ts async function myAsyncFunction(): Promise { @@ -83,9 +87,9 @@ struct Index { } ``` -In the preceding code, the await keyword is used to wait for the parsing of the Promise object and store its parsed value in the **result** variable. +In this code, the await keyword is used to wait for the resolution of the Promise object and store its resolved value in the **result** variable. -Note that the entire operation must be packed in the **async** function and used together with the **await** keyword because the code needs to wait for the asynchronous operation to complete. In addition to **await**, you can use the try/catch block to capture exceptions in asynchronous operations. +Since you need to wait for the completion of the asynchronous operation, the entire operation must be wrapped in an async function and used with the await keyword. In addition to using await within async functions, you can also use try/catch blocks to catch exceptions in asynchronous operations. ```ts async function myAsyncFunction(): Promise { diff --git a/en/application-dev/arkts-utils/batch-database-operations-guide.md b/en/application-dev/arkts-utils/batch-database-operations-guide.md index bbdd847bd92255ae7b4e55d528c44ea16a11e05a..ab9413682587ce28a4ea79fa81da1c0b40a5ecb1 100644 --- a/en/application-dev/arkts-utils/batch-database-operations-guide.md +++ b/en/application-dev/arkts-utils/batch-database-operations-guide.md @@ -1,14 +1,14 @@ -# Batch Data Writing to the Database +# Batch Database Operations ## Using TaskPool for Frequent Database Operations -In scenarios where frequent database operations are required, it is time-consuming to read and write the database. Therefore, you are advised to perform operations in sub-threads to avoid blocking the UI thread. +When dealing with scenarios that require frequent database operations, the time-consuming nature of reading from and writing to the database can lead to UI thread blockages. To mitigate this, you are advised to offload these operations to background threads. -The TaskPool capability provided by ArkTS can be used to move database operation tasks to subthreads. The implementation is as follows: +By leveraging the TaskPool capabilities provided by ArkTS, database operations can be efficiently moved to background threads. The implementation involves the following steps: -1. Create multiple subtasks and supports operations such as database creation, insertion, query, and clearing. +1. Create multiple tasks to support various database operations such as creation, insertion, querying, and clearing. -2. The UI main thread calls subtasks to perform database operations such as adding, deleting, modifying, and querying data. +2. The UI main thread calls these tasks to perform database operations such as adding, deleting, modifying, and querying data. ```ts // Index.ets @@ -65,7 +65,7 @@ async function query(context: Context): Promise(resultSet.rowCount) @@ -139,11 +139,11 @@ struct Index { } ``` -## Using Sendable for Large-Capacity Database Operations +## Using Sendable for Large-Scale Database Operations -It takes a long time to transfer database data across threads. When the data volume is large, the UI main thread is still occupied. You are advised to use Sendable to encapsulate database data to reduce the cross-thread overhead. +When handling large volumes of database data, cross-thread data transfer may still block the UI main thread due to its time-consuming nature. To address this, you are advised to use Sendable to encapsulate database data, thereby reducing cross-thread overhead. -1. Define the data format in the database. Sendable can be used to reduce the cross-thread time consumption. +1. Define the data format in the database. Sendable can be used to minimize cross-thread latency. ```ts // SharedValuesBucket.ets @@ -170,7 +170,7 @@ It takes a long time to transfer database data across threads. When the data vol } ``` -2. Initiated by the UI main thread to add, delete, modify, and query data in subthreads. +2. Initiate from the UI main thread and perform Create, Read, Update, Delete (CRUD) operations in the background thread. ```ts // Index.ets @@ -228,7 +228,7 @@ It takes a long time to transfer database data across threads. When the data vol // Obtain the result set. let predicates: relationalStore.RdbPredicates = new relationalStore.RdbPredicates("test"); - let resultSet = await store.query (predicates); // Query all data. + let resultSet = await store.query(predicates); // Query all data. console.info(`Query data successfully! row count:${resultSet.rowCount}`); let index = 0; let result = collections.Array.create(resultSet.rowCount, undefined) @@ -308,3 +308,211 @@ It takes a long time to transfer database data across threads. When the data vol } } ``` + +## Using Sendable for Large-Scale Database Operations with Complex Class Instances + +The properties of regular class instances can contain Sendable class instances. + +For complex regular class instances, you can first wrap the relevant database data fields in Sendable class instances and then let the regular class instances hold these Sendable class instances. This can help lower the cost of cross-thread operations. + +1. Define the data format in the database. Sendable can be used to minimize cross-thread latency. + + ```ts + // SharedValuesBucket.ets + export interface IValueBucket { + id: number; + name: string; + age: number; + salary: number; + } + + @Sendable + export class SharedValuesBucket implements IValueBucket { + id: number = 0; + name: string = ""; + age: number = 0; + salary: number = 0; + + constructor(v: IValueBucket) { + this.id = v.id; + this.name = v.name; + this.age = v.age; + this.salary = v.salary; + } + } + ``` + +2. Define a regular class instance to hold the Sendable class instance. + + ```ts + // Material.ets + import { SharedValuesBucket } from './SharedValuesBucket'; + import { collections } from '@kit.ArkTS'; + + export class Material { + seq: number = 0; + materialName: string = ""; + //... Other properties are omitted. + buckets: collections.Array; + + constructor(seq: number, materialName: string, buckets: collections.Array) { + this.seq = seq; + this.materialName = materialName; + this.buckets = buckets; + } + + getBuckets() : collections.Array{ + return this.buckets; + } + + setBuckets(buckets: collections.Array) { + this.buckets = buckets; + } + } + ``` + +3. Initiate from the UI main thread and perform Create, Read, Update, Delete (CRUD) operations in the background thread. + + ```ts + // Index.ets + import { relationalStore, ValuesBucket } from '@kit.ArkData'; + import { collections, taskpool } from '@kit.ArkTS'; + import { IValueBucket, SharedValuesBucket } from './SharedValuesBucket'; + import { Material } from './Material'; + + @Concurrent + async function create(context: Context) { + const CONFIG: relationalStore.StoreConfig = { + name: "Store.db", + securityLevel: relationalStore.SecurityLevel.S1, + }; + + // The default database file path is context.databaseDir + rdb + StoreConfig.name. + let store: relationalStore.RdbStore = await relationalStore.getRdbStore(context, CONFIG); + console.info(`Create Store.db successfully!`); + + // Create a table. + const CREATE_TABLE_SQL = "CREATE TABLE IF NOT EXISTS test (" + + "id INTEGER PRIMARY KEY AUTOINCREMENT, " + + "name TEXT NOT NULL, " + + "age INTEGER, " + + "salary REAL, " + + "blobType BLOB)"; + await store.executeSql(CREATE_TABLE_SQL); + console.info(`Create table test successfully!`); + } + + @Concurrent + async function insert(context: Context, valueBucketArray: collections.Array) { + const CONFIG: relationalStore.StoreConfig = { + name: "Store.db", + securityLevel: relationalStore.SecurityLevel.S1, + }; + + // The default database file path is context.databaseDir + rdb + StoreConfig.name. + let store: relationalStore.RdbStore = await relationalStore.getRdbStore(context, CONFIG); + console.info(`Create Store.db successfully!`); + + // Insert data. + await store.batchInsert("test", valueBucketArray as Object as Array); + } + + @Concurrent + async function query(context: Context): Promise> { + const CONFIG: relationalStore.StoreConfig = { + name: "Store.db", + securityLevel: relationalStore.SecurityLevel.S1, + }; + + // The default database file path is context.databaseDir + rdb + StoreConfig.name. + let store: relationalStore.RdbStore = await relationalStore.getRdbStore(context, CONFIG); + console.info(`Create Store.db successfully!`); + + // Obtain the result set. + let predicates: relationalStore.RdbPredicates = new relationalStore.RdbPredicates("test"); + let resultSet = await store.query(predicates); // Query all data. + console.info(`Query data successfully! row count:${resultSet.rowCount}`); + let index = 0; + let result = collections.Array.create(resultSet.rowCount, undefined) + resultSet.goToFirstRow() + do { + let v: IValueBucket = { + id: resultSet.getLong(resultSet.getColumnIndex("id")), + name: resultSet.getString(resultSet.getColumnIndex("name")), + age: resultSet.getLong(resultSet.getColumnIndex("age")), + salary: resultSet.getLong(resultSet.getColumnIndex("salary")) + }; + result[index++] = new SharedValuesBucket(v) + } while (resultSet.goToNextRow()); + resultSet.close(); + return result + } + + @Concurrent + async function clear(context: Context) { + const CONFIG: relationalStore.StoreConfig = { + name: "Store.db", + securityLevel: relationalStore.SecurityLevel.S1, + }; + + // The default database file path is context.databaseDir + rdb + StoreConfig.name. + await relationalStore.deleteRdbStore(context, CONFIG); + console.info(`Delete Store.db successfully!`); + } + + function initMaterial() : Material { + // Prepare data. + const count = 5 + let valueBucketArray = collections.Array.create(count, undefined); + for (let i = 0; i < count; i++) { + let v: IValueBucket = { + id: i, + name: "zhangsan" + i, + age: 20, + salary: 5000 + 50 * i + }; + valueBucketArray[i] = new SharedValuesBucket(v); + } + let material = new Material(1, "test", valueBucketArray); + return material; + } + + @Entry + @Component + struct Index { + @State message: string = 'Hello World'; + + build() { + RelativeContainer() { + Text(this.message) + .id('HelloWorld') + .fontSize(50) + .fontWeight(FontWeight.Bold) + .alignRules({ + center: { anchor: '__container__', align: VerticalAlign.Center }, + middle: { anchor: '__container__', align: HorizontalAlign.Center } + }) + .onClick(async () => { + let context = getContext(this); + let material = initMaterial(); + await taskpool.execute(create, context); + await taskpool.execute(insert, context, material.getBuckets()); + let index = 0; + let ret: collections.Array = + await taskpool.execute(query, context) as collections.Array; + material.setBuckets(ret); + for (let v of ret.values()) { + console.info(`Row[${index}].id = ${v.id}`); + console.info(`Row[${index}].name = ${v.name}`); + console.info(`Row[${index}].age = ${v.age}`); + console.info(`Row[${index}].salary = ${v.salary}`); + index++; + } + await taskpool.execute(clear, context); + }) + } + .height('100%') + .width('100%') + } + } + ``` diff --git a/en/application-dev/arkts-utils/buffer.md b/en/application-dev/arkts-utils/buffer.md index bfe54b358c5194009f4208a6981f8c984c4dc230..17ef341d7b08b56e6237c1d7288be4e0f1799a7b 100644 --- a/en/application-dev/arkts-utils/buffer.md +++ b/en/application-dev/arkts-utils/buffer.md @@ -1,23 +1,23 @@ -# Buffer Introduction +# Buffer -Based on the memory management mechanism, the buffer module abstracts the memory area into logical objects that can be read, written, and modified, aiming to provide efficient interfaces for binary data processing. Each buffer instance object is a continuous byte sequence. You can create memory blocks of a customized size to store and operate various types of data. +The Buffer module, built on memory management mechanisms, abstracts memory regions into logical objects that can be read, written, and modified, aiming to provide an efficient interface for handling binary data. Each Buffer instance is a contiguous sequence of bytes. It supports the creation of custom-sized memory blocks, which facilitates the storage and manipulation of various data types. -The core functions of the buffer module are as follows: +The core functionalities of the Buffer module are as follows: -1. Memory creation and allocation: allows you to initialize the buffer based on the specified size limited by uint32. After the buffer is created, it has a fixed memory capacity. +1. **Memory allocation**: You can initialize a buffer with a specified size, limited by uint32, resulting in a fixed memory capacity upon creation. -2. Reads, writes, and copies data: accesses bytes in the buffer by index, reads and writes data by byte block, and copies a part of the buffer to another buffer or array. +2. **Data read/write and copying**: You can access bytes within a buffer by index, read and write data byte-by-byte, and copy parts of a buffer to another buffer or array. -3. Conversion operation: provides methods for converting between buffers and basic types (such as Uint8Array and string) to meet different data processing requirements. +3. **Conversion operations**: Methods are provided for converting buffers to and from basic types such as Uint8Array and string, catering to diverse data processing needs. -4. Memory operation: The system can intercept some buffers, slice the buffers, and combine multiple buffers to facilitate data flow processing and management. +4. **Memory manipulation**: Buffers can be sliced, spliced, and concatenated, making it easier to manage and process data streams. -The buffer module is used in the following scenarios: +The Buffer module is primarily used in the following scenarios: -1. Big data transmission: When a large amount of data needs to be transmitted, such as binary files, database records, or network packets, the buffer functions as a data storage and processing container to reduce copy and memory consumption and improve transmission efficiency. +1. **Large data transfers**: When transmitting large volumes of data, like binary files, database records, or network packets, buffers serve as efficient containers for data storage and processing, reducing memory overhead and enhancing transfer efficiency. -2. Image and audio processing: In terms of image encoding, decoding, and audio data stream processing, the buffer helps developers easily operate pixels or sample data to ensure data integrity. +2. **Image and audio processing**: Buffers help you manipulate pixel and sample data during image encoding/decoding and audio stream processing, ensuring data integrity. -3. Binary data operation: The buffer provides stable interfaces for parsing and operating binary data. +3. **Binary data operation**: The Buffer module offers a stable interface for parsing and manipulating binary data. -For details about the APIs of the buffer module, see [@ohos.buffer](../reference/apis-arkts/js-apis-buffer.md). +For details about the APIs of the Buffer module, see [@ohos.buffer](../reference/apis-arkts/js-apis-buffer.md). diff --git a/en/application-dev/arkts-utils/compilation-tool-chain-overview.md b/en/application-dev/arkts-utils/compilation-tool-chain-overview.md index 7c597023b45f4f8a3f850348d7353b51b153dff1..1cab882e6448ea04218b27a57eb216fee7038182 100644 --- a/en/application-dev/arkts-utils/compilation-tool-chain-overview.md +++ b/en/application-dev/arkts-utils/compilation-tool-chain-overview.md @@ -1,22 +1,22 @@ -# ArkTS Compilation Toolchain Overview +# Overview of the ArkTS Compilation Toolchain -To support ArkTS application compilation, the ArkTS compilation and building SDK provides a complete compilation tool chain, which can be deployed on the orchestration tool of Hvigor compilation tasks, compile the ArkTS/TS/JS source code of your app into an ARK bytecode file (\*.abc). +To support the compilation of ArkTS applications, the ArkTS compilation and build SDK offers a comprehensive toolchain. This toolchain is integrated into the Hvigor task orchestration tool to compile ArkTS/TS/JS source code into Ark bytecode files (*.abc). -During the compilation, the first phase is the syntax conversion phase, including syntax check and UI conversion. To ensure source code security, use [ArkGuard](source-obfuscation.md) to obfuscate the source code and determine whether to [customize the bytecode](customize-bytecode-during-compilation.md) before the bytecode is flushed to disks, if necessary, load and execute the customized code. After the bytecode file is generated, use [Disassembler](tool-disassembler.md) to view the content in the bytecode file. For details about the bytecode, see [Ark Bytecode Overview](arkts-bytecode-overview.md). +The compilation process begins with syntax transformation, including syntax check and UI transformation. To ensure source code security, [ArkGuard](source-obfuscation.md) is used to obfuscate the source code. Before the bytecode is written to disk, the toolchain checks whether [custom bytecode modifications](customize-bytecode-during-compilation.md) are required. If modifications are required, custom modification code is loaded and executed. After generating the bytecode file, the [Disassembler](tool-disassembler.md) tool is used to inspect the file content. For details about the bytecode, see [Overview of Ark Bytecode](arkts-bytecode-overview.md). The ArkTS compilation toolchain provides the following functions: 1. Syntax check: checks whether the ArkTS/TS syntax is correct. -2. UI conversion: converts the UI normal form syntax of ArkTS to the standard TS syntax. +2. UI transformation: converts ArkTS UI paradigm syntax to standard TS syntax. -3. Source code obfuscation: Use the ArkGuard source code obfuscation tool to obfuscate the source code. You can enable this function based on service requirements. +3. Source code obfuscation: uses the ArkGuard tool to obfuscate the source code. You can enable this function based on service requirements. -4. Bytecode compilation: The Ark compiler compiles the Ark bytecode file (\*.abc). +4. Bytecode compilation: The Ark compiler generates Ark bytecode files (\*.abc). -5. Custom modification of Ark bytecode: provides an entry for developers to modify bytecode. This API is called before bytecode compilation and flushing. +5. Custom bytecode modification: provides an entry for you to modify bytecode before it is written to disk. -6. Disassembly: Use the Disassembler tool to disassemble byte data into readable assembly instructions. +6. Disassembly: uses the Disassembler tool to convert bytecode into human-readable assembly instructions. The following figure shows the process details. diff --git a/en/application-dev/arkts-utils/concurrency-overview.md b/en/application-dev/arkts-utils/concurrency-overview.md index 0e6ad38973a7b0eee3651c293b7673935085c2dc..3f709f8d74a45958c68684238e2146759614baa8 100644 --- a/en/application-dev/arkts-utils/concurrency-overview.md +++ b/en/application-dev/arkts-utils/concurrency-overview.md @@ -1,14 +1,14 @@ -# Concurrency Overview +# Overview of Concurrency -Concurrency refers to the situation where multiple tasks are executed at the same time. For a multi-core device, these tasks may be executed on different CPUs concurrently. For a single-core device, multiple concurrent tasks are not executed at the same time. However, the CPU switches tasks when a task is in the sleep state or is performing I/O operations, and schedules and executes other tasks to improve CPU resource utilization. +Concurrency refers to the situation where multiple tasks are executed at the same time. On multi-core devices, these tasks can run in parallel across different CPUs. On single-core devices, while multiple tasks cannot run in parallel at the exact same moment, the CPU can switch between tasks when one is idle or performing I/O operations, thereby optimizing CPU resource utilization. -To improve the response speed and frame rate of applications and prevent time-consuming tasks from blocking the main thread, the system provides two policies: asynchronous concurrency and multithread concurrency. +To improve the response speed and frame rate of applications and mitigate the impact of time-consuming tasks on the UI main thread, ArkTS provides two concurrency strategies: asynchronous concurrency and multithreaded concurrency. -- Asynchronous concurrency means that an action in asynchronous code is suspended and will resume later. Only one segment of code is executed at a time. Promise and async/await: implement asynchronous concurrency and apply to the development of a single I/O task. For details, see [Asynchronous Concurrency Overview](async-concurrency-overview.md). +- Asynchronous concurrency involves pausing asynchronous code at a certain point and resuming its execution later, ensuring that only one piece of code is running at any given moment. ArkTS supports asynchronous concurrency through Promises and async/await, which are well-suited for scenarios involving single I/O operations. For details, see [Asynchronous Concurrency](async-concurrency-overview.md). -- Multithreaded concurrency allows multiple segments of code to be executed at a time. When the main thread responds to user operations and updates the UI, time-consuming operations are performed in the background, avoiding application freezing. ArkTS uses TaskPool and Worker to provide the multi-thread concurrency capability, which is applicable to concurrency scenarios such as [time-consuming tasks](time-consuming-task-overview.md). For details, see [Multithreaded Concurrency Overview](multi-thread-concurrency-overview.md). +- Multithreaded concurrency allows multiple segments of code to run simultaneously. While the UI main thread continues to handle user interactions and update the UI, background threads can perform time-consuming operations, thereby preventing application lag. ArkTS supports multithreaded concurrency through TaskPool and Worker, which are ideal for scenarios involving [time-consuming tasks](time-consuming-task-overview.md). For details, see [Multithreaded Concurrency](multi-thread-concurrency-overview.md). -In a concurrent multi-thread scenario, data communication needs to be performed between different concurrent threads, and transmission modes of different types of objects are different, including copy or memory sharing. +In multithreaded concurrency scenarios, data communication between different threads is necessary, and the transfer methods for different types of objects can vary, including copy or memory sharing. -The concurrency capability is used in multiple scenarios, including []asynchronous concurrent tasks (async-concurrency-overview.md) and [time-consuming tasks](time-consuming-task-overview.md) ([CPU-intensive tasks](cpu-intensive-task-development.md), [I/O-intensive tasks](io-intensive-task-development.md), [synchronization tasks](sync-task-development.md)), [continuous tasks](long-time-task-overview.md), and [resident tasks](resident-task-overview.md) You can select a concurrency policy for optimization and development based on different task requirements and scenarios. For details, see [Multithreaded Development Practice Cases](batch-database-operations-guide.md). +Concurrency capabilities are used in various scenarios, including [asynchronous tasks](async-concurrency-overview.md), [time-consuming tasks](time-consuming-task-overview.md) ([CPU intensive tasks](cpu-intensive-task-development.md), [I/O intensive tasks](io-intensive-task-development.md), and [synchronous tasks](sync-task-development.md)), [continuous tasks](long-time-task-overview.md), and [resident tasks](resident-task-overview.md). You can select the appropriate concurrency strategy based on the specific task requirements and scenarios for optimization and development. You can also refer to [Multithreaded Development Practice Cases](batch-database-operations-guide.md). diff --git a/en/application-dev/arkts-utils/concurrent-loading-modules-guide.md b/en/application-dev/arkts-utils/concurrent-loading-modules-guide.md index 218d1c7feb265aad2d302c138346d066bb1d3298..797a07b80fc95d1489d4027dafc0c175775230d4 100644 --- a/en/application-dev/arkts-utils/concurrent-loading-modules-guide.md +++ b/en/application-dev/arkts-utils/concurrent-loading-modules-guide.md @@ -1,11 +1,12 @@ # Concurrent Loading of Service Modules -During app startup, multiple service modules need to be loaded. For example, if different modules of a map app, such as positioning, taxi hailing, and navigation, are all initialized in the UI main thread, the cold start time will be greatly affected. In this case, the functions of these modules need to be loaded in different sub-threads in parallel to reduce the startup time. +During application launch, multiple service modules need to be loaded. For example, in a mapping application, different modules such as positioning, ride-hailing, and navigation are required. Initializing all these modules in the UI main thread can significantly increase the cold start time. To address this, these modules should be loaded concurrently in separate background threads to reduce launch latency. -The TaskPool capability provided by ArkTS can be used to move different service initialization tasks to subthreads. Service modules can be implemented as [NativeBinding object](transferabled-object.md) by sinking C++, or [Sendable object](arkts-sendable.md) can be defined at the ArkTS layer. The initialized module can be returned to the UI main thread for calling. The implementation is as follows: +By leveraging the TaskPool capabilities provided by ArkTS, different service initialization tasks can be offloaded to background threads. Service modules can be implemented in C++ as [NativeBinding objects](transferabled-object.md) or defined in ArkTS as [Sendable objects](arkts-sendable.md). The initialized modules can then be returned to the UI main thread for use. The implementation involves the following steps: -1. Definition of each service function (SDK) module (The Sendable object is used as an example.) - The calculator service module is defined as follows: +1. Define each service module (SDK) (using Sendable objects as an example). + + Define the calculator service module as follows: ```ts // sdk/Calculator.ets @@ -64,7 +65,7 @@ The TaskPool capability provided by ArkTS can be used to move different service } ``` - The timer service module is defined as follows: + Define the timer service module as follows: ```ts // sdk/TimerSdk.ets @@ -85,7 +86,7 @@ The TaskPool capability provided by ArkTS can be used to move different service } ``` -2. The UI main thread triggers the distribution of each service module to the sub-thread. After the loading is complete, the UI main thread uses the service module. +2. In the UI main thread, trigger the distribution of service modules to child threads, and use them in the UI main thread after loading is complete. ```ts // Index.ets diff --git a/en/application-dev/arkts-utils/container-overview.md b/en/application-dev/arkts-utils/container-overview.md index 772b909b808ece36cdc6ce6cbc8d537ee0b66ec9..eb623469175bccfeb4fae6a6782dc0111c947114 100644 --- a/en/application-dev/arkts-utils/container-overview.md +++ b/en/application-dev/arkts-utils/container-overview.md @@ -1,7 +1,7 @@ -# Container Overview +# Overview of the ArkTS Container Library -The container classes provide a set of methods to process elements of various data types stored in containers. It has advantages as a pure data structure container. +The ArkTS container library provides a set of methods to process elements of various data types stored in containers. It can yield certain benefits when being used as pure data structure containers. -The container classes are implemented in a way similar to static languages. By restricting storage locations and attributes, they remove redundant logic while providing the complete functionalities for each type of data, ensuring efficient data access and improving application performance. +Container classes are implemented similarly to static languages, with constraints on storage locations and properties. This approach allows each data type to fulfill its purpose without unnecessary logic, ensuring efficient data access and boosting application performance. -There are linear and nonlinear containers, The bottom layer of linear containers is implemented through arrays, and the bottom layer of non-linear containers is implemented through hash or red-black tree. [Linear containers](linear-container.md) and [non-linear containers](nonlinear-container.md) are non-multi-thread secure. +At present, two categories of containers are available: [linear containers](linear-container.md) and [nonlinear containers](nonlinear-container.md). Linear containers are backed by arrays, whereas non-linear containers rely on hash tables or red-black trees. Neither type of container is designed to be thread-safe. diff --git a/en/application-dev/arkts-utils/cpu-intensive-task-development.md b/en/application-dev/arkts-utils/cpu-intensive-task-development.md index 6d2317b89494c60336e20618b7f0c4b883dcf3bd..ec19141a550e6324509b1c3874a45db1a8474cb3 100644 --- a/en/application-dev/arkts-utils/cpu-intensive-task-development.md +++ b/en/application-dev/arkts-utils/cpu-intensive-task-development.md @@ -1,25 +1,26 @@ # CPU Intensive Task Development (TaskPool and Worker) -CPU intensive tasks are tasks that occupy a significant amount of system computing resources and that may block other tasks in the same thread. Example CPU intensive tasks are image processing, video encoding, and data analysis. +CPU intensive tasks are those that require significant computational resources and can run for extended periods. If executed in the UI main thread, these tasks can block other events. Examples include image processing, video encoding, and data analysis. -To improve CPU utilization and application response speeds, use multithread concurrency in processing CPU intensive tasks. +To improve CPU utilization and enhance application responsiveness, you can use multithreaded concurrency in processing CPU intensive tasks. -If a task can be completed in a background thread within 3 minutes, you are advised to use TaskPool. Otherwise, use Worker. +When tasks are discrete and do not need to occupy a background thread for an extended period (3 minutes), TaskPool is recommended. For tasks that require long-running background processing, Worker is more suitable. -The following uses histogram processing and a time-consuming model prediction task in the background as examples. +The following examples illustrate how to handle image histogram processing using TaskPool and long-running model prediction tasks using Worker. -## Using TaskPool to Process Histograms +## Using TaskPool for Image Histogram Processing 1. Implement the logic of image processing. -2. Segment the data, and initiate associated task scheduling through task groups. - Create a [task group](../reference/apis-arkts/js-apis-taskpool.md#taskgroup10), call [addTask()](../reference/apis-arkts/js-apis-taskpool.md#addtask10) to add tasks, and call [execute()](../reference/apis-arkts/js-apis-taskpool.md#taskpoolexecute10) to execute the tasks in the task group at a [a high priority](../reference/apis-arkts/js-apis-taskpool.md#priority). After all the tasks in the task group are complete, the histogram processing result is returned simultaneously. +2. Segment the data, and schedule related tasks using a TaskGroup. -3. Summarize and process the result arrays. + Create a [task group](../reference/apis-arkts/js-apis-taskpool.md#taskgroup10), call [addTask()](../reference/apis-arkts/js-apis-taskpool.md#addtask10) to add tasks, and call [execute()](../reference/apis-arkts/js-apis-taskpool.md#taskpoolexecute10) to execute the tasks in the task group, specifying [high priority](../reference/apis-arkts/js-apis-taskpool.md#priority). After all the tasks in the group are complete, the histogram processing result is returned collectively. + +3. Aggregate and process the result arrays. ```ts import { taskpool } from '@kit.ArkTS'; @@ -31,7 +32,7 @@ function imageProcessing(dataSlice: ArrayBuffer): ArrayBuffer { } function histogramStatistic(pixelBuffer: ArrayBuffer): void { - // Step 2: Perform concurrent scheduling for data in three segments. + // Step 2: Segment the data and schedule tasks concurrently. let number: number = pixelBuffer.byteLength / 3; let buffer1: ArrayBuffer = pixelBuffer.slice(0, number); let buffer2: ArrayBuffer = pixelBuffer.slice(number, number * 2); @@ -43,7 +44,7 @@ function histogramStatistic(pixelBuffer: ArrayBuffer): void { group.addTask(imageProcessing, buffer3); taskpool.execute(group, taskpool.Priority.HIGH).then((ret: Object) => { - // Step 3: Summarize and process the result arrays. + // Step 3: Aggregate and process the result arrays. }) } @@ -71,15 +72,15 @@ struct Index { ``` -## Using Worker for Time-Consuming Model Prediction +## Using Worker for Time-Consuming Data Analysis -The following uses the training of a region-specific house price prediction model as an example. This model can be used to predict house prices in the region based on the house area and number of rooms. The model needs to run for a long time, and each prediction needs to use the previous running result. Due to these considerations, Worker is used for the development. +This example demonstrates training a simple housing price prediction model using housing data from a specific region. The model supports predicting housing prices based on input parameters like house size and number of rooms. Since the model requires long-running execution and the prediction relies on the model's previous results, Worker is the appropriate choice. -1. In DevEco Studio, add a worker named **MyWorker** to your project. +1. In DevEco Studio, add a Worker thread named **MyWorker** to your project. ![newWorker](figures/newWorker.png) -2. In the main thread, call [constructor()](../reference/apis-arkts/js-apis-worker.md#constructor9) of **ThreadWorker** to create a **Worker** object. The calling thread is the host thread. +2. In the host thread, call [constructor()](../reference/apis-arkts/js-apis-worker.md#constructor9) of **ThreadWorker** to create a Worker object. ```ts // Index.ets @@ -88,14 +89,15 @@ The following uses the training of a region-specific house price prediction mode const workerInstance: worker.ThreadWorker = new worker.ThreadWorker('entry/ets/workers/MyWorker.ts'); ``` -3. In the host thread, call [onmessage()](../reference/apis-arkts/js-apis-worker.md#onmessage9) to receive messages from the worker thread, and call [postMessage()](../reference/apis-arkts/js-apis-worker.md#postmessage9) to send messages to the worker thread. - For example, the host thread sends training and prediction messages to the worker thread, and receives messages sent back by the worker thread. +3. In the host thread, call [onmessage()](../reference/apis-arkts/js-apis-worker.md#onmessage9) to receive messages from the Worker thread, and call [postMessage()](../reference/apis-arkts/js-apis-worker.md#postmessage9) to send messages to the Worker thread. + + For example, the host thread sends training and prediction messages to the Worker thread and receive responses. ```ts // Index.ets let done = false; - // Receive the result from the worker thread. + // Receive results from the Worker thread. workerInstance.onmessage = (() => { console.info('MyWorker.ts onmessage'); if (!done) { @@ -105,14 +107,14 @@ The following uses the training of a region-specific house price prediction mode }) workerInstance.onerror = (() => { - // Receive error information from the worker thread. + // Receive error messages from the Worker thread. }) - // Send a training message to the worker thread. + // Send a training message to the Worker thread. workerInstance.postMessage({ 'type': 0 }); ``` -4. Bind the **Worker** object in the **MyWorker.ts** file. The calling thread is the worker thread. +4. Bind the Worker object in the **MyWorker.ts** file. The calling thread is the Worker thread. ```ts // MyWorker.ts @@ -121,12 +123,13 @@ The following uses the training of a region-specific house price prediction mode let workerPort: ThreadWorkerGlobalScope = worker.workerPort; ``` -5. In the worker thread, call [onmessage()](../reference/apis-arkts/js-apis-worker.md#onmessage9-1) to receive messages sent by the host thread, and call [postMessage()](../reference/apis-arkts/js-apis-worker.md#postmessage9-2) to send messages to the host thread. - For example, the prediction model and its training process are defined in the worker thread, and messages are exchanged with the main thread. +5. In the Worker thread, call [onmessage()](../reference/apis-arkts/js-apis-worker.md#onmessage9-1) to receive messages sent by the host thread, and call [postMessage()](../reference/apis-arkts/js-apis-worker.md#postmessage9-2) to send messages to the host thread. + + For example, define the prediction model and training process in the Worker thread and interact with the host thread. ```ts // MyWorker.ts - // Define the training model and result. + // Define the training model and results. let result: Array; // Define the prediction function. function predict(x: number): number { @@ -136,20 +139,20 @@ The following uses the training of a region-specific house price prediction mode function optimize(): void { result = [0]; } - // onmessage logic of the worker thread. + // onmessage logic of the Worker thread. workerPort.onmessage = (e: MessageEvents): void => { // Perform operations based on the type of data to transmit. switch (e.data.type as number) { case 0: // Perform training. optimize(); - // Send a training success message to the main thread after training is complete. + // Send a training success message to the host thread after training. workerPort.postMessage({ type: 'message', value: 'train success.' }); break; case 1: - // Execute the prediction. + // Perform prediction. const output: number = predict(e.data.value as number); - // Send the prediction result to the main thread. + // Send the prediction result to the host thread. workerPort.postMessage({ type: 'predict', value: output }); break; default: @@ -159,27 +162,27 @@ The following uses the training of a region-specific house price prediction mode } ``` -6. After the task is completed in the worker thread, destroy the worker thread. The worker thread can be destroyed by itself or the host thread. +6. After the task is completed, destroy the Worker thread. The Worker thread can be destroyed by itself or the host thread. - Then, call [onexit()](../reference/apis-arkts/js-apis-worker.md#onexit9) in the host thread to define the processing logic after the worker thread is destroyed. + After the Worker thread is destroyed, call [onexit()](../reference/apis-arkts/js-apis-worker.md#onexit9) in the host thread to define the logic for handling the destruction. ```ts - // After the worker thread is destroyed, execute the onexit() callback. + // After the Worker thread is destroyed, execute the onexit callback. workerInstance.onexit = (): void => { console.info("main thread terminate"); } ``` - Method 1: In the host thread, call [terminate()](../reference/apis-arkts/js-apis-worker.md#terminate9) to destroy the worker thread and stop the worker thread from receiving messages. + Method 1: In the host thread, call [terminate()](../reference/apis-arkts/js-apis-worker.md#terminate9) to destroy the Worker thread and stop it from receiving messages. ```ts - // Destroy the worker thread. + // Destroy the Worker thread. workerInstance.terminate(); ``` - Method 2: In the worker thread, call [close()](../reference/apis-arkts/js-apis-worker.md#close9) to destroy the worker thread and stop the worker thread from receiving messages. + Method 2: In the Worker thread, call [close()](../reference/apis-arkts/js-apis-worker.md#close9) to destroy the Worker thread and stop it from receiving messages. ```ts - // Destroy the worker thread. + // Destroy the Worker thread. workerPort.close(); ``` diff --git a/en/application-dev/arkts-utils/customize-bytecode-during-compilation.md b/en/application-dev/arkts-utils/customize-bytecode-during-compilation.md index f16330077753cbba63a1be4d9ee8984978cb7fb9..c65726a632826f3c6b77a32e68a2b0db281a3023 100644 --- a/en/application-dev/arkts-utils/customize-bytecode-during-compilation.md +++ b/en/application-dev/arkts-utils/customize-bytecode-during-compilation.md @@ -1,24 +1,24 @@ # Customizing Ark Bytecode During Compilation -If you want to customize the content of the Ark bytecode file, you can use the ArkTS compilation toolchain to customize the Ark bytecode file. +You can modify Ark bytecode files using the customization capabilities provided by the ArkTS compilation toolchain. -## Capability Configuration Description +## Configuration -Prepare a dynamic library file for operating the ARK bytecode file. In the build-profile.json5 configuration file of the project, configure the [compilation option transformLib](arkoptions-guide.md) and set the option value to the path of the dynamic library, the compiler loads the dynamic library at the specified time and executes the specific Transform method in the library. +Develop a dynamic library file to manipulate ARK bytecode files. In the **build-profile.json5** file of the project, add the [transformLib option](arkoptions-guide.md) and set its value to the path of the dynamic library. The compiler loads the dynamic library at the specified time and executes the **Transform** method in the library. -## Capability execution mechanism +## Execution -If the transformLib option is not configured in the build-profile.json5 file of the project, the compiler directly generates the ARK bytecode file to the default location. If transformLib is configured and the corresponding dynamic library file can be correctly loaded, the compiler generates an ARK bytecode file to the default destination location, calls the Transform method in the dynamic library, and transfers the path of the ARK bytecode file as a parameter. The Transform method is used to customize the logic for regenerating the ARK bytecode file. +If **transformLib** is not configured in the **build-profile.json5** file, the compiler generates the ARK bytecode file to the default location. If **transformLib** is configured and the dynamic library file is successfully loaded, the compiler generates an ARK bytecode file to the default location, and calls the **Transform** method in the dynamic library, passing the path of the ARK bytecode file as a parameter. The **Transform** method contains your custom logic to modify and regenerate the bytecode. -The following development example is a dynamic library template. You need to implement the specific logic of Transform based on your requirements. +Below is an example template of the dynamic library. You should implement the specific logic of the **Transform** method based on your service requirements. ## How to Develop -1. Create the source code for modifying the dynamic library. +1. Create the source code for the dynamic library. ``` /** - * @brief Entry method for modifying the ARK bytecode file + * @brief Entry method for modifying the ARK bytecode file. * @param abc_path Path for storing the ARK bytecode file to be processed. */ extern "C" int Transform(const char *abc_path) @@ -28,30 +28,30 @@ The following development example is a dynamic library template. You need to imp } ``` -2. Use the C language compilation tool (G++) to compile the link library file of the corresponding platform. +2. Use a C language compiler (g++) to compile the link library file. - Windows + Windows: ``` g++ --share -o example.dll example.cpp ``` - Linux + Linux: ``` g++ --share -o example.so example.cpp ``` - Mac platform: + macOS: ``` g++ --shared -o example.so example.cpp ``` -3. Configure the transformLib option in the build-profile.json5 file in the IDE. The following uses the Windows environment as an example. +3. In DevEco Studio, configure the **transformLib** option in the **build-profile.json5** file. (The following uses the Windows environment as an example.) - The path configured in the option is the path of the link library file generated in step 2 in the project (in this example, the path is in the dll directory). + Set the option to the path of the link library file generated in step 2. In this example, the path is in the **dll** directory. - !image_0000002079773605](figures/image_0000002079773605.png) + ![image_0000002079773605](figures/image_0000002079773605.png) 4. Recompile the project to customize the Ark bytecode. diff --git a/en/application-dev/arkts-utils/figures/compilation-process.png b/en/application-dev/arkts-utils/figures/compilation-process.png new file mode 100644 index 0000000000000000000000000000000000000000..faa13f6fe9b3b1435018a2aa6325a7a0dacb3ec1 Binary files /dev/null and b/en/application-dev/arkts-utils/figures/compilation-process.png differ diff --git a/en/application-dev/arkts-utils/figures/copy_transfer.png b/en/application-dev/arkts-utils/figures/copy_transfer.png index 02a2ef35617a28893c0518d1ba97c3517625b918..eb8fb0383cf017ba3a0a51daa02bfb95f11e48f8 100644 Binary files a/en/application-dev/arkts-utils/figures/copy_transfer.png and b/en/application-dev/arkts-utils/figures/copy_transfer.png differ diff --git a/en/application-dev/arkts-utils/figures/generational-model.png b/en/application-dev/arkts-utils/figures/generational-model.png new file mode 100644 index 0000000000000000000000000000000000000000..91bbbdb31ead9bdf505f5789f5758772f58719e3 Binary files /dev/null and b/en/application-dev/arkts-utils/figures/generational-model.png differ diff --git a/en/application-dev/arkts-utils/figures/mark-clearn.png b/en/application-dev/arkts-utils/figures/mark-clearn.png new file mode 100644 index 0000000000000000000000000000000000000000..b62ebfc6738d75afb3ea2016a73f50db26bdaec9 Binary files /dev/null and b/en/application-dev/arkts-utils/figures/mark-clearn.png differ diff --git a/en/application-dev/arkts-utils/figures/mark-copy.png b/en/application-dev/arkts-utils/figures/mark-copy.png new file mode 100644 index 0000000000000000000000000000000000000000..3f3d9be7ae4d7b03b8900c613ee486d0a0a166ef Binary files /dev/null and b/en/application-dev/arkts-utils/figures/mark-copy.png differ diff --git a/en/application-dev/arkts-utils/figures/mark-shuffle.png b/en/application-dev/arkts-utils/figures/mark-shuffle.png new file mode 100644 index 0000000000000000000000000000000000000000..b3343d55379bffccc8b2baa8f84c076c43fd3ad4 Binary files /dev/null and b/en/application-dev/arkts-utils/figures/mark-shuffle.png differ diff --git a/en/application-dev/arkts-utils/figures/obfuscation-product.png b/en/application-dev/arkts-utils/figures/obfuscation-product.png index 5ec2986d31170adedccb0025a3515cf6d089f3ad..1908045ea14fea19a0291d052f44119b34f4b5dd 100644 Binary files a/en/application-dev/arkts-utils/figures/obfuscation-product.png and b/en/application-dev/arkts-utils/figures/obfuscation-product.png differ diff --git a/en/application-dev/arkts-utils/figures/oh_modules.png b/en/application-dev/arkts-utils/figures/oh_modules.png new file mode 100644 index 0000000000000000000000000000000000000000..7fd8463c1c6839848a61e2eb768528f78a44c528 Binary files /dev/null and b/en/application-dev/arkts-utils/figures/oh_modules.png differ diff --git a/en/application-dev/arkts-utils/figures/sharedarraybufer.png b/en/application-dev/arkts-utils/figures/sharedarraybufer.png index 6b787a44b80ab3cdd0489701c3a5c6ea2b4ced48..270d110c763ac3b3f6ec3373fba6cb180b820851 100644 Binary files a/en/application-dev/arkts-utils/figures/sharedarraybufer.png and b/en/application-dev/arkts-utils/figures/sharedarraybufer.png differ diff --git a/en/application-dev/arkts-utils/figures/tracing-gc.png b/en/application-dev/arkts-utils/figures/tracing-gc.png new file mode 100644 index 0000000000000000000000000000000000000000..04da24294cd772a6e7471022ab2790343cc09527 Binary files /dev/null and b/en/application-dev/arkts-utils/figures/tracing-gc.png differ diff --git a/en/application-dev/arkts-utils/figures/transfer.png b/en/application-dev/arkts-utils/figures/transfer.png index b5574f343dee75df47f5f7a9da138774ef1188eb..feeba5b48f3bc5bd3327b53ac8151ff16f58801b 100644 Binary files a/en/application-dev/arkts-utils/figures/transfer.png and b/en/application-dev/arkts-utils/figures/transfer.png differ diff --git a/en/application-dev/arkts-utils/gc-introduction.md b/en/application-dev/arkts-utils/gc-introduction.md index 552ac1750135ffacb4c8c632c44ba1ce70438b7a..0b4ba6f4740cbfb9ce69cdd5a9e39d39f2d9590f 100644 --- a/en/application-dev/arkts-utils/gc-introduction.md +++ b/en/application-dev/arkts-utils/gc-introduction.md @@ -1,189 +1,288 @@ # GC -Garbage Collection (GC) is the process of finding garbage in memory and releasing and reclaiming memory space. Two GC algorithms are mainly used: reference counting and tracing GC. Based on the generational model (young generation and old generation), ArkTS uses both the reference counting and object tracking algorithms to concurrently execute GC tasks, achieving high-performance memory reclamation in different scenarios. +Garbage Collection (GC) is a process that identifies and reclaims memory no longer in use by a program. It aims to free up unused memory space. Modern programming languages implement two primary types of GC algorithms: reference counting and tracing GC. -In ArkTS, data types are classified into simple type and reference type. Data of the simple type is stored in stacks, and its space is automatically allocated and reclaimed by the operating system. Data of the reference type is stored in heaps, and its space must be manually reclaimed by the engine. GC is a management mechanism for automatically reclaiming heap space. +## GC Algorithm Overview -## Heap Space Structure and Parameters +### Types of GC -### Heap Space Structure +#### Reference Counting +When object A is referenced by object B, A's reference count increases by 1. Conversely, when the reference is removed, A's reference count decreases by 1. When A's reference count reaches 0, object A is reclaimed. -![image](./figures/gc-heap-space.png) +- Pros: Reference counting is simple to implement and allows for immediate memory reclamation, avoiding a dedicated Stop The World (STW) phase where the application is paused. +- Cons: The extra counting step during object manipulation increases the overhead of memory allocation and assignment, affecting performance. Most critically, it fails to handle circular references. -- Semi Space: stores young generation, that is, newly created objects, which may be short-lived. The copying algorithm is used to reclaim memory. -- Old Space: stores old generation, that is, long-surviving objects. Multiple algorithms are used to reclaim memory based on scenarios. -- Huge Object Space: stores huge objects. A separate region is used to store a huge object. -- Read Only Space: stores read-only data at runtime. -- Non-Movable Space: stores unmovable objects. -- Snapshot Space: stores heap snapshots. -- Machine Code Space: stores machine codes. +``` +class Parent { + constructor() { + this.child = null; + } + child: Child | null = null; +} -Each space is divided into one or more regions for refined management. A region is the unit applied for from the memory allocator. +class Child { + constructor() { + this.parent = null; + } + parent: Parent | null = null; +} -### Parameters +function main() { + let parent: Parent = new Parent(); + let child: Child = new Child(); + parent.child = child; + child.parent = parent; +} +``` +In the example above, parent holds a reference to child, and child holds a reference to parent. This circular reference means that neither object's reference count will reach zero, even after the **main** function ends, resulting in a memory leak. -> **NOTE** -> -> Among all the parameters described in this section, if no description is provided for how to configure a parameter, then the parameter is automatically set by the system. +#### Tracking GC -For some of the parameters, three values or value ranges are provided, corresponding to the three value ranges of the total heap size: 64–128 MB/128–256 MB/ > 256 MB. If the remaining memory space is sufficient, the third value range (> 256 MB) is used by default. +![image](./figures/tracing-gc.png) -#### Parameters of Semi Space +Tracing GC identifies live objects by traversing the object graph starting from root objects, which include stack objects and global objects that are guaranteed to be alive. Objects referenced by these root objects are also considered live. The traversal marks all reachable objects (blue) as live, whereas unreachable objects (yellow) are considered garbage. -Two Semi Spaces are generated in the heap for the copying algorithm to use. +- Pros: Tracing GC solves the circular reference problem and does not incur additional overhead during memory allocation and assignment. +- Cons: Tracing GC is more complex than reference counting and introduces a brief STW phase. Additionally, GC can be delayed, leading to floating garbage. -| Parameter| Value or Value Range| Description| -| --- | --- | :--- | -| semiSpaceSize | 2–4 MB/2–8 MB/2–16 MB| Size of Semi Space. The value varies according to the total heap size.| -| semiSpaceTriggerConcurrentMark | 1 M/1.5 M/1.5 M| Threshold for independently triggering the concurrent marking phase of Semi Space for the first time.| -| semiSpaceStepOvershootSize| 2 MB | Maximum overshoot size of Semi Space.| +Given the limitations of reference counting, especially the critical issue of circular references, ArkTS Runtime uses tracing GC. -#### Parameters of Other Spaces +### Types of Tracing GC -| Parameter| Value or Value Range| Description| -| --- | --- | :--- | -| defaultReadOnlySpaceSize | 256 KB | Default size of Read Only Space.| -| defaultNonMovableSpaceSize | 2 MB/6 MB/64 MB | Default size of Non-Movable Space.| -| defaultSnapshotSpaceSize | 512 KB/512 KB/ 4 MB | Default size of Snapshot Space.| -| defaultMachineCodeSpaceSize | 2 MB/2 MB/8 MB | Default size of Machine Code Space.| +Tracing GC algorithms identify garbage by traversing the object graph. Based on the collection method, tracing GC can be categorized into three basic types: mark-sweep, mark-copy, and mark-compact. In the diagrams below, blue indicates live objects, whereas yellow indicates garbage. -#### Parameters of Old Space and Huge Object Space +#### Mark-Sweep Collection -During initialization, the parameter is set to the size of the unallocated heap space left. +![image](./figures/mark-clearn.png) -| Parameter| Value or Value Range| Description| -| --- | --- | :--- | -| oldSpaceOvershootSize | 4 MB/8 MB/8 MB | Maximum overshoot size of Old Space.| +After traversing the object graph, the algorithm clears the contents of unreachable objects and places them in a free list for future allocations. +This approach is highly efficient as it does not move objects. However, it can lead to memory fragmentation, reducing allocation efficiency and potentially preventing the allocation of large objects despite ample free memory. + +#### Mark-Copy Collection + +![image](./figures/mark-copy.png) + +During the traversal of the object graph, reachable objects are copied to a new, contiguous memory space. After the traversal, the old memory space is reclaimed entirely. +This approach eliminates memory fragmentation and completes the GC process in a single traversal, making it efficient. However, it requires reserving half of the memory space to ensure all live objects can be copied, resulting in lower space utilization. + +#### Mark-Compact Collection + +![image](./figures/mark-shuffle.png) + +After the traversal, live objects (blue) are copied to the beginning of the current space (or a designated area), and the copied objects are reclaimed and placed in the free list. +This approach addresses memory fragmentation without wasting half of the memory space, though it incurs higher performance overhead when compared with mark-copy collection. + +### HPP GC + +High Performance Partial Garbage Collection (HPP GC) is designed for high performance in partial GC, leveraging generational models, hybrid algorithms, and optimized GC processes. In terms of algorithms, HPP GC uses different collection approaches based on different object regions. + +#### Generational Model + +ArkTS Runtime uses a traditional generational model, categorizing objects based on their lifetimes. Given that most newly allocated objects are short-lived and collected during the first GC cycle, whereas objects surviving multiple GC cycles are likely to remain alive, ArkTS Runtime divides objects into young and old generations, allocating them to separate spaces. + +![image](./figures/generational-model.png) + +Newly allocated objects are placed in the **from** space of Young Space. After surviving one GC cycle, they are moved to the **to** space, which then swaps roles with the **from** space. Objects surviving another GC cycle are copied to Old Space. + +#### Hybrid Algorithm + +HPP GC employs a hybrid algorithm combining mark-copy, mark-compact, and mark-sweep, tailored to the characteristics of young and old generation objects. + +- Mark-copy for young generation +Given the short lifetimes, small size, and frequent collection of young generation objects, ArkTS Runtime uses the mark-copy algorithm to efficiently reclaim memory for these objects. +- Mark-compact + mark-sweep for old generation +Based on the characteristics of old generation objects, a heuristic collection set (CSet) algorithm is used. The fundamental idea behind this algorithm is to collect the sizes of live objects in each region during the marking phase. During the collection phase, ArkTS Runtime uses mark-compact for regions with fewer live objects and lower collection costs, but mark-sweep for the remaining regions. + +The collection policies are as follows: + +- Identifies regions with live object sizes below a threshold, places them in the initial CSet, and sorts them by liveness (survival rate = live object size/region size). + +- Selects a final CSet based on a predefined number of regions for compaction. + +- Sweeps the remaining regions. + +This heuristic approach combines the benefits of mark-compact and mark-sweep algorithms, addressing memory fragmentation while maintaining performance. + +#### Process Optimization + +HPP GC introduces extensive concurrency and parallelism optimizations to minimize the impact on application performance. The GC process includes concurrent and parallel marking, sweeping, evacuation, updating, and clearing tasks. + +## Heap Structure and Parameters + +### Heap Structure + +![image](./figures/gc-heap-space.png) + +- Semi Space: space for storing young generation, that is, newly created objects with low survival rates. The copying algorithm is used to reclaim memory. +- Old Space: space for storing old generation, that is, objects that survive multiple GC cycles. Multiple algorithms are used for memory reclamation. +- Huge Object Space: dedicated regions for storing large objects. +- Read Only Space: space for storing read-only data at runtime. +- Non-Movable Space: space for storing non-movable objects. +- Snapshot Space: space for storing heap snapshots. +- Machine Code Space: space for storing machine codes. + +Each space is managed in regions, which are the units requested from the memory allocator. + +### Parameters + +> **NOTE** +> +> Parameters not marked as configurable are system-defined and cannot be adjusted by developers. + +Based on the total heap size ranges (64 MB to 128 MB, 128 MB to 256 MB, or greater than 256 MB), the system sets different sizes for the following parameters. If a parameter has a single value in the range, it remains constant regardless of the total heap size. The default total heap size for mobile phones is greater than 256 MB. +You can use related APIs to query memory information by referring to [HiDebug API Reference](../reference/apis-performance-analysis-kit/js-apis-hidebug.md). #### Heap Size Parameters -| Parameter| Value or Value Range| Description| -| --- | --- | :--- | -| HeapSize | 448–1024 MB | Total heap size. The actual size allocated varies according to the heap type. The lower limit is reduced in the case of an insufficient memory pool.| -| SemispaceSize | 2–4 MB/2–8 MB/2–16 MB| Size of Semi Space.| +| Name| Value or Value Range| Description| +| --- | --- | --- | +| HeapSize | 448 MB| Default total heap size for the main thread. The value is adjusted for low-memory devices based on the actual memory pool size.| +| SemiSpaceSize | 2–4 MB/2–8 MB/2–16 MB| Size of Semi Space.| | NonmovableSpaceSize | 2 MB/6 MB/64 MB | Size of Non-Movable Space.| | SnapshotSpaceSize | 512 KB| Size of Snapshot Space.| | MachineCodeSpaceSize | 2 MB| Size of Machine Code Space.| -#### Maximum Number of Worker Thread Heaps +#### Worker Thread Heap Limit -| Parameter| Value or Value Range| Description| +| Name| Value| Description| | --- | --- | --- | -| heapSize | 768 MB | Size of the heap space of the work type.| +| HeapSize | 768 MB | Heap size for worker threads.| -#### Size of the Interpreter Stack +#### Parameters of Semi Space +The heap contains two Semi Spaces for copying. -| Parameter| Value or Value Range| Description| +| Name| Value or Value Range| Description| | --- | --- | --- | -| maxStackSize | 128 KB| Maximum frame size of the interpreter stack.| +| semiSpaceSize | 2–4 MB/2–8 MB/2–16 MB| Size of Semi Space. The value varies according to the total heap size.| +| semiSpaceTriggerConcurrentMark | 1 M/1.5 M/1.5 M| Threshold for independently triggering concurrent marking in Semi Space for the first time.| +| semiSpaceStepOvershootSize| 2 MB | Maximum overshoot size of Semi Space.| + +#### Parameters of Old Space and Huge Object Space +Both spaces are initialized to the remaining unallocated heap size. By default, the upper limit of OldSpaceSize of the main thread on mobile phones approaches 350 MB. + +| Name| Value or Value Range| Description| +| --- | --- | --- | +| oldSpaceOvershootSize | 4 MB/8 MB/8 MB | Maximum overshoot size of Old Space.| + +#### Parameters of Other Spaces + +| Name| Value or Value Range| Description| +| --- | --- | --- | +| defaultReadOnlySpaceSize | 256 KB | Default size of Read Only Space.| +| defaultNonMovableSpaceSize | 2 MB/6 MB/64 MB | Default size of Non-Movable Space.| +| defaultSnapshotSpaceSize | 512 KB/512 KB/ 4 MB | Default size of Snapshot Space.| +| defaultMachineCodeSpaceSize | 2 MB/2 MB/8 MB | Default size of Machine Code Space.| + +#### Interpreter Stack Size + +| Name| Value or Value Range| Description| +| --- | --- | --- | +| maxStackSize | 128 KB| Maximum size of the interpreter stack.| #### Concurrency Parameters -| Parameter| Value| Description| -| --- | ---: | --- | +| Name| Value| Description| +| --- | --- | --- | | gcThreadNum | 7 | Number of GC threads. The default value is 7. You can set this parameter using **gc-thread-num**.| | MIN_TASKPOOL_THREAD_NUM | 3 | Minimum number of threads in the thread pool.| | MAX_TASKPOOL_THREAD_NUM | 7 | Maximum number of threads in the thread pool.| -Note: The thread pool is used to execute concurrent tasks in the GC process. During thread pool initialization, all the three parameters need to be considered. If **gcThreadNum** is a negative value, the number of threads in the initialized thread pool is the number of CPU cores divided by 2. +Note: The thread pool is used to execute concurrent tasks in the GC process. During thread pool initialization, all the three parameters need to be considered. If **gcThreadNum** is negative, the number of threads in the initialized thread pool is the number of CPU cores divided by 2. #### Other Parameters -| Parameter| Value| Description| +| Name| Value| Description| | --- | --- | --- | -| minAllocLimitGrowingStep | 2 M/4 M/8 M| Minimum increase step of **oldSpace**, **heapObject**, and **globalNative** when the heap space size is recalculated.| -| minGrowingStep | 4 M/8 M/16 M | Minimum increase step of **oldSpace**.| -| longPauseTime | 40 ms| Threshold for checking for a long GC pause. In the case of long GC pauses, complete GC log is printed, facilitating fault locating and analysis. You can set this parameter using **gc-long-paused-time**.| +| minAllocLimitGrowingStep | 2 M/4 M/8 M| Minimum growth step of **oldSpace**, **heapObject**, and **globalNative** when the heap size is recalculated.| +| minGrowingStep | 4 M/8 M/16 M| Minimum growth step of **oldSpace**.| +| longPauseTime | 40 ms| Threshold for identifying long GC pauses, which trigger detailed GC log printing for analysis. It can be set using **gc-long-paused-time**.| -### Other: The maximum native memory of the ArrayBuffer in a single VM is 4 GB. +### Additional: The native total memory limit for ArrayBuffer within a single VM is set to 4 GB. ## GC Process - ![image](./figures/gc-process.png) -### HPP GC - -High Performance Partial Garbage Collection (HPP GC) achieves efficient garbage collection by employing generational models, hybrid algorithms, and GC process optimization. +### Types of HPP GC #### Young GC -- **When to trigger**: The young GC trigger threshold ranges from 2 MB to 16 MB, depending on the allocation speed and survival rate. -- **Description**: Reclaims the young-generation objects newly allocated to Semi Space. -- **Scenario**: Foreground +- **When to trigger**: The young GC threshold ranges from 2 MB to 16 MB, and it can be adjusted dynamically based on the allocation speed and survival rate. +- **Description**: primarily collects newly allocated objects in Semi Space. +- **Scenario**: foreground - **Log keywords**: [ HPP YoungGC ] #### Old GC -- **When to trigger**: The old GC trigger threshold ranges from 20 MB to 300 MB. In most cases, the threshold of the first old GC is about 20 MB, and the threshold for subsequent old GC operations is adjusted based on the survival rate and memory usage. -- **Description**: Sorts and compresses the space of the young generation and some space of the old generation, and sweeps other spaces. The trigger frequency is much lower than that of the young GC. Due to full marking, a single old GC operation takes about 5 ms to 10 ms, longer than that of the young GC. -- **Scenario**: Foreground +- **When to trigger**: The old GC threshold ranges from 20 MB to 300 MB. Typically, the threshold of the first old GC is about 20 MB, and the threshold for subsequent old GC operations is adjusted based on the survival rate and memory usage. +- **Description**: compacts and compresses the young generation space and parts of the old generation space while sweeping other spaces. It occurs less frequently than young GC, with a longer duration (approximately 5 ms to 10 ms) due to full marking. +- **Scenario**: foreground - **Log keywords**: [ HPP OldGC ] #### Full GC -- **When to trigger**: Full GC is not triggered based on the memory threshold. After the application is switched to the background, full GC is triggered if the size of the object that can be reclaimed is expected to be greater than 2 MB. You can also trigger full GC using the DumpHeapSnapshot and AllocationTracker tools or calling native interfaces and JS/TS interfaces. -- **Description**: Performs full compression on the young generation and old generation. Full GC is mainly used in performance-insensitive scenarios to reclaim memory space to the maximum extent. -- **Scenario**: Background -- **Log keywords**: [CompressGC] +- **When to trigger**: Full GC is not triggered based on the memory threshold. After the application transitions to the background, full GC is triggered if the predicted reclaimable object size exceeds 2 MB. You can also trigger full GC using the DumpHeapSnapshot and AllocationTracker tools or calling native interfaces and ArkTS interfaces. +- **Description**: fully compacts both young and old generations, maximizing memory reclamation in performance-insensitive scenarios. +- **Scenario**: background +- **Log keywords**: [ CompressGC ] -Smart GC or idle GC is based on these three GC modes. +Subsequent Smart GC or IDLE GC selections are made from the above three types of GC. -### Trigger Policy +### Trigger Strategies -#### GC Triggered by Space Thread +#### Space Threshold Triggering - Functions: **AllocateYoungOrHugeObject**, **AllocateHugeObject**, and other allocation-related functions - Restriction parameters: corresponding space thresholds -- Description: GC is triggered when the space applied for by an object reaches the corresponding threshold. +- Description: GC is triggered when object allocation reaches the space threshold. - Log keywords: **GCReason::ALLOCATION_LIMIT** -#### GC Triggered by Native Binding Size +#### Native Binding Size Triggering - Functions: **GlobalNativeSizeLargerThanLimit** - Restriction parameters: **globalSpaceNativeLimit** - Description: It affects the decision for performing full marking and concurrent marking. -#### GC Triggered Upon Switching to Background +#### Background Switch Triggering - Functions: **ChangeGCParams** - Description: Full GC is triggered when the application switches to the background. - Log keywords: **app is inBackground**, **app is not inBackground**, and **GCReason::SWITCH_BACKGROUND** -### Execution Policy +### Execution Strategies #### Concurrent Marking - Function: **TryTriggerConcurrentMarking** -- Description: Attempts to trigger concurrent marking and hand over the object traversal task to the thread pool to reduce the time that the main thread is being suspended. -- Log keywords: **fullMarkRequested, trigger full mark**, **Trigger the first full mark**, **Trigger full mark**, **Trigger the first semi mark**, and **Trigger semi mark** +- Description: attempts to trigger concurrent marking and delegate the task of marking objects to the thread pool to reduce the suspension time of the UI main thread. +- Log keywords: **fullMarkRequested**, **trigger full mark**, **Trigger the first full mark**, **Trigger full mark**, **Trigger the first semi mark**, and **Trigger semi mark** -#### Threshold Adjustment Before and After GC of Semi Space +#### Adjusting Thresholds Before and After New Space GC - Function: **AdjustCapacity** -- Description: Adjusts the GC trigger threshold of Semi Space after GC to optimize the space structure. -- Log keywords: There is no direct log. The GC statistics logs show that the young space threshold before GC is dynamically adjusted. +- Description: adjusts the Semi Space trigger threshold after GC to optimize space structure. +- Log keywords: There is no direct log. The GC statistics logs show dynamic adjustments to young space thresholds before and after GC. -#### Threshold Adjustment After the First Old GC +#### Adjusting Threshold After First Old GC - Function: **AdjustOldSpaceLimit** -- Description: Adjusts the old space threshold based on the minimum increase step and average survival rate. -- Log keywords: **"AdjustOldSpaceLimit oldSpaceAllocLimit_: "<< oldSpaceAllocLimit <<" globalSpaceAllocLimit_: " << globalSpaceAllocLimit_;** +- Description: adjusts the Old Space threshold based on the minimum growth step and average survival rate. +- Log keyword: `"AdjustOldSpaceLimit oldSpaceAllocLimit_: " << oldSpaceAllocLimit << " globalSpaceAllocLimit_: " << globalSpaceAllocLimit_;` -#### Old Space/Global Space Threshold and Increase Factor for the Second and Later Old GC Operations +#### Adjusting Old Space/Global Space Thresholds and Growth Factors After Subsequent Old GCs - Function: **RecomputeLimits** -- Description: Recalculates and adjusts **newOldSpaceLimit**, **newGlobalSpaceLimit**, **globalSpaceNativeLimit**, and the increase factor based on the current GC statistics. -- Log keywords: **"RecomputeLimits oldSpaceAllocLimit_: "<< newOldSpaceLimit_ <<" globalSpaceAllocLimit_: "<< globalSpaceAllocLimit_ <<" globalSpaceNativeLimit_: "<< globalSpaceNativeLimit_;** +- Description: recalculates and adjusts **newOldSpaceLimit**, **newGlobalSpaceLimit**, **globalSpaceNativeLimit**, and growth factors based on current GC statistics. +- Log keyword: `"RecomputeLimits oldSpaceAllocLimit_: " << newOldSpaceLimit_ << " globalSpaceAllocLimit_: " << globalSpaceAllocLimit_ << " globalSpaceNativeLimit_:" << globalSpaceNativeLimit_;` -#### CSet for Partial GC +#### CSet Selection Strategies for Partial GC -- Function: **OldSpace::SelectCSet ()** -- Description: Selects a region with a small number of living objects and a low reclamation cost for partial GC. -- Log keywords: **Select CSet failure: number is too few**, - **"Max evacuation size is 6_MB. The CSet region number: " << selectedRegionNumber;**, - and **"Select CSet success: number is " << collectRegionSet_.size();** +- Function: **OldSpace::SelectCSet()** +- Description: selects regions with fewer live objects and lower collection costs for partial GC. +- Typical logs: `Select CSet failure: number is too few`, + `"Max evacuation size is 6_MB. The CSet region number: " << selectedRegionNumber;`, + `"Select CSet success: number is " << collectRegionSet_.size();` ## SharedHeap @@ -191,29 +290,29 @@ Smart GC or idle GC is based on these three GC modes. ![image](./figures/gc-shared-heap.png) -- Shared Old Space: stores common shared objects. The young generation and old generation are not distinguished in the shared heap. -- Shared Huge Object Space: stores huge shared objects. A separate region is used to store a huge object. -- Shared Read Only Space: stores read-only shared data at runtime. -- Shared Non-Movable Space: stores unmovable shared objects. +- Shared Old Space: shared space for storing general shared objects. The young generation and old generation are not distinguished in the shared heap. +- Shared Huge Object Space: shared space for storing large objects. A separate region is used for each large object. +- Shared Read Only Space: shared space for storing read-only data at runtime. +- Shared Non-Movable Space: shared space for storing non-movable objects. -Note: The shared heap is mainly used to share objects between threads. It improves efficiency and reduces memory usage. The shared heap does not belong to a specific thread. It stores objects with shared value and has a higher survival rate. It does not evolve Semi Space. +Note: The shared heap is designed for objects shared across threads to improve efficiency and save memory. It does not belong to any single thread and stores objects with shared value. It typically has higher survival rates and does not involve Semi Space. -## Technical Features +## Features ### Smart GC #### Description -In performance-sensitive scenarios, the GC trigger threshold of the JS thread is temporarily adjusted to the maximum JS heap size (448 MB by default) to prevent frame loss caused by the GC trigger. (Smart GC does not take effect for the Worker thread and TaskPool thread.) However, if the performance-sensitive scenario lasts for a long period of time and the allocated objects reach the maximum heap size, GC is triggered. This GC takes a long time because too many objects are accumulated. +In performance-sensitive scenarios, the GC trigger threshold of the thread is temporarily adjusted to the maximum heap size (448 MB for the main thread by default), minimizing GC-triggered frame drops. (Smart GC does not take effect for the Worker thread and TaskPool thread.) However, if a performance-sensitive scenario persists too long and object allocation reaches the maximum heap size, GC is triggered, potentially resulting in longer GC times due to accumulated objects. #### Performance-Sensitive Scenarios - Application cold start -- Application sliding -- Page redirection upon click +- Application scrolling +- Page transitions via clicks - Jumbo frame -Currently, this feature is controlled by the system. Third-party apps do not have APIs to directly call this feature. +Currently, this feature is managed by the system, and third-party applications do not have APIs to directly call this feature. Log keyword: **SmartGC** @@ -221,18 +320,33 @@ Log keyword: **SmartGC** ![image](./figures/gc-smart-feature.png) -Mark performance-sensitive scenarios. When entering or exiting a performance-sensitive scenario, mark the scenario on the heap to avoid unnecessary GC and maintain high performance. +Mark performance-sensitive scenarios by tagging the heap upon entry and exit to avoid unnecessary GCs and maintain high performance. + +## Log Interpretation + +### Enabling Full Logs -## Log Description +By default, detailed GC logs are printed only when GC duration exceeds 40 ms. To enable logs for all GC executions, run commands on the device. + +**Example** + +```shell +# Enable full GC logs with parameter 0x905d. Disable full GC logs and revert to the default value (0x105c). +hdc shell param set persist.ark.properties 0x905d +# Reboot to apply changes. +hdc shell reboot +``` ### Typical Logs +The following logs represent a complete GC execution, with variations based on the type of GC. You can search for the keyword [gc] in the exported log file to view GC-related logs. You can also check for the keyword ArkCompiler to view more comprehensive VM-related logs. + ``` -// Actual size occupied by the object before GC (actual size occupied by the region) - > Actual size occupied by the object after GC (actual size occupied by the region), total duration (+concurrentMark duration), and GC triggering cause +// Pre-GC object size (region size) -> Post-GC object size (region size), total duration (+concurrentMark duration), GC trigger reason. C03F00/ArkCompiler: [gc] [ CompressGC ] 26.1164 (35) -> 7.10049 (10.5) MB, 160.626(+0)ms, Switch to background -// GC statuses and application name -C03F00/ArkCompiler: [gc] IsInBackground: 1; SensitiveStatus: 0; OnStartupEvent: 0; BundleName: com.huawei.hmos.filemanager; -// Time consumption statistics of each GC phase +// Various states during GC execution and application name. +C03F00/ArkCompiler: [gc] IsInBackground: 1; SensitiveStatus: 0; OnStartupEvent: 0; BundleName: com.example.demo; +// Duration statistics for each GC phase. C03F00/ArkCompiler: [gc] /***************** GC Duration statistic: ****************/ C03F00/ArkCompiler: [gc] TotalGC: 160.626 ms C03F00/ArkCompiler: Initialize: 0.179 ms @@ -241,7 +355,7 @@ C03F00/ArkCompiler: MarkRoots: 6.925 ms C03F00/ArkCompiler: ProcessMarkStack: 158.99 ms C03F00/ArkCompiler: Sweep: 0.957 ms C03F00/ArkCompiler: Finish: 0.277 ms -// Memory size occupied by each part after GC +// Memory usage statistics after GC. C03F00/ArkCompiler: [gc] /****************** GC Memory statistic: *****************/ C03F00/ArkCompiler: [gc] AllSpaces used: 7270.9KB committed: 10752KB C03F00/ArkCompiler: ActiveSemiSpace used: 0KB committed: 256KB @@ -259,7 +373,7 @@ C03F00/ArkCompiler: ArrayBufferNativeSize: 0.0117188KB C03F00/ArkCompiler: RegExpByteCodeNativeSize:0.280273KB C03F00/ArkCompiler: ChunkNativeSize: 19096 KB C03F00/ArkCompiler: [gc] Heap alive rate: 0.202871 -// Overall statistics of this type of GC on the VM +// Summary statistics for this type of GC in the VM. C03F00/ArkCompiler: [gc] /***************** GC summary statistic: *****************/ C03F00/ArkCompiler: [gc] CompressGC occurs count 6 C03F00/ArkCompiler: CompressGC max pause: 2672.33 ms @@ -268,36 +382,37 @@ C03F00/ArkCompiler: CompressGC average pause:1076.06 ms C03F00/ArkCompiler: Heap average alive rate: 0.635325 ``` -- GC type, which can be [HPP YoungGC], [HPP OldGC], [CompressGC] and [SharedGC]. -- **TotalGC**: total duration. The following lists the time required for each phase, including Initialize, Mark, MarkRoots, ProcessMarkStack, Sweep, and Finish. The actual phase varies according to the GC process. -- **IsInBackground**: specifies whether it is a background scenario. The options are **1** (background scenario) and **0** (non-background scenario). -- **SensitiveStatus**: specifies whether it is a sensitive scenario. The options are **1** (sensitive scenario) and **0** (non-sensitive scenario). -- **OnStartupEvent**: specifies whether it is a cold start scenario. The options are **1** (cold start scenario) and **0** (non-cold start scenario). -- **used**: actual memory space occupied by the allocated object. -- **committed**: size of the memory allocated to the heap. Memory space is allocated by region, and a region is not fully occupied by objects. Therefore, if **committed** is greater than or equal to **used**, the values of **HugeObjectSpace** is the same under **used** and **committed** because one object occupies the region. -- **Anno memory usage size**: memory size applied by all heaps of the current process, including the heap and shared heap. -- **Native memory usage size**: native memory size requested by the current process. -- **NativeBindingSize**: size of the native memory bound to the objects in the heap of the current process. -- **ArrayBufferNativeSize**: native memory size of the array cache requested by the current process. -- **RegExpByteCodeNativeSize**: native memory size of the regular expression bytecode requested by the current process. -- **ChunkNativeSize**: chunk native memory size requested by the current process. +- GC type, which can be [HPP YoungGC], [HPP OldGC], [CompressGC], and [SharedGC]. +- **TotalGC**: total duration. The following lists the duration for each phase, including Initialize, Mark, MarkRoots, ProcessMarkStack, Sweep, and Finish. The actual phases may vary depending on the GC process. +- **IsInBackground**: specifies whether the application is in the background (**1**) or foreground (**0**). +- **SensitiveStatus**: specifies whether the application is in a sensitive scenario (**1**) or not (**0**). +- **OnStartupEvent**: specifies whether the application is in a cold start scenario (**1**) or not (**0**). +- **used**: actual memory usage of allocated objects. +- **committed**: actual memory allocated to the heap. Since memory spaces are allocated in regions that are not always fully utilized by objects, **committed** is greater than or equal to **used**. For Huge Space, these values are equal because each object occupies a separate region. +- **Anno memory usage size**: total memory usage of all heaps in the process, including heap and shared heap. +- **Native memory usage size**: total native memory usage of the process. +- **NativeBindingSize**: native memory usage of objects bound to the heap. +- **ArrayBufferNativeSize**: native memory usage of array buffers requested by the process. +- **RegExpByteCodeNativeSize**: native memory usage of regular expression bytecode requested by the process. +- **ChunkNativeSize**: native memory usage of chunks requested by the process. - **Heap alive rate**: survival rate of objects in the heap. ## GC Developer Debugging Interfaces > **NOTE** -> The following interfaces are used only for debugging. They are informal external SDK interfaces and should not be used in official application versions. +> +> The following interfaces are for debugging purposes only and are not official SDK interfaces. They should not be used in production applications. ### ArkTools.hintGC() -- Call method: **ArkTools.hintGC()** -- Type: JS interface -- Description: Determines whether full GC is required. In the background scenario or if the expected survival rate is lower than the preset value, full GC is triggered. In performance-sensitive scenarios, full GC is not triggered. -- Use scenario: The developer asks the system to perform GC. +- Invocation: **ArkTools.hintGC()** +- Type: ArkTS interface +- Description: triggers the VM to assess whether a full GC should be executed. Full GC is initiated in the background or if the expected memory survival rate is below a threshold. It will not trigger in sensitive scenarios. +- Use case: developers prompting the system to perform GC. - Log keywords: There is no direct log. Only external trigger (**GCReason::TRIGGER_BY_JS**) can be found. -Example: +Usage example: ``` // Declare the interface first. @@ -316,7 +431,7 @@ struct Index { .fontSize(50) .fontWeight(FontWeight.Bold) Button("Trigger Hint GC").onClick((event: ClickEvent) => { - ArkTools.hintGC(); // Directly called in a method. + ArkTools.hintGC(); // Call the method directly. }) } .width('100%') diff --git a/en/application-dev/arkts-utils/global-configuration-guide.md b/en/application-dev/arkts-utils/global-configuration-guide.md index a537d7c43540c97eeda813d22aa9fa88041f006b..4ad86923b511f74e32c7aa9f8b67aeeb4b4105b4 100644 --- a/en/application-dev/arkts-utils/global-configuration-guide.md +++ b/en/application-dev/arkts-utils/global-configuration-guide.md @@ -1,10 +1,10 @@ -# Global Configuration Items +# Global Configuration -In scenarios where a single process instance is required, for example, global configuration item services that require data consistency between different concurrent instances, the shared module can be used. +In cases where a process-wide singleton is necessary, for example, for maintaining data consistency across multiple concurrent instances for global configuration services, a shared module can be used. -The following example implements the service function that can be downloaded only after Wi-Fi is enabled and users log in to the system. The procedure is as follows: +The following example illustrates the service logic where downloads are permitted only when Wi-Fi is enabled and the user is logged in. The implementation involves the following steps: -1. Compile the global configuration file. +1. Create a global configuration file. ```ts // Config.ets @@ -62,7 +62,7 @@ The following example implements the service function that can be downloaded onl export let config = new Config() ``` -2. The UI main thread and subthreads access global configuration items. +2. Enable both the UI main thread and child threads to access the global configuration. ```ts import { config } from './Config' @@ -100,7 +100,7 @@ The following example implements the service function that can be downloaded onl center: { anchor: '__container__', align: VerticalAlign.Center }, middle: { anchor: '__container__', align: HorizontalAlign.Center } }) - TextInput ({placeholder: "Please enter a user name."}) + TextInput({ placeholder: "Enter user name" }) .fontSize(20) .fontWeight(FontWeight.Bold) .alignRules({ diff --git a/en/application-dev/arkts-utils/independent-time-consuming-task.md b/en/application-dev/arkts-utils/independent-time-consuming-task.md index 9fe6404e98744877575a0d04018a55af01f212ee..c83281a78dced4f504707fc8e68598aefa528a61 100644 --- a/en/application-dev/arkts-utils/independent-time-consuming-task.md +++ b/en/application-dev/arkts-utils/independent-time-consuming-task.md @@ -1,10 +1,10 @@ # Using TaskPool for Independent Time-Consuming Tasks -For a time-consuming task that runs independently, you only need to return the result to the host thread after the task is executed. There is no context dependency. You can implement the task in the following way: +For a time-consuming task that runs independently, you only need to return the result to the host thread after the task is executed. There is no context dependency. You can use the approach described in this topic. -The following uses image loading as an example. +This example uses image loading to illustrate the process. -1. Implement the task to be executed by the sub-thread. +1. Implement the task to be executed in a child thread. ```ts // IconItemSource.ets @@ -23,14 +23,14 @@ The following uses image loading as an example. // IndependentTask.ets import { IconItemSource } from './IconItemSource'; - @Concurrent // Methods executed in the task must be decorated by @Concurrent. Otherwise, they cannot be called. + // Methods executed in the task must be decorated by @Concurrent. Otherwise, they cannot be called. @Concurrent export function loadPicture(count: number): IconItemSource[] { let iconItemSourceList: IconItemSource[] = []; - // Traverse and add six IconItem data records. + // Add six IconItem data records. for (let index = 0; index < count; index++) { const numStart: number = index * 6; - // Six images are used cyclically. + // Use six images in the loop. iconItemSourceList.push(new IconItemSource('$media:startIcon', `item${numStart + 1}`)); iconItemSourceList.push(new IconItemSource('$media:background', `item${numStart + 2}`)); iconItemSourceList.push(new IconItemSource('$media:foreground', `item${numStart + 3}`)); @@ -42,7 +42,7 @@ The following uses image loading as an example. } ``` -2. The execute method in TaskPool is used to execute the preceding task, that is, load images. +2. Use the **execute** method of TaskPool to execute the task, that is, to load the images. ```ts // Index.ets @@ -67,7 +67,7 @@ The following uses image loading as an example. let lodePictureTask: taskpool.Task = new taskpool.Task(loadPicture, 30); // Execute the task and return the result. taskpool.execute(lodePictureTask).then((res: object) => { - // Execution result of the loadPicture API. + // Execution result of the loadPicture method. iconItemSourceList = res as IconItemSource[]; }) }) diff --git a/en/application-dev/arkts-utils/interthread-communication-overview.md b/en/application-dev/arkts-utils/interthread-communication-overview.md index af5506f735f45aa4ba443d1ddcfb80e0b0b1111e..602daf9518ecd20bb83ff4cb8e424f0d4dbce509 100644 --- a/en/application-dev/arkts-utils/interthread-communication-overview.md +++ b/en/application-dev/arkts-utils/interthread-communication-overview.md @@ -1,18 +1,18 @@ -# ArkTS Inter-Thread Communication Overview +# Overview of ArkTS Inter-Thread Communication -Inter-thread communication refers to data exchange between concurrent threads. ArkTS is compatible with TS and JS. Similar to all other JS engines, ArkTS provides concurrency capabilities based on the Actor memory isolation concurrency model. +Inter-thread communication involves the exchange of data between concurrent threads. Given that ArkTS is compatible with TS/JS, its runtime is implemented using the actor model with memory isolation, similar to other JS engines. -For different data objects, the communication behavior between ArkTS threads is different, such as common JS objects, ArrayBuffer objects, and SharedArrayBuffer objects. The cross-thread behavior is different, including serialization and deserialization copy, data transfer, and data sharing. +The behavior of inter-thread communication in ArkTS varies depending on the type of data object involved. For instance, regular JS objects, ArrayBuffer objects, and SharedArrayBuffer objects each exhibit different behaviors, including serialization and deserialization, data transfer, and data sharing. -Take a JS object as an example. The standard Structure Clone algorithm (serialization and deserialization) is used for communication between concurrent tasks. The JS object is converted into data (such as character strings or memory blocks) irrelevant to the engine through serialization, and then deserialized in another concurrent instance, to restore a JS object to a new object that is the same as the original JS object, deep copy is required, which is inefficient. In addition to the serialization and deserialization capabilities of the JS standard, the native JS object transmission and [Sendable object](arkts-sendable.md) sharing capabilities are also supported. +Taking JS objects as an example, inter-thread communication uses the standard Structured Clone algorithm for serialization and deserialization. This process involves converting JS objects into engine-independent data (such as strings or memory blocks) and then restoring them into new objects with the same content in another concurrent instance. This typically requires deep copying, which can be less efficient. In addition to standard JS serialization and deserialization, ArkTS supports the transfer of native JS object and the sharing of [Sendable objects](arkts-sendable.md). -Currently, ArkTS provides two concurrency capabilities to support inter-thread communication: TaskPool and Worker. +Currently, ArkTS provides two concurrency capabilities for inter-thread communication: TaskPool and Worker. -- Worker is a standard cross-thread communication API of the Actor concurrency model. It is used in the same way as Web Worker or Node.js Worker. +- Worker is the standard API for cross-thread communication in the actor model. Its usage patterns are similar to those of Web Worker or Node.js Worker. -- TaskPool provides a task pool API with more powerful functions and easier concurrent programming. The object transfer behavior of TaskPool across concurrent instances is the same as that of Worker. TaskPool uses the standard Structured Clone algorithm. The larger the objects in concurrent communication, the longer the time required. +- TaskPool provides a more powerful and user-friendly API for concurrent programming. The behavior of object passing across concurrent instances in TaskPool is consistent with that of Worker, utilizing the standard Structured Clone algorithm. The time required for concurrent communication increases with the size of the objects involved. -Based on the TaskPool and Worker concurrency APIs provided by ArkTS, multiple inter-thread communication capabilities are supported to meet the requirements of different [inter-thread communication scenarios](independent-time-consuming-task.md). for example, an independent time-consuming task scenario, a scenario of a plurality of time-consuming tasks, a scenario of communication between a TaskPool thread and a host thread, a scenario of asynchronous communication between a worker thread and a host thread, and a scenario in which a worker synchronously calls an interface of a host thread. In addition, based on the mechanism provided by [Node-API](../napi/napi-introduction.md), C++ threads can call ArkTS APIs across threads. +Leveraging the TaskPool and Worker concurrency APIs, ArkTS supports a variety of inter-thread communication capabilities to satisfy different development needs in [inter-thread communication scenarios](independent-time-consuming-task.md). These include scenarios involving independent time-consuming tasks, multiple time-consuming tasks, communication between TaskPool threads and the host thread, asynchronous communication between Worker threads and the host thread, and synchronous calls from Worker threads to the host thread's interfaces. In addition, ArkTS supports cross-thread calls to ArkTS interfaces from C++ threads, based on the mechanisms provided by [Node-API](../napi/napi-introduction.md). Figure 1 Serialization and deserialization principles diff --git a/en/application-dev/arkts-utils/io-intensive-task-development.md b/en/application-dev/arkts-utils/io-intensive-task-development.md index feadc3e2eff3a54b8888e45715220978f39d4b53..d3e7803d428761e040e2202a10b64af451220b19 100644 --- a/en/application-dev/arkts-utils/io-intensive-task-development.md +++ b/en/application-dev/arkts-utils/io-intensive-task-development.md @@ -1,18 +1,18 @@ # I/O Intensive Task Development (TaskPool) -I/O intensive tasks are tasks that require frequent I/O operations such as disk read/write and network communication. While asynchronous concurrency can address the thread blocking issue for single I/O tasks, it falls short in the case of I/O intensive tasks. This is where multithread concurrency comes into play. +I/O intensive tasks are those requiring frequent I/O operations such as disk read/write and network communication. While asynchronous concurrency can address the thread blocking issue for single I/O tasks, it falls short in the case of I/O intensive tasks. This is where multithreaded concurrency comes into play. -The performance focus of I/O intensive tasks is not the CPU processing capability, but the speed and efficiency of I/O operations, since such a task usually requires frequent operations such as disk read/write and network communication. The following uses frequent read/write operations on a system file to simulate concurrency processing of I/O intensive tasks. +The performance focus of I/O intensive tasks is not the CPU processing capability, but the speed and efficiency of I/O operations, since these tasks usually require frequent operations such as disk read/write and network communication. The following uses frequent read/write operations on a system file to simulate concurrency processing of I/O intensive tasks. -1. Define a concurrency function that internally calls I/O capabilities intensively. +1. Define a concurrent function that frequently calls I/O operations. ```ts // write.ets import { fileIo } from '@kit.CoreFileKit' - // Define a concurrency function that internally calls I/O capabilities intensively. + // Define a concurrent function that frequently calls I/O operations. // Write data to the file. export async function write(data: string, filePath: string): Promise { let file: fileIo.File = await fileIo.open(filePath, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE); @@ -48,7 +48,7 @@ The performance focus of I/O intensive tasks is not the CPU processing capabilit } ``` -2. Use **TaskPool** to execute the concurrency function that contains the intensive I/O operations. Specifically, call [execute()](../reference/apis-arkts/js-apis-taskpool.md#taskpoolexecute) to execute the tasks and process the scheduling result in a callback. For details about how to obtain **filePath1** and **filePath2** in the example, see [Obtaining Application File Paths](../application-models/application-context-stage.md#obtaining-application-file-paths). To use the context in **TaskPool**, prepare the context outside the concurrent function and pass in the context to the concurrent function as an input parameter. +2. Use **TaskPool** to execute the concurrent function with frequent intensive I/O operations. Specifically, call [execute()](../reference/apis-arkts/js-apis-taskpool.md#taskpoolexecute) to execute the tasks and process the scheduling result in the callback. For details about how to obtain **filePath1** and **filePath2** in the example, see [Obtaining Application File Paths](../application-models/application-context-stage.md#obtaining-application-file-paths). When using context in TaskPool, it must be prepared outside the concurrent function and passed as an argument. ```ts // Index.ets @@ -65,8 +65,8 @@ The performance focus of I/O intensive tasks is not the CPU processing capabilit .onClick(() => { let context = getContext() as common.UIAbilityContext; - // Use TaskPool to execute the concurrency function that contains the intensive I/O operations. - // In the case of a large array, the distribution of I/O intensive tasks also preempts the UI main thread. Therefore, multiple threads are required. + // Use TaskPool to execute the concurrent function with frequent I/O operations. + // In the case of a large array, the distribution of I/O intensive tasks can block the UI main thread. Therefore, multithreading is necessary. taskpool.execute(concurrentTest, context).then(() => { // Process the scheduling result. console.info("taskpool: execute success") diff --git a/en/application-dev/arkts-utils/js-apis-load-native-module.md b/en/application-dev/arkts-utils/js-apis-load-native-module.md index 9948c567a0630096389dc3c1cc742d4c8e750480..f1e0ac2365b1783be3a2e9b875ad4b41dd3cf210 100644 --- a/en/application-dev/arkts-utils/js-apis-load-native-module.md +++ b/en/application-dev/arkts-utils/js-apis-load-native-module.md @@ -1,6 +1,6 @@ -# Dynamically Loading a Native Module in Synchronous Mode +# Dynamically Loading Native Modules in Synchronous Mode -The **loadNativeModule** API is used to dynamically load a native module in synchronous mode. It can be used to load a module only when the module needs to be used, shortening the cold start time. However, the API call involves the loading the .so file. You need to evaluate the impact caused by the .so file loading. +The **loadNativeModule** API is used to dynamically load native modules in synchronous mode. It is used to load native modules only when needed, preventing unnecessary modules from being loaded during application startup. However, using this API incurs a delay due to the loading of the .so file, and therefore you need to assess whether this will impact functionality. ## API Description @@ -13,66 +13,67 @@ loadNativeModule(moduleName: string): Object; | moduleName | Name of the module to load. | > **NOTE** +> > **moduleName** must be set to the module name configured in the **module.json5** file in the HAP to which the module to load belongs. > -> **loadNativeModule** can be used only to load modules in the main thread. +> **loadNativeModule** can be used only to load modules in the UI main thread. > > Dependencies must be configured for the API call regardless of whether the input parameter is a constant string or variable expression. ## Supported Scenarios -| Scenario | Example | -| :------------- | :----------------------------- | -| System library module | Load **@ohos.** or **@system.**. | +| Scenario | Example | +| :------------- | :----------------------------- | +| System library module | Load **@ohos.** or **@system.**. | | Native module in an application| Load **libNativeLibrary.so**.| -## Example +## Usage Example - **Loading a system library module to a HAP** -```js -let hilog: ESObject = loadNativeModule("@ohos.hilog"); -hilog.info(0, "testTag", "loadNativeModule ohos.hilog success"); -``` + ```js + let hilog: ESObject = loadNativeModule("@ohos.hilog"); + hilog.info(0, "testTag", "loadNativeModule ohos.hilog success"); + ``` - **Loading a native library to a HAP** -The **index.d.ts** file of **libentry.so** is as follows: - -```javascript -//index.d.ts -export const add: (a: number, b: number) => number; -``` - -1. Configure dependencies in the **oh-package.json5** file. - -```json -{ - "dependencies": { - "libentry.so": "file:../src/main/cpp/types/libentry" - } -} -``` - -2. Configure the source package in **build-profile.json5**. - -```json -{ - "buildOption" : { - "arkOptions" : { - "runtimeOnly" : { - "packages": [ - "libentry.so" - ] - } - } - } -} -``` + The **index.d.ts** file of **libentry.so** is as follows: + + ```javascript + //index.d.ts + export const add: (a: number, b: number) => number; + ``` + +1. When loading a local .so library, configure dependencies in the **oh-package.json5** file. + + ```json + { + "dependencies": { + "libentry.so": "file:../src/main/cpp/types/libentry" + } + } + ``` + +2. Configure the **build-profile.json5** file. + + ```json + { + "buildOption" : { + "arkOptions" : { + "runtimeOnly" : { + "packages": [ + "libentry.so" + ] + } + } + } + } + ``` 3. Use **loadNativeModule** to load **libentry.so** and call the **add** function. -```js -let module: ESObject = loadNativeModule("libentry.so"); -let sum: number = module.add(1, 2); -``` + ```js + let module: ESObject = loadNativeModule("libentry.so"); + let sum: number = module.add(1, 2); + ``` \ No newline at end of file diff --git a/en/application-dev/arkts-utils/linear-container.md b/en/application-dev/arkts-utils/linear-container.md index e2b8b7f4e724f0274e5bc9a22e75c3f45ebef088..1005647fa6d56131a444b8da0181b37ca115ac82 100644 --- a/en/application-dev/arkts-utils/linear-container.md +++ b/en/application-dev/arkts-utils/linear-container.md @@ -1,209 +1,209 @@ # Linear Containers -Linear containers, underpinned by arrays, implement a data structure that enables sequential access. There are several types of linear containers: **ArrayList**, **Vector**, **List**, **LinkedList**, **Deque**, **Queue**, and **Stack**. +Linear containers, underpinned by arrays, implement a data structure that enables sequential access. There are several types of linear containers: ArrayList, Vector, List, LinkedList, Deque, Queue, and Stack. -To accelerate data access, linear containers support Create, Read, Update, and Delete (CRUD) through a bytecode instruction at runtime. +Linear containers prioritize data access speed, enabling operations such as adding, removing, modifying, and accessing elements with a single bytecode instruction at runtime. -## Comparison of linear container types +## Comparison of Linear Container Types -| Class| Characteristics and Recommended Application Scenarios| +| Type| Characteristics and Recommended Use Cases| | --------- | ------- | -| ArrayList | Dynamic array, which occupies a continuous memory space. This method is recommended when elements need to be frequently read.| -| List | Unidirectional linked list. The occupied space can be discontinuous. This mode is recommended when elements need to be frequently inserted and deleted and a unidirectional linked list is required.| -| LinkedList | A doubly linked list. The occupied space can be discontinuous. It is recommended when elements need to be frequently inserted and deleted and a doubly linked list is required.| -| Deque | Dual-ended queue. Elements can be entered and exited from the head and tail of a container, occupying a continuous memory space. It is recommended when the head and tail elements need to be frequently accessed and operated.| -| Queue | A queue is used to insert elements from the tail of a container and pop elements from the header of the container, occupying a continuous memory space. You are advised to use **Queue** in FIFO scenarios.| -| Stack | A stack can be inserted or deleted only from one end of a container, occupying a continuous memory space. You are advised to use **Stack** in LOFI scenarios.| -| Vector | Dynamic array, which occupies a continuous memory space. This type is no longer maintained. You are advised to use ArrayList.| +| ArrayList | Dynamic array, which occupies a contiguous block of memory. This type is recommended for frequent element access.| +| List | Singly linked list, where memory can be non-contiguous. This type is recommended for frequent insertions and deletions when using a singly linked list.| +| LinkedList | Doubly linked list, where memory can be non-contiguous. This type is recommended for frequent insertions and deletions when using a doubly linked list.| +| Deque | Double-ended queue, which allows element operations at both ends, and occupies a contiguous block of memory. This type is recommended for frequent access and manipulation of head and tail elements.| +| Queue | Queue, which inserts elements at the tail and removes them from the head, and occupies a contiguous block of memory. This type is suitable for First In First Out (FIFO) scenarios.| +| Stack | Stack, which allows insertions and deletions only at one end, and occupies a contiguous block of memory. This type is suitable for Last In First Out (LIFO) scenarios.| +| Vector | Dynamic array, which occupies a contiguous block of memory. This type is no longer maintained; use ArrayList instead.| ## ArrayList -[ArrayList](../reference/apis-arkts/js-apis-arraylist.md) is a dynamic array that can be used to construct a global array object. You are advised to use **ArrayList** when elements in a container need to be frequently read. +[ArrayList](../reference/apis-arkts/js-apis-arraylist.md) is a dynamic array used to construct a global array object. It is recommended for frequent element access. -**ArrayList** uses generics and must be stored in a contiguous memory space. Its initial capacity is 10, and it increases capacity 1.5-fold in each dynamic expansion. +Defined by generics, ArrayList requires a contiguous block of memory for storage, with an initial capacity of 10 and supports dynamic resizing, increasing its size by 1.5 times the original capacity each time. -**ArrayList** provides the following CRUD APIs. +Common APIs for adding, removing, modifying, and accessing elements in ArrayList are as follows: | Operation| API| Description| | --------- | ------- | ------- | -| Create| add(element: T) | // Add an item to the end of the data.| -| Create| insert(element: T, index: number) | * Inserts a value to a specified index.| -| Read| arr\[index: number] | Obtains the value corresponding to a specified index. The value is obtained by running commands to ensure the access speed.| -| Read| forEach(callbackFn: (value: T, index?: number, arrlist?: ArrayList<T>) => void, thisArg?: Object) | Accesses the elements of the entire ArrayList container.| -| Read| \[Symbol.iterator]():IterableIterator<T> | Creates an iterator for data access.| -| Update| arr\[index] = xxx | Modifies the value corresponding to a specified index.| -| Delete| remove(element: T) | Deletes the first matched element.| -| Delete| removeByRange(fromIndex: number, toIndex:number) | Removes elements in a specified range from this container.| +| Adding elements| add(element: T) | Adds an element to the end of the array.| +| Adding elements| insert(element: T, index: number) | Inserts an element at the specified index.| +| Accessing elements| arr\[index: number] | Obtains the value at the specified index, ensuring fast access.| +| Accessing elements| forEach(callbackFn: (value: T, index?: number, arrlist?: ArrayList<T>) => void, thisArg?: Object) | Iterates over all elements in the ArrayList.| +| Accessing elements| \[Symbol.iterator]():IterableIterator<T> | Creates an iterator for data access.| +| Modifying elements| arr\[index] = xxx | Modifies the value at the specified index.| +| Removing elements| remove(element: T) | Removes the first matching element.| +| Removing elements| removeByRange(fromIndex: number, toIndex:number) | Removes elements within the specified range.| ## List -[List](../reference/apis-arkts/js-apis-list.md) can be used to construct a singly linked list, which supports access only through the head node to the tail node. **List** uses generics and can be stored in a non-contiguous memory space. +[List](../reference/apis-arkts/js-apis-list.md) is used to construct a singly linked list, which supports access only through the head node to the tail node. Defined by generics, List's storage locations in memory can be non-contiguous. -Unlike [LinkedList](../reference/apis-arkts/js-apis-linkedlist.md), which is a doubly linked list, **List** does not support insertion or removal at both ends. +Unlike [LinkedList](../reference/apis-arkts/js-apis-linkedlist.md), which is a doubly linked list and allows quick insertions and deletions at both ends, List is a singly linked list and does not support bidirectional operations. -If elements need to be frequently inserted and deleted and a unidirectional linked list is required, you are advised to use List to perform efficient operations. +If elements need to be frequently inserted and deleted and a singly linked list is required, you are advised to use List. -**List** provides the following CRUD APIs. +Common APIs for adding, removing, modifying, and accessing elements in List are as follows: | Operation| API| Description| | --------- | ------- | ------- | -| Create| add(element: T) | // Add an item to the end of the data.| -| Create| insert(element: T, index: number) | * Inserts a value to a specified index.| -| Read| get(index: number) | Obtains the element corresponding to the specified index.| -| Read| list\[index: number] | Obtains the element corresponding to the specified index position. However, this will result in undefined results.| -| Read| getFirst() | Obtains the first element.| -| Read| getLast() | Obtaining the last element| -| Read| getIndexOf(element: T) | Obtains the position of the first element that matches the specified element.| -| Read| getLastIndexOf(element: T) | Obtains the position of the last element that matches the specified element.| -| Read| forEach(callbackfn: (value:T, index?: number, list?: List<T>)=> void,thisArg?: Object) | Traverses the elements of the entire list container.| -| Read| \[Symbol.iterator]():IterableIterator<T> | Creates an iterator for data access.| -| Update| set(index:number, element: T) | Changes the value of an element with a specified index to element.| -| Update| list\[index] = element | Changes the value of an element at the specified index position to element. However, the result is not defined.| -| Update| replaceAllElements(callbackFn:(value: T,index?: number,list?: List<T>)=>T,thisArg?: Object) | Replaces elements in a list one by one.| -| Delete| remove(element: T) | Deletes the first matched element.| -| Delete| removeByIndex(index:number) | Deletes the element corresponding to the index position.| +| Adding elements| add(element: T) | Adds an element to the end of the array.| +| Adding elements| insert(element: T, index: number) | Inserts an element at the specified index.| +| Accessing elements| get(index: number) | Obtains the element at the specified index.| +| Accessing elements| list\[index: number] | Obtains the element at the specified index. However, this will result in undefined behavior.| +| Accessing elements| getFirst() | Obtains the first element.| +| Accessing elements| getLast() | Obtains the last element.| +| Accessing elements| getIndexOf(element: T) | Obtains the index of the first matching element.| +| Accessing elements| getLastIndexOf(element: T) | Obtains the index of the last matching element.| +| Accessing elements| forEach(callbackfn: (value:T, index?: number, list?: List<T>)=> void,thisArg?: Object) | Iterates over all elements in the List.| +| Accessing elements| \[Symbol.iterator]():IterableIterator<T> | Creates an iterator for data access.| +| Modifying elements| set(index:number, element: T) | Modifies the element at the specified index.| +| Modifying elements| list\[index] = element | Modifies the element at the specified index. However, this will result in undefined behavior.| +| Modifying elements| replaceAllElements(callbackFn:(value: T,index?: number,list?: List<T>)=>T,thisArg?: Object) | Replaces all elements in the List.| +| Removing elements| remove(element: T) | Removes the first matching element.| +| Removing elements| removeByIndex(index:number) | Removes the element at the specified index.| ## LinkedList -[LinkedList](../reference/apis-arkts/js-apis-linkedlist.md) can be used to construct a doubly linked list, which can be traversed at both ends. **LinkedList** uses generics and can be stored in a non-contiguous memory space. +[LinkedList](../reference/apis-arkts/js-apis-linkedlist.md) is used to construct a doubly linked list, which can be traversed in both directions from any node. Defined by generics, LinkedList's storage locations in memory can be non-contiguous. -Unlike [List](../reference/apis-arkts/js-apis-list.md), which is a singly linked list, **LinkedList** supports insertion and removal at both ends. +Unlike [List](../reference/apis-arkts/js-apis-list.md), which is a singly linked list and does not support bidirectional operations, LinkedList is a doubly linked list and allows quick insertions and deletions at both ends. -**LinkedList** is more efficient in data insertion than [ArrayList](../reference/apis-arkts/js-apis-arraylist.md), but less efficient in data access. +Compared with [ArrayList](../reference/apis-arkts/js-apis-arraylist.md), LinkedList is more efficient for inserting data, whereas ArrayList is more efficient for querying data. -If elements need to be frequently inserted and deleted and a doubly linked list is required, you are advised to use LinkedList to perform efficient operations. +If elements need to be frequently inserted and deleted and a doubly linked list is required, you are advised to use LinkedList. -**LinkedList** provides the following CRUD APIs. +Common APIs for adding, removing, modifying, and accessing elements in LinkedList are as follows: | Operation| API| Description| | --------- | ------- | ------- | -| Create| add(element: T) | // Add an item to the end of the data.| -| Create| insert(element: T, index: number) | * Inserts a value to a specified index.| -| Read| get(index: number) | Obtains the element corresponding to the specified index.| -| Read| list\[index: number] | Obtains the element corresponding to the specified index position. However, this will result in undefined results.| -| Read| getFirst() | Obtains the first element.| -| Read| getLast() | Obtaining the last element| -| Read| getIndexOf(element: T) | Obtains the position of the first element that matches the specified element.| -| Read| getLastIndexOf(element: T) | Obtains the position of the last element that matches the specified element.| -| Read| forEach(callbackFn: (value: T, index?: number, list?: LinkedList<T>) => void, thisArg?: Object) | Traverses the elements of the entire LinkedList container.| -| Read| \[Symbol.iterator]():IterableIterator<T> | Creates an iterator for data access.| -| Update| set(index:number, element: T) | Changes the value of an element with a specified index to element.| -| Update| list\[index] = element | Changes the value of an element at the specified index position to element. However, the result is not defined.| -| Delete| remove(element: T) | Deletes the first matched element.| -| Delete| removeByIndex(index:number) | Deletes the element corresponding to the index position.| +| Adding elements| add(element: T) | Adds an element to the end of the array.| +| Adding elements| insert(element: T, index: number) | Inserts an element at the specified index.| +| Accessing elements| get(index: number) | Obtains the element at the specified index.| +| Accessing elements| list\[index: number] | Obtains the element at the specified index. However, this will result in undefined behavior.| +| Accessing elements| getFirst() | Obtains the first element.| +| Accessing elements| getLast() | Obtains the last element.| +| Accessing elements| getIndexOf(element: T) | Obtains the index of the first matching element.| +| Accessing elements| getLastIndexOf(element: T) | Obtains the index of the last matching element.| +| Accessing elements| forEach(callbackFn: (value: T, index?: number, list?: LinkedList<T>) => void, thisArg?: Object) | Iterates over all elements in the LinkedList.| +| Accessing elements| \[Symbol.iterator]():IterableIterator<T> | Creates an iterator for data access.| +| Modifying elements| set(index:number, element: T) | Modifies the element at the specified index.| +| Modifying elements| list\[index] = element | Modifies the element at the specified index. However, this will result in undefined behavior.| +| Removing elements| remove(element: T) | Removes the first matching element.| +| Removing elements| removeByIndex(index:number) | Deletes the element at the specified index.| ## Deque -[Deque](../reference/apis-arkts/js-apis-deque.md) can be used to construct a double-ended queue (deque) that follows the principles of First In First Out (FIFO) and Last In First Out (LIFO). It allows insertion and removal of elements at both ends. +[Deque](../reference/apis-arkts/js-apis-deque.md) is used to construct a double-ended queue (deque) that follows the principles of FIFO and LIFO. It allows insertion and removal of elements at both ends. -**Deque** uses generics and must be stored in a contiguous memory space. Its initial capacity is 8, and it has capacity doubled in each dynamic expansion. The bottom layer of **Deque** is implemented by cyclic queues, delivering a high efficiency in enqueuing and dequeuing. +Defined by generics, Deque requires a contiguous block of memory for storage, with an initial capacity of 8 and supports dynamic resizing, doubling its size each time. Deque is implemented using a circular queue, ensuring efficient enqueue and dequeue operations. -Compared with [Queue](../reference/apis-arkts/js-apis-queue.md), Deque allows you to add or delete elements at both ends. Queue allows you to delete elements only at the beginning and add elements at the end. +Unlike [Queue](../reference/apis-arkts/js-apis-queue.md), which only allows element removal at the head and insertion at the tail, Deque allows operations at both ends. -Unlike [Vector](../reference/apis-arkts/js-apis-vector.md), **Deque** does not support insertion and deletion of elements in between. When compared with **Vector**, **Deque** is more efficient in inserting and removing header elements, but less efficient in accessing elements. +Compared with [Vector](../reference/apis-arkts/js-apis-vector.md), both support element operations at both ends, but Deque does not allow insertions in the middle. Deque is more efficient for inserting and deleting elements at the head, whereas Vector is more efficient for accessing elements. -You are advised to use **Deque** when you need to frequently insert or remove elements at both the ends of a container. +Deque is recommended for frequent insertions and deletions at both ends of the container. -**Deque** provides the following CRUD APIs. +Common APIs for adding, removing, modifying, and accessing elements in Deque are as follows: | Operation| API| Description| | --------- | ------- | ------- | -| Create| insertFront(element: T) | Adds an element to the header.| -| Create| insertEnd(element: T) | Adds an element to the end.| -| Read| getFirst() | Obtains the first element and does not dequeue the element.| -| Read| getLast() | Obtains the last element and does not dequeue the element.| -| Read| popFirst() | Obtains the first element and dequeues it.| -| Read| popLast() | Obtains the last element and dequeues it.| -| Read| forEach(callbackFn:(value: T, index?: number, deque?: Deque<T>) => void, thisArg?: Object) | Traverses the elements of the entire Deque container.| -| Read| \[Symbol.iterator]():IterableIterator<T> | Creates an iterator for data access.| -| Update| forEach(callbackFn:(value: T, index?: number, deque?: Deque<T>)=> void, thisArg?: Object) | Modify the elements of the entire Deque container through traversal.| -| Delete| popFirst() | Dequeues and deletes the head element.| -| Delete| popLast() | Dequeues and deletes the tail element.| +| Adding elements| insertFront(element: T) | Adds an element to the front of the Deque.| +| Adding elements| insertEnd(element: T) | Adds an element to the end of the Deque.| +| Accessing elements| getFirst() | Obtains the first element without dequeuing.| +| Accessing elements| getLast() | Obtains the last element without dequeuing.| +| Accessing elements| popFirst() | Obtains and removes the first element.| +| Accessing elements| popLast() | Obtains and removes the last element.| +| Accessing elements| forEach(callbackFn:(value: T, index?: number, deque?: Deque<T>) => void, thisArg?: Object) | Iterates over all elements in the Deque.| +| Accessing elements| \[Symbol.iterator]():IterableIterator<T> | Creates an iterator for data access.| +| Modifying elements| forEach(callbackFn:(value: T, index?: number, deque?: Deque<T>)=> void, thisArg?: Object) | Modifies all elements in the Deque through iteration.| +| Removing elements| popFirst() | Removes and returns the first element.| +| Removing elements| popLast() | Removes and returns the last element.| ## Queue -[Queue](../reference/apis-arkts/js-apis-queue.md) can be used to construct a queue that follows the FIFO principle. +[Queue](../reference/apis-arkts/js-apis-queue.md) is used to construct a queue that follows the FIFO principle. -**Queue** uses generics and must be stored in a contiguous memory space. Its initial capacity is 8, and it has capacity doubled in each dynamic expansion. +Defined by generics, Queue requires a contiguous block of memory for storage, with an initial capacity of 8 and supports dynamic resizing, doubling its size each time. -The bottom layer of **Queue** is implemented by cyclic queues, delivering a high efficiency in enqueuing and dequeuing. +Queue is implemented using a circular queue, ensuring efficient enqueue and dequeue operations. -Unlike [Deque](../reference/apis-arkts/js-apis-deque.md), which supports insertion and removal at both the ends, **Queue** supports insertion at one end and removal at the other. +Unlike [Deque](../reference/apis-arkts/js-apis-deque.md), which supports insertion and removal at both the ends, Queue supports insertion at one end and removal at the other. -You are advised to use **Queue** in FIFO scenarios. +Queue is suitable for FIFO scenarios. -**Queue** provides the following CRUD APIs. +Common APIs for adding, removing, modifying, and accessing elements in Queue are as follows: | Operation| API| Description| | --------- | ------- | ------- | -| Create| add(element: T) | Adds an element to the end.| -| Read| getFirst() | Obtains the head element of a queue and does not dequeue the element.| -| Read| pop() | Obtains the head element and dequeues it.| -| Read| forEach(callbackFn: (value: T, index?: number, queue?: Queue<T>) => void,thisArg?: Object) | Traverses and accesses the elements of the entire queue container.| -| Read| \[Symbol.iterator]():IterableIterator<T> | Creates an iterator for data access.| -| Update| forEach(callbackFn: (value: T, index?: number, queue?: Queue<T>) => void,thisArg?: Object) | Modify the elements of the entire queue container through traversal.| -| Delete| pop() | Dequeues and deletes the head element.| +| Adding elements| add(element: T) | Adds an element to the end of the Queue.| +| Accessing elements| getFirst() | Obtains the first element without dequeuing.| +| Accessing elements| pop() | Obtains and removes the first element.| +| Accessing elements| forEach(callbackFn: (value: T, index?: number, queue?: Queue<T>) => void,thisArg?: Object) | Iterates over all elements in the Queue.| +| Accessing elements| \[Symbol.iterator]():IterableIterator<T> | Creates an iterator for data access.| +| Modifying elements| forEach(callbackFn: (value: T, index?: number, queue?: Queue<T>) => void,thisArg?: Object) | Modifies all elements in the Queue through iteration.| +| Removing elements| pop() | Removes and returns the first element.| ## Stack -[Stack](../reference/apis-arkts/js-apis-stack.md) can be used to construct a stack that follows the Last Out First In (LOFI) principle. +[Stack](../reference/apis-arkts/js-apis-stack.md) is used to construct a stack that follows the Last Out First In (LOFI) principle. -**Stack** uses generics and must be stored in a contiguous memory space. Its initial capacity is 8, and it increases capacity 1.5-fold in each dynamic expansion. The bottom layer of **Stack** is implemented based on arrays. It supports data insertion and removal at one end. +Defined by generics, Stack requires a contiguous block of memory for storage, with an initial capacity of 8 and supports dynamic resizing, increasing its size by 1.5 times the original capacity each time. Stack is implemented using an array, with all operations performed at one end. -Unlike [Queue](../reference/apis-arkts/js-apis-queue.md), which supports insertion at one end and removal at the other, **Stack** supports insertion and removal at the same end. +Unlike [Queue](../reference/apis-arkts/js-apis-queue.md), which is implemented using a circular queue and allows insertion at one end and removal at the other, Stack supports insertion and removal at one end. -You are advised to use **Stack** in LOFI scenarios. +Stack is suitable for LOFI scenarios. -**Stack** provides the following CRUD APIs. +Common APIs for adding, removing, modifying, and accessing elements in Stack are as follows: | Operation| API| Description| | --------- | ------- | ------- | -| Create| push(item: T) | Adds an element to the top of the stack.| -| Read| peek() | Obtains the top element of the stack and does not dequeue the element.| -| Read| pop() | Obtains the top element of the stack and dequeues it.| -| Read| locate(element: T) | Obtains the position of an element.| -| Read| forEach(callbackFn: (value: T, index?: number, stack?: Stack<T>) => void, thisArg?: Object) | Traverses and accesses the elements of the entire stack container.| -| Read| \[Symbol.iterator]():IterableIterator<T> | Creates an iterator for data access.| -| Update| forEach(callbackFn: (value: T, index?: number, stack?: Stack<T>) => void, thisArg?: Object) | Modify the elements of the entire stack container through traversal.| -| Delete| pop() | Dequeues and deletes the top element from the stack.| +| Adding elements| push(item: T) | Adds an element to the top of the Stack.| +| Accessing elements| peek() | Obtains the top element of the Stack without dequeuing.| +| Accessing elements| pop() | Obtains and removes the top element of the Stack.| +| Accessing elements| locate(element: T) | Obtains the position of an element.| +| Accessing elements| forEach(callbackFn: (value: T, index?: number, stack?: Stack<T>) => void, thisArg?: Object) | Iterates over all elements in the Stack.| +| Accessing elements| \[Symbol.iterator]():IterableIterator<T> | Creates an iterator for data access.| +| Modifying elements| forEach(callbackFn: (value: T, index?: number, stack?: Stack<T>) => void, thisArg?: Object) | Modifies all elements in the Stack through iteration.| +| Removing elements| pop() | Removes and returns the top element.| ## Vector > **NOTE** > -> The APIs provided by **Vector** are deprecated since API version 9. You are advised to use [ArrayList](../reference/apis-arkts/js-apis-arraylist.md). +> Since API version 9, this API is no longer maintained. Use [ArrayList](../reference/apis-arkts/js-apis-arraylist.md) instead. -[Vector](../reference/apis-arkts/js-apis-vector.md) is a continuous storage structure that can be used to construct a global array object. **Vector** uses generics and must be stored in a contiguous memory space. Its initial capacity is 10, and it has capacity doubled in each dynamic expansion. +[Vector](../reference/apis-arkts/js-apis-vector.md) is a continuous storage structure used to construct a global array object. Defined by generics, Vector requires a contiguous block of memory for storage, with an initial capacity of 10 and supports dynamic resizing, doubling its size each time. -Both **Vector** and [ArrayList](../reference/apis-arkts/js-apis-arraylist.md) are implemented based on arrays, but **Vector** provides more interfaces for operating the arrays. In addition to operator access, **Vector** provides the getter and setter to provide a more complete verification and error tolerance mechanism. +Vector, like [ArrayList](../reference/apis-arkts/js-apis-arraylist.md), is based on arrays but provides more array manipulation interfaces. In addition to operator access, Vector provides the getter and setter to provide more comprehensive verification and error tolerance mechanisms. -**Vector** provides the following CRUD APIs. +Common APIs for adding, removing, modifying, and accessing elements in Vector are as follows: | Operation| API| Description| | --------- | ------- | ------- | -| Create| add(element: T) | // Add an item to the end of the data.| -| Create| insert(element: T, index: number) | * Inserts a value to a specified index.| -| Read| get(index: number) | Obtains the element corresponding to the specified index.| -| Read| vec\[index: number] | Obtains the element corresponding to the specified index position. The access speed is ensured by obtaining the element by using instructions.| -| Read| getFirst() | Obtains the first element.| -| Read| getLastElement() | Obtaining the last element| -| Read| getIndexOf(element: T) | Obtains the position of the first element that matches the specified element.| -| Read| getLastIndexOf(element: T) | Obtains the position of the last element that matches the specified element.| -| Read| forEach(callbackFn: (value: T, index?: number, Vector?: Vector<T>) => void, thisArg?: Object) | Traverses the elements of the entire Vector container.| -| Read| \[Symbol.iterator]():IterableIterator<T> | Creates an iterator for data access.| -| Update| set(index:number, element: T) | Changes the value of an element with a specified index to element.| -| Update| vec\[index] = element | Changes the value of an element with a specified index to element.| -| Update| replaceAllElements(callbackFn:(value: T,index?: number,list?: List<T>)=>T,thisArg?: Object) | Replaces elements in a vector one by one.| -| Update| setLength(newSize:number) | Sets the vector length.| -| Delete| remove(element: T) | Deletes the first matched element.| -| Delete| removeByIndex(index:number) | Deletes the element corresponding to the index position.| -| Delete| removeByRange(fromIndex:number,toIndex:number) | Removes elements in a specified range from this container.| +| Adding elements| add(element: T) | Adds an element to the end of the array.| +| Adding elements| insert(element: T, index: number) | Inserts an element at the specified index.| +| Accessing elements| get(index: number) | Obtains the element at the specified index.| +| Accessing elements| vec\[index: number] | Obtains the element at the specified index, ensuring fast access.| +| Accessing elements| getFirst() | Obtains the first element.| +| Accessing elements| getLastElement() | Obtains the last element.| +| Accessing elements| getIndexOf(element: T) | Obtains the index of the first matching element.| +| Accessing elements| getLastIndexOf(element: T) | Obtains the index of the last matching element.| +| Accessing elements| forEach(callbackFn: (value: T, index?: number, Vector?: Vector<T>) => void, thisArg?: Object) | Iterates over all elements in the Vector.| +| Accessing elements| \[Symbol.iterator]():IterableIterator<T> | Creates an iterator for data access.| +| Modifying elements| set(index:number, element: T) | Modifies the element at the specified index.| +| Modifying elements| vec\[index] = element | Modifies the element at the specified index.| +| Modifying elements| replaceAllElements(callbackFn:(value: T,index?: number,list?: List<T>)=>T,thisArg?: Object) | Replaces all elements in the Vector.| +| Modifying elements| setLength(newSize:number) | Sets the length of the Vector.| +| Removing elements| remove(element: T) | Removes the first matching element.| +| Removing elements| removeByIndex(index:number) | Removes the element at the specified index.| +| Removing elements| removeByRange(fromIndex:number,toIndex:number) | Removes elements within the specified range.| ## Use of Linear Containers -Refer to the code snippet below to add, access, and modify elements in **ArrayList**, **Deque**, **Stack**, and **List**. +This section provides usage examples for common linear containers, including ArrayList, Deque, Stack, and List, covering importing modules, adding elements, accessing elements, and modifying elements. The example code is as follows: ```ts @@ -211,45 +211,45 @@ Refer to the code snippet below to add, access, and modify elements in **ArrayLi import { ArrayList } from '@kit.ArkTS'; // Import the ArrayList module. let arrayList1: ArrayList = new ArrayList(); -arrayList1.add ('a'); // Add an element whose value is'a'. +arrayList1.add('a'); // Add an element with the value 'a'. let arrayList2: ArrayList = new ArrayList(); -arrayList2.add (1); // Add an element whose value is 1. -console.info ('result: ${arrayList2[0]}'); // Access the element whose index is 0. Output: result: 1 -arrayList1[0] = 'one'; // Modify the element whose index is 0. -console.info ('result: ${arrayList1[0]}'); // Output: result: one +arrayList2.add(1); // Add an element with the value 1. +console.info(`result: ${arrayList2[0]}`); // Access the element at index 0. Output: result: 1 +arrayList1[0] = 'one'; // Modify the element at index 0. +console.info(`result: ${arrayList1[0]}`); // Output: result: one // Deque import { Deque } from '@kit.ArkTS'; // Import the Deque module. let deque1: Deque = new Deque(); -deque1.insertFront ('a'); // Add an element whose value is'a' to the header. +deque1.insertFront('a'); // Add an element with the value 'a' to the header. let deque2: Deque = new Deque(); -deque2.insertFront (1); // Add an element whose value is 1 to the header. -console.info ('result: ${deque2.getFirst () }'); // Access the element in the queue header. Output: result: 1 -deque1.insertEnd ('one'); // Add an element whose value is'one' to the end. -console.info ('result: ${deque1.getLast () }'); // Access the element at the end of the queue. Output: result: one +deque2.insertFront(1); // Add an element with the value 1 to the header. +console.info(`result: ${deque2.getFirst()}`); // Access the first element. Output: result: 1 +deque1.insertEnd('one'); // Add an element with the value 'one'. +console.info(`result: ${deque1.getLast()}`); // Access the last element. Output: result: one // Stack import { Stack } from '@kit.ArkTS'; // Import the Stack module. let stack1: Stack = new Stack(); -stack1.push ('a'); // Add an element whose value is'a' to the stack. +stack1.push('a'); // Add an element with the value 'a' to the Stack. let stack2: Stack = new Stack(); -stack2.push (1); // Add an element whose value is 1 to the stack. -console.info ('result: ${stack1.peek () }'); // Access the top element of the stack. Output: result: a -console.info ('result: ${stack2.pop () }'); // Delete the top element of the stack and return the deleted element. Output: result: 1 -console.info ('result: ${stack2.length}'); // Output: result: 0 +stack2.push(1); // Add an element with the value 1 to the Stack. +console.info(`result: ${stack1.peek()}`); // Access the top element of the Stack. Output: result: a +console.info(`result: ${stack2.pop()}`); // Remove and return the top element. Output: result: 1 +console.info(`result: ${stack2.length}`); // Output: result: 0 // List import { List } from '@kit.ArkTS'; // Import the List module. let list1: List = new List(); -list1.add ('a'); // Add an element whose value is'a'. +list1.add('a'); // Add an element with the value 'a'. let list2: List = new List(); -list2.insert (0, 0); // Insert (add) an element whose value is 0 at position 0. +list2.insert(0, 0); // Insert an element with the value 0 at index 0. let list3: List> = new List(); let b2 = [1, 2, 3]; -list3.add (b2); // Add an element of the Array type. -console.info ('result: ${list1[0]}'); // Access the element whose index is 0. Output: result: a -console.info ('result: ${list3.get (0) }'); // Access the element whose index is 0. Output: result: 1,2,3 +list3.add(b2); // Add an element of the Array type. +console.info(`result: ${list1[0]}`); // Access the element at index 0. Output: result: a +console.info(`result: ${list3.get(0)}`); // Access the element at index 0. Output: result: 1,2,3 ``` diff --git a/en/application-dev/arkts-utils/load-module-base-nodeapi.md b/en/application-dev/arkts-utils/load-module-base-nodeapi.md index 88d8ba30820677bc1548d234fccd3276548e3afd..bc39ec5f5b056dbb15299f683232855221551e41 100644 --- a/en/application-dev/arkts-utils/load-module-base-nodeapi.md +++ b/en/application-dev/arkts-utils/load-module-base-nodeapi.md @@ -1,3 +1,3 @@ # Loading Modules Using Node-API -The [napi_load_module](../napi/use-napi-load-module.md) interface in the Node-API is used to load modules in the current HAP/HSP package project in the host thread. The usage scenarios are limited, but the parameter transfer is simple. The [napi_load_module_with_info](../napi/use-napi-load-module-with-info.md) can be used to load multiple file types, such as the HAR package, cross-HSP package, and native module, in the host thread or subthread. However, the information about the loaded package needs to be marked when the [napi_load_module_with_info](../napi/use-napi-load-module-with-info.md) is used. +The [napi_load_module](../napi/use-napi-load-module.md) function in Node-API is used to load modules within the current HAP/HSP package project from the host thread. Although its usage scenarios are somewhat restricted, it features a straightforward parameter structure. In contrast, the [napi_load_module_with_info](../napi/use-napi-load-module-with-info.md) function supports loading of multiple file types, including HAR packages, HSP packages, and native modules, from both the host thread and child threads. This interface provides more extensive capabilities but requires marking the information of the loaded package during usage. diff --git a/en/application-dev/arkts-utils/long-time-task-guide.md b/en/application-dev/arkts-utils/long-time-task-guide.md index d90205509717a292aee6dcfb6d7afe2442744486..9f03f1a2aab813f90c7f248121662b27c38b290c 100644 --- a/en/application-dev/arkts-utils/long-time-task-guide.md +++ b/en/application-dev/arkts-utils/long-time-task-guide.md @@ -1,8 +1,8 @@ # Continuous Task Development (TaskPool) -This section describes how to use TaskPool to develop a continuous task. The following uses periodic sensor data collection as an example. +This section provides a development guide for continuous tasks using TaskPool, with the example of periodically collecting sensor data. -## Using TaskPool to Listen to Sensor Data +## Using TaskPool to Listen for Sensor Data 1. Import the required modules. @@ -13,7 +13,7 @@ This section describes how to use TaskPool to develop a continuous task. The fol import { BusinessError, emitter } from '@kit.BasicServicesKit'; ``` -2. Defines a long-term task, listens to sensor data internally, and registers a destruction notification through the emitter. +2. Define a continuous task to listen for sensor data internally and register a destruction notification via emitter. ```ts // Index.ets @@ -30,9 +30,9 @@ This section describes how to use TaskPool to develop a continuous task. The fol } ``` -3. The host thread defines the registration and destruction behavior. - - Registration: Initiate a long-term task and receive listening data through the emitter. - - Destroy: Sends the event for canceling the sensor listening and ends the continuous task. +3. Define the registration and destruction behavior in the host thread. + - Registration: Initiate the continuous task and receive listening data via emitter. + - Destruction: Send an event to cancel sensor listening and terminate the continuous task. ```ts // Index.ets diff --git a/en/application-dev/arkts-utils/long-time-task-overview.md b/en/application-dev/arkts-utils/long-time-task-overview.md index 508894b19c95ff719b53f9dcf2bdeeab54fca0d6..b1654cc8d131539c4957e0d13032ffa75bd3a459 100644 --- a/en/application-dev/arkts-utils/long-time-task-overview.md +++ b/en/application-dev/arkts-utils/long-time-task-overview.md @@ -1,13 +1,13 @@ -# Concurrent Continuous Task Scenarios +# Overview of Concurrency in Continuous Tasks -During the implementation of application services, tasks that need to run for a long time and irregularly are called long-term tasks. If a long-duration task is executed in the UI main thread, the UI service of the UI main thread is blocked, and problems such as frame freezing and frame loss occur, affecting user experience. You can execute the independent continuous task in an independent child thread. +During the implementation of application services, tasks that require extended and irregular execution periods are known as continuous tasks. Executing continuous tasks in the UI main thread may block the thread's normal operations, leading to performance issues such as freezing and frame loss, which degrade user experience. To avoid this, these independent tasks are typically run in separate background threads. -Typical scenarios of continuous tasks are as follows. +The following describes typical service scenarios for continuous tasks. -| Common Service Scenario| Description| +| Service Scenario| Description| | -------- | -------- | -| Periodically collects sensor data.| Periodically collects sensor information (such as location information and speed sensor information), and runs continuously for a long time during application running.| -| Listening to Socket Port Information| Listens for socket data for a long time and responds irregularly.| +| Periodic sensor data collection| Regularly collecting data of sensors (such as location and speed) that run continuously throughout the application's operation without interruption.| +| Listening for socket port information| Continuously monitoring socket data and responding to it at irregular intervals.| -The preceding table lists independent continuous tasks with long task execution period and simple interaction with external systems. After these tasks are distributed to the background thread, you need to respond irregularly to obtain results. Therefore, using **TaskPool** can reduce development workload, and avoid complex lifecycle management and too many threads. You only need to place the preceding independent continuous tasks in the **TaskPool** queue and wait for the result. +These scenarios involve independent continuous tasks with extended execution periods and minimal external interaction. Once dispatched to background threads, these tasks need to respond periodically to retrieve results. Therefore, using TaskPool can streamline development efforts by eliminating the need to manage complex lifecycles and prevent thread overload. You simply need to enqueue these independent continuous tasks into a task pool and wait for the results. diff --git a/en/application-dev/arkts-utils/makeobserved-sendable.md b/en/application-dev/arkts-utils/makeobserved-sendable.md index b8911534cf26c97a9a59dd69974235edd497cff6..4c9f3f8ff3b6386f6a81cd011cb6902ea200b6cf 100644 --- a/en/application-dev/arkts-utils/makeobserved-sendable.md +++ b/en/application-dev/arkts-utils/makeobserved-sendable.md @@ -1,12 +1,12 @@ # ArkUI Data Updates -When data downloaded from the Internet or generated locally needs to be sent to the UI thread for display, the ArkUI annotation and [\@Sendable decorator](../arkts-utils/arkts-sendable.md#sendable-decorator) cannot modify variables and objects at the same time, in this scenario, you need to use [makeObserved](../quick-start/arkts-new-makeObserved.md) to import the observable Sendable shared data to ArkUI. +When data, regardless of whether it is downloaded from the Internet or generated locally, needs to be sent to the UI thread for display, the annotations and the [\@Sendable decorator](../arkts-utils/arkts-sendable.md#sendable-decorator) in ArkUI cannot simultaneously decorate variables and objects. Therefore, for such scenarios, it is necessary to use [makeObserved](../quick-start/arkts-new-makeObserved.md) to import observable Sendable data into ArkUI. This example describes the following scenarios: -- **makeObserved** has the observation capability after data of the @Sendable type is passed in, and the change of the data can trigger UI re-rendering. -- Obtain an entire data from the subthread and replace the entire observable data of the UI thread. -- Re-execute **makeObserved** from the data obtained from the subthread to change the data to observable data. -- When data is passed from the main thread to a subthread, only unobservable data is passed. The return value of **makeObserved** cannot be directly passed to a subthread. +- When **makeObserved** is used with @Sendable data, it enables observability of changes that can trigger UI refreshes. +- A complete set of data is fetched from a child thread and used to replace the observable data in the UI thread entirely. +- The data fetched from the child thread is reprocessed with **makeObserved** to become observable. +- Only non-observable data is passed from the UI main thread back to the child thread. The return value of **makeObserved** is not directly passed to child threads. ```ts // SendableData.ets @@ -27,7 +27,7 @@ import { UIUtils } from '@kit.ArkUI'; @Concurrent function threadGetData(param: string): SendableData { - // Process data in the subthread. + // Process data in the child thread. let ret = new SendableData(); console.info(`Concurrent threadGetData, param ${param}`); ret.name = param + "-o"; @@ -39,23 +39,23 @@ function threadGetData(param: string): SendableData { @Entry @ComponentV2 struct Index { - // Use makeObserved to add the observation capability to a common object or a @Sendable decorated object. + // Use makeObserved to add observation to a regular object or a @Sendable object. @Local send: SendableData = UIUtils.makeObserved(new SendableData()); build() { Column() { Text(this.send.name) Button("change name").onClick(() => { - // Change of the attribute can be observed. + // Changes to properties are observable. this.send.name += "0"; }) Button("task").onClick(() => { - // Places a function to be executed in the internal queue of the task pool. The function will be distributed to the worker thread for execution. - **NOTE**
Data can be constructed and processed in subthreads. However, observable data can be processded only in the main thread. - // Therefore, only the'name' attribute of'this.send' is transferred to the subthread. + // Enqueue the function to be executed in the task pool, waiting to be dispatched to a worker thread. + // Data construction and processing can be done in the child thread, but observable data cannot be passed to the child thread (observable data can only be manipulated in the UI main thread). + // Therefore, only the 'name' property of 'this.send' is passed to the child thread. taskpool.execute(threadGetData, this.send.name).then(val => { - // Used together with @Local to observe the change of this.send. + // Used together with @Local to observe changes to 'this.send'. this.send = UIUtils.makeObserved(val as SendableData); }) }) diff --git a/en/application-dev/arkts-utils/module-principle.md b/en/application-dev/arkts-utils/module-principle.md index 406f5b9fba984fc1ddbec4900771cbe4bccec2a1..7a175177ef08bc7bbaefca5bb9c1bcd1430e31ae 100644 --- a/en/application-dev/arkts-utils/module-principle.md +++ b/en/application-dev/arkts-utils/module-principle.md @@ -1,67 +1,67 @@ -# Introduction to Modular Operation +# Overview of Modular Operation -During the development of large-scale and complex applications, some code is copied for multiple times during compilation. As a result, the package size increases, file dependency, code and resource sharing is difficult, and singleton and global variable pollution occurs. In addition, ArkTS supports modular compilation, packaging, and running of applications to facilitate code compilation and function maintenance. +To address challenges of large and complex application development—such as increased package size due to multiple copies of code during compilation, file dependencies, difficulties in sharing code and resources, and pollution of singletons and global variables—ArkTS supports modular compilation, packaging, and running. This approach not only streamlines the development process but also facilitates easier code writing and feature maintenance. -Modularization refers to the process of splitting ArkTS/TS/JS into multiple modules (files or fragments) and loading, parsing, combining, and executing these modules using compilation tools or runtime mechanisms. +Modularization refers to the process of splitting ArkTS/TS/JS into multiple modules (files or fragments) and then [loading](#loading-process-of-modular-operation), parsing, combining, and executing these modules using compilation tools or runtime mechanisms. -ArtTS supports ETS/TS/JS files, JSON files, and native modules. ArkTS supports [ECMAScript module specifications](#ecmascript-module) and [CommonJS module specifications](#commonjs-module). In addition, ArkTS extends the loading modes, including dynamic loading (arkts-dynamic-import.md), delayed loading (arkts-lazy-import.md), and synchronous dynamic loading of native modules (js-apis-load-native-module.md). [Node-API interface loading file](load-module-base-nodeapi.md) +ArkTS supports various module types, including ETS/TS/JS files, JSON files, and native modules. It adheres to both [ECMAScript module specifications](#ecmascript-module) and [CommonJS module specifications](#commonjs-module). In addition, ArkTS extends loading modes to include [dynamic import](arkts-dynamic-import.md), [lazy import](arkts-lazy-import.md), [synchronous dynamic loading of native modules](js-apis-load-native-module.md), and [loading files using Node-API](load-module-base-nodeapi.md). ## Loading Process of Modular Operation -ArkTS modular runs are implemented according to the ECMA specification, and modules are executed in a later sequential traversal manner: starting from the leftmost subtree of the module diagram, executing the modules, then executing their peers, and then executing their parent. This algorithm runs recursively until it reaches the root of the module graph. +ArkTS modular operation is implemented according to the ECMA specification and executes modules using a post-order traversal method: starting from the leftmost subtree of the module graph, it executes the modules, then their peers, and finally their parents. This algorithm runs recursively until it reaches the root of the module graph. -As shown in the following figure, each parent node loads the corresponding child nodes and executes the child nodes at the same level based on the import sequence in the code. The following module diagram files are executed in the sequence of D->F->G->E->B->I->H->C->A. +For example, in the figure below, each parent node loads its corresponding child nodes and executes peers in the order specified by the **import** statements in the code. The execution order for the module graph files is as follows: D->F->G->E->B->I->H->C->A. ![image_0000002043487154](figures/image_0000002043487154.png) -The file A is referred to as an entry file, that is, the file is an execution start point. Some built-in loading interfaces, such as [windowStage.loadContent](../reference/apis-arkui/js-apis-window.md#loadcontent9) and [Navigation](../ui/arkts-navigation-navigation.md), are used to start pages (that is, files that are not started by using the import method). The input parameter file is executed as the entry file. +Here, file A is referred to as the entry file, which is the starting point for execution. Certain built-in interfaces for loading content, such as [windowStage.loadContent](../reference/apis-arkui/js-apis-window.md#loadcontent9) and [Navigation](../ui/arkts-navigation-navigation.md), will also be executed as entry files, especially when these files are not loaded using the **import** syntax. -File A is used as the entry to load a complete set of files, including file A, files on which file A depends, and files on which file A depends until each branch leaf node. +Starting from file A, a complete set of files will be loaded, including file A, files on which file A depends, and subsequently dependent files, until the leaf nodes of each branch is reached. ## Modular Specifications Supported by ArkTS ### ECMAScript Module -The ECMAScript module (ES Module) is a module function implemented by JavaScript from the standard level (ECMAScript® 2025 Language Specification (tc39.es)) since ECMAScript6.0. The module function consists of two commands: export and import. +ECMAScript modules (ES modules) are a module feature implemented in JavaScript starting from ECMAScript 6.0, standardized in the ECMAScript® 2025 Language Specification (tc39.es). The module functionality is composed of two commands: **export** and **import**. -For details about how to use export and import in ArkTS, see [ArkTS Introduction](../quick-start/introduction-to-arkts.md#module). +For details about how to use **export** and **import** in ArkTS, see [ArkTS Introduction](../quick-start/introduction-to-arkts.md#modules). ### CommonJS Module -The CommonJS module is a standard proposed by the JavaScript community in 2009. Some standards are first adopted and implemented in Node.js. The CommonJS considers each file as a module and uses the module variable to represent the current module. The module.exports variable is the variable exported by the module. Each module has the exports variable (exports = = = module.exports). +CommonJS modules were proposed as a standard by the JavaScript community in 2009 and first partially adopted and implemented in Node.js. CommonJS treats each file as a module, with the **module** variable representing the current module. **module.exports** is the variable exported by the module, and each module also has an **exports** variable (exports === module.exports). -The following table lists the import and export methods. +The following table lists the import and export syntax. -| Loading Type| Module import| Module export (module.exports and exports cannot be used together.)| +| Loading Type| Module Import| Module Export (Do Not Mix module.exports with exports)| | -------- | -------- | -------- | -| Name| const ohos = require('ohos') | exports.add = add
module.exports.name = name | -| const ohos = require('ohos') | module.exports = add | -| Functions| const ohos = require('ohos')
ohos.fun(); | exports.fun = function foo () {}
module.exports.fun = function foo () {} | +| Variable| const ohos = require('ohos') | exports.add = add
module.exports.name = name | +| Variable| const ohos = require('ohos') | module.exports = add | +| Function| const ohos = require('ohos')
ohos.fun(); | exports.fun = function foo () {}
module.exports.fun = function foo () {} | -> **Note** +> **NOTE** > -> The CommonJS module applies only to third-party package export and cannot be created or used by developers in projects. +> CommonJS modules can be used only to export third-party packages. They cannot be created or used in projects. -### Specifications Supported by CommonJS and ES Modules +### Compatibility Between CommonJS and ES Modules -The following table lists the specifications for mutual reference between CommonJS and ES Module. The import and export syntax complies with the specifications of each module. -| Mutual reference relationship| ES Module Export| CommonJS export| +The following table lists the compatibility between CommonJS and ES modules, with the import and export syntax following their respective specifications: +| Inter-Module Reference| ES Module Export| CommonJS Export| | -------- | -------- | -------- | -| ES Module Import| Yes.| Yes.| -| Importing CommonJS| Not supported| Yes| +| ES Module Import| Supported| Supported| +| CommonJS Import| Not supported| Supported| -## Types of Modules That Can Be Loaded by ArkTS +## Module Types Supported by ArkTS -### ets/ts/js +### ETS/TS/JS -The loading of the ETS, TS, and JS modules complies with [ECMAScript](#ecmascript-module) and [CommonJS](#commonjs-module) module specifications. +Loading of the ETS, TS, and JS modules complies with the [ECMAScript module specifications](#ecmascript-module) and [CommonJS module specifications](#commonjs-module). ### JSON File -JavaScript Object Notation (JSON) is a lightweight data interaction format that uses a text format that is completely independent of programming languages to store and represent data. +JavaScript Object Notation (JSON) is a lightweight data interchange format that uses a text-based format independent of any programming language to store and represent data. -The JSON file can be imported only in default mode, as shown in the following: +JSON files can only be imported using the **default** method, as shown below: ``` import data from './example.json' @@ -69,11 +69,11 @@ import data from './example.json' ### Native Module -The syntax specifications for importing and exporting the native module (.so) are the same as those for loading the ETS, TS, and JS files. +The syntax specifications for importing and exporting the native module (.so) are the same as those for loading the ETS, TS, and JS files. Native modules (.so files) follow the same import/export and loading syntax as ETS/TS/JS modules. For details, see [Statically Loading Native Modules](./arkts-import-native-module.md). -> **Note** +> **NOTE** > -> The Native module cannot be imported to the CommonJS module. +> Native modules cannot be imported to CommonJS modules. Example: @@ -88,23 +88,23 @@ import { add } from 'libentry.so' add(2, 3) ``` -ArkTS does not support namespaces for both native module export and import. +Currently, ArkTS does not support namespaces for native module exports or imports. -Non-compliant code example: +Anti-example: ``` // test1.ets -export * from'libentry.so' // Use the namespace to export data. +export * from 'libentry.so' // Use the namespace to export data. ``` ``` // test2.ets import('./test1').then((ns:ESObject) => { - // The ns object cannot be obtained during dynamic loading. - // If you want to use this method to load the Native module, change the export mode in test1.ets to named export or default export. + // The ns object cannot be obtained during dynamic import. + // To use this method to load native modules, change the export in test1.ets to named or default export. }) ``` -> **Note** +> **NOTE** > -> You are not advised to import data in import \* as xxx from 'xxx' mode. This import mode will cause runtime exceptions. You are advised to use the default import mode. +> You are not advised to import data using import \* as xxx from 'xxx'. This import mode will cause runtime exceptions. Default imports are recommended. diff --git a/en/application-dev/arkts-utils/multi-thread-concurrency-overview.md b/en/application-dev/arkts-utils/multi-thread-concurrency-overview.md index a1d48c134fbb512251743e506e52fe2172667a18..739719446a6a2cecc99be8e2e1bba7a559f22727 100644 --- a/en/application-dev/arkts-utils/multi-thread-concurrency-overview.md +++ b/en/application-dev/arkts-utils/multi-thread-concurrency-overview.md @@ -1,35 +1,35 @@ -# Multithreaded Concurrency Overview +# Overview of Multithreaded Concurrency -Concurrency models are used to implement concurrent tasks in different scenarios. Common concurrency models are classified into shared memory models and message passing models. +Concurrency models are programming paradigms designed to implement concurrent tasks in various scenarios. Common concurrency models include those based on shared memory and those based on message passing. -A typical message passing model is actor. It supports high-scale concurrency while eliminating a series of complex and occasional issues caused by locks. +The actor model, as a typical example of a message-passing concurrency model, eliminates the need for you to deal with the complex and sporadic issues associated with locks. It also offers relatively high concurrency, which has led to its widespread adoption and use. Currently, ArkTS provides two concurrency capabilities: TaskPool and Worker, both of which are implemented based on the actor model. -For details about the comparison between the Actor concurrency model and the memory sharing concurrency model, see [Multithreaded Concurrency Model](#multithreaded concurrency model). +For details about the comparison between the actor model and the shared memory concurrency model, see [Multithreaded Concurrency Models](#multithreaded-concurrency-models). -## Multithreaded Concurrency Model +## Multithreaded Concurrency Models -In the memory sharing model, multiple threads execute complex tasks simultaneously. These threads depend on the same memory and have the permission to access the memory. Before accessing the memory, a thread must preempt and lock the memory. In this case, other threads have to wait for the thread to release the memory. +Shared memory concurrency model: In this model, multiple threads execute tasks simultaneously. These threads rely on the same memory and have access permissions. Before accessing memory, threads must compete for and lock the memory's usage rights. Threads that fail to acquire the lock must wait for other threads to release the lock before proceeding. -In the actor model, each thread is an independent actor, which has its own memory. Actors trigger the behavior of each other through message transfer. They cannot directly access the memory space of each other. +Actor model: In this model, each thread is an independent actor, which has its own memory. Actors trigger the behavior of each other through message transfer. They cannot directly access the memory space of each other. -Different from the memory sharing model, the actor model provides independent memory space for each thread. As such, it avoids memory preemption and resulting function and performance problems. +Different from the shared memory concurrency model, the actor model provides independent memory space for each thread. As such, it avoids memory preemption and resulting functional and performance issues. In the actor model, concurrent tasks and task results are transmitted through the inter-thread communication. -This topic describes the differences between the two models when solving the producer-consumer problem. +This topic uses the classic producer-consumer problem as an example to illustrate the differences between these two models in solving specific problems. -### Memory Sharing Model +### Shared Memory Model -The following figure shows how the producer-consumer problem is resolved in the memory sharing model. +The following figure illustrates how to solve the producer-consumer issue using the shared memory model. ![image_0000002001497485](figures/image_0000002001497485.png) -To prevent dirty reads and writes caused by simultaneous access, only one producer or consumer can access a shared memory container at a time. This means that producers and consumers need to compete for the lock of the container. After a role obtains the lock, other roles have to wait. +To prevent problems like dirty reads and writes caused by simultaneous access, only one producer or consumer can access a shared memory container at any given moment. This means that producers and consumers need to compete for the lock of the container. Once a role secures the lock, others must wait until the lock is released before they can attempt to access the container. ```ts -// The pseudocode is used only as a logic example to help developers understand the differences between the memory sharing model and the Actor model. +// The pseudocode is used here to help you understand the differences between the shared memory model and the actor model. class Queue { // ... push(value: number) {} @@ -82,7 +82,7 @@ class BufferQueue { } } -// Construct a globally shared memory segment. +// Construct a globally shared memory buffer. let g_bufferQueue = new BufferQueue() class Producer { @@ -90,7 +90,7 @@ class Producer { } run() { let value = Math.random() - // Initiate cross-thread access to the bufferQueue object. + // Access to the bufferQueue object across threads. g_bufferQueue.add(value) } } @@ -99,11 +99,11 @@ class ConsumerTest { constructor() { } run() { - // Initiate cross-thread access to the bufferQueue object. + // Access to the bufferQueue object across threads. let num = 123; let res = g_bufferQueue.take(num) if (res != null) { - // Add consumption logic. + // Add consumption logic here. } } } @@ -123,11 +123,11 @@ function Main(): void { ### Actor Model -The following figure shows how the producer-consumer problem is resolved by using **TaskPool** in the actor model. +The following figure demonstrates how to use the TaskPool concurrency capability based on the actor model to solve the producer-consumer issue. ![image_0000001964697544](figures/image_0000001964697544.png) -In the Actor model, different roles do not share memory. The producer thread and UI thread have their own VM instances. The two VM instances have exclusive memory and are isolated from each other. After producing the result, the producer sends the result to the UI thread through serialization. After consuming the result, the UI thread sends a new production task to the producer thread. +In the actor model, different roles operate independently without sharing memory. Each role, such as the producer thread and the UI thread, runs within its own virtual machine instance, each with its own exclusive memory space. After generating a result, the producer sends the result to the UI thread through serialization. The UI thread processes the result and then sends a new task to the producer thread. ```ts import { taskpool } from '@kit.ArkTS'; @@ -135,14 +135,14 @@ import { taskpool } from '@kit.ArkTS'; // Cross-thread concurrent tasks @Concurrent async function produce(): Promise { - // Add production logic. + // Add production logic here. console.info("producing..."); return Math.random(); } class Consumer { public consume(value: Object) { - // Add consumption logic. + // Add consumption logic here. console.info("consuming value: " + value); } } @@ -185,4 +185,4 @@ struct Index { ## TaskPool and Worker -For details about the operation mechanisms and precautions, see [TaskPool Introduction](taskpool-introduction.md) and [Worker Introduction](worker-introduction.md). For details about their differences in the implementation features and use cases, see [Comparison Between TaskPool and Worker](taskpool-vs-worker.md). +ArkTS provides two concurrency capabilities for you to choose from: TaskPool and Worker. For details about their operation mechanisms and precautions, see [TaskPool](taskpool-introduction.md) and [Worker](worker-introduction.md). For details about their differences in the implementation features and use cases, see [Comparison Between TaskPool and Worker](taskpool-vs-worker.md). diff --git a/en/application-dev/arkts-utils/multi-time-consuming-tasks.md b/en/application-dev/arkts-utils/multi-time-consuming-tasks.md index e3d15837b2c418911d66f1acc670b31051208edb..77b6f6960f04507c7d7ca8dcffd25772465e5a12 100644 --- a/en/application-dev/arkts-utils/multi-time-consuming-tasks.md +++ b/en/application-dev/arkts-utils/multi-time-consuming-tasks.md @@ -1,12 +1,12 @@ # Using TaskPool for Multiple Time-Consuming Tasks -If multiple tasks are executed simultaneously, their execution time and result return time vary according to the task complexity. If the main thread requires the execution results of all tasks, you can use the following code snippet: +When multiple tasks are executed concurrently, their execution times can vary due to differences in complexity, and the timing of their completion is unpredictable. If the host thread requires the results of all tasks after they are completed, you can use the approach described in this topic. -In addition, if a task needs to process a large amount of data (for example, a list contains 10,000 data records), it is time-consuming to process all the data in one task. In this case, you can split the data into multiple sublists, allocate one task for each sublist, and combine the results of all the tasks. This pattern reduces the processing time and improves user experience. +Additionally, if the volume of data to be processed is large (for example, a list with 10,000 items), processing all the data in a single task can be time-consuming. Instead, you can split the original data into multiple sublists and assign each sublist to an independent task. After all tasks are completed, you can combine the results into a complete dataset. This approach can reduce processing time and enhance user experience. -The following uses image loading of a plurality of tasks as an example for description. +This example uses image loading of multiple tasks to illustrate the process. -1. Implement the task to be executed by the sub-thread. +1. Implement the task to be executed in a child thread. ```ts // IconItemSource.ets @@ -25,14 +25,14 @@ The following uses image loading of a plurality of tasks as an example for descr // IndependentTask.ets import { IconItemSource } from './IconItemSource'; - @Concurrent // Methods executed in the task must be decorated by @Concurrent. Otherwise, they cannot be called. + // Methods executed in the task must be decorated by @Concurrent. Otherwise, they cannot be called. @Concurrent export function loadPicture(count: number): IconItemSource[] { let iconItemSourceList: IconItemSource[] = []; - // Traverse and add six IconItem data records. + // Add six IconItem data records. for (let index = 0; index < count; index++) { const numStart: number = index * 6; - // Six images are used cyclically. + // Use six images in the loop. iconItemSourceList.push(new IconItemSource('$media:startIcon', `item${numStart + 1}`)); iconItemSourceList.push(new IconItemSource('$media:background', `item${numStart + 2}`)); iconItemSourceList.push(new IconItemSource('$media:foreground', `item${numStart + 3}`)); @@ -45,7 +45,7 @@ The following uses image loading of a plurality of tasks as an example for descr } ``` -2. In this scenario, all the tasks to be executed are placed in a task group. After all the tasks in the task group are executed, the execution result of each task is placed in an array and returned to the main thread. The main thread can obtain all task execution results at a time. +2. Add the tasks to a task group and execute them collectively. When all the tasks in the task group finish executing, their results are placed in an array and sent back to the host thread. In this way, the host thread can access the combined results of all tasks at once, rather than receiving results individually as each task completes. ```ts // MultiTask.ets diff --git a/en/application-dev/arkts-utils/multithread-develop-overview.md b/en/application-dev/arkts-utils/multithread-develop-overview.md index 741a1bb5ca64230021f16c37ff94978560be8e8a..0eea8a9605926e0ac9e2192a6b04c1c2486aef8f 100644 --- a/en/application-dev/arkts-utils/multithread-develop-overview.md +++ b/en/application-dev/arkts-utils/multithread-develop-overview.md @@ -1,9 +1,15 @@ -# Multithreaded Development Overview +# Overview of Multithreaded Development -During ArkTS application development, the concurrency capability is required in many service scenarios. Different service scenarios require different concurrency capabilities and correspond to different task types. +During ArkTS application development, the concurrency capability is required in many service scenarios. Different service scenarios demand different types of concurrency and corresponding task types. -For common service scenarios, there are three types of concurrent tasks: [time-consuming task](time-consuming-task-overview.md), [continuous task](long-time-task-overview.md), and [resident task](resident-task-overview.md). +For common service scenarios, there are mainly three types of concurrent tasks: -Different types of tasks can be further divided. For example, typical time-consuming tasks include CPU-intensive tasks, I/O-intensive tasks, and synchronization tasks, which correspond to different typical service scenarios. Select the concurrency capability based on the scenario-based task type. +- [Time-consuming tasks](time-consuming-task-overview.md): These involve significant computation or multiple I/O operations and take a long time to execute. +- [Continuous tasks](long-time-task-overview.md): These include tasks like listening or periodically collecting data that need to run continuously over extended periods. -The following sections describe some common scenarios during multi-thread development of applications. +- [Resident tasks](resident-task-overview.md): These are bound to the lifecycle of the main thread or closely integrated with it. + + +Each task type can be further divided. For example, time-consuming tasks can be CPU intensive, I/O intensive, or synchronous, each corresponding to different service scenarios. You should select the appropriate concurrency capabilities based on the specific scenario and task type. + +In the following sections, we will explore some case studies for common scenarios encountered during multithreaded application development. diff --git a/en/application-dev/arkts-utils/native-interthread-shared.md b/en/application-dev/arkts-utils/native-interthread-shared.md index f0f26fa80d76a4f214eb221c6adb5fd1375a9ff6..a7cc480bdf84c55fc40ffdbdfd5eabb33ac24ac0 100644 --- a/en/application-dev/arkts-utils/native-interthread-shared.md +++ b/en/application-dev/arkts-utils/native-interthread-shared.md @@ -1,17 +1,17 @@ -# Data Sharing Between C++ Threads +# C++ Inter-Thread Data Sharing -When an application performs multi-thread concurrent computing at the C++ layer, the ArkTS API needs to be executed in the ArkTS environment. To prevent the non-UI main thread from waiting for the API calling result in the ArkTS environment, you need to create an ArkTS execution environment and directly call APIs on these C++ threads. In addition, you may need to share and operate Sendable objects between C++ threads. +When an application performs multithreaded computations at the C++ layer, ArkTS APIs needs to be executed within the ArkTS environment. To prevent the non-UI main thread from waiting for the API call results within the ArkTS environment of the UI main thread, you need to create an ArkTS execution environment on these C++ threads and directly call the APIs. In addition, you may need to share and manipulate Sendable objects across C++ threads. -To support this scenario, you need to create and call ArkTS on the C++ thread, and perform multi-thread sharing and operations on the Sendable object. +To support this scenario, you must create the capabilities to call ArkTS APIs on C++ threads, and share and manipulate Sendable objects across threads. -## Calling ArkTS Capabilities on a C++ Thread +## Calling ArkTS APIs on C++ Threads -For details about how to use Node-APIs to create and call an ArkTS runtime environment in a C++ thread, see [Creating an ArkTs Runtime Environment Using Node-API](../napi/use-napi-ark-runtime.md). +For details about how to use Node-API to create an ArkTS runtime environment and call ArkTS APIs on C++ threads, see [Creating an ArkTS Runtime Environment Using Node-API](../napi/use-napi-ark-runtime.md). The core code snippet is as follows: -ArkTS File Definition +ArkTS file definition ```ts // SendableObjTest.ets @@ -24,7 +24,7 @@ export class SendableObjTest { ``` -The Naitve implements the capability of loading the ArkTS module. +Native implementation to load ArkTS modules ```cpp // napi_init.cpp @@ -38,7 +38,7 @@ static void *CreateArkRuntimeFunc(void *arg) if (ret != napi_ok) { std::abort(); } - // 2. Load the customized module. Assume that SendableObjTest provides the newSendable method for creating the sendable object. + // 2. Load the custom module, assuming that SendableObjTest provides the newSendable function for creating Sendable objects. napi_value test = nullptr; ret = napi_load_module_with_info(env, "entry/src/main/ets/pages/SendableObjTest", "com.example.myapplication/entry", &test); if (ret != napi_ok) { @@ -49,39 +49,39 @@ static void *CreateArkRuntimeFunc(void *arg) if (ret != napi_ok) { std::abort(); } - // 3. Use newSendable in ArkTS. Assume that the newSendable function in sendableObjTest can return the sendable object. + // 3. Use newSendable in ArkTS, assuming that the newSendable function in sendableObjTest returns a Sendable object. napi_value newSendable = nullptr; ret = napi_get_named_property(env, sendableObjTest, "newSendable", &newSendable); if (ret != napi_ok) { std::abort(); } - // 4. Call the newSendable function to return the newly created sendable object and save it in the result. + // 4. Call the newSendable function to return the newly created Sendable object and store it in result. napi_value result = nullptr; ret = napi_call_function(env, sendableObjTest, newSendable, 0, nullptr, &result); if (ret != napi_ok) { std::abort(); } - // 4. Obtain the result returned by ArkTS. + // 5. Obtain the result returned by ArkTS. int value0; napi_get_value_int32(env, result, &value0); if (value0 != 1024) { std::abort(); } - // 6. Destroy the ArkTS environment. + // 6. Destroy the ArkTS runtime environment. ret = napi_destroy_ark_runtime(&env); return nullptr; } ``` -The process consists of four steps: creating an execution environment, loading a module, searching for and calling the functions of the module (or directly creating a Sendable object through the Node-API), and destroying the execution environment. For details about how to load a module in the second step, see [Loading a Module Using Node-API](../napi/use-napi-load-module-with-info.md). For details about how to search for and call a function and more Node-API interface capabilities, see [Node-API](../reference/native-lib/napi.md). +The process consists of four steps: creating an execution environment, loading modules, searching for and calling functions (or directly creating Sendable objects through Node-API), and finally destroying the execution environment. For details about how to load modules, see [Loading a Module Using Node-API](../napi/use-napi-load-module-with-info.md). For details about how to search for and call functions and more Node-API capabilities, see [Node-API](../reference/native-lib/napi.md). -## Operates Sendable shared objects between C++ threads. +## Manipulating Sendable Objects Across C++ Threads -After the ArkTS capability is called in C++, the implementation needs to be transferred across threads through serialization and deserialization. The napi_value variable cannot be directly shared among multiple threads because it is not multi-thread secure. +After implementing the capabilities to call ArkTS APIs from C++, serialize and deserialize objects for cross-thread transfer. The **napi_value** variable cannot be directly shared across threads because it is not thread-safe. -The following code example describes how to serialize and deserialize the transferred object. Note that the Sendable shared object is transferred by reference. Therefore, serialization does not generate another copy of data. Instead, the object reference is directly transferred to the deserialization thread. Therefore, the performance is more efficient than that of serialization and deserialization of non-Sendable objects. +The following code example demonstrates how to serialize and deserialize objects. Since Sendable objects are passed by reference, serialization does not create an additional copy of the data but directly passes the object reference to the deserializing thread. This makes serialization and deserialization more efficient than non-Sendable objects. -ArkTS File Definition +ArkTS file definition ```ts // SendableObjTest.ets @@ -93,7 +93,7 @@ export class SendableObjTest { } ``` -The Naitve implements the serialization and deserialization logic of the Sendable of two threads. +Native implementation for serialization and deserialization of Sendable objects ```cpp // napi_init.cpp @@ -108,7 +108,7 @@ static void *CreateEnvAndSendSendable(void *) { if (ret != napi_ok) { std::abort(); } - // 2. Load the customized module. Assume that SendableObjTest provides the newSendable method for creating the sendable object. + // 2. Load the custom module, assuming that SendableObjTest provides the newSendable function for creating Sendable objects. napi_value test = nullptr; ret = napi_load_module_with_info(env, "entry/src/main/ets/pages/SendableObjTest", "com.example.myapplication/entry", &test); @@ -120,19 +120,19 @@ static void *CreateEnvAndSendSendable(void *) { if (ret != napi_ok) { std::abort(); } - // 3. Use newSendable in ArkTS. Assume that the newSendable function in sendableObjTest can return the sendable object. + // 3. Use newSendable in ArkTS, assuming that the newSendable function in sendableObjTest returns a Sendable object. napi_value newSendable = nullptr; ret = napi_get_named_property(env, sendableObjTest, "newSendable", &newSendable); if (ret != napi_ok) { std::abort(); } - // 4. Call the newSendable function to return the newly created sendable object and save it in the result. + // 4. Call the newSendable function to return the newly created Sendable object and store it in result. napi_value result = nullptr; ret = napi_call_function(env, sendableObjTest, newSendable, 0, nullptr, &result); if (ret != napi_ok) { std::abort(); } - // 5. Serialize the sendable object. + // 5. Serialize the Sendable object. napi_value undefined; napi_get_undefined(env, &undefined); ret = napi_serialize(env, result, undefined, undefined, &serializationData); @@ -149,13 +149,13 @@ static void *CreateEnvAndReceiveSendable(void *) { if (ret != napi_ok) { std::abort(); } - // 2. Obtain the sendable shared object through deserialization and save the result in the result. The result can be used to perform various operations through the napi interface. + // 2. Deserialize the Sendable object and store it in result, which can then be manipulated via Node-API. napi_value result = nullptr; ret = napi_deserialize(env, serializationData, &result); if (ret != napi_ok) { std::abort(); } - // 3. Delete serialized data. + // 3. Delete the serialization data. ret = napi_delete_serialization_data(env, serializationData); if (ret != napi_ok) { std::abort(); @@ -211,7 +211,7 @@ extern "C" __attribute__((constructor)) void RegisterEntryModule(void) { export const testSendSendable: () => void; ``` -The UI main thread initiates an invoking request. +UI main thread invocation ```ts // Index.ets @@ -246,10 +246,10 @@ struct Index { The logic implementation of the entire process is as follows: -1. Create the ArkTS running environment in the UI main thread where the main function is located, create a Sendable object and save it to the result, and serialize the Sendable object referenced by the result to a global serialization data serializationData. +1. In the UI main thread where the **main** function resides, create an ArkTS runtime environment and initiate a C++child thread to create a Sendable object and store the object in **result**. Serialize the Sendable object referenced by **result** into global serialization data **serializationData**. -2. After these processes are complete, another C++ subthread is initiated and the ArkTS runtime environment is created in the new thread. Then, the Sendable object created by the UI main thread is deserialized from serializationData through the deserialization interface, and is saved to the result. In this way, the Sendable object is transferred across C++ threads. After deserialization is complete, destroy the deserialized data to avoid memory leakage. In this case, both the UI main thread and sub-threads hold the Sendable shared object. You can perform object operations through the Node-API, such as reading, writing, or transferring the object to the ArkTS layer. +2. After the preceding steps are complete, initiate another C++ child thread. In this new thread, create the ArkTS runtime environment. Then, deserialize the Sendable object created in the UI main thread from **serializationData** using the deserialization interface and store it in **result**. This enables the transfer of Sendable objects across C++ thread. After deserialization, the deserialization data must be destroyed to prevent memory leaks. In this case, both the UI main thread and the child thread hold the Sendable object, which can be manipulated via Node-API, such as reading/writing or passing it to the ArkTS layer. - > **Note** + > **NOTE** > - > The operation object must comply with the rules of the Sendable object. For details, see [Sendable Usage Rules and Constraints](sendable-constraints.md). + > The object being manipulated must comply with the rules of Sendable objects. For details, see [Usage Rules and Constraints for Sendable](sendable-constraints.md). diff --git a/en/application-dev/arkts-utils/nonlinear-container.md b/en/application-dev/arkts-utils/nonlinear-container.md index b84e504a5c7a20dc9d1b4483b72bfd8afda0368a..4f86ade1bd970cc1ec8c74f79fc10550c04cd041 100644 --- a/en/application-dev/arkts-utils/nonlinear-container.md +++ b/en/application-dev/arkts-utils/nonlinear-container.md @@ -1,217 +1,217 @@ # Nonlinear Containers -Nonlinear containers, underpinned by hash tables or red-black trees, implement a data structure that enables quick search. There are several types of nonlinear containers: **HashMap**, **HashSet**, **TreeMap**, **TreeSet**, **LightWeightMap**, **LightWeightSet**, and **PlainArray**. The types of **key** and **value** in nonlinear containers must meet the ECMA standard. +Nonlinear containers, underpinned by hash tables or red-black trees, implement a data structure that enables quick lookup operations. There are several types of nonlinear containers: HashMap, HashSet, TreeMap, TreeSet, LightWeightMap, LightWeightSet, and PlainArray. The types of **key** and **value** in nonlinear containers comply with the ECMA standard. -## Comparison of Non-linear Container Types +## Comparison of Nonlinear Container Types -| Class| Characteristics and Recommended Application Scenarios| +| Type| Characteristics and Recommended Use Cases| | --------- | ------- | -| HashMap | Stores a set of key-value pairs that have association relationships. The key in the storage element is unique, and the storage location is determined based on the hash value of the key. The access speed is fast, but the sorting cannot be customized. Recommended for quick access, insertion, and deletion of key-value pair data.| -| HashSet | A set of values. Each value in a storage element is unique. The storage location is determined based on the hash of the value. Null values can be added, but the sorting cannot be customized. It can be used when a non-repeated collection is required or a collection needs to be deduplicated.| -| TreeMap | Stores a set of key-value pairs that have association relationships. The key in the storage element is unique. You can customize the sorting method. Generally, this mode can be used in scenarios where key-value pairs need to be stored in sequence.| -| TreeSet | A set of values. The values in the storage element are unique. You can customize the sorting method, but you are not advised to put null values. Generally, this method can be used in scenarios where collections need to be stored in sequence.| -| LightWeightMap | Stores a set of key-value pairs that have association relationships. The key in the storage element is unique. The bottom layer uses a more lightweight structure and occupies less space. This mode is recommended when key-value pair data needs to be accessed and the memory is insufficient.| -| LightWeightSet | Stores a set of values. The values in the storage element are unique. The bottom layer uses a more lightweight structure and occupies less space. This method is recommended when you need a unique set or a set to be deduplicated.| -| PlainArray | Stores a set of key-value pairs that have association relationships. The key in the storage element is unique. The bottom layer uses a more lightweight structure like LightWeightMap, and the key is of the number type. You are advised to use PlainArray when you need to store KV pairs whose keys are of the number type.| +| HashMap | Stores a collection of key-value (KV) pairs with unique keys. It uses the hash code of the key to determine the storage location, offering fast access but no custom sorting. It is recommended for scenarios requiring quick storage, retrieval, and removal of KV pairs.| +| HashSet | Stores a collection of unique values. It uses the hash code of the value to determine the storage location. It allows null values but does not support custom sorting. It is useful for creating non-redundant collections or removing duplicates.| +| TreeMap | Stores a collection of KV pairs with unique keys. It allows users to customize sorting methods. It is suitable for scenarios requiring ordered storage of KV pairs.| +| TreeSet | Stores a collection of unique values. It allows users to customize sorting methods but does not recommend storing null values. It is suitable for scenarios requiring ordered storage of collections.| +| LightWeightMap | Stores a collection of KV pairs with unique keys. It uses a more lightweight structure, occupying less memory. It is recommended for scenarios with limited memory and the need to store KV pairs.| +| LightWeightSet | Stores a collection of unique values. It uses a more lightweight structure, occupying less memory. It is recommended for creating non-redundant collections or removing duplicates.| +| PlainArray | Stores a collection of KV pairs with unique keys, where keys are of the number type. It uses a lightweight structure and a binary search algorithm for key lookup. It is suitable for storing KV pairs with number-type keys.| ## HashMap -[HashMap](../reference/apis-arkts/js-apis-hashmap.md) is used to store a set of associated key-value (KV) pairs. In a hash map, each key is unique and corresponds to a value. +[HashMap](../reference/apis-arkts/js-apis-hashmap.md) is used to store a collection of KV pairs with unique keys. Each key corresponds to a value. -**HashMap** uses generics. In a hash map, a key is located based on its hash code. The initial capacity of a hash map is 16, and it has capacity doubled in each dynamic expansion. The bottom layer of **HashMap** is implemented based on a hash table. It uses chaining to avoid collisions in hash tables. +Defined by generics, HashMap uses the hash code of the key to determine the storage location, enabling quick access to KV pairs. The initial capacity is 16, and it supports dynamic resizing, doubling its size each time. HashMap is implemented using a hash table with a chain address conflict resolution strategy. -**HashMap** is faster in accessing data than [TreeMap](../reference/apis-arkts/js-apis-treemap.md), because the former accesses the keys based on the hash codes, whereas the latter stores and accesses the keys in sorted order. +HashMap is faster in accessing data than [TreeMap](../reference/apis-arkts/js-apis-treemap.md), because the former accesses the keys based on the hash codes, whereas the latter stores and accesses the keys in sorted order. -[HashSet](../reference/apis-arkts/js-apis-hashset.md) is implemented based on **HashMap**. The input parameter of **HashMap** consists of **key** and **value**. In **HashSet**, only the **value** object is processed. +[HashSet](../reference/apis-arkts/js-apis-hashset.md) is implemented based on HashMap. HashMap takes **key** and **value** as input parameters. In HashSet, only the **value** object is processed. -You are advised to use **HashMap** when you need to quickly access, remove, and insert KV pairs. +You are advised to use HashMap when you need to quickly access, remove, and insert KV pairs. -**HashMap** provides the following Create, Read, Update, and Delete (CRUD) APIs. +Common APIs for adding, removing, modifying, and accessing elements in HashMap are as follows: | Operation| API| Description| | --------- | ------- | ------- | -| Create| set(key: K, value: V) | Adds a key-value pair.| -| Read| get(key: K) | Value corresponding to the target key.| -| Read| keys() | Use **keys()** to return an iterator that contains all the keys in this container.| -| Read| values() | Use **values()** to return an iterator that contains all the values in this container.| -| Read| entries() | Use **entries()** to return an iterator that contains all the elements in this container.| -| Read| forEach(callbackFn: (value?: V, key?: K, map?: HashMap) => void, thisArg?: Object) | Traverses the elements of the entire map.| -| Read| \[Symbol.iterator]():IterableIterator<[K,V]> | Creates an iterator for data access.| -| Update| replace(key: K, newValue: V) | Value corresponding to the target key.| -| Update| forEach(callbackFn: (value?: V, key?: K, map?: HashMap) => void, thisArg?: Object) | Modify the elements of the entire map through traversal.| -| Delete| remove(key: K) | Deletes the matched key-value pair from the map.| -| Delete| clear() | Clears the entire map.| +| Adding elements| set(key: K, value: V) | Adds a KV pair.| +| Accessing elements| get(key: K) | Obtains the value corresponding to the specified key.| +| Accessing elements| keys() | Returns an iterator that contains all the keys in the map.| +| Accessing elements| values() | Returns an iterator that contains all the values in the map.| +| Accessing elements| entries() | Returns an iterator that contains all the KV pairs in the map.| +| Accessing elements| forEach(callbackFn: (value?: V, key?: K, map?: HashMap) => void, thisArg?: Object) | Iterates over all elements in the map.| +| Accessing elements| \[Symbol.iterator]():IterableIterator<[K,V]> | Creates an iterator for data access.| +| Modifying elements| replace(key: K, newValue: V) | Modifies the value corresponding to the specified key.| +| Modifying elements| forEach(callbackFn: (value?: V, key?: K, map?: HashMap) => void, thisArg?: Object) | Modifies all elements in the map through iteration.| +| Removing elements| remove(key: K) | Removes the KV pair matching the specified key from the map.| +| Removing elements| clear() | Clears the entire map.| ## HashSet -[HashSet](../reference/apis-arkts/js-apis-hashset.md) is used to store a set of values, each of which is unique in a hash set. +[HashSet](../reference/apis-arkts/js-apis-hashset.md) is used to store a collection of unique values. -**HashSet** uses generics. In a hash set, a value is located based on its hash code. The initial capacity of a hash set is 16, and it has capacity doubled in each dynamic expansion. The type of **value** must comply with the ECMA standard. HashSet is implemented based on [HashMap](../reference/apis-arkts/js-apis-hashmap.md) and processes only the value object. The bottom-layer data structure is the same as that of HashMap. +Defined by generics, HashSet uses the hash code of the value to determine the storage location, enabling quick access to the value. The initial capacity is 16, and it supports dynamic resizing, doubling its size each time. The type of **value** must comply with the ECMA standard. HashSet is implemented based on [HashMap](../reference/apis-arkts/js-apis-hashmap.md) and processes only the **value** object. The underlying data structure is consistent with HashMap. -Compared with [TreeSet](../reference/apis-arkts/js-apis-treeset.md), data in HashSet is stored in an unordered manner, that is, users cannot specify the sorting mode. However, data in TreeSet is stored in an ordered manner, that is, elements can be sorted based on the sorting function specified by users. Both of them allow only unique elements. However, null values are allowed in **HashSet**, but not in **TreeSet**, because null values may affect the order of elements in the container. +Compared with [TreeSet](../reference/apis-arkts/js-apis-treeset.md), which stores data in an ordered manner and allows users to define sorting functions, HashSet stores data in an unordered manner and does not support custom sorting. Neither allows duplicate elements, but HashSet permits null values, whereas TreeSet does not recommend storing null values as it may affect sorting results. -You are advised to use **HashSet** when you need a set that has only unique elements or need to deduplicate a set. +You are advised to use HashSet when you need to create non-redundant collections or remove duplicates. -**HashSet** provides the following CRUD APIs. +Common APIs for adding, removing, modifying, and accessing elements in HashSet are as follows: | Operation| API| Description| | --------- | ------- | ------- | -| Create| add(value: T) | Adds a value.| -| Read| values() | Use **values()** to return an iterator that contains all the values in this container.| -| Read| entries() | Use **entries()** to return an iterator that contains all the elements in this container.| -| Read| forEach(callbackFn: (value?: T, key?: T, set?: HashSet\) => void, thisArg?: Object) | Traverses and accesses the elements of the entire set.| -| Read| \[Symbol.iterator]():IterableIterator<T> | Creates an iterator for data access.| -| Update| forEach(callbackFn: (value?: T, key?: T, set?: HashSet\) => void, thisArg?: Object) | Modify the elements of the entire set through traversal.| -| Delete| remove(value: T) | Deletes the matched value from the set.| -| Delete| clear() | Clears the entire set.| +| Adding elements| add(value: T) | Adds a value.| +| Accessing elements| values() | Returns an iterator that contains all the values in the set.| +| Accessing elements| entries() | Returns an iterator object containing array-like KV pairs, where both keys and values are the same.| +| Accessing elements| forEach(callbackFn: (value?: T, key?: T, set?: HashSet\) => void, thisArg?: Object) | Iterates over all elements in the set.| +| Accessing elements| \[Symbol.iterator]():IterableIterator<T> | Creates an iterator for data access.| +| Modifying elements| forEach(callbackFn: (value?: T, key?: T, set?: HashSet\) => void, thisArg?: Object) | Modifies all elements in the set through iteration.| +| Removing elements| remove(value: T) | Removes the matching value from the set.| +| Removing elements| clear() | Clears the entire set.| ## TreeMap -[TreeMap](../reference/apis-arkts/js-apis-treemap.md) is used to store a set of associated KV pairs. In a tree map, each key is unique and corresponds to a value. +[TreeMap](../reference/apis-arkts/js-apis-treemap.md) is used to store a collection of KV pairs with unique keys. Each key corresponds to a value. -**TreeMap** uses generics, and the keys in a tree map are ordered. The bottom layer of **TreeMap** is a binary tree, which supports quick search of KV pairs through the children (left child and right child) of the tree. The type of **key** must comply with the ECMA standard. Keys in a tree map are stored in order. The bottom layer of **TreeMap** is implemented based on the red-black tree and supports quick insertion and removal. +Defined by generics, TreeMap stores keys in an ordered manner. The underlying structure is a binary tree, allowing for quick lookup of KV pairs through binary tree search. The type of **key** must comply with the ECMA standard. Keys in a TreeMap are stored in order. TreeMap is implemented using a red-black tree, enabling fast insertion and removal. -[HashMap](../reference/apis-arkts/js-apis-hashmap.md) is faster in accessing data than **TreeMap**, because the former accesses the keys based on the hash codes, whereas the latter stores and accesses the keys in sorted order. +Compared with [HashMap](../reference/apis-arkts/js-apis-hashmap.md), which provides faster access based on the key's hash code, TreeMap is ordered and thus less efficient. -You are advised to use **TreeMap** when you need to store KV pairs in sorted order. +You are advised to use TreeMap when you need to store KV pairs in sorted order. -**TreeMap** provides the following CRUD APIs. +Common APIs for adding, removing, modifying, and accessing elements in TreeMap are as follows: | Operation| API| Description| | --------- | ------- | ------- | -| Create| set(key: K, value: V) | Adds a key-value pair.| -| Read| get(key: K) | Value corresponding to the target key.| -| Read| getFirstKey() | Use **getFirstKey()** to obtain the first key in this container.| -| Read| getLastKey() | Use **getLastKey()** to obtain the last key in this container.| -| Read| keys() | Use **keys()** to return an iterator that contains all the keys in this container.| -| Read| values() | Use **values()** to return an iterator that contains all the values in this container.| -| Read| entries() | Use **entries()** to return an iterator that contains all the elements in this container.| -| Read| forEach(callbackFn: (value?: V, key?: K, map?: TreeMap) => void, thisArg?: Object) | Traverses the elements of the entire map.| -| Read| \[Symbol.iterator]():IterableIterator<[K,V]> | Creates an iterator for data access.| -| Update| replace(key: K, newValue: V) | Value corresponding to the target key.| -| Update| forEach(callbackFn: (value?: V, key?: K, map?: TreeMap) => void, thisArg?: Object) | Modify the elements of the entire map through traversal.| -| Delete| remove(key: K) | Deletes the matched key-value pair from the map.| -| Delete| clear() | Clears the entire map.| +| Adding elements| set(key: K, value: V) | Adds a KV pair.| +| Accessing elements| get(key: K) | Obtains the value corresponding to the specified key.| +| Accessing elements| getFirstKey() | Obtains the first key in the map.| +| Accessing elements| getLastKey() | Obtains the last key in the map.| +| Accessing elements| keys() | Returns an iterator that contains all the keys in the map.| +| Accessing elements| values() | Returns an iterator that contains all the values in the map.| +| Accessing elements| entries() | Returns an iterator that contains all the KV pairs in the map.| +| Accessing elements| forEach(callbackFn: (value?: V, key?: K, map?: TreeMap) => void, thisArg?: Object) | Iterates over all elements in the map.| +| Accessing elements| \[Symbol.iterator]():IterableIterator<[K,V]> | Creates an iterator for data access.| +| Modifying elements| replace(key: K, newValue: V) | Modifies the value corresponding to the specified key.| +| Modifying elements| forEach(callbackFn: (value?: V, key?: K, map?: TreeMap) => void, thisArg?: Object) | Modifies all elements in the map through iteration.| +| Removing elements| remove(key: K) | Removes the KV pair matching the specified key from the map.| +| Removing elements| clear() | Clears the entire map.| ## TreeSet -[TreeSet](../reference/apis-arkts/js-apis-treeset.md) is used to store a set of values, each of which is unique in a tree set. +[TreeSet](../reference/apis-arkts/js-apis-treeset.md) is used to store a collection of unique values. -**TreeSet** uses generics, and the values in a tree set are ordered. The bottom layer of **TreeSet** is a binary tree, which supports quick search of a value through the children (left child and right child) of the tree. The type of **value** must meet the ECMA standard. Values in a tree set are stored in order. The bottom layer of **TreeSet** is implemented based on the red-black tree and supports quick insertion and removal. +Defined by generics, TreeSet stores values in an ordered manner. The underlying structure is a binary tree, allowing for quick lookup of values through binary tree search. The type of **value** must comply with the ECMA standard. Values in a TreeSet are stored in order. TreeSet is implemented using a red-black tree, enabling fast insertion and removal. -**TreeSet** is implemented based on [TreeMap](../reference/apis-arkts/js-apis-treemap.md). In **TreeSet**, only **value** objects are processed. A TreeSet can be used to store a set of values. The value in an element is unique and can be sorted based on the sorting function specified by the user. +TreeSet is based on [TreeMap](../reference/apis-arkts/js-apis-treemap.md) and processes only the **value** object. It allows for ordered storage of a collection of values and can be sorted according to a custom sorting function. -[HashSet](../reference/apis-arkts/js-apis-hashset.md) stores data in a random order, whereas **TreeSet** stores data in sorted order. Both of them allow only unique elements. However, null values are allowed in **HashSet**, but not in **TreeSet**, because null values may affect the order of elements in the container. +Compared with [HashSet](../reference/apis-arkts/js-apis-hashset.md), which stores data in an unordered manner, TreeSet stores data in an ordered manner. Neither allows duplicate elements, but HashSet permits null values, whereas TreeSet does not recommend storing null values as it may affect sorting results. -You are advised to use **TreeSet** when you need to store data in sorted order. +You are advised to use TreeSet when you need to store data in sorted order. -**TreeSet** provides the following CRUD APIs. +Common APIs for adding, removing, modifying, and accessing elements in TreeSet are as follows: | Operation| API| Description| | --------- | ------- | ------- | -| Create| add(value: T) | Adds a value.| -| Read| values() | Use **values()** to return an iterator that contains all the values in this container.| -| Read| entries() | Use **entries()** to return an iterator that contains all the elements in this container.| -| Read| getFirstValue() | Use **getFirstValue()** to obtain the first value in this container.| -| Read| getLastValue() | Use **getLastValue()** to obtain the last value in this container.| -| Read| forEach(callbackFn: (value?: T, key?: T, set?: TreeSet\) => void, thisArg?: Object) | Traverses and accesses the elements of the entire set.| -| Read| \[Symbol.iterator]():IterableIterator<T> | Creates an iterator for data access.| -| Update| forEach(callbackFn: (value?: T, key?: T, set?: TreeSet\) => void, thisArg?: Object) | Modify the elements of the entire set through traversal.| -| Delete| remove(value: T) | Deletes the matched value from the set.| -| Delete| clear() | Clears the entire set.| +| Adding elements| add(value: T) | Adds a value.| +| Accessing elements| values() | Returns an iterator that contains all the values in the set.| +| Accessing elements| entries() | Returns an iterator object containing array-like KV pairs, where both keys and values are the same.| +| Accessing elements| getFirstValue() | Obtains the first value in the set.| +| Accessing elements| getLastValue() | Obtains the last value in the set.| +| Accessing elements| forEach(callbackFn: (value?: T, key?: T, set?: TreeSet\) => void, thisArg?: Object) | Iterates over all elements in the set.| +| Accessing elements| \[Symbol.iterator]():IterableIterator<T> | Creates an iterator for data access.| +| Modifying elements| forEach(callbackFn: (value?: T, key?: T, set?: TreeSet\) => void, thisArg?: Object) | Modifies all elements in the set through iteration.| +| Removing elements| remove(value: T) | Removes the matching value from the set.| +| Removing elements| clear() | Clears the entire set.| ## LightWeightMap -[LightWeightMap](../reference/apis-arkts/js-apis-lightweightmap.md) is used to store a set of associated KV pairs. In a lightweight map, each key is unique and corresponds to a value. **LightWeightMap** uses generics and a more lightweight structure. It uses the hash code to uniquely identify a key at the bottom layer. It uses linear probing to avoid collisions. In a lightweight map, a key is located by using the hash code and binary search algorithm. The hash code is stored in an array and mapped to a key and its value in another array. The type of **key** must comply with the ECMA standard. +[LightWeightMap](../reference/apis-arkts/js-apis-lightweightmap.md) is used to store a collection of KV pairs with unique keys. Each key corresponds to a value. Defined by generics, LightWeightMap uses a more lightweight structure. The underlying structure uses hash codes to identify unique keys, with a conflict resolution strategy of linear probing. The lookup of keys relies on hash codes and binary search algorithms, storing hash codes in an array and mapping them to **key** and **value** values in other arrays. The type of **key** must comply with the ECMA standard. -The default initial capacity of a lightweight map is 8, and it has capacity doubled in each expansion. +The default initial capacity is 8, and it supports dynamic resizing, doubling its size each time. -Compared with [HashMap](../reference/apis-arkts/js-apis-hashmap.md), which can also store KV pairs, **LightWeightMap** occupies less memory. +LightWeightMap and [HashMap](../reference/apis-arkts/js-apis-hashmap.md) are both used to store KV pairs, but LightWeightMap occupies less memory. -You are advised to use **LightWeightMap** when you need to store and access **KV pairs**. +You are advised to use LightWeightMap when you need to store and access KV pairs. -**LightWeightMap** provides the following CRUD APIs. +Common APIs for adding, removing, modifying, and accessing elements in LightWeightMap are as follows: | Operation| API| Description| | --------- | ------- | ------- | -| Create| set(key: K, value: V) | Adds a key-value pair.| -| Read| get(key: K) | Value corresponding to the target key.| -| Read| getIndexOfKey(key: K) | Obtains the index of a specified key in a map.| -| Read| getIndexOfValue(value: V) | Obtains the first index of a specified value in a map.| -| Read| keys() | Use **keys()** to return an iterator that contains all the keys in this container.| -| Read| values() | Use **values()** to return an iterator that contains all the values in this container.| -| Read| entries() | Use **entries()** to return an iterator that contains all the elements in this container.| -| Read| getKeyAt(index: number) | Pointer to the function used to obtain the cookie value of a specified URL.| -| Read| getValueAt(index: number) | Pointer to the function used to obtain the cookie value of a specified URL.| -| Read| forEach(callbackFn: (value?: V, key?: K, map?: LightWeightMap) => void, thisArg?: Object) | Traverses the elements of the entire map.| -| Read| \[Symbol.iterator]():IterableIterator<[K,V]> | Creates an iterator for data access.| -| Update| setValueAt(index: number, newValue: V) | Modifies the value of a specified index.| -| Update| forEach(callbackFn: (value?: V, key?: K, map?: LightWeightMap) => void, thisArg?: Object) | Modify the elements of the entire map through traversal.| -| Delete| remove(key: K) | Deletes the key-value pair that matches a specified key in a map.| -| Delete| removeAt(index: number) | Removes a key-value pair with the specified key.| -| Delete| clear() | Clears the entire map.| +| Adding elements| set(key: K, value: V) | Adds a KV pair.| +| Accessing elements| get(key: K) | Obtains the value corresponding to the specified key.| +| Accessing elements| getIndexOfKey(key: K) | Obtains the index of the specified key in the map.| +| Accessing elements| getIndexOfValue(value: V) | Obtains the index of the first occurrence of the specified value in the map.| +| Accessing elements| keys() | Returns an iterator that contains all the keys in the map.| +| Accessing elements| values() | Returns an iterator that contains all the values in the map.| +| Accessing elements| entries() | Returns an iterator that contains all the KV pairs in the map.| +| Accessing elements| getKeyAt(index: number) | Obtains the key at the specified index.| +| Accessing elements| getValueAt(index: number) | Obtains the value at the specified index.| +| Accessing elements| forEach(callbackFn: (value?: V, key?: K, map?: LightWeightMap) => void, thisArg?: Object) | Iterates over all elements in the map.| +| Accessing elements| \[Symbol.iterator]():IterableIterator<[K,V]> | Creates an iterator for data access.| +| Modifying elements| setValueAt(index: number, newValue: V) | Modifies the value at the specified index.| +| Modifying elements| forEach(callbackFn: (value?: V, key?: K, map?: LightWeightMap) => void, thisArg?: Object) | Modifies all elements in the map through iteration.| +| Removing elements| remove(key: K) | Removes the KV pair matching the specified key from the map.| +| Removing elements| removeAt(index: number) | Removes the KV pair at the specified index from the map.| +| Removing elements| clear() | Clears the entire map.| ## LightWeightSet -[LightWeightSet](../reference/apis-arkts/js-apis-lightweightset.md) is used to store a set of values, each of which is unique in a lightweight set. +[LightWeightSet](../reference/apis-arkts/js-apis-lightweightset.md) is used to store a collection of unique values. -**LightWeightSet** uses generics and a lightweight structure. Its default initial capacity is 8, and it has capacity doubled in each expansion. In a lightweight set, a value is located by using the hash code and binary search algorithm. The hash code is stored in an array and mapped to a value in another array. The type of **value** must comply with the ECMA standard. +Defined by generics, LightWeightSet uses a more lightweight structure. The default initial capacity is 8, and it supports dynamic resizing, doubling its size each time. The lookup of values relies on hash codes and binary search algorithms, storing hash codes in an array and mapping them to values in other arrays. The type of **value** must comply with the ECMA standard. -**LightWeightSet** uses the hash code to uniquely identify a value at the bottom layer. It uses linear probing to avoid collisions and adopts the binary search algorithm. +LightWeightSet identifies unique values based on hash at the underlying layer, with a conflict resolution strategy of linear probing and a lookup strategy based on binary search. -Compared with [HashSet](../reference/apis-arkts/js-apis-hashset.md), which can also store values, **LightWeightSet** occupies less memory. +LightWeightSet and [HashSet](../reference/apis-arkts/js-apis-hashset.md) are both used to store unique values, but LightWeightSet occupies less memory. -You are advised to use **LightWeightSet** when you need a set that has only unique elements or need to deduplicate a set. +You are advised to use LightWeightSet when you need a collection that contains unique elements or need to deduplicate a collection with limited memory. -**LightWeightSet** provides the following CRUD APIs. +Common APIs for adding, removing, modifying, and accessing elements in LightWeightSet are as follows: | Operation| API| Description| | --------- | ------- | ------- | -| Create| add(value: T) | Adds a value.| -| Read| getIndexOf(key: T) | Key of the value to obtain.| -| Read| getValueAt(index: number) | Pointer to the function used to obtain the cookie value of a specified URL.| -| Read| values() | Use **values()** to return an iterator that contains all the values in this container.| -| Read| entries() | Use **entries()** to return an iterator that contains all the elements in this container.| -| Read| forEach(callbackFn: (value?: T, key?: T, set?: LightWeightSet\) => void, thisArg?: Object) | Traverses and accesses the elements of the entire set.| -| Read| \[Symbol.iterator]():IterableIterator<T> | Creates an iterator for data access.| -| Update| forEach(callbackFn: (value?: T, key?: T, set?: LightWeightSet\) => void, thisArg?: Object) | Modify the elements of the entire set through traversal.| -| Delete| remove(key: K) | Deletes the matched key-value pair from the set.| -| Delete| removeAt(index: number) | Deletes the value of a specified index from a set.| -| Delete| clear() | Clears the entire set.| +| Adding elements| add(value: T) | Adds a value.| +| Accessing elements| getIndexOf(key: T) | Obtains the index corresponding to the specified key.| +| Accessing elements| getValueAt(index: number) | Obtains the value at the specified index.| +| Accessing elements| values() | Returns an iterator that contains all the values in the set.| +| Accessing elements| entries() | Returns an iterator object containing array-like KV pairs, where both keys and values are the same.| +| Accessing elements| forEach(callbackFn: (value?: T, key?: T, set?: LightWeightSet\) => void, thisArg?: Object) | Iterates over all elements in the set.| +| Accessing elements| \[Symbol.iterator]():IterableIterator<T> | Creates an iterator for data access.| +| Modifying elements| forEach(callbackFn: (value?: T, key?: T, set?: LightWeightSet\) => void, thisArg?: Object) | Modifies all elements in the set through iteration.| +| Removing elements| remove(key: K) | Removes the KV pair matching the specified key from the set.| +| Removing elements| removeAt(index: number) | Removes the value at the specified index from the set.| +| Removing elements| clear() | Clears the entire set.| ## PlainArray -[PlainArray](../reference/apis-arkts/js-apis-plainarray.md) is used to store a set of associated KV pairs. In a plain array, each key is unique, corresponds to a value, and is of the number type. **PlainArray** uses generics and a more lightweight structure. In a plain array, a key is located by using the binary search algorithm and is mapped to a value in another array. +[PlainArray](../reference/apis-arkts/js-apis-plainarray.md) is used to store a collection of KV pairs with unique keys, where keys are of the number type. Each key corresponds to a value. Defined by generics, PlainArray uses a more lightweight structure, with key lookup relying on binary search algorithms and mapping to **value** values in other arrays. -The default initial capacity of a plain array is 16, and it has capacity doubled in each expansion. +The default initial capacity is 16, and it supports dynamic resizing, doubling its size each time. -Both **PlainArray** and [LightWeightMap](../reference/apis-arkts/js-apis-lightweightmap.md) are used to store KV pairs in the lightweight structure. However, the key type of **PlainArray** can only be **number**. +PlainArray and [LightWeightMap](../reference/apis-arkts/js-apis-lightweightmap.md) are both used to store KV pairs with a lightweight structure, but PlainArray's keys can only be of the number type. You are advised to use PlainArray when you need to store KV pairs whose keys are of the number type. -**PlainArray** provides the following CRUD APIs. +Common APIs for adding, removing, modifying, and accessing elements in PlainArray are as follows: | Operation| API| Description| | --------- | ------- | ------- | -| Create| add(key: number,value: T) | Adds a key-value pair.| -| Read| get(key: number) | Value corresponding to the target key.| -| Read| getIndexOfKey(key: number) | Obtains the index of a specified key in PlainArray.| -| Read| getIndexOfValue(value: T) | Obtains the first index of a specified value in a PlainArray.| -| Read| getKeyAt(index: number) | Pointer to the function used to obtain the cookie value of a specified URL.| -| Read| getValueAt(index: number) | Pointer to the function used to obtain the cookie value of a specified URL.| -| Read| forEach(callbackFn: (value: T, index?: number, PlainArray?: PlainArray\) => void, thisArg?: Object) | Traverses the elements of the entire PlainArray.| -| Read| \[Symbol.iterator]():IterableIterator<[number, T]> | Creates an iterator for data access.| -| Update| setValueAt(index:number, value: T) | Modifies the value of a specified index.| -| Update| forEach(callbackFn: (value: T, index?: number, PlainArray?: PlainArray\) => void, thisArg?: Object) | Modify the elements of the entire PlainArray through traversal.| -| Delete| remove(key: number) | Deletes the key-value pair that matches a specified key in PlainArray.| -| Delete| removeAt(index: number) | Removes a key-value pair with the specified key.| -| Delete| removeRangeFrom(index: number, size: number) | Deletes elements in a specified range from PlainArray.| -| Delete| clear() | Clears the entire PlainArray.| +| Adding elements| add(key: number,value: T) | Adds a KV pair.| +| Accessing elements| get(key: number) | Obtains the value corresponding to the specified key.| +| Accessing elements| getIndexOfKey(key: number) | Obtains the index of the specified key in the PlainArray.| +| Accessing elements| getIndexOfValue(value: T) | Obtains the index of the first occurrence of the specified value in the PlainArray.| +| Accessing elements| getKeyAt(index: number) | Obtains the key at the specified index.| +| Accessing elements| getValueAt(index: number) | Obtains the value at the specified index.| +| Accessing elements| forEach(callbackFn: (value: T, index?: number, PlainArray?: PlainArray\) => void, thisArg?: Object) | Iterates over all elements in the PlainArray.| +| Accessing elements| \[Symbol.iterator]():IterableIterator<[number, T]> | Creates an iterator for data access.| +| Modifying elements| setValueAt(index:number, value: T) | Modifies the value at the specified index.| +| Modifying elements| forEach(callbackFn: (value: T, index?: number, PlainArray?: PlainArray\) => void, thisArg?: Object) | Modifies all elements in the PlainArray through iteration.| +| Removing elements| remove(key: number) | Removes the KV pair matching the specified key.| +| Removing elements| removeAt(index: number) | Removes the KV pair at the specified index.| +| Removing elements| removeRangeFrom(index: number, size: number) | Removes elements within the specified range in the PlainArray.| +| Removing elements| clear() | Clears the entire PlainArray.| ## Use of Nonlinear Containers -Refer to the code snippet below to add, access, and modify elements in **HashMap**, **TreeMap**, **LightWeightMap**, **Stack**, and **PlainArray**. +Here are usage examples for common nonlinear containers, including HashMap, TreeMap, LightWeightMap, and PlainArray, covering importing modules, adding elements, accessing elements, and modifying elements. The example code is as follows: ```ts @@ -219,38 +219,38 @@ Refer to the code snippet below to add, access, and modify elements in **HashMap import { HashMap } from '@kit.ArkTS'; // Import the HashMap module. let hashMap1: HashMap = new HashMap(); -hashMap1.set ('a', 123); // Add an element whose key is'a' and value is 123. +hashMap1.set('a', 123); // Add an element with key 'a' and value 123. let hashMap2: HashMap = new HashMap(); -hashMap2.set (4, 123); // Add an element whose key is 4 and value is 123. -console.info ('result: ${hashMap2.hasKey (4) }'); // Check whether an element whose key is 4 exists. Output: result: true -console.info ('result: ${hashMap1.get ('a') }'); // Element whose access key is'a'. Output: result: 123 +hashMap2.set(4, 123); // Add an element with key 4 and value 123. +console.info(`result: ${hashMap2.hasKey(4)}`); // Check whether an element with key 4 exists. Output: result: true +console.info(`result: ${hashMap1.get('a')}`); // Access an element with key 'a'. Output: result: 123 // TreeMap import { TreeMap } from '@kit.ArkTS'; // Import the TreeMap module. let treeMap: TreeMap = new TreeMap(); -treeMap.set ('a', 123); // Add an element whose key is'a' and value is 123. -treeMap.set ('6', 356); // Add an element whose key is '6' and value is 356. -console.info ('result: ${treeMap.get ('a') }'); // Element whose access key is'a'. Output: result: 123 -console.info ('result: ${treeMap.getFirstKey () }'); // Access the first element. Output: result: 6 -console.info ('result: ${treeMap.getLastKey () }'); // Access the last element. Output: result: a +treeMap.set('a', 123); // Add an element with key 'a' and value 123. +treeMap.set('6', 356); // Add an element with key '6' and value 356. +console.info(`result: ${treeMap.get('a')}`); // Access an element with key 'a'. Output: result: 123 +console.info(`result: ${treeMap.getFirstKey()}`); // Access the first element. Output: result: 6 +console.info(`result: ${treeMap.getLastKey()}`); // Access the last element. Output: result: a // LightWeightMap import { LightWeightMap } from '@kit.ArkTS'; // Import the LightWeightMap module. let lightWeightMap: LightWeightMap = new LightWeightMap(); -lightWeightMap.set ('x', 123); // Add an element whose key is'x' and value is 123. -lightWeightMap.set ('8', 356); // Add an element whose key is '8' and value is 356. -console.info ('result: ${lightWeightMap.get ('a') }'); // Element whose access key is'a'. Output: result: undefined -console.info ('result: ${lightWeightMap.get ('x') }'); // Obtain the value of the element whose access key is 'x'. Output: result: 123 -console.info(`result: ${lightWeightMap.getIndexOfKey('8')}`); // accesses the element whose key is '8' and obtains its index. Output: result: 0 +lightWeightMap.set('x', 123); // Add an element with key 'x' and value 123. +lightWeightMap.set('8', 356); // Add an element with key '8' and value 356. +console.info(`result: ${lightWeightMap.get('a')}`); // Access an element with key 'a'. Output: result: undefined +console.info(`result: ${lightWeightMap.get('x')}`); // Obtain the value of the element with key 'x'. Output: result: 123 +console.info(`result: ${lightWeightMap.getIndexOfKey('8')}`); // Obtain the index of the element with key '8'. Output: result: 0 // PlainArray import { PlainArray } from '@kit.ArkTS'; // Import the PlainArray module. let plainArray: PlainArray = new PlainArray(); -plainArray.add (1,'sdd'); // Add an element whose key is 1 and value is'sdd'. -plainArray.add (2, 'sff'); // Add an element whose key is 2 and value is'sff'. -console.info ('result: ${plainArray.get (1) }'); // Access the element whose key is 1 to obtain the value. Output: result: sdd -console.info ('result: ${plainArray.getKeyAt (1) }'); // Access the element whose index is 1 to obtain the key. Output: result: 2 +plainArray.add(1, 'sdd'); // Add an element with key 1 and value 'sdd'. +plainArray.add(2, 'sff'); // Add an element with key 2 and value 'sff'. +console.info(`result: ${plainArray.get(1)}`); // Obtain the value of the element with key 1. Output: result: sdd +console.info(`result: ${plainArray.getKeyAt(1)}`); // Obtain the key of the element at index 1. Output: result: 2 ``` diff --git a/en/application-dev/arkts-utils/normal-object.md b/en/application-dev/arkts-utils/normal-object.md index 35f51ea350b4ffb5c1a6c3a7d138904b15c0bf85..2a739491dd7c9dc66df0f0f29ffaa6d91452f0a1 100644 --- a/en/application-dev/arkts-utils/normal-object.md +++ b/en/application-dev/arkts-utils/normal-object.md @@ -1,17 +1,20 @@ -# Common Object +# Regular Object -When a common object is transferred across threads, the object content of the two threads is the same, but the object points to the isolated memory area of each thread. For example, objects such as Object, Array, and Map defined in the Ecmascript262 specification implement cross-concurrent instance communication in this manner. The following figure shows the communication process. +Regular objects are passed by copy between threads. The objects in the two threads have the same content but point to isolated memory areas in their respective threads, allocated in the local heap of each thread's virtual machine. For example, objects defined by the ECMAScript 262 specification, such as Object, Array, and Map, use this method to communicate across concurrent instances. The following figure shows the communication process. ![deep_copy](figures/deep_copy.png) +> **NOTE** +> +> Regular class instances are passed by copy across threads, which means only data is passed, and any methods associated with the class instances are lost. To enable class instances to retain their methods when being passed across threads, you can use the [@Sendable decorator](./arkts-sendable.md#sendable decorator) to mark the class as Sendable. -## Samples +## Usage Example -A simple example of transferring a common object is provided here. The implementation is as follows: +The following is a simple example of passing a regular object. ```ts // Test.ets -// Customize class TestA. +// Custom class TestA. export class TestA { constructor(name: string) { this.name = name; @@ -49,9 +52,9 @@ struct Index { .onClick(() => { // 1. Create a test instance objA. let objA = new TestA("TestA"); - // 2. Create a task and transfer objA to the task. objA is not a sendable object and is transferred to the subthread through serialization. + // 2. Create a task and transfer objA to the task. objA is not a Sendable object and is transferred to the child thread through serialization. let task = new taskpool.Task(test1, objA); - 3. Execute the task. + // 3. Execute the task. taskpool.execute(task).then(() => { console.info("taskpool: execute task success!"); }).catch((e:BusinessError) => { diff --git a/en/application-dev/arkts-utils/resident-task-guide.md b/en/application-dev/arkts-utils/resident-task-guide.md index ae3763f6f108132555bbf7b8da33a2e73404c9c8..a61c63b42eb382d647b63e8f48d700c6b0555984 100644 --- a/en/application-dev/arkts-utils/resident-task-guide.md +++ b/en/application-dev/arkts-utils/resident-task-guide.md @@ -1,12 +1,12 @@ # Resident Task Development (Worker) -This section describes how to use a worker to execute a resident task. The worker continuously executes the task until the host thread sends a termination instruction. +This section describes how to use Worker to execute a resident task. Worker continuously executes the task until it receives a termination command from the host thread. -The development process and example are as follows: +The development process and example are outlined as follows: -1. DevEco Studio supports one-click Worker generation. Right-click any position in the {moduleName} directory and choose > New > Worker from the shortcut menu to automatically generate the Worker template file and configuration information. This section uses Worker as an example. +1. Create Worker with DevEco Studio. Specifically, in DevEco Studio, right-click anywhere in the {moduleName} directory and choose **New > Worker** to automatically generate the Worker template file and configuration information. In this example, we will create a Worker named "Worker". - In addition, you can manually create a worker file. For details, see [Precautions for Worker](worker-introduction.md#precautions-for-worker). + You can also manually create Worker files. For details, see [Precautions for Worker](worker-introduction.md#precautions-for-worker). 2. Import the Worker module. @@ -15,14 +15,14 @@ The development process and example are as follows: import { worker } from '@kit.ArkTS'; ``` -3. In the host thread, call [constructor()](../reference/apis-arkts/js-apis-worker.md#constructor9) of **ThreadWorker** to create a **Worker** object. The calling thread is the host thread. +3. In the host thread, call [constructor()](../reference/apis-arkts/js-apis-worker.md#constructor9) of ThreadWorker to create a Worker object. ```ts // Index.ets const workerInstance: worker.ThreadWorker = new worker.ThreadWorker('entry/ets/workers/Worker.ets'); ``` -4. The host thread is the UI main thread. The host thread sends'start' to execute a long-running task and receive related messages returned by the sub-thread. When the task does not need to be executed, send'stop' to stop the task. In this example, the task is stopped 10 seconds later. +4. Enable the host thread to send messages. The host thread (UI main thread) sends 'start' to initiate a long-running task and receive messages from the Worker thread. When the task is no longer needed, the host thread sends 'stop' to terminate the task. In this example, the task is terminated after 10 seconds. ```ts // Index.ets @@ -39,9 +39,9 @@ The development process and example are as follows: .onClick(() => { workerInstance.postMessage({type: 'start'}) workerInstance.onmessage = (event) => { - console.info ('The UI main thread receives a message:', event.data); + console.info('The UI main thread receives a message:', event.data); } - // Stop the worker after 10 seconds. + // Stop the Worker thread after 10 seconds. setTimeout(() => { workerInstance.postMessage({ type: 'stop' }); }, 10000); @@ -53,7 +53,7 @@ The development process and example are as follows: } ``` -5. When the Worker thread receives a start message from the host thread, the Worker thread starts to execute a task that runs irregularly for a long time and returns a message to the host thread in real time. When the received message is "stop," the task execution is ended and a corresponding message is returned to the host thread. +5. Handle messages in the Worker thread. When receiving 'start' from the host thread, the Worker thread starts executing the long-running, non-periodic task and sends messages back to the host thread in real-time. When receiving 'stop', it terminates the task and sends a corresponding message back to the host thread. ```ts // Worker.ets @@ -70,15 +70,15 @@ The development process and example are as follows: } } else if (type === 'stop') { isRunning = false; - workerPort.close (); // Close the worker. + workerPort.close(); // Close the Worker thread. } } // Simulate a resident task. function performTask() { if (isRunning) { - // Simulate a long-term task. + // Simulate a long-running task. workerPort.postMessage('Worker is performing a task'); - // Execute the task again 1 second later. + // Execute the task again after 1 second. setTimeout(performTask, 1000); } workerPort.postMessage('Worker is stop performing a task'); diff --git a/en/application-dev/arkts-utils/resident-task-overview.md b/en/application-dev/arkts-utils/resident-task-overview.md index 2179bfc1de68366d0cec8d6564d8589b2d30e5fd..a4d0043180a4f1ff42834f563756113c2c6d2563 100644 --- a/en/application-dev/arkts-utils/resident-task-overview.md +++ b/en/application-dev/arkts-utils/resident-task-overview.md @@ -1,12 +1,12 @@ -# Concurrent Resident Task Scenarios +# Overview of Concurrency in Resident Tasks -During application service implementation, for some resident task scenarios that take a long time (more than 3 minutes) and have a small number of concurrent tasks, use **Worker** to run the time-consuming logic in the background thread, so as not to block the main thread or cause frame loss and lag that affect user experience. +During the development of application services, certain tasks that are time-consuming (lasting longer than 3 minutes) and have low concurrency are best handled by running them in background threads using Worker. This approach prevents these tasks from blocking the UI main thread, which could otherwise lead to performance issues such as frame loss and freezing, ultimately degrading user experience. -A resident task refers to a task that takes a longer time than a transient task. The lifecycle of a resident task may be the same as that of the UI main thread. Compared with long-term tasks, resident tasks tend to be bound to threads and run for a longer time (for example, more than 3 minutes). +Persistent tasks are those that last significantly longer than transient tasks and may share the same lifecycle as the UI main thread. Unlike continuous tasks, persistent tasks are more tightly bound to their threads and typically have longer single-run durations (for example, over 3 minutes). -Common service scenarios of resident tasks are as follows: +The following describes typical service scenarios for resident tasks. -| Common Service Scenario| Description| +| Service Scenario| Description| | -------- | -------- | -| Game platform scenario| Enables the child thread as the main logic thread of the game service. The UI thread is only responsible for rendering.| -| Time-consuming task scenario| Long-time model prediction tasks or hardware tests in the background| +| Game platform scenario| A child thread is launched to serve as the main logic thread for gaming services, whereas the UI thread is only responsible for rendering.| +| Long-duration task scenario| Tasks that require extended periods of time in the background, such as model predictions or hardware testing.| diff --git a/en/application-dev/arkts-utils/sendable-constraints.md b/en/application-dev/arkts-utils/sendable-constraints.md index 919c80a267482e60e2b1412f767007c17ffe8da0..042f92d460fa6a424190e85db814477edd4995a8 100644 --- a/en/application-dev/arkts-utils/sendable-constraints.md +++ b/en/application-dev/arkts-utils/sendable-constraints.md @@ -1,12 +1,10 @@ -# Sendable Usage Rules and Constraints +# Usage Rules and Constraints for Sendable -## A sendable class can inherit only from another sendable class. +## Sendable Classes Must Inherit Only from Other Sendable Classes -> **Note** -> -> The class here does not include variables. In other words, a sendable class cannot inherit from a variable. +The layout and prototype chain of Sendable objects are immutable. Non-Sendable objects can modify their layout in special ways, but they cannot inherit from or be inherited by Sendable classes. This rule applies to classes, not variables. In other words, Sendable classes cannot inherit from variables. -**Positive Example:** +**Correct Example** ```ts @Sendable @@ -23,7 +21,7 @@ class B extends A { } ``` -**Negative Example:** +**Incorrect Example** ```ts class A { @@ -40,9 +38,11 @@ class B extends A { ``` -## A non-sendable class can inherit only from a non-sendable class. +## Non-Sendable Classes Must Inherit Only from Other Non-Sendable Classes + +The layout and prototype chain of Sendable objects are immutable. Since non-Sendable objects can modify their layout in special ways, they cannot inherit from or be inherited by Sendable classes. -**Positive Example:** +**Correct Example** ```ts class A { @@ -57,7 +57,7 @@ class B extends A { } ``` -**Negative Example:** +**Incorrect Example** ```ts @Sendable @@ -74,9 +74,11 @@ class B extends A { ``` -## A non-sendable class can implement only a non-sendable interface. +## Non-Sendable Classes Can Only Implement Non-Sendable Interfaces -**Positive Example:** +If a non-Sendable class implements a Sendable interface, it may be mistakenly considered as Sendable, leading to incorrect usage. + +**Correct Example** ```ts interface I {}; @@ -84,7 +86,7 @@ interface I {}; class B implements I {}; ``` -**Negative Example:** +**Incorrect Example** ```ts import { lang } from '@kit.ArkTS'; @@ -97,9 +99,11 @@ class B implements I {}; ``` -## The member variables of a sendable class or interface must be of a sendable data type. +## Member Variables of Sendable Classes/Interfaces Must Be Sendable Data Types + +Sendable objects cannot hold non-Sendable data. Therefore, member properties of Sendable objects must be of Sendable data types. -**Positive Example:** +**Correct Example** ```ts @Sendable @@ -110,7 +114,7 @@ class A { } ``` -**Negative Example:** +**Incorrect Example** ```ts @Sendable @@ -122,9 +126,11 @@ class A { ``` -## The member variables of a sendable class or interface cannot use the exclamation mark (!) for assertion. +## Member Variables of Sendable Classes/Interfaces Cannot Use the Exclamation Mark (!) for Assertion -**Positive Example:** +Member properties of Sendable objects must be initialized. The assertion using the exclamation mark (!) allows variables to remain uninitialized. Therefore, using the exclamation mark (!) for assertion is not supported. + +**Correct Example** ```ts @Sendable @@ -135,7 +141,7 @@ class A { } ``` -**Negative Example:** +**Incorrect Example** ```ts @Sendable @@ -147,9 +153,11 @@ class A { ``` -## The member variables of a sendable class or interface do not support computed property names. +## Member Variables of Sendable Classes/Interfaces Cannot Use Computed Property Names + +The layout of Sendable objects is immutable. Computed properties cannot statically determine the object layout, and therefore they cannot be used for Sendable objects. -**Positive Example:** +**Correct Example** ```ts @Sendable @@ -162,7 +170,7 @@ class A { } ``` -**Negative Example:** +**Incorrect Example** ```ts enum B { @@ -176,9 +184,11 @@ class A { ``` -## The template type of a sendable class, collections.Array, collections.Map, and collections.Set in the generic class must be Sendable. +## Template Types for Sendable Classes, collections.Array, collections.Map, and collections.Set Must Be Sendable -**Positive Example:** +Sendable objects cannot hold non-Sendable data. Therefore, template types for Sendable data in generic classes must be Sendable. + +**Correct Example** ```ts import { collections } from '@kit.ArkTS'; @@ -192,7 +202,7 @@ try { } ``` -**Negative Example:** +**Incorrect Example** ```ts import { collections } from '@kit.ArkTS'; @@ -208,15 +218,15 @@ try { ``` -## Variables defined in the context of the current module cannot be used in a sendable class. +## Sendable Classes Cannot Use Variables Defined in the Context of the Current Module -Because the context of a sendable object varies among concurrent instances, direct access may cause unexpected behavior. A sendable object cannot use the variables defined in the context of the current module. Otherwise, a compile-time error is reported. +Sendable objects operate in different concurrent instances with distinct context environments within a single virtual machine instance. Direct access to variables defined in the context of the current module can lead to unexpected behavior. Therefore, Sendable objects cannot use variables defined in the context of the current module. Violations will result in compile-time errors. -> **Note** +> **NOTE** > -> Since API version 12, a sendable class object of the top level can be used internally by the sendable class itself. +> Since API version 12, Sendable classes can use top-level Sendable class objects. -**Positive Example:** +**Correct Example** ```ts import { lang } from '@kit.ArkTS'; @@ -244,7 +254,7 @@ class C { } ``` -**Negative Example:** +**Incorrect Example** ```ts import { lang } from '@kit.ArkTS'; @@ -268,22 +278,22 @@ let b = new B(); @Sendable class C { - u: I = bar(); // bar is not a sendable class object. A compile-time error is reported. - v: I = new A(); // A is not defined in the top level. A compile-time error is reported. + u: I = bar(); // bar is not a Sendable class object. A compile-time error is reported. + v: I = new A(); // A is not defined at the top level. A compile-time error is reported. foo() { - return b; // b is not a sendable class object but an instance of the sendable class. A compile-time error is reported. + return b; // b is not a Sendable class object but an instance of the Sendable class. A compile-time error is reported. } } } ``` -## A sendable class and sendable function can only use the @Sendable decorator. +## Sendable Classes and Functions Cannot Use Decorators Other Than @Sendable -If the class decorator is defined in a .ts file, any modification to the class layout causes a runtime error. +If a class decorator modifies the class layout and is defined in a .ts file, it can cause runtime errors. -**Positive Example:** +**Correct Example** ```ts @Sendable @@ -292,7 +302,7 @@ class A { } ``` -**Negative Example:** +**Incorrect Example** ```ts @Sendable @@ -303,11 +313,11 @@ class C { ``` -## The Sendable type cannot be initialized using an object literal or array literal. +## Object Literals/Array Literals Cannot Be Used to Initialize Sendable Types -A sendable data type can be created only by using the **new** expression of the Sendable type. +Object literals and array literals are non-Sendable types. Sendable data types can only be created using **new** expressions of Sendable types. -**Positive Example:** +**Correct Example** ```ts import { collections } from '@kit.ArkTS'; @@ -315,7 +325,7 @@ import { collections } from '@kit.ArkTS'; let arr1: collections.Array = new collections.Array(1, 2, 3); // The type is Sendable. ``` -**Negative Example:** +**Incorrect Example** ```ts import { collections } from '@kit.ArkTS'; @@ -326,13 +336,11 @@ let arr4: number[] = new collections.Array(1, 2, 3); // A compile-time e ``` -## A non-sendable type cannot be converted to a sendable type using **as**. +## Non-Sendable Types Cannot Be Cast to Sendable Types Using **as** -> **Note** -> -> A sendable type must be compatible with a non-sendable type without violating the sendable usage rules. Therefore, a sendable type can be converted to a non-sendable type using **as**. +Except for the Object type, non-Sendable types cannot be cast to Sendable types using **as**. Using **as** to cast a non-Sendable type to a Sendable type results in an object that is still non-Sendable, leading to incorrect usage. Sendable types, however, can be cast to non-Sendable types using **as** to maintain compatibility, provided they do not violate Sendable rules. -**Positive Example:** +**Correct Example** ```ts class A { @@ -347,7 +355,7 @@ class SendableA { let a1: A = new SendableA() as A; ``` -**Negative Example:** +**Incorrect Example** ```ts class A { @@ -363,11 +371,11 @@ let a2: SendableA = new A() as SendableA; ``` -## An arrow function is not sendable. +## Arrow Functions Are Not Supported for Sharing -An arrow function cannot be decorated by @Sendable. +Arrow functions do not support the @Sendable decorator and are non-Sendable. Therefore, they cannot be shared. -**Positive Example:** +**Correct Example** ```ts @Sendable @@ -389,7 +397,7 @@ class SendableClass { let sendableClass = new SendableClass(SendableFunc); ``` -**Negative Example:** +**Incorrect Example** ```ts @Sendable @@ -403,18 +411,18 @@ class SendableClass { ``` -## The @Sendable decorator supports type decoration for functions only. +## @Sendable Can Only Be Applied to Function Types -The @Sendable decorator supports type decoration for functions only. +Currently, The @Sendable decorator only supports declaring Sendable function types. -**Positive Example:** +**Correct Example** ```ts @Sendable type SendableFuncType = () => void; ``` -**Negative Example:** +**Incorrect Example** ```ts @Sendable @@ -431,7 +439,7 @@ type D = C; // A compile-time error is reported. ## Notice -When using **Sendable** in HAR, enable the configuration of generating TS files. For details, see [Building TS Files](../quick-start/har-package.md#building-ts-files). +When using Sendable in HAR, you must enable the configuration for compiling and generating TS files. For details, see [Building TS Files](../quick-start/har-package.md#building-ts-files). ## Rules for Interaction with TS/JS @@ -439,27 +447,27 @@ When using **Sendable** in HAR, enable the configuration of generating TS files. ### ArkTS General Rules (Only for Sendable Objects Currently) -| Rule Description| +| Rule| | -------- | -| When a sendable object is passed to a TS/JS interface, the object layout cannot be operated (adding or deleting properties, or changing property types).| -| When a sendable object is set to a TS/JS object, the object layout cannot be operated (adding or deleting properties, or changing property types) after the TS/JS object obtains the sendable object.| -| When a sendable object is placed in a TS/JS container, the object layout cannot be operated (adding or deleting properties, or changing property types) after the TS/JS object obtains the sendable object.| +| Do not modify the object layout (add or delete properties, or change property types) of Sendable objects when passing them to TS/JS interfaces.| +| Do not modify the object layout (add or delete properties, or change property types) of Sendable objects when setting them to TS/JS objects.| +| Do not modify the object layout (add or delete properties, or change property types) of Sendable objects when placing them in TS/JS containers.| -> **Note** +> **NOTE** > -> Changes of the property types do not include changes of the sendable object types, for example, from Sendable class A to Sendable class B. +> Changing the property type does not include changing the type of a Sendable object, such as from Sendable class A to Sendable class B. -### Native API Rules (Only for Sendable Objects Currently) +### NAPI Rules (Only for Sendable Objects Currently) -| Rule Description| +| Rule| | -------- | -| Do not delete properties. The **napi_delete_property** interface cannot be used.| -| Do not add properties. The following interfaces cannot be used: **napi_set_property**, **napi_set_named_property**, and **napi_define_properties**.| -| Do not modify property types. The following interfaces cannot be used: **napi_set_property**, **napi_set_named_property**, and **napi_define_properties**.| -| Symbol-related interfaces and types are not supported. The following interfaces cannot be used: **napi_create_symbol**, **napi_is_symbol_object**, and **napi_symbol**.| +| Do not delete properties. Prohibited interfaces: **napi_delete_property**.| +| Do not add properties. Prohibited interfaces: **napi_set_property**, **napi_set_named_property**, and **napi_define_properties**.| +| Do not change property types. Prohibited interfaces: **napi_set_property**, **napi_set_named_property**, and **napi_define_properties**.| +| Symbol-related interfaces and types are not supported. Prohibited interfaces: **napi_create_symbol**, **napi_is_symbol_object**, and **napi_symbol**.| ## Rules for Interaction with the UI -The Sendable data needs to be used together with the [makeObserved](../quick-start/arkts-new-makeObserved.md) to observe the data changes of the Sendable object. For details, see [Using makeObserved Together with @Sendable Decorated Classes](../quick-start/arkts-new-makeObserved.md#using-makeobserved-together-with-sendable-decorated-classes). +To observe data changes in Sendable objects when interacting with UI, Sendable data must be used in conjunction with [makeObserved](../quick-start/arkts-new-makeObserved.md). For more information, see [Using makeObserved and @Sendable Decorated Class Together](../quick-start/arkts-new-makeObserved.md#using-makeobserved-and-sendable-decorated-class-together). diff --git a/en/application-dev/arkts-utils/sendable-freeze.md b/en/application-dev/arkts-utils/sendable-freeze.md index e739b2bb3b7633b4d72a64bcf36dcfc708532f90..5c51a4654e199443ca3cc4ca1c77d685b010e21d 100644 --- a/en/application-dev/arkts-utils/sendable-freeze.md +++ b/en/application-dev/arkts-utils/sendable-freeze.md @@ -1,10 +1,10 @@ -# Freezing a Sendable Object +# Freezing Sendable Objects -Sendable objects can be frozen. Frozen objects become read-only objects and cannot be added, deleted, or modified. Therefore, no lock is required for concurrent access between multiple instances. You can call the [Object.freeze](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze) API to freeze objects. +Sendable objects can be frozen, making them read-only and preventing any additions, deletions, or modifications to their properties. Once frozen, these objects can be safely accessed across multiple concurrent instances without the need for locks. This is achieved using the [Object.freeze](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze) method. -## Samples +## Usage Example -1. Provides the Object.freeze method encapsulated in TS files. +1. Encapsulate the **Object.freeze** method in a TS file. ```ts // helper.ts @@ -13,7 +13,7 @@ Sendable objects can be frozen. Frozen objects become read-only objects and cann } ``` -2. Call the freeze method to freeze the object and send the object to the subthread. +2. Call the **freeze** method to freeze an object and send it to a child thread. ```ts // Index.ets @@ -22,10 +22,10 @@ Sendable objects can be frozen. Frozen objects become read-only objects and cann @Sendable export class GlobalConfig { - // Configuration attributes and methods. + // Configuration properties and methods init() { - // Initialize the logic. - freezeObj(this) // Freeze this object after the initialization is complete. + // Initialization logic + freezeObj(this) // Freeze the object after the initialization is complete. } } @@ -51,7 +51,7 @@ Sendable objects can be frozen. Frozen objects become read-only objects and cann } ``` -3. Subthreads directly operate objects without locking them. +3. Perform operations on the frozen object directly in the child thread without locking. ```ts // Worker.ets diff --git a/en/application-dev/arkts-utils/sendable-guide.md b/en/application-dev/arkts-utils/sendable-guide.md index 151209d3292cb338c9c1ab4f52990863f77940a8..b7e9770414b8aef91a29c1b75588bb45b24c59ee 100644 --- a/en/application-dev/arkts-utils/sendable-guide.md +++ b/en/application-dev/arkts-utils/sendable-guide.md @@ -1,13 +1,13 @@ -# Sendable Use Scenarios -Sendable objects can be passed by reference between concurrent instances. Compared with the serialization mode, the reference transfer mode is more efficient and does not lose the member methods carried in the class. Therefore, Sendable can solve the following problems: +# Use Scenarios of Sendable +Sendable objects can be passed by reference between concurrent instances. This approach is more efficient than serialization and preserves methods carried in class instances. As a result, Sendable is particularly useful in two scenarios: -- Transferring a large amount of data (for example, more than 100 KB) across concurrent instances +- Transmitting a large amount of data (for example, data exceeding 100 KB) across concurrent instances -- Passing a class instance object carrying methods across concurrent instances +- Passing class instances carrying methods across concurrent instances -## Big data transmission across concurrent instances +## Transmitting Large Data Across Concurrent Instances -The overhead of serialization across concurrent instances increases linearly with the data volume. When a large amount of data is transmitted (100 KB data takes about 1 ms to transmit), the overhead of data copy across concurrent instances is high, adversely affecting the parallelization performance. On the contrary, passing objects by reference improves performance. +Serialization overhead increases linearly with the amount of data. When transmitting large data volumes (100 KB taking approximately 1 ms), the copying overhead can significantly impact application performance. On the contrary, passing objects by reference can greatly enhance performance. **Example** @@ -24,7 +24,7 @@ async function taskFunc(obj: Test) { } async function test() { - // Use TaskPool for data transfer. + // Use TaskPool to pass data. let a: testTypeA = new testTypeA("testTypeA"); let b: testTypeB = new testTypeB("testTypeB"); let obj: Test = new Test(a, b); @@ -75,7 +75,7 @@ struct Index { ```ts // sendable.ets -// Assemble the data of a large size in a sendable class. +// Assemble large data in a Sendable class. @Sendable export class testTypeA { name: string = "A"; @@ -104,9 +104,9 @@ export class Test { ``` -## Passing a class instance object carrying methods across concurrent instances +## Passing Class Instances Carrying Methods Across Concurrent Instances -Methods will be lost during serialization of instance objects. In scenarios where instance methods must be called, use pass-by-reference. If data needs to be parsed during data processing, you can use the [ASON tool](ason-parsing-generation.md) to parse the data. +Methods are lost during serialization of instance objects. Therefore, in scenarios where instance methods must be called, passing objects by reference is essential. If data parsing is required during processing, the [ASON utility](ason-parsing-generation.md) can be used for data parsing. **Example** @@ -131,12 +131,12 @@ async function taskFunc(sendableObj: SendableTestClass) { let jsonStr = '{"name": "Alexa", "age": 23, "sex": "female"}'; let obj = ArkTSUtils.ASON.parse(jsonStr) as ISendable; console.info("SendableTestClass: type is: " + typeof obj); - console.info("SendableTestClass: name is: " + (obj as object)?.["name"]); // output: 'Alexa' - console.info("SendableTestClass: age is: " + (obj as object)?.["age"]); // output: 23 - console.info("SendableTestClass: sex is: " + (obj as object)?.["sex"]); // output: 'female' + console.info("SendableTestClass: name is: " + (obj as object)?.["name"]); // Output: 'Alexa' + console.info("SendableTestClass: age is: " + (obj as object)?.["age"]); // Output: 23 + console.info("SendableTestClass: sex is: " + (obj as object)?.["sex"]); // Output: 'female' } async function test() { - // Use TaskPool for data transfer. + // Use TaskPool to pass data. let obj: SendableTestClass = new SendableTestClass(); let task: taskpool.Task = new taskpool.Task(taskFunc, obj); await taskpool.execute(task); @@ -169,7 +169,7 @@ struct Index { ```ts // sendable.ets -// Define a Test class to simulate the transfer of a class carrying methods. +// Define a Test class to simulate the operation of passing a class instance carrying methods. import { lang, collections } from '@kit.ArkTS' export type ISendable = lang.ISendable; diff --git a/en/application-dev/arkts-utils/shared-arraybuffer-object.md b/en/application-dev/arkts-utils/shared-arraybuffer-object.md index 59d9623cc5d5d021656372b39688ee4eb346acab..64a9a6bd2f8aa7037a27833d5c9fbe47d3b56de4 100644 --- a/en/application-dev/arkts-utils/shared-arraybuffer-object.md +++ b/en/application-dev/arkts-utils/shared-arraybuffer-object.md @@ -1,13 +1,13 @@ # SharedArrayBuffer Object -SharedArrayBuffer contains a native memory block, which can be shared across concurrent instances. However, the Atomics class must be used for access and modification to prevent data competition. SharedArrayBuffer can be used for state sharing or data sharing between multiple concurrent instances. The following figure shows the communication process. +A SharedArrayBuffer object contains a block of native memory, and its JS object wrapper is allocated in the local heap of the virtual machine. It allows sharing across concurrent instances but requires the use of the Atomics class to manage access and modifications, thereby preventing data races. It is suitable for sharing state or data among multiple concurrent instances. The following figure shows the communication process. ![sharedarraybufer](figures/sharedarraybufer.png) -## Samples +## Usage Example -The following is a simple example of using TaskPool to transfer an Int32Array object: +The following is a simple example of using TaskPool to pass an Int32Array object: ```ts import { taskpool } from '@kit.ArkTS'; diff --git a/en/application-dev/arkts-utils/source-obfuscation.md b/en/application-dev/arkts-utils/source-obfuscation.md index 650661244ee097e358ee14d26dde86aabb7db595..f9d9939c199786b742c0f65cb79fbae691fba801 100644 --- a/en/application-dev/arkts-utils/source-obfuscation.md +++ b/en/application-dev/arkts-utils/source-obfuscation.md @@ -1,4 +1,4 @@ -# ArkGuard +# ArkGuard for Code Obfuscation ## Overview @@ -6,14 +6,13 @@ Source code obfuscation helps reduce the risk of application hacking as well as >**NOTE** > -> 1. In versions earlier than DevEco Studio 5.0.3.600, code obfuscation is enabled by default for a new project. It automatically obfuscates the code of the stage model of API10 or later. This operation applies only to code compiled in [release mode](#usage-description), and obfuscation is limited to parameter names and local variable names. -> 2. In DevEco Studio 5.0.3.600 and later versions, code obfuscation is disabled by default when you create a project. To enable code obfuscation, set the ruleOptions.enable field in the build-profile.json5 file of the module to true. In addition, the obfuscation-rules.txt configuration file enables four recommended obfuscation options by default: -enable-property-obfuscation, -enable-toplevel-obfuscation, -enable-filename-obfuscation, and -enable-export-obfuscation. You can modify the obfuscation configuration as required. Note that enabling the four rules may cause the app to crash during running. Therefore, you are advised to rectify the app functions by referring to [Troubleshooting](#troubleshooting). +> 1. In DevEco Studio versions prior to 5.0.3.600, code obfuscation is enabled by default for new projects, and code developed on the stage model using API version 10 or later is automatically obfuscated. This applies only to code compiled in [release mode](#remarks), and obfuscation applies only to parameter names and local variable names. +> 2. In DevEco Studio 5.0.3.600 and later versions, code obfuscation is disabled by default for new projects. If you want to enable obfuscation, set the **ruleOptions.enable** field in the **build-profile.json5** file of the module to **true**. The **obfuscation-rules.txt** file has the following options enabled by default: **-enable-property-obfuscation**, **-enable-toplevel-obfuscation**, **-enable-filename-obfuscation**, and **-enable-export-obfuscation**. You can customize the obfuscation settings as needed. Enabling the four options may cause the application to crash at runtime. You are advised to read [Enabling Code Obfuscation](#enabling-code-obfuscation) to rectify the fault. ### Constraints * Only the projects developed on the stage model are supported. * The build mode of the project is release. -* The **disable-obfuscation** option is not configured for the module and the HAR on which the module depends. ### Code Obfuscation Scope @@ -22,83 +21,141 @@ In a project, the following files can be obfuscated, and the cache files after o * ArkTS files * TS files * JS files + +### Limitations -## Enabling Code Obfuscation +**Language Limitations** -Code obfuscation has been integrated into the system and can be enabled for use in DevEco Studio. +Code obfuscation tools vary in type analysis mechanisms, obfuscation strategies, and execution efficiency based on the target language. For example, ProGuard targets strongly-typed languages like Java, where each type has a clear definition source. This feature makes the type relationship tracing and processing in the obfuscation process more accurate, greatly reducing the need for retention rules. -Currently, only name obfuscation is provided. Other obfuscation capabilities deteriorate performance. You can use code obfuscation to obfuscate the following names: +In contrast, ArkGuard targets JS, TS, and ArkTS. JS supports dynamic modification of objects and functions at runtime, but obfuscation is a static process in the compilation phase. This difference may cause a failure in parsing obfuscated named at runtime, resulting in runtime exceptions. TS and ArkTS use a structural type system, where different named types with the same structure are considered as equivalent types. Therefore, it is difficult to trace the exact source of types. As such, when using ArkGuard, you need to configure trustlists for more syntax scenarios. Moreover, ArkGuard uses a global property retention mechanism that retains all properties with the same name according to the trustlist. It does not support precise retention settings for specific types. -* Parameter names and local variable names -* Top-level scope names -* Property names -* Exported names -* File names +To illustrate, consider this example: -After code obfuscation is enabled, parameter names and local variable names will be obfuscated by default. No option needs to be configured. Obfuscation of top-level scope name, property names, exported names, and file names may cause runtime errors. You can enable or disable these obfuscation capabilities by configuring obfuscate options. +Assume that ArkGuard allows the configuration of a trustlist for specific types. If class A1 is configured in a trustlist with its property prop1, but prop1 in class A2 is not in the trustlist, passing an instance of A2 (a2) to the **test** function would cause issues when accessing the prop1 property. -When a module is created, the following content is automatically generated in the module-level build-profile.json5 file: +```typescript +// Before obfuscation: +class A1 { + prop1: string = ''; +} -``` -"arkOptions": { - "obfuscation": { - "ruleOptions": { - "enable": true, - "files": ["./obfuscation-rules.txt"], - } - } +class A2 { + prop1: string = ''; } -``` -When a library is created, the **consumerFiles** field is automatically generated in addition to the preceding content. +function test(input: A1) { + console.log(input.prop1); +} +let a2 = new A2(); +a2.prop1 = 'prop a2'; +test(a2); ``` -"arkOptions": { - "obfuscation": { - "ruleOptions": { - "enable": true, - "files": ["./obfuscation-rules.txt"], - } - "consumerFiles": ["./consumer-rules.txt"] - } + +```typescript +// After obfuscation: +class A1 { + prop1: string = ''; +} + +class A2 { + a: string = ''; } + +function test(input: A1) { + console.log(input.prop1); +} + +let a2 = new A2(); +a2.a = 'prop a2'; +test(a2); ``` -If you disable code obfuscation and then want to enable it again, the value of **ruleOptions.enable** must be **true**. +You should be aware of these differences and use unique names to achieve better obfuscation results. -The obfuscation configuration files specified in the **ruleOptions.files** field take effect when the HAP, HSP, or HAR is built. -The obfuscation configuration files specified in the **consumerFiles** field take effect when the module that depends on the library is built. The contents of these obfuscation configuration files are also merged into the **obfuscation.txt** file in the HAR. +**Limited Security Assurance** -During the build of the HAP, HSP, or HAR, the final obfuscation rules are the combination of the **ruleOptions.files** field of the current module, the **consumerFiles** field of the dependent library, and the **obfuscation.txt** file in the dependent HAR. -During HAR build, the **obfuscation.txt** file in the HAR contains the combination of the **consumerFiles** field of the current HAR, the **consumerFiles** field of the dependent library, and the **obfuscation.txt** file in the dependent HAR. No **obfuscation.txt** file is generated during HAP or HSP build. For details about the merge policy, see [Obfuscation Rule Merge Policy](#obfuscation-rule-merge-policy). +Like other obfuscation tools, ArkGuard increases reverse engineering difficulty but cannot prevent it entirely. -### Obfuscation Rule Configuration File +You should not rely solely on ArkGuard for security. For higher security requirements, consider [application encryption](https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V5/code-protect-V5) and third-party hardening measures. -During the creation of a project or library, DevEco Studio automatically generates the **obfuscation-rules.txt** and **consumer-rules.txt** files. You can write obfuscation rules into these files or other user-defined files, and then add the file paths in **ruleOptions.files** and **consumerFiles**, as shown in the following example. +## Enabling Code Obfuscation -``` -"buildOption": { - "arkOptions": { - "obfuscation": { - "ruleOptions": { - "enable": true, - "files": ["./obfuscation-rules.txt", "./myrules.txt"], // Place myrules.txt in the same directory as the build-profile.json5 file. +### How to Use +Code obfuscation has been integrated into the system and can be enabled for use in DevEco Studio. + +* Enabling the obfuscation switch + + To enable obfuscation, set the **enable** field to **true** under **arkOptions.obfuscation.ruleOptions** in the **build-profile.json5** file of your module. The default values of the **enable** field may vary across different versions of DevEco Studio. For details, see [version differences](#overview). + ``` + "arkOptions": { + "obfuscation": { + "ruleOptions": { + "enable": true, + "files": ["./obfuscation-rules.txt"], + } } - "consumerFiles": ["./consumer-rules.txt", "./my-consumer-rules.txt"] } - } -} -``` + ``` + +* Configuring obfuscation rules + + Enabling the obfuscation switch activates the default settings, which include obfuscation of local variables and parameters. To enable additional obfuscation features, customize the **obfuscation-rules.txt** file specified in the **files** field. The default values in the **obfuscation-rules.txt** file may vary across different versions of DevEco Studio. For details, see [version differences](#overview). + +* Specifying release compilation + + Currently, code obfuscation is supported only for release builds, not for debug builds. This means that obfuscation will only be applied when a module is compiled in release mode, not in debug mode. You can view and modify the build mode by referring to [Specifying a Build Mode](https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V5/ide-hvigor-compilation-options-customizing-guide-V5#section192461528194916). + + > **NOTE** + > + > The differences between release and debug builds extend beyond obfuscation. To determine whether application behavior differences are due to obfuscation, you should enable or disable the obfuscation switch rather than simply switching between release and debug builds. + +### Obfuscation Configuration Files +* `obfuscation-rules.txt` + + For HAP, HAR, and HSP modules, the **arkOptions.obfuscation.ruleOptions.files** field in the **build-profile.json5** file specifies obfuscation rules applied during module compilation. A default **obfuscation-rules.txt** file is created when a new project is set up. + +* `consumer-rules.txt` + + For HAR modules, an additional **arkOptions.obfuscation.consumerFiles** field is available in the **build-profile.json5** file. This field specifies obfuscation rules that should be applied when this package is depended upon in other modules. A default **consumer-rules.txt** file is created when a new HAR module is set up. The key difference between **consumer-rules** and **obfuscation-rules** is as follows: **obfuscation-rules** applies to the compilation of the current module, whereas **consumer-rules** applies to the compilation of other modules that depend on the current module. + ``` + "arkOptions": { + "obfuscation": { + "ruleOptions": { + "enable": true, + "files": ["./obfuscation-rules.txt"], + } + "consumerFiles": ["./consumer-rules.txt"] + } + } + ``` + +* `obfuscation.txt` + + Unlike the above two files, **obfuscation.txt** is automatically generated based on **consumer-rules.txt** and the obfuscation rules of dependent modules during HAR compilation. It exists as a compilation product within the released HAR package and used to apply obfuscation rules when other applications use this package. For details about the generation and logic of **obfuscation.txt**, see [Obfuscation Rule Merging Strategies](#obfuscation-rule-merging-strategies). + + > **NOTE** + > + > For third-party libraries, the **obfuscation.txt** file only takes effect when the module's **oh-package.json5** file depends on the library. If the dependency is specified in the project's **oh-package.json5** file, the **obfuscation.txt** file in the third-party library will not take effect. + +The following table summarizes the differences between these configuration files. + +| Configuration File| Configuration Type| Modifiable | Affects Obfuscation of This Module | Affects Obfuscation of Other Modules | +| --- | --- | --- | --- | --- | +| obfuscation-rules.txt | Customizable | Yes| Yes| No| +| consumer-rules.txt | Customizable | Yes| No| Yes| +| obfuscation.txt | Compilation product| Not applicable (automatically generated during HAR compilation)| Not applicable| Yes| -## Configuring Obfuscation Rules +## Obfuscation Rules -There are two types of obfuscation rules: [obfuscate options](#obfuscate-options) and [keep options](#keep-options). The former provides a switch for multiple obfuscation capabilities, such as obfuscation of top-level scope names, property names, and file names. The latter provides the trustlist configuration of various obfuscation capabilities. +There are two types of obfuscation rules: [obfuscation options](#obfuscation-options) and [retention options](#retention-options). The former provides a switch for multiple obfuscation capabilities, such as obfuscation of top-level scope names, property names, and file names. The latter provides the trustlist configuration of various obfuscation capabilities. **NOTE** -Any modification to the obfuscation configuration takes effect only after a full build of the application. +Any modification to the obfuscation configuration file takes effect only after a full build. -### Obfuscate Options +### Obfuscation Options #### -disable-obfuscation @@ -108,7 +165,7 @@ Disables code obfuscation. If this option is used, the built HAP, HSP, or HAR is Enables property obfuscation. If this option is used, all property names except the following are obfuscated: -* Property names of classes and objects that are directly imported or exported by using the **import** or **export** statement. For example, the property name **data** in the following example is not obfuscated. +* Property names of classes and objects that are directly imported or exported by using **import** or **export**. For example, the property name **data** in the following example is not obfuscated. ``` export class MyClass { @@ -122,12 +179,12 @@ Enables property obfuscation. If this option is used, all property names except @Component struct MyExample { @State message: string = "hello"; data: number[] = []; - ... + // ... } ``` -* Property names specified by [keep options](#keep-options). -* Property names in the SDK API list. The SDK API list is a name set automatically extracted from the SDK during build. The cache file is **systemApiCache.json**, which is stored in **build/default/cache/{...}/release/obfuscation** in the project directory. +* Property names specified by [retention options](#retention-options). +* Property names in the SDK API list. The SDK API list is a set of names automatically extracted from the SDK during build. Its cache file is **systemApiCache.json**, which is stored in **build/default/cache/{...}/release/obfuscation** in the project directory. * String literal property names. For example, **"name"** and **"age"** in the following example are not obfuscated. ``` @@ -135,7 +192,7 @@ Enables property obfuscation. If this option is used, all property names except person["age"] = 22; ``` - If you want to obfuscate the string literal property name, use the **-enable-string-property-obfuscation** option in addition to the current option, as follows: + If you want to obfuscate the string literal property name, use the **-enable-string-property-obfuscation** option in addition to the current option, Example: ``` -enable-property-obfuscation @@ -144,7 +201,7 @@ Enables property obfuscation. If this option is used, all property names except **NOTE** - **1.** If a string literal property name in the code contains special characters, for example, **let obj = {"\n": 123, "": 4, " ": 5}**, you are advised not to use the **-enable-string-property-obfuscation** option because these names may fail to be kept using [keep options](#keep-options). Special characters refer to characters other than lowercase letters a-z, uppercase letters A-Z, digits 0-9, and underscores (_). + **1.** If a string literal property name in the code contains special characters, for example, **let obj = {"\n": 123, "": 4, " ": 5}**, you are advised not to use the **-enable-string-property-obfuscation** option because these names may fail to be kept using [retention options](#retention-options). Special characters refer to characters other than lowercase letters a-z, uppercase letters A-Z, digits 0-9, and underscores (_). **2.** The property trustlist of the SDK API list does not contain the string constants used in the declaration file. For example, the string **'ohos.want.action.home'** in the example is not included in the property trustlist. ``` @@ -156,7 +213,7 @@ Enables property obfuscation. If this option is used, all property names except let params = obj['ohos.want.action.home']; ``` - When the **-enable-string-property-obfuscation** option is used, use the keep option if you want to keep the property names of the SDK API string constants used in the source code, for example, **obj['ohos.want.action.home']**. + When the **-enable-string-property-obfuscation** option is used, use the retention option if you want to retain the property names of the SDK API string constants used in the source code, for example, **obj['ohos.want.action.home']**. #### -enable-toplevel-obfuscation @@ -164,12 +221,12 @@ Enables top-level scope name obfuscation. If this option is used, all names of a * Top-level scope names imported or exported using the **import** or **export** statement. * Top-level scope names that are not declared in the current file. -* Top-level scope names specified by [keep options](#keep-options). +* Top-level scope names specified by [retention options](#retention-options). * Top-level scope names in the SDK API list. #### -enable-filename-obfuscation -Enables file or folder name obfuscation. If this option is used, all file/folder names will be confused. For example: +Enables file or folder name obfuscation. If this option is used, all file or folder names are obfuscated. For example: ``` // Both directory and filename are confused. @@ -182,29 +239,23 @@ In addition to the following scenarios: * File or folder names specified by the **main** and **types** fields in the **oh-package.json5** file. * File or folder names specified by the **srcEntry** field in the **module.json5** file of the module. -* File or folder names specified by [-keep-file-name](#keep-options). -* File or folder names in non-ECMAScript module reference mode. An ECMAScript module example is **import {foo} from './filename'**. -* File or folder names in non-path reference mode. For example, **json5** in the example **import module from 'json5'** is not obfuscated. +* File or folder names specified by [-keep-file-name](#retention-options). +* File or folder names in non-ECMAScript module reference mode (for example, const module = require('./module')). +* File or folder names in non-path reference mode. For example, **json5** in the example **import module from 'json5'** is not obfuscated. **NOTE** -The system loads certain files during application running. For these files, manually configure a trustlist in the [`-keep-file-name`] option to prevent them from being obfuscated. Otherwise, the application may fail to run. -In the following scenarios, you need to manually configure a trustlist: +For files that the system needs to load files during application running, manually configure them into a trustlist using the [-keep-file-name](#retention-options) option. Otherwise, the application may fail to run. -* The module contains an ability component. In this case, add all paths configured for **srcEntry** under the **abilities** field in **src/main/module.json5** to the trustlist. -* The module contains the multithreading service: Worker. In this case, add all paths under the **buildOption'-'sourceOption'-'workers'** field in **build-profiles.json5** to the trustlist. - -**Reminder** - -The names of the compilation entry file, ability component file, and worker multithreaded file cannot be obfuscated and have been automatically added to the trustlist in DevEco Studio 5.0.3.500. No manual configuration is required. For other files that cannot be obfuscated, you need to manually configure their names in the trustlist. +The names of the compilation entry file, ability component file, and Worker multithreaded file cannot be obfuscated and have been automatically added to the trustlist in DevEco Studio 5.0.3.500. No manual configuration is required. For other files that cannot be obfuscated, you need to manually configure their names in the trustlist. #### -enable-export-obfuscation Enables obfuscation for names of classes or objects that are directly imported or exported and their property names. If this option is used, the names directly imported or exported in the module are obfuscated, except the following: -* Names of classes or objects exported from remote HARs (packages whose real paths are in oh_modules) and their property names. -* Names and property names specified by [keep options](#keep-options). -* Names in the SDK API list. +* Names of classes or objects exported from remote HARs (packages whose real paths are in **oh_modules**) and their property names are not obfuscated. +* Names and property names specified by [retention options](#retention-options) are not obfuscated. +* Names in the SDK API list are not obfuscated. **NOTE** @@ -216,7 +267,7 @@ Enables obfuscation for names of classes or objects that are directly imported o // Code example (entry file Index.ets in the HSP): export { add, customApiName } from './src/main/ets/utils/Calc' - // Example of keeping an interface name: + // Example of retaining an interface name: // Configuration of the obfuscation-rules.txt file in the HSP and modules that depend on the HSP: -keep-global-name add @@ -236,9 +287,21 @@ The stack information built in release mode contains the line number of code, bu Removes the expressions involving direct calls to the **console.** statement in the following scenarios: 1. Calls at the top layer of a file. -2. Calls within a code block. -3. Calls within a module. -4. Calls within a switch statement. +2. Calls within a code block. + Example: + ``` + function foo() { + console.log('in block'); + } + ``` +3. Calls with a module or namespace. + Example: + ``` + namespace ns { + console.log('in ns'); + } + ``` +4. Calls within a **switch** statement. #### -print-namecache *filepath* @@ -246,7 +309,7 @@ Saves the name cache to the specified file path. The name cache contains mapping **NOTE** -A new **namecache.json** file is generated each time the module if fully built. Save a copy of the file each time you publish a new version. +A new **namecache.json** file is generated each time the module if fully built. Therefore, save a copy of the file each time you publish a new version. #### -apply-namecache *filepath* @@ -254,7 +317,7 @@ Reuses the specified name cache file. The names will be obfuscated according to This option should be used in incremental build scenarios. By default, DevEco Studio saves cache files in a temporary cache directory and automatically applies the cache files during incremental build. -Cache Directory: **build/default/cache/{...}/release/obfuscation** +Default cache directory: **build/default/cache/{...}/release/obfuscation** #### -remove-comments @@ -262,69 +325,14 @@ Removes JsDoc comments from the declaration file generated after compilation. **NOTE** -By default, all comments in the source code file generated after the build are removed and cannot be kept. -You can configure **keep-comments** to keep the JsDoc comments in the declaration file from being obfuscated. - -#### -print-kept-names *filepath* - -Prints the keep-name list and full trustlist. The **filepath** parameter is optional. - -If the **filepath** parameter is not specified, the keep-name list (**keptNames.json**) and full trustlist (**whitelist.json**) are output to the cache directory **build/default/cache/{...}/release/obfuscation** by default. - -If the **filepath** parameter is specified, the keep-name list is also exported to the path specified by this parameter. The file path specified must be a relative path, which starts from the directory where the obfuscation configuration file is currently located. The file name extension in the file path must be .json. +By default, all comments in the source code file generated after the compilation are removed and cannot be retained. +You can configure **keep-comments** to retain the JsDoc comments in the declaration file. -The full trustlist (**whitelist.json**) contains all trustlists collected during module compilation. It is classified into the following types: - -(1) 'sdk': system APIs. - -(2) 'lang': keywords in the language. - -(3) 'conf': trustlist in the user-defined keep options. - -(4) 'struct': properties in ArkUI structs. - -(5) 'export': names and properties exported. - -(6) 'strProp': string properties. - -(7) 'enum': indicates a member in the enum. - -The **keptNames.json** file contains the names that are not obfuscated and the reasons why they are not obfuscated. There are seven reasons: The name is the same as that in the SDK trustlist, language trustlist, user-defined trustlist, struct trustlist, exported name trustlist, or string property trustlist (when string property obfuscation is disabled), or enum trustlist (during HAR module compilation). - -**NOTE** - -1. When the har module is compiled and attribute obfuscation is enabled, the'enum' whitelist collects the member names in the enum. - -Example: - -``` -enum Test { - member1, - member2 -} -``` - -The enum whitelist content is ['member1', 'member2']. This is because the compilation intermediate product of the HAR module in earlier versions is a JS file. In the JS file, the enum type is converted into an immediate execution function, and the enum member is converted into a string attribute and a string constant. Therefore, to ensure that the function is normal when attribute obfuscation is enabled, you need to collect the enum member names as a whitelist. This feature is retained when the new bytecode har module is compiled. - -2. When the hap/hsp/bytecode har module is compiled and attribute obfuscation is enabled, the'enum' whitelist collects the variable names contained in the initialization expression when the members of enum are initialized. - -Example: - -``` -let outdoor = 1; -enum Test { - member1, - member2 = outdoor + member1 + 2 -} -``` - -When the hap/hsp module is compiled, content of the enum whitelist is ['outdoor', 'member1']. When the bytecode har module is compiled, content of the enum whitelist is ['outdoor', 'member1', 'member2']. - -### Keep Options +### Retention Options #### -keep-property-name *[,identifiers,...]* -Keeps the specified property names from being obfuscated. Name wildcards are supported. An example is as follows. +Retains the specified property names. Name wildcards are supported. An example is as follows. ``` -keep-property-name @@ -337,89 +345,115 @@ lastName > > - This option takes effect when **-enable-property-obfuscation** is used. > -> - The attribute whitelist takes effect globally. That is, if multiple attributes with the same name exist in the code, they will not be confused as long as they are the same as those in the whitelist configured in -keep-property-name. - -What property names should be kept? +> - The property trustlist applies globally. That is, if multiple properties with the same name exist in the code, they will not be confused as long as they match the names in the trustlist configured in **-keep-property-name**. -For safety, you are advised to keep all properties that are not accessed through dot notation. +**Which property names should be retained?** -Example: +1. To ensure correct obfuscation, you are advised to retain all properties that are not accessed using dot notation. For example, object properties accessed via strings: ``` var obj = {x0: 0, x1: 0, x2: 0}; for (var i = 0; i <= 2; i++) { - console.log(obj['x' + i]); // x0, x1, and x2 should be kept. + console.info(obj['x' + i]); // x0, x1, and x2 should be retained. } -Object.defineProperty(obj, 'y', {}); // y should be kept. +Object.defineProperty(obj, 'y', {}); // y should be retained. +Object.getOwnPropertyDescriptor(obj, 'y'); // y should be retained. console.info(obj.y); obj.s = 0; let key = 's'; -console.log(obj[key]); // s should be kept. - -obj.u = 0; -console.log(obj.u); // u can be correctly obfuscated. +console.info(obj[key]); // The variable value s corresponding to key should be retained. -obj.t = 0; -console.log(obj['t']); // When obfuscation of string literal property names is enabled, both t and 't' can be correctly obfuscated. However, it is recommended that 't' be kept. - -obj['v'] = 0; -console.log(obj['v']); // When obfuscation of string literal property names is enabled, 'v' can be correctly obfuscated. However, it is recommended that 'v' be kept. +obj.t1 = 0; +console.info(obj['t' + '1']); // t1 should be retained. ``` -In the case of indirect exports, for example, **export MyClass** and **let a = MyClass; export {a}**, if you do not want to obfuscate property names, use [keep options](#keep-options) to keep them. For property names of directly exported classes or objects, such as **name** and **age** in the following example, if you do not want to obfuscate them, use [keep options](#keep-options) to keep them. +For the following string literal property calls, you can choose to retain them. ``` -export class MyClass { - person = {name: "123", age: 100}; -} -``` - -If an API (for example, **foo** in the example) of the .so library needs to be used in the ArkTS/TS/JS file, manually keep the API name. - -``` -import testNapi from 'library.so' -testNapi.foo() // foo should be kept. Example: -keep-property-name foo -``` - -Manually keep the fields used in JSON files. - -``` -const jsonData = ('./1.json') -let jsonStr = JSON.parse(jsonData) -let jsonObj = jsonStr.jsonProperty // jsonProperty should be kept. -``` - -Manually keep database-related fields. - -``` -const dataToInsert = { - value1: 'example1', // value1 should be kept. -}; -``` - -The custom decorator in the source code modifies member variables, member methods, and parameters, and the intermediate product of the source code compilation is a JS file (for example, the HAR of the release source code is compiled or the source code contains @ts-ignore and @ts-nocheck). The names of the member variables or member methods where these decorators are located need to be retained. This is because when the advanced TS syntax feature is converted to the standard JS syntax, the member variable or member method name of the preceding decorator is hard-coded into a string constant. - -Example: +// Obfuscation configuration: +// -enable-property-obfuscation +// -enable-string-property-obfuscation -``` -class A { - // 1. Member variable decorator - @CustomDecoarter - The propetyName: string = "" // propetyName needs to be reserved. - // 2. Member method decorator - @MethodDecoarter - methodName1 () {} // methodName1 needs to be reserved. - // 3. Method parameter decorator. - The methodName2(@ParamDecorator param: string): void { // methodName2 needs to be reserved. - } -} -``` +obj.t = 0; +console.info(obj['t']); // 't' will be correctly confused, and t can be retained. + +obj.['v'] = 0; +console.info(obj['v']); // 'v' will be correctly confused, and v can be retained. +``` + +2. In the case of indirect exports, for example, **export MyClass** and **let a = MyClass; export {a}**, if you do not want to obfuscate property names, use [retention options](#retention-options) to retain them. For property names of directly exported classes or objects, such as **name** and **age** in the following example, if you do not want to obfuscate them, use [retention options](#retention-options) to retain them. + + ``` + export class MyClass { + person = {name: "123", age: 100}; + } + ``` + +3. If an API (for example, **foo** in the example) of the .so library needs to be used in the ArkTS/TS/JS file, manually retain the API name. + + ``` + import testNapi from 'library.so' + testNapi.foo() // foo should be retained Example: -keep-property-name foo + ``` + +4. Fields used in JSON parsing and object serialization should be retained. + + ``` + // Example JSON file structure (test.json): + /* + { + "jsonProperty": "value", + "otherProperty": "value2" + } + */ + + const jsonData = fs.readFileSync('./test.json', 'utf8'); + let jsonObj = JSON.parse(jsonData); + let jsonProp = jsonObj.jsonProperty; // jsonProperty should be retained. + + class jsonTest { + prop1: string = ''; + prop2: number = 0 + } + + let obj = new jsonTest(); + const jsonStr = JSON.stringify(obj); // prop1 and prop2 will be obfuscated and should be retained. + ``` + +5. Database-related fields should be manually retained. For example, properties in the database key-value pair type (ValuesBucket): + + ``` + const valueBucket: ValuesBucket = { + 'ID1': ID1, // ID1 should be retained. + 'NAME1': name, // NAME1 should be retained. + 'AGE1': age, // AGE1 should be retained. + 'SALARY1': salary // SALARY1 should be retained. + } + ``` + +6. When custom decorators are used on member variables, member methods, or parameters in the source code, and the intermediate product of source code compilation is a JS file (for example, compiling release-mode source code HAR or source code containing @ts-ignore or @ts-nocheck), the names of these member variables or member methods should be retained. This is because the names of these member variables/methods are hardcoded as string literals during conversion from TS syntax to standard JS syntax. + + Example: + + ``` + class A { + // 1. Member variable decorator + @CustomDecoarter + propertyName: string = "" // propertyName should be retained. + // 2. Member method decorator + @MethodDecoarter + methodName1(){} // methodName1 should be retained. + // 3. Method parameter decorator + methodName2(@ParamDecorator param: string): void { // methodName2 should be retained. + } + } + ``` #### -keep-global-name *[,identifiers,...]* -Keep the top-level scope names from being obfuscated. Name wildcards are supported. Example: +Retains the specified top-level scope names or imported/exported element names. Name wildcards are supported. Example: ``` -keep-global-name @@ -427,34 +461,34 @@ Person printPersonName ``` -The names exported from the namespace can also be retained using -keep-global-name. +Names exported from the namespace can also be retained using the **-keep-global-name** option. The following is an example: ``` export namespace Ns { - export const age = 18; // -keep-global-name age: reserved variable age - export function myFunc () {}; // -keep-global-name myFunc: reserved function myFunc + export const age = 18; // -keep-global-name age: retains variable age. + export function myFunc () {}; // -keep-global-name myFunc: retains function myFunc. } ``` > **NOTE** > -> The whitelist specified by -keep-global-name takes effect globally. That is, if multiple top-level scope names or export names exist in the code, they will not be confused as long as they are the same as the whitelist names configured in -keep-global-name. +> The trustlist specified by `-keep-global-name` applies globally. That is, if multiple top-level scope names or exported names exist in the code, they will not be confused as long as they match the names in the trustlist configured in **-keep-global-name**. -What top-level scope names should be kept? +**Which top-level scope names should be retained?** -In JavaScript, variables in the top-level scope are properties of **globalThis**. If **globalThis** is used to access a global variable in the code, the variable name should be kept. +In JavaScript, variables in the top-level scope are properties of **globalThis**. If **globalThis** is used to access a global variable in the code, the variable name should be retained. Example: ``` var a = 0; -console.log(globalThis.a); // a should be kept. +console.info(globalThis.a); // a should be retained. function foo(){} -globalThis.foo(); // foo should be kept. +globalThis.foo(); // foo should be retained. var c = 0; -console.log(c); // c can be correctly obfuscated. +console.info(c); // c can be correctly obfuscated. function bar(){} bar(); // bar can be correctly obfuscated. @@ -463,15 +497,15 @@ class MyClass {} let d = new MyClass(); // MyClass can be correctly obfuscated. ``` -When an API of the SO library is imported by name, if both -enable-toplevel-obfuscation and -enable-export-obfuscation are enabled, you need to manually retain the API name. +When importing API names from .so libraries using named imports, if both **-enable-toplevel-obfuscation** and **-enable-export-obfuscation** are configured, the API names should be manually retained. ``` -import { testNapi, testNapi1 as myNapi } from 'library.so' // testNapi and testNapi1 should be reserved. +import { testNapi, testNapi1 as myNapi } from 'library.so' // testNapi and testNapi1 should be retained. ``` #### -keep-file-name *[,identifiers,...]* -Keeps the file or folder names from being obfuscated. You do not need to specify the file name extension. Name wildcards are supported. Example: +Retains the file or folder names. You do not need to specify the file name extension. Name wildcards are supported. Example: ``` -keep-file-name @@ -479,41 +513,41 @@ index entry ``` -What file names should be kept? +**Which file names should be retained?** -1. When the require command is used to introduce a file path, the path should be retained because ArkTS does not support the [CommonJS](../arkts-utils/module-principle.md#commonjs module) syntax. +1. When **require** is used to import file paths, the path should be retained. This is because ArkTS does not support [CommonJS](../arkts-utils/module-principle.md#commonjs module) syntax. -``` -The const module1 = require('./file1') // file1 should be reserved. -``` + ``` + const module1 = require('./file1') // file1 should be retained. + ``` -2. In dynamic reference mode, whether the parameter in the import function is a path cannot be identified. Therefore, the path should be reserved in this case. +2. For dynamically imported paths, since it is impossible to determine whether the parameter in the **import** function is a path, the path should be retained. -``` -The const moduleName = './file2' // file2 should be reserved. -const module2 = import(moduleName) -``` + ``` + const moduleName = './file2' // The path name file2 corresponding to moduleName should be retained. + const module2 = import(moduleName) + ``` -3. When using [dynamic routing](../ui/arkts-navigation-navigation.md#cross-package-dynamic-routing) for route jump, the path passed to the route should be preserved. Dynamic routing provides system routing tables and custom routing tables. If a custom route table is used for redirection, the method of configuring a whitelist is the same as that in the second dynamic reference scenario. If the system routing table is used for redirection, you need to add the path corresponding to the pageSourceFile field in the resources/base/profile/route_map.json file of the module to the whitelist. +3. When [dynamic routing](../ui/arkts-navigation-navigation.md#cross-package-dynamic-routing) is used for navigation, the path passed to the dynamic routing should be retained. Dynamic routing provides two modes: system routing table and custom routing table. If a custom routing table is used for redirection, the way to configure a trustlist is consistent with the second dynamic reference scenario. However, if the system routing table is used for redirection, the path corresponding to the **pageSourceFile** field in the **resources/base/profile/route_map.json** file of the module should be added to the trustlist. -``` - { - "routerMap": [ - { - "name": "PageOne", - The "pageSourceFile": "src/main/ets/pages/directory/PageOne.ets", // path must be reserved. - "buildFunction": "PageOneBuilder", - "data": { - "description" : "this is PageOne" - } - } - ] - } -``` + ``` + { + "routerMap": [ + { + "name": "PageOne", + "pageSourceFile": "src/main/ets/pages/directory/PageOne.ets", // The path should be retained. + "buildFunction": "PageOneBuilder", + "data": { + "description" : "this is PageOne" + } + } + ] + } + ``` #### -keep-comments *[,identifiers,...]* -Keeps the classes, functions, namespaces, enums, structs, interfaces, modules, types, and JsDoc comments above properties in the declaration file generated after compilation from being obfuscated. Name wildcards are supported. For example, to keep the JSDoc comments above the **Human** class in the declaration file, use the following configuration: +Retains the classes, functions, namespaces, enums, structs, interfaces, modules, types, and JsDoc comments above properties in the declaration file generated after compilation. Name wildcards are supported. For example, to retain the JSDoc comments above the **Human** class in the declaration file, use the following configuration: ``` -keep-comments @@ -523,7 +557,7 @@ Human **NOTE** 1. This option takes effect when **-remove-comments** is used. -2. If the classes, functions, namespaces, enums, structs, interfaces, modules, types, and property names in the declaration file generated after compilation are confused, the JsDoc comments above the element cannot be kept using **-keep-comments**. For example, when **exportClass** is configured in **-keep-comments**, if the class name is **exportClass** obfuscated, its JSDoc comments cannot be kept: +2. If the classes, functions, namespaces, enums, structs, interfaces, modules, types, and property names in the declaration file generated after compilation are confused, the JsDoc comments above the element cannot be retained using **-keep-comments**. For example, when **exportClass** is configured in **-keep-comments**, if the class name is **exportClass** obfuscated, its JSDoc comments cannot be retained: ``` /* @@ -534,11 +568,12 @@ export class exportClass {} #### -keep-dts *filepath* -Names (such as variable names, class names, and attribute names) in the .d.ts file of the specified path are added to the -keep-global-name and -keep-property-name whitelists. Note that filepath supports only absolute paths and can be specified as a directory. In this case, the names in all .d.ts files in the directory are retained. +Adds names (such as variable names, class names, and property names) in the .d.ts file of the specified file path into the trustlist of **-keep-global-name** and **-keep-property-name**. Note that **filepath** supports only absolute paths and can be specified as a directory. In this case, the names in all .d.ts files in the directory are retained. #### -keep *filepath* -Keeps all names (such as variable names, class names, and property names) in the specified relative path from being obfuscated. The path can be a file or directory. If the path is a directory, the files in the directory and subdirectories are not obfuscated. +Retains all names (such as variable names, class names, and property names) in the specified relative path. The path can be a file or directory. If the path is a directory, the files in the directory and subdirectories are not obfuscated. + The path must be a relative path. **./** and **../** are relative to the directory where the obfuscation configuration file is located. Path wildcards are supported. ``` @@ -548,12 +583,40 @@ The path must be a relative path. **./** and **../** are relative to the directo ../oh_modules/json5 // Names in all the files in the imported third-party library json5 are not obfuscated. ``` +**How to retain remote HAR packages in modules?** + +Method 1: Specify the exact path of the remote HAR package in the module-level oh_modules. This path is a symbolic link to the real path in the project-level oh_modules. When configuring the path in the module-level oh_modules as a trustlist, you should specify the bundle name or a directory following the bundle name to correctly link to the real directory path. Therefore, configuring only the parent directory name of the HAR package is not supported. + +``` +// Positive example: +-keep +./oh_modules/harName1 // Names in all the files under the harName1 directory and its subdirectories are not confused. +./oh_modules/harName1/src // Names in all the files under the src directory and its subdirectories are not confused. +./oh_modules/folder/harName2 // Names in all the files under the harName2 directory and its subdirectories are not confused. + +// Negative example: +-keep +./oh_modules // To retain the HAR package in the module-level oh_modules, configuring the parent directory name of the HAR package is not supported. +``` + +Method 2: Specify the exact path of the remote HAR package in the project-level oh_modules. Since the file paths in the project-level oh_modules are all real paths, any path can be configured. + +``` +-keep +../oh_modules // Names in all the files under the project-level oh_modules and its subdirectories are not confused. +../oh_modules/harName3 // Names in all the files under the harName3 directory and its subdirectories are not confused. +``` + +The following figure shows the directory structure of module-level oh_moudles and project-level oh_modules in DevEco Studio. + +![oh_modules](./figures/oh_modules.png) + **NOTE** -1. For files retained by -keep filepath, the exported names and attributes in the files on the dependent links are retained. -2. NOTE: This option does not affect the capability provided by the **-enable-filename-obfuscation** option. +1. For files retained by **-keep filepath**, all exported names and their properties in the dependency chain of these files are also retained. +2. This option does not affect the capability provided by the **-enable-filename-obfuscation** option. -#### Wildcards Supported by Keep Options +#### Wildcards Supported by Retention Options ##### Name Wildcards @@ -566,21 +629,21 @@ The table below lists the name wildcards supported. **Use Example** -Keep all property names that start with **a**. +Retain all property names that start with **a**. ``` -keep-property-name a* ``` -Keep all single-character property names. +Retain all single-character property names. ``` -keep-property-name ? ``` -Keep all property names. +Retain all property names. ``` -keep-property-name @@ -600,21 +663,21 @@ The table below lists the path wildcards supported. **Use Example** -Keep the **c.ets** file in the **../a/b/** directory (excluding subdirectories). +Retain the **c.ets** file in the **../a/b/** directory (excluding subdirectories). ``` -keep ../a/b/*/c.ets ``` -Keep the **c.ets** file in the **../a/b/** directory and its subdirectories. +Retain the **c.ets** file in the **../a/b/** directory and its subdirectories. ``` -keep ../a/b/**/c.ets ``` -Keep all files except the **c.ets** file in the **../a/b/** directory. The exclamation mark (!) cannot be used alone. It can only be used to exclude existing cases in the trustlist. +Retain all files except the **c.ets** file in the **../a/b/** directory. The exclamation mark (!) cannot be used alone. It can only be used to exclude existing cases in the trustlist. ``` -keep @@ -622,21 +685,21 @@ Keep all files except the **c.ets** file in the **../a/b/** directory. The excla !../a/b/c.ets ``` -Keep all the files in the **../a/** directory (excluding subdirectories). +Retain all the files in the **../a/** directory (excluding subdirectories). ``` -keep ../a/* ``` -Keep all the files in the **../a/** directory and its subdirectories. +Retain all the files in the **../a/** directory and its subdirectories. ``` -keep ../a/** ``` -Keep all the files in the module. +Retain all the files in the module. ``` -keep @@ -657,7 +720,7 @@ class A { * ``` -In this example, * indicates any number of characters, and all property names are kept (not obfuscated). It does not mean that only the * property is kept. +In this example, * indicates any number of characters, and all property names are retained (not obfuscated). It does not mean that only the * property is retained. (2) In the **-keep** option, only the path format / is allowed. The path format \ or \\ is not. @@ -679,15 +742,15 @@ age During HAR build, comments are not merged into the final **obfuscation.txt** file. -### Obfuscation Rule Merge Policy +### Obfuscation Rule Merging Strategies -A project often has many obfuscation rule files, which are: +When a module in a project is built, the obfuscation rules used are a combination of the obfuscation rules in the following files: -* **ruleOptions.files** of the main project (the project being built) +* File specified by the **ruleOptions.files** field in the **build-profile.json5** file of the module * File specified by the **consumerFiles** field in the local dependent libraries * **obfuscation.txt** file in remote dependent HARs -When the main project is built, the obfuscation rules in these files are merged according to the following policy (in pseudo code): +The priorities of obfuscation rules in the preceding files are the same. When building a module, these files are merged according to the following merging strategies (pseudo code). ``` let `listRules` indicates the list of all obfuscation rule files mentioned above. @@ -743,70 +806,114 @@ end-for The final obfuscation rule comes from the object **finalRule**. -If the HAR is built, the final obfuscation.txt file content comes from the consumerFiles option of the HAR and the local dependent library, and the combination of the obfuscation.txt file of the dependent HAR. +During HAR build, the final **obfuscation.txt **file comes from the combination of the **consumerFiles** field of the HDR and the local dependent libraries, and the **obfuscation.txt** file of the dependent HARs. -If the obfuscation configuration file specified by consumerFiles contains the following obfuscation rules, these rules will be merged into the obfuscation.txt file in the HAR package. +When the obfuscation configuration file specified by **consumerFiles** contains the following obfuscation rules, these rules will be merged into the **obfuscation.txt** file of a HAR, whereas other obfuscation rules will not. ``` -Obfuscate Options +// Obfuscation options -enable-property-obfuscation -enable-string-property-obfuscation -enable-toplevel-obfuscation -compact -remove-log -Keep Options +// Retention options -keep-property-name -keep-global-name ``` -Precautions for Obfuscation in the Library +**Precautions for Obfuscation in the Library** -1. If the obfuscation configuration file specified by consumerFiles contains the preceding obfuscation options, these obfuscation options will be combined with the obfuscation rules of the main module when other modules depend on the HAR package. As a result, the main module is affected. Therefore, you are not advised to configure obfuscation options in the consumer-rules.txt file. You are advised to configure only reserved options. +1. If the obfuscation configuration file specified by **consumerFiles** contains the above obfuscation options, when other modules depend on this HAR, these obfuscation options will be merged with the main module's obfuscation rules, thereby affecting the main module. Therefore, you are not advised to configure obfuscation options in the **consumer-rules.txt** file. Instead, configure only retention options in the file. -2. If the -keep-dts option is added to the obfuscation configuration file specified by consumerFiles, it will be converted into -keep-global-name and -keep-property-name. +2. If the **-keep-dts** option is added to the obfuscation configuration file specified by **consumerFiles**, it will be converted into **-keep-global-name** and **-keep-property-name**. -## Retracing Stack Traces +## Deobfuscating Error Stacks -The function names of an application project after obfuscation are changed. As a result, the stack trace printed during crash is more difficult to understand because it is not completely consistent with the source code. You can use the hstack plugin in DevEco Studio Command Line Tools to restore the source stack trace and analyze problems. The **sourceMap.json** file generated during compilation and the obfuscation name mapping file **nameCache.json** are essential for de-obfuscation. Ensure to back them up locally. +In applications that have undergone obfuscation, code names are changed, making the error stacks printed during crashes harder to understand because they do not match the source code exactly. You can use the hstack plugin in DevEco Studio Command Line Tools to restore the source stack trace and analyze problems. The deobfuscation tool requires the **sourceMaps.map** file and the obfuscation name mapping file **nameCache.json** generated during compilation. Be sure to back them up locally. ![obfuscation-product](figures/obfuscation-product.png) -## Usage Description +## Enabling Code Obfuscation -* Currently, custom obfuscation plugins cannot be inserted into the hvigor build process. +1. Prerequisites for using obfuscation: + 1. Check whether obfuscation is enabled for the current module and whether the release build mode is selected. + 2. Before using obfuscation, you are advised to learn about the capabilities of [obfuscation options](obfuscation-options) and [retention options](retention-options). +3. Enable the obfuscation options in sequence to adapt and verify application functionalities one by one. + 1. When **-enable-toplevel-obfuscation** is configured, access to global variables using **globalThis** fails. To rectify the fault, use **-keep-global-name** to retain the global variable name. + 2. After the preceding adaptation is successful, configure **-enable-property-obfuscation**, and perform adaptation in the following scenarios: + 1. If the code statically defines properties but dynamically accesses them (or vice versa), use **-keep-property-name** to retain the property names. Example: + ``` + // Static definition, dynamic access: The property name is static during object definition, but is accessed by dynamically constructing the property name (usually using string concatenation). + const obj = { + staticName: value // Static definition + }; + const fieldName = 'static' + 'Name'; // Dynamic construction of the property name + console.log(obj[fieldName]); // Use square bracket notation to dynamically access the property. + ``` + ``` + // Dynamic definition, static access: The property name is determined during object definition through a dynamic expression, but is statically accessed using dot notation (assuming that you know the result of the property name). + const obj = { + [dynamicExpression]: value // Dynamic definition + }; + console.log(obj.dynamicPropertyName); // Use dot notation to statically access the property. + ``` + 2. If the code uses dot notation to access fields not defined in ArkTS/TS/JS code (for example, native so libraries, fixed JSON files, or database fields): + 1. For API calls to so libraries (for example, **import testNapi from 'library.so'; testNapi.foo();**), use **-keep-property-name** to retain the property name **foo**. + 2. For fields in JSON files, use **-keep-property-name** to retain the JSON field names. + 3. For database-related fields, use **-keep-property-name** to retain the database field names. + 3. When building a HAR module for use by other modules, use **-keep-property-name** in the **consumer-rules.txt** file of the HAR module to retain properties that should not be re-obfuscated. The **consumer-rules.txt** file generates the **obfuscation.txt** file during HAR compilation. When the HAR module is depended upon by other modules, DevEco Studio parses the **obfuscation.txt** file to read the trustlist. + 4. Verify application functionality and identify any missed scenarios. If the application functionality is abnormal, find the code of the error line in the corresponding [intermediate products](#viewing-obfuscation-effects) based on the obfuscated error stack, identify the necessary trustlist configurations, and use **-keep-property-name** to retain them. + 3. After the preceding adaptations are successful, configure **-enable-export-obfuscation**, and perform adaptation in the following scenarios: + 1. For HSP modules that provide interfaces and properties to other modules, use **-keep-global-name** to retain the interface names and **-keep-property-name** to retain the property names in exposed classes/interfaces. + 2. When building HAR modules for use by other modules, use **-keep-global-name** to retain interface names and **-keep-property-name** to retain the property names in exposed classes/interfaces in the **obfuscation-rules.txt** file. + 3. For API calls to so libraries (for example, **import { napiA } from 'library.so'**), use **-keep-global-name** to retain the so interface name **napiA**. + 4. Verify application functionality and interface call functionality when the module is depended upon, and identify any missed scenarios. If the application functionality is abnormal, find the code of the error line in the corresponding [intermediate products](#viewing-obfuscation-effects) based on the obfuscated error stack, identify the necessary trustlist configurations, and retain them. + 4. After the preceding adaptations are successful, configure **-enable-filename-obfuscation**, and perform adaptation in the following scenarios: + 1. If the code contains dynamic import statements (for example, **const path = './filePath'; import(path)**), use **-keep-file-name filePath** to retain the file path. + 2. If the application has a [routerMap configuration](https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V5/module-configuration-file-V5#routermap) that describes routing information, use **-keep-file-name** to retain the page source file path, which is specified by **pageSourceFile** field in the routing information. + 3. If the code uses **ohmUrl** for page navigation (for example, **router.pushUrl({url: '@bundle:com.example.routerPage/Library/Index'})**), use **-keep-file-name** to retain the path. + 4. Verify application functionality and identify any missed scenarios. If the application function is abnormal and the error stack contains obfuscated paths, you can query the original path in the **build/default/[...]/release/obfuscation/nameCache.json** file within the module and then locate the source code file. You can also use the [hstack plugin](https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V5/ide-command-line-hstack-V5) to trigger automatic deobfuscation of error stacks. After locating the paths to retain, use **-keep-file-name** to retain them. + +## Remarks + +* Currently, custom obfuscation plugins are not supported in the hvigor build process. * If a module that depends on an obfuscated HAR enables obfuscation, the HAR will be obfuscated again. -* To enable the release build mode, select **Product** in the upper right corner of DevEco Studio and set **Build Mode** to **release**. +* To enable the release build mode, select **Product** in the upper right corner of DevEco Studio and set **Build Mode** to **release**. ![product-release](figures/product-release.png) -## Appendix +## FAQs -### Mappings Between Obfuscate Options and Minimum SDK Versions +### Mappings Between Obfuscation Options and Minimum SDK Versions -| Obfuscate Option| Description | Minimum SDK Version| +| Obfuscation Option| Description | Minimum SDK Version| | ------- | --------- | ------ | | -disable-obfuscation | Disables obfuscation.| 4.0.9.2 | -| -enable-property-obfuscation | Enables property obfuscation.| 4.0.9.2 | +| -enable-property-obfuscation | Enables property name obfuscation.| 4.0.9.2 | | -enable-string-property-obfuscation | Enables obfuscation for string literal property names.| 4.0.9.2 | | -enable-toplevel-obfuscation | Enables top-level scope name obfuscation.| 4.0.9.2 | | -enable-filename-obfuscation | Enables file or folder name obfuscation for the HAR.
Enables file or folder name obfuscation for the HAP/HSP.| 4.1.5.3
5.0.0.19 | -| -enable-export-obfuscation | Enables obfuscation for imported or exported names.| 4.1.5.3 | +| -enable-export-obfuscation | Enables obfuscation for imported/exported names.| 4.1.5.3 | | -compact | Removes unnecessary spaces and all line feeds.| 4.0.9.2 | -| -remove-log | Removes the expressions involving direct calls to the **console.** statement in specific scenarios.| 4.0.9.2 | +| -remove-log | Removes the expressions involving direct calls to the console. statement in specific scenarios.| 4.0.9.2 | | -print-namecache | Saves the name cache to the specified file path.| 4.0.9.2 | | -apply-namecache | Reuses the specified name cache file.| 4.0.9.2 | | -remove-comments | Removes all comments in the file.| 4.1.5.3 | -| -keep-property-name | Keeps property names from being obfuscated.| 4.0.9.2 | -| -keep-global-name | Keeps top-level scope names from being obfuscated.| 4.0.9.2 | -| -keep-file-name | Keeps file or folder names in the HAR from being obfuscated.
Keeps file or folder names in the HAP/HSP from being obfuscated.| 4.1.5.3
5.0.0.19 | -| -keep-dts | Keeps the names in the .d.ts file in the specified path from being obfuscated.| 4.0.9.2 | -| -keep-comments | Keeps the classes, functions, namespaces, enums, structs, interfaces, modules, types, and JsDoc comments above properties in the declaration file generated after compilation from being obfuscated.| 4.1.5.3 | -| -keep | Keeps all names in the specified path from being obfuscated.| 5.0.0.18 | -| Wildcard | The keep options of the name classes and path classes support wildcards.| 5.0.0.24 | +| -keep-property-name | Retains property names.| 4.0.9.2 | +| -keep-global-name | Retains top-level scope names.| 4.0.9.2 | +| -keep-file-name | Retains file or folder names in the HAR.
Retains file or folder names in the HAP/HSP.| 4.1.5.3
5.0.0.19 | +| -keep-dts | Retains the names in the .d.ts file in the specified path.| 4.0.9.2 | +| -keep-comments | Retains the classes, functions, namespaces, enums, structs, interfaces, modules, types, and JsDoc comments above properties in the declaration file generated after compilation.| 4.1.5.3 | +| -keep | Retains all names in the specified path.| 5.0.0.18 | +| Wildcard | The retention options of the name classes and path classes support wildcards.| 5.0.0.24 | -### Viewing the Obfuscation Effect +### Viewing Obfuscation Effects +The following figure shows a simplified compilation process. -You can find the obfuscated files, name mapping file, and system API trustlist file in the **build** directory of the build product. +![compilation-process](figures/compilation-process.png) + +After obfuscation is complete, intermediate products are generated. You can find the obfuscated intermediate products in the **build** directory of the compilation output, as well as the name mapping file and system API trustlist files. * Obfuscated file directory: build/default/[...]/release/moduleName * Directory of the name mapping file and system API trustlist file: build/default/[...]/release/obfuscation @@ -815,45 +922,68 @@ You can find the obfuscated files, name mapping file, and system API trustlist f ![build-product](figures/build-product.png) -### Troubleshooting - -1. Configure the **-disable-obfuscation** option in **obfuscation-rules.txt** to disable obfuscation, and check whether the exception is caused by obfuscation. -2. If the function is abnormal after obfuscation is enabled, read the document to understand the capabilities of obfuscation rules, such as [-enable-property-obfuscation](#keep-options), [-enable-toplevel-obfuscation](#keep-options), [-enable-filename-obfuscation](#keep-options), and [-enable-export-obfuscation](#keep-options), and the syntax scenarios that require the configuration of a [trustlist](#keep-options) to ensure that the application functions properly. The following briefly describes the four keep options that are enabled by default. For details, see the complete description of the corresponding options. - [-enable-toplevel-obfuscation](#keep-options): keeps top-level scope name from being obfuscated. - [-enable-property-obfuscation](#keep-options): keeps properties from being obfuscated. You need to use [-keep-property-name](#keep-options) to configure a trustlist for specified property names in scenarios where obfuscation is not allowed, such as network data access, JSON field access, dynamic property access, and .so library API calls. - [-enable-export-obfuscation](#keep-options): keeps exported names from being obfuscated. Generally, this option is used together with the preceding two options. You need to use [-keep-global-name](#keep-options) to configure a trustlist for exported or imported names in scenarios where external APIs of the module cannot be obfuscated. - [-enable-filename-obfuscation]: keeps file names from being obfuscated. You need to use [-keep-file-name](#keep-options) to configure a trustlist for file paths and names in scenarios where file paths are dynamically imported or directly loaded at runtime. -3. If you find a [troubleshooting](#troubleshooting) case similar to your scenario, you can quickly resolve the issue by following the recommended solution. -4. If no similar case is found, you should identify the issue by examining the configuration functions. If the relevant functions are unnecessary, you can remove the corresponding configuration items. -5. Analyze application crashes during running as follows: - Open the application run log or click the Crash dialog box in DevEco Studio to find the crash stack. - The line number in the crash stack is the line number of the [build product](#viewing-the-obfuscation-effect), and the method name may also be the obfuscated name. Therefore, you are advised to check the build product based on the crash stack, analyze the names that cannot be obfuscated, and add them to the trustlist. -6. If the app does not crash during running but functions are abnormal (for example, a white screen is displayed): - 1. Open the app run log: Select HiLog, search for logs directly related to the function exception, and locate the context where the problem occurs. - 2. Locate the abnormal code segment: Analyze logs to find the specific code block that causes the function exception. - 3. Enhanced log output: Logs are added to the processed data fields in the function code that may be abnormal. - 4. Analyze and determine key fields: Analyze the output of new logs to check whether the data of this field is abnormal due to confusion. - 5. Configure the whitelist to protect key fields: Add the key fields that directly affect application functions after obfuscation to the whitelist. - -### **FAQs** +### Troubleshooting Functional Issues +#### Procedure +1. Configure the **-disable-obfuscation** option in the **obfuscation-rules.txt** file to disable obfuscation, and check whether the issue is caused by obfuscation. +2. If the function is abnormal after obfuscation is enabled, read the document to understand the capabilities of obfuscation rules, such as [-enable-property-obfuscation](#retention-options), [-enable-toplevel-obfuscation](#retention-options), [-enable-filename-obfuscation](#retention-options), and [-enable-export-obfuscation](#retention-options), and the syntax scenarios that require the configuration of a trustlist to ensure that the application functions properly. The following briefly describes the four retention options that are enabled by default. For details, see the complete description of the corresponding options. + 1. [-enable-toplevel-obfuscation](#retention-options): retains top-level scope name. + 2. [-enable-property-obfuscation](#retention-options): retains properties. You need to use [-keep-property-name](#retention-options) to configure a trustlist for specified property names in scenarios where obfuscation is not allowed, such as network data access, JSON field access, dynamic property access, and .so library API calls. + 3. [-enable-export-obfuscation](#retention-options): retains exported names. Generally, this option is used together with **-enable-toplevel-obfuscation** and **-enable-property-obfuscation**. You need to use [-keep-global-name](#retention-options) to configure a trustlist for exported or imported names in scenarios where external APIs of the module cannot be obfuscated. + 4. [-enable-filename-obfuscation]: retains file names. You need to use [-keep-file-name](#retention-options) to configure a trustlist for file paths and names in scenarios where file paths are dynamically imported or directly loaded at runtime. +3. If your problem matches any troubleshooting cases listed in [Common Issues](common-issues), apply the suggested solutions. +4. If the issue is not covered, use a positive approach to identify the problem (remove specific configuration items if the corresponding functionality is not needed). +5. Analyze runtime crashes as follows: + 1. Open the application runtime logs or the **Crash** dialog box in DevEco Studio to find the crash stack. + 2. The line number in the crash stack is the line number of the [build product](#viewing-obfuscation-effects), and the method name may also be the obfuscated name. Therefore, you are advised to check the build product based on the crash stack, analyze the names that cannot be obfuscated, and add them to the trustlist. +6. Analyze functional exceptions (for example, white screens) as follows: + 1. Opening the application runtime logs: Select HiLog and search for logs directly related to the exceptions. + 2. Locating the problematic code segment: Identify the specific code block causing the exceptions through log analysis. + 3. Enhancing log output: Add log records for data fields in the suspected code segment. + 4. Analyzing and identifying critical fields: Determine if the data exception is caused by obfuscation through the enhanced log output. + 5. Configuring a trustlist for critical fields: Add fields that directly affect application functionality after obfuscation to the trustlist. + +#### Troubleshooting Unexpected Obfuscation Behavior +If unexpected obfuscation behavior occurs, check whether certain obfuscation options are configured for the dependent local modules or third-party libraries. + +Example: +If **-compact** is not configured for the current module, but the code in the obfuscated intermediate product is compressed into a single line, perform the following steps: + +1. Check the **dependencies** field in the **oh-package.json5** file of the current module to identify dependencies. +2. Search for **-compact** in the obfuscation configuration file of the dependent modules or third-party libraries. + * Search for **-compact** in the **consumer-rules.txt** file in the local libraries. + * Search for **-compact** in all **obfuscation.txt** files in the project-level **oh_modules** directory. + +**NOTE** + +You are not advised to configure the following options in the **obfuscation.txt** file of third-party libraries, as they can cause unexpected behavior or crashes when the main module is obfuscated. Contact the library providers to remove these options and repackage the libraries. + +``` +-enable-property-obfuscation +-enable-string-property-obfuscation +-enable-toplevel-obfuscation +-remove-log +-compact +``` + +### Common Issues #### Errors That May Occur When -enable-property-obfuscation Is Configured Case 1: The error message "Cannot read property 'xxx' of undefined" is reported. ``` -// Before obfuscation +// Before obfuscation: const jsonData = ('./1.json') let jsonStr = JSON.parse(jsonData) let jsonObj = jsonStr.jsonProperty -// After obfuscation +// After obfuscation: const jsonData = ('./1.json') let jsonStr = JSON.parse(jsonData) let jsonObj = jsonStr.i ``` -After property obfuscation is enabled, **jsonProperty** is obfuscated as a random character **i**. However, the original name is used in the JSON file, causing the error. +After property name obfuscation is enabled, **jsonProperty** is obfuscated as a random character **i**. However, the original name is used in the JSON file, causing the error. **Solution**: Use the **-keep-property-name** option to add the fields used in JSON files to the trustlist. @@ -861,19 +991,60 @@ Case 2: An error message is reported when database-related fields are used and p The error message is "table Account has no column named a23 in 'INSET INTO Account(a23)'." -Database fields are used in the code. During obfuscation, the field names in the SQL statements are obfuscated, but the original field names are used in the database, causing the error. +The SQL statement uses database field names that are obfuscated, whereas the database expects the original names. **Solution**: Use the **-keep-property-name** option to add the database fields to the trustlist. +**Case 3: Properties Obfuscated When Record Is Used as an Object Type** + +**Symptom** + +When **Record** is used as an object type, properties like **linkSource** are obfuscated, causing the error. Example: + +``` +// Before obfuscation: +import { Want } from '@kit.AbilityKit'; +let petalMapWant: Want = { + bundleName: 'com.example.myapplication', + uri: 'maps://', + parameters: { + linkSource: 'com.other.app' + } +} + +// After obfuscation: +import type Want from "@ohos:app.ability.Want"; +let petalMapWant: Want = { + bundleName: 'com.example.myapplication', + uri: 'maps://', + parameters: { + i: 'com.other.app' + } +}; +``` + +**Possible Causes** + +In this example, the object's properties need to be passed to the system to load a specific page, so the property names should not be obfuscated. The type **Record** is a generic definition for an object with string keys and does not describe the internal structure or property types in detail. Therefore, the obfuscation tool cannot identify which properties should not be obfuscated, leading to the obfuscation of internal property names like **linkSource**. + +**Solution** + +Add the problematic property names to the property trustlist. The following is an example: + +``` +-keep-property-name +linkSource +``` + #### Errors That May Occur When -enable-export-obfuscation and -enable-toplevel-obfuscation Are Configured When the two options are configured, method name confusion in the following scenarios is involved when the main module calls the methods of other modules: -| Main Module| Dependent Module| Confusion of Imported and Exported Names| +| Main Module| Dependent Module| Imported/Exported Name Obfuscation| | ------- | ------- | ----------------------------| -| HAP/HSP | HSP | The HSP and main module are built independently, and different names are generated after obfuscation. Therefore, a trustlist must be configured for both the HSP and main module.| -| HAP/HSP | Local HAR| The local HAR is built together with the main module. After obfuscation, the names are the same.| -| HAP/HSP | Third-party library | The names and properties exported from a third-party library are collected to the trustlist. They are not confused during import and export.| +| HAP/HSP | HSP | The HSP and main module are independently compiled, resulting in inconsistent obfuscated names. Both need trustlist configurations.| +| HAP/HSP | Local HAR| The local HAR is compiled together with the main module, resulting in consistent obfuscated names.| +| HAP/HSP | Third-party library | Exported names and their properties in third-party libraries are collected into the trustlist, so they are not obfuscated during import/export.| For the HSP, you must add the methods used by other modules to the trustlist. You must add the same trustlist for the main module. Therefore, you are advised to add the obfuscation file configured with the trustlist (for example, **hsp-white-list.txt**) to the obfuscation configuration item of the module that depends on the obfuscation file, that is, the **files** field shown in the following figure. @@ -882,25 +1053,25 @@ For the HSP, you must add the methods used by other modules to the trustlist. Yo Case 1: When a class is dynamically imported, the class definition is confused, but the class name is not, causing an error. ``` -// Before obfuscation +// Before obfuscation: export class Test1 {} let mytest = (await import('./file')).Test1 -// After obfuscation +// After obfuscation: export class w1 {} let mytest = (await import('./file')).Test1 ``` -The exported class **Test1** is a top-level domain name. When **Test1** is dynamically used, it is a property. Because the **-enable-property-obfuscation** option is not configured, the class name is confused, but the property name is not. +The exported class **Test1** is a top-level domain name. When being dynamically used, it is a property. Because the **-enable-property-obfuscation** option is not configured, the class name is confused, but the property name is not. **Solution**: Use the **-keep-global-name** option to add **Test1** to the trustlist. Case 2: For a method in a namespace, the method definition is confused, but the statement that uses the method is not, causing an error. ``` -// Before obfuscation +// Before obfuscation: export namespace ns1 { export class person1 {} } @@ -908,7 +1079,7 @@ export namespace ns1 { import {ns1} from './file1' let person1 = new ns1.person1() -// After obfuscation +// After obfuscation: export namespace a3 { export class b2 {} } @@ -917,9 +1088,9 @@ import {a3} from './file1' let person1 = new a3.person1() ``` -**person1** in the namespace is a top-level class name. When it is called by using **ns1.person1**, **person1** is a property and is not obfuscated because property obfuscation is not enabled. +**person1** in the namespace is an exported element. When being called through **ns1.person1**, it is a property. Because the **-enable-property-obfuscation** option is not configured, the property name is not obfuscated during the call. -**Solution:** +**Solution** 1. Configure the **-enable-property-obfuscation** option. 2. Use the **-keep-global-name** option to add the methods exported from the namespace to the trustlist. @@ -927,12 +1098,12 @@ let person1 = new a3.person1() Case 3: When declare global is used, a syntax error is reported after obfuscation. ``` -// Before obfuscation +// Before obfuscation: declare global { var age : string } -// After obfuscation +// After obfuscation: declare a2 { var b2 : string } @@ -950,7 +1121,7 @@ person["age"] = 22; // Before obfuscation person["b"] = 22; // After obfuscation ``` -**Solution:** +**Solution** 1. Check whether **-enable-string-property-obfuscation** is configured for the dependent HAR. If it is configured, the main project will be affected, and you should disable it. 2. If it must be configured, add the property name to the trustlist. @@ -964,7 +1135,7 @@ As shown below, the outer layer of the **library1** module contains a directory ![directory-offuscation](figures/directory-obfuscation.png) -**Solution:** +**Solution** 1. If the project directory structure and error message are similar, update the SDK to 5.0.0.26 or later. 2. Use the **-keep-file-name** option to add the directory name **directory** of the module to the trustlist. @@ -989,12 +1160,83 @@ The error message "Cannot read properties of undefined (reading 'has')" is repor #### The HAP and HSP depend on the same local source code HAR module. -* If file name obfuscation is enabled, the following problems may occur: - * Problem 1: The singleton function is abnormal. The reason is that the build and obfuscation processes of HAP and HSP are executed independently. In the local source code HAR module, the same file name may be obfuscated into different file names in the HAP and HSP packages. - * Problem 2: The interface fails to be called. The reason is that the build and obfuscation processes of HAP and HSP are executed independently. In the local source code HAR module, different file names may be obfuscated into the same file name in the HAP and HSP packages. -* If the -enable-export-obfuscation and -enable-toplevel-obfuscation options are enabled, the interface fails to be loaded during application running. -The reason is that HAP and HSP independently execute the build and obfuscation processes. The interfaces exposed in the HAR module of the local source code are obfuscated into different names in HAP and HSP. +* If file name obfuscation is enabled, the following issue may occur: + * Singleton function exceptions: The reason is that the HAP and HSP modules execute independent build and obfuscation processes. The same file names in the shared local source code HAR may be obfuscated differently in the HAP and HSP packages. + * Interface call failures: The reason is that the HAP and HSP modules execute independent build and obfuscation processes. Different file names in the shared local source code HAR may be obfuscated to the same name in the HAP and HSP packages. +* If **-enable-export-obfuscation** and **-enable-toplevel-obfuscation** are configured, the interface loading failures may occur at runtime. +The HAP and HSP modules execute independent build and obfuscation processes, resulting in different obfuscated names for the interfaces exposed by the shared local source code HAR. + +**Solution** + +1. Change the shared local source code HAR to a [bytecode HAR](https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V5/ide-hvigor-build-har-V5#section179161312181613). This prevents the HAR from being re-obfuscated when being depended upon. +2. Build the shared local source code HAR in [release mode](https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V5/ide-hvigor-build-har-V5#section19788284410). This ensures that file names and exported interfaces are not obfuscated when the HAR is depended upon. + +#### Problems that may occur when **both -enable-property-obfuscation** and **-keep** are enabled. + +**Symptom** + +The following obfuscation configuration is used: + +``` +-enable-property-obfuscation +-keep +./file1.ts +``` -**Solution:** -1. Change the local source code HAR on which HAP and HSP depend to [bytecode HAR](https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V5/ide-hvigor-build-har-V5#section179161312181613). In this way, the HAR will not be confused when it is depended on. -2. The local source code HAR on which HAP and HSP depend is [built and packaged in release mode](https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V5/ide-hvigor-build-har-V5#section19788284410). In this way, when the HAR is depended on, its file name is not confused with the external interface. +**file2.ts** imports an interface from **file1.ts**, and the interface contains object-type properties. As a result, these properties are retained in **file1.ts** but obfuscated in **file2.ts**, leading to function exceptions. Example: + +``` +// Before obfuscation: +// file1.ts +export interface MyInfo { + age: number; + address: { + city1: string; + } +} + +// file2.ts +import { MyInfo } from './file1'; +const person: MyInfo = { + age: 20, + address: { + city1: "shanghai" + } +} + +// After obfuscation, the code of file1.ts is retained. +// file2.ts +import { MyInfo } from './file1'; +const person: MyInfo = { + age: 20, + address: { + i: "shanghai" + } +} +``` + +**Possible Causes** + +The **-keep** option retains the code in the **file1.ts** file, but properties within exported types (for example, **address**) are not automatically added to the property trustlist. Therefore, these properties are obfuscated when being used in other files. + +**Solution** + +Solution 1: Define the property type using **interface** and export it. This will automatically add the property to the trustlist. Example: + +``` +// file1.ts +export interface AddressType { + city1: string +} +export interface MyInfo { + age: number; + address: AddressType; +} +``` + +Solution 2: Use the **-keep-property-name** option to add properties within types that are not directly exported to the trustlist. Example: + +``` +-keep-property-name +city1 +``` diff --git a/en/application-dev/arkts-utils/sync-task-development.md b/en/application-dev/arkts-utils/sync-task-development.md index cf8c937ae8ff58ee2e17f964f896cbd3c2a12dfb..65f66b6676274c33f22d6e90bdf97e7551e871fb 100644 --- a/en/application-dev/arkts-utils/sync-task-development.md +++ b/en/application-dev/arkts-utils/sync-task-development.md @@ -1,39 +1,39 @@ # Synchronous Task Development (TaskPool and Worker) -Synchronous tasks are executed in order among multiple threads. Synchronization primitives, such as locks, are used by these tasks for coordination between each other. +Synchronous tasks involve coordinating execution across multiple threads to ensure that tasks run in a specific order and adhere to certain rules, such as using locks to prevent data races. -To implement synchronous tasks, you must consider the collaboration and synchronization between multiple threads and ensure the correctness of data and program execution. +To implement synchronous tasks, you must consider the collaboration and synchronization between multiple threads and ensure data integrity and correct program execution. -If synchronous tasks are independent of each other, you are advised to use **TaskPool**, which focuses on single independent tasks. For example, a series of imported static methods or methods implemented in singletons are independent. If synchronous tasks are associated with each other, use **Worker**, for example, methods implemented in class objects (not singleton class objects). +TaskPool is well-suited for individual, independent tasks. Therefore, it is recommended for scenarios where synchronous tasks are relatively independent, such as a series of static methods or methods implemented using a singleton pattern. Conversely, if synchronous tasks are interdependent, Worker is the better choice, especially when methods rely on class objects. -## Using TaskPool to Process Independent Synchronous Tasks +## Using TaskPool for Independent Synchronous Tasks -**TaskPool** is recommended for scheduling independent tasks. Typical independent tasks are those using static methods. If a unique handle or class object constructed using a singleton points to multiple tasks and these tasks can be used between different worker threads, you can also use **TaskPool**. +TaskPool is ideal for scheduling independent tasks or when a series of tasks is implemented as static methods. It is also suitable when unique handles or class objects can be constructed via a singleton pattern and used across different task threads. > **NOTE** > -> Due to the memory isolation feature between different threads in the [Actor model](multi-thread-concurrency-overview.md#actor-model), common singletons cannot be used between different threads. This issue can be solved by exporting a singleton through the sendable module. +> Due to the memory isolation feature of the [actor model](multi-thread-concurrency-overview.md#actor-model) between threads, regular singletons cannot be shared across threads. This issue can be solved by exporting singletons through sendable modules. -1. Define concurrent functions to implement service logic. +1. Define a concurrent function to implement service logic. -2. Create a task [Task](../reference/apis-arkts/js-apis-taskpool.md#task) and execute the task through the [execute()](../reference/apis-arkts/js-apis-taskpool.md#taskpoolexecute-1) interface. +2. Create a [task](../reference/apis-arkts/js-apis-taskpool.md#task), and execute the task using the [execute()](../reference/apis-arkts/js-apis-taskpool.md#taskpoolexecute-1) interface. 3. Perform operations on the task result. -In the following example, the service uses TaskPool to call the code of the related synchronization method. Define the concurrent function taskpoolFunc first. Note that the function must be decorated by the [@Concurrent decorator](taskpool-introduction.md#concurrent-decorator). Define the mainFunc function. This function is used to create and execute a task and perform operations on the returned result of the task. +In the following example, the service logic uses TaskPool to call related synchronous methods. First, define the concurrent function **taskpoolFunc**, which must be decorated with [@Concurrent](taskpool-introduction.md#concurrent-decorator). Then, define the function **mainFunc**, which creates tasks, executes them, and performs operations on the results returned by the tasks. ```ts // Index.ets code import { taskpool} from '@kit.ArkTS'; -// Step 1: Define a concurrent function to implement the service logic. +// Step 1: Define a concurrent function to implement service logic. @Concurrent async function taskpoolFunc(num: number): Promise { - // Implement the corresponding function based on the service logic. + // Implement the corresponding functionality based on the service logic. let tmpNum: number = num + 100; return tmpNum; } @@ -44,7 +44,7 @@ async function mainFunc(): Promise { let res1: number = await taskpool.execute(task1) as number; let task2: taskpool.Task = new taskpool.Task(taskpoolFunc, res1); let res2: number = await taskpool.execute(task2) as number; - // Step 3: Perform operations on the returned task result. + // Step 3: Perform operations on the result returned by the task. console.info("taskpool: task res1 is: " + res1); console.info("taskpool: task res2 is: " + res2); } @@ -72,11 +72,11 @@ struct Index { ``` -## Using Worker to Process Associated Synchronous Tasks +## Using Worker for Interdependent Synchronous Tasks -Use **Worker** when you want to schedule a series of synchronous tasks using the same handle or depending on the same class object. +When a series of synchronous tasks needs to be scheduled using the same handle, or when they depend on a specific class object that cannot be shared across different task pools, Worker is the appropriate choice. -1. Create a **Worker** object in the main thread and receive messages from the worker thread. DevEco Studio supports one-click Worker generation. Right-click any position in the {moduleName} directory and choose New > Worker from the shortcut menu to automatically generate the Worker template file and configuration information. +1. Create a Worker object in the UI main thread and receive messages from the Worker thread. DevEco Studio supports generation of Worker templates with a single click. In the corresponding {moduleName} directory, right-click anywhere and choose **New > Worker** to automatically generate the Worker template files and configuration information. ```ts // Index.ets @@ -96,17 +96,17 @@ Use **Worker** when you want to schedule a series of synchronous tasks using the .onClick(() => { let w: worker.ThreadWorker = new worker.ThreadWorker('entry/ets/workers/MyWorker.ts'); w.onmessage = (): void => { - // Receive the result of the worker thread. + // Receive results from the Worker thread. } w.onerror = (): void => { - // Receive error information of the worker thread. + // Receive error messages from the Worker thread. } - // Send a Set message to the worker thread. + // Send a Set message to the Worker thread. w.postMessage({'type': 0, 'data': 'data'}) - // Send a Get message to the worker thread. + // Send a Get message to the Worker thread. w.postMessage({'type': 1}) // ... - // Select a time to destroy the thread based on the actual situation. + // Destroy the thread based on actual service requirements. w.terminate() }) } @@ -118,7 +118,7 @@ Use **Worker** when you want to schedule a series of synchronous tasks using the ``` -2. Bind the **Worker** object in the worker thread and process the synchronous task logic. +2. Bind the Worker object in the Worker thread and process the synchronous task logic. ```ts // handle.ts code @@ -136,14 +136,14 @@ Use **Worker** when you want to schedule a series of synchronous tasks using the ```ts // MyWorker.ts code import { worker, ThreadWorkerGlobalScope, MessageEvents } from '@kit.ArkTS'; - import Handle from './handle' // Return a handle. + import Handle from './handle' // Import the handle. let workerPort : ThreadWorkerGlobalScope = worker.workerPort; // Handle that cannot be transferred. All operations depend on this handle. let handler: Handle = new Handle() - // onmessage() logic of the worker thread. + // onmessage() logic of the Worker thread. workerPort.onmessage = (e : MessageEvents): void => { switch (e.data.type as number) { case 0: diff --git a/en/application-dev/arkts-utils/taskpool-communicates-with-mainthread.md b/en/application-dev/arkts-utils/taskpool-communicates-with-mainthread.md index 1e7ecb44c359ceb8ba910e7867fc02e3477625bb..01115d9105e8b35aac2786e611fffed3333bdd73 100644 --- a/en/application-dev/arkts-utils/taskpool-communicates-with-mainthread.md +++ b/en/application-dev/arkts-utils/taskpool-communicates-with-mainthread.md @@ -1,19 +1,19 @@ # Communication Between the TaskPool Task and Host Thread -If a subthread needs to periodically notify the main thread of the task status and data changes, or needs to return a large amount of data by segment (for example, a large amount of data read from the database), you can perform the following operations: +When a task needs to do more than just return a final result—such as periodically updating the host thread on its status, reporting data changes, or returning large volumes of data in segments (for example, fetching large datasets from a database)—you can use the approach described in this topic. -The following uses an example in which results of a plurality of image loading tasks are returned in real time. +The following example uses multiple image loading tasks that provide real-time updates to illustrate the process. -1. First, implement a method to receive messages sent by the task. +1. Implement a method to receive messages sent by the task. ```ts // TaskSendDataUsage.ets function notice(data: number): void { - console.info("The subthread task has been executed. Total images loaded:", data) + console.info("Child thread task completed. Total images loaded:", data); } ``` -2. Then, add **sendData()** to the task to enable the subthread to send messages to the main thread. +2. In the task, use **sendData()** to send messages to the host thread. ```ts // IconItemSource.ets @@ -33,14 +33,14 @@ The following uses an example in which results of a plurality of image loading t import { taskpool } from '@kit.ArkTS'; import { IconItemSource } from './IconItemSource'; - // Use sendData to notify the main thread of information in real time. + // Use sendData to notify the host thread of information in real time. @Concurrent export function loadPictureSendData(count: number): IconItemSource[] { let iconItemSourceList: IconItemSource[] = []; - // Traverse and add six IconItem data records. + // Add six IconItem data records. for (let index = 0; index < count; index++) { const numStart: number = index * 6; - // Six images are used cyclically. + // Use six images in the loop. iconItemSourceList.push(new IconItemSource('$media:startIcon', `item${numStart + 1}`)); iconItemSourceList.push(new IconItemSource('$media:background', `item${numStart + 2}`)); iconItemSourceList.push(new IconItemSource('$media:foreground', `item${numStart + 3}`)); @@ -54,8 +54,8 @@ The following uses an example in which results of a plurality of image loading t } ``` -3. Finally, use **onReceiveData()** to enable the main thread to receive messages. - In this way, the main thread can receive the data sent by the task through **notice()**. +3. In the host thread, use **onReceiveData()** to receive messages. + This allows the host thread to receive data sent by the task through **notice()**. ```ts // TaskSendDataUsage.ets @@ -72,10 +72,10 @@ The following uses an example in which results of a plurality of image loading t .fontWeight(FontWeight.Bold) .onClick(() => { let iconItemSourceList: IconItemSource[]; - let lodePictureTask: taskpool.Task = new taskpool.Task(loadPictureSendData, 30); - // Use notice to receive messages sent by the task. - lodePictureTask.onReceiveData(notice); - taskpool.execute(lodePictureTask).then((res: object) => { + let loadPictureTask: taskpool.Task = new taskpool.Task(loadPictureSendData, 30); + // Use notice to receive messages from the task. + loadPictureTask.onReceiveData(notice); + taskpool.execute(loadPictureTask).then((res: object) => { iconItemSourceList = res as IconItemSource[]; }) }) diff --git a/en/application-dev/arkts-utils/taskpool-introduction.md b/en/application-dev/arkts-utils/taskpool-introduction.md index 8ce11b407e07a8b8e97a202d994e1dc5fa32d810..7a10f279b5db98298908b229695d6868d7f1b789 100644 --- a/en/application-dev/arkts-utils/taskpool-introduction.md +++ b/en/application-dev/arkts-utils/taskpool-introduction.md @@ -1,40 +1,42 @@ -# TaskPool Introduction +# TaskPool -TaskPool provides a multithreaded environment for applications. It helps reduce resource consumption and improve system performance. It also frees you from caring about the lifecycle of thread instances. For details about the APIs and their usage, see [TaskPool](../reference/apis-arkts/js-apis-taskpool.md). +TaskPool is designed to provide a multithreaded runtime environment for applications. It helps reduce overall resource consumption and improve system performance. It also frees you from caring about the lifecycle of thread instances. For details about the APIs and their usage, see [TaskPool](../reference/apis-arkts/js-apis-taskpool.md). ## TaskPool Operating Mechanism -TaskPool operating mechanism +The figure below illustrates the operating mechanism of TaskPool. ![image_0000001964858368](figures/image_0000001964858368.png) -With TaskPool, you can encapsulate tasks in the main thread and throw the tasks to the task queue. The system selects proper worker threads to distribute and execute the tasks, and then returns the result to the main thread. TaskPool provides APIs to execute and cancel tasks, and set the task priority. It minimizes system resource usage through unified thread management, dynamic scheduling, and load balancing. By default, the system starts a worker thread and increases the thread quantity as the number of tasks increases. The maximum number of worker threads that can be created depends on the number of physical cores of the device. The actual number is managed internally to ensure optimal scheduling and execution efficiency. If no task is distributed for a long period of time, the system reduces the number of worker threads. +With TaskPool, you can encapsulate tasks in the host thread and submit the tasks to the task queue. The system selects appropriate worker threads to distribute and execute the tasks, and then returns the result to the host thread. TaskPool provides APIs to execute and cancel tasks, and set the task priority. It minimizes system resource usage through unified thread management, dynamic scheduling, and load balancing. By default, the system starts a worker thread and increases the thread quantity as the number of tasks increases. The maximum number of worker threads that can be created depends on the number of physical cores of the device. The actual number is managed internally to ensure optimal scheduling and execution efficiency. If no task is distributed for an extended period, the system reduces the number of worker threads. ## Precautions for TaskPool -- A task function must be decorated with [\@Concurrent](#concurrent-decorator) and can be used only in .ets files. +- Functions implementing tasks must be decorated with [\@Concurrent](#concurrent-decorator) and are supported only in .ets files. -- Since API version 11, when an instance object with a method is passed across concurrent instances, the class must be annotated with the decorator [@Sendable](arkts-sendable.md#sendable) and can be used only in .ets files. +- Starting from API version 11, when passing instances with methods across concurrent instances, the class must be decorated with [@Sendable](arkts-sendable.md#sendable) and are supported only in .ets files. -- A task function in the TaskPool worker thread must finish the execution within 3 minutes (excluding the time used for Promise or async/await asynchronous call, for example, the duration of I/O tasks such as network download and file read/write). Otherwise, it forcibly exits. +- A task function must finish the execution in a TaskPool worker thread within 3 minutes (excluding the time used for Promise or async/await asynchronous call, such as the duration of I/O tasks like network download and file read/write operation). Otherwise, it is forcibly terminated. -- The input parameters of the function for implementing the task must meet the types supported by serialization. For details, see [Inter-Thread Communication Object](interthread-communication-overview.md). +- Parameters of functions implementing tasks must be of types supported by serialization. For details, see [Inter-Thread Communication](interthread-communication-overview.md). - Parameters of the ArrayBuffer type are transferred in TaskPool by default. You can set the transfer list by calling [setTransferList()](../reference/apis-arkts/js-apis-taskpool.md#settransferlist10). -- The context objects in different threads are different. Therefore, **TaskPool** worker threads can use only thread-safe libraries, rather than UI-related non-thread-safe libraries. +- The context objects in different threads are different. Therefore, TaskPool worker threads can use only thread-safe libraries. For example, non-thread-safe UI-related libraries cannot be used. - A maximum of 16 MB data can be serialized. -- Among all the values of [Priority](../reference/apis-arkts/js-apis-taskpool.md#priority), **IDLE** is used to mark time-consuming tasks (such as data synchronization and backup) that need to run in the background Tasks marked with **IDLE** are executed only when all threads are idle and occupy only one thread for execution. +- Among all the values of [Priority](../reference/apis-arkts/js-apis-taskpool.md#priority), **IDLE** is used to mark time-consuming tasks that need to run in the background (such as data synchronization and backup), and it has the lowest priority. Tasks marked with this priority are executed only when all threads are idle and occupy only one thread for execution. -- Promises cannot be transferred across threads. If the TaskPool returns a promise in the pending or rejected state, a failure message is returned. For a promise in the fulfilled state, the TaskPool parses the returned result. If the result can be transferred across threads, a success message is returned. +- Promises cannot be transferred across threads. If TaskPool returns a Promise in the pending or rejected state, a failure message is returned. For a Promise in the fulfilled state, TaskPool parses the returned result. If the result can be transferred across threads, a success message is returned. -- [AppStorage](../quick-start/arkts-appstorage.md) cannot be used in the TaskPool worker thread. +- [AppStorage](../quick-start/arkts-appstorage.md) cannot be used in TaskPool worker threads. + +- TaskPool allows you to package tasks in the host thread and submit them to the task queue. While it can theoretically handle an unlimited number of tasks, the actual task execution is influenced by the task priority and the availability of system resources. Once the Worker threads reach their maximum capacity, the efficiency of task execution might be compromised. ## \@Concurrent Decorator -To pass function verification, the concurrent functions executed in a [TaskPool](../reference/apis-arkts/js-apis-taskpool.md) must be decorated using \@Concurrent. +To pass function verification, concurrent functions executed in a [TaskPool](../reference/apis-arkts/js-apis-taskpool.md) must be decorated using \@Concurrent. > **NOTE** > @@ -45,14 +47,14 @@ To pass function verification, the concurrent functions executed in a [TaskPool] | \@Concurrent Decorator| Description| | -------- | -------- | | Decorator parameters| None.| -| Use Scenario| The decorator can be used only in projects of the stage model. It can be used only in .ets files.| -| Decorated function types| This decorator can be used for asynchronous functions and common functions. It cannot be used for generators, arrow functions, or methods. It does not support class member functions or anonymous functions.| -| Variable types in decorated functions| Local variables, input parameters, and variables imported through **import** are supported. Closure variables are not allowed.| -| Return value types in decorated functions| For details about the supported types, see [Inter-Thread Communication Object](interthread-communication-overview.md).| +| Use scenario| Used only in projects of the stage model and only in .ets files.| +| Decorated function types| Used for async functions or regular functions. It cannot be used for generators, arrow functions, or class methods. It does not support class member functions or anonymous functions.| +| Variable types in decorated functions| Local variables, parameters, and variables imported via **import** are allowed. Closure variables are prohibited.| +| Return value types in decorated functions| Supported types are listed in [Inter-Thread Communication](interthread-communication-overview.md).| -> **Note** +> **NOTE** > -> Functions marked by \@Concurrent cannot access closures. Therefore, functions marked by \@Concurrent cannot call other functions of the current file. For example: +> Functions decorated with \@Concurrent cannot access closures. Therefore, they cannot call other functions within the same file. The following provides an example. > > ```ts > function bar() { @@ -60,15 +62,15 @@ To pass function verification, the concurrent functions executed in a [TaskPool] > > @Concurrent > function foo() { -> bar (); // The closure principle is violated. An error is reported. +> bar(); // This violates the closure principle. An error is reported. > } > ``` -### Decorator Example +### Decorator Usage Examples -#### Commonly used by concurrent functions +#### General Use of Concurrent Functions -A concurrent function is a common function that calculates the sum of two numbers. The taskpool executes the function and returns the result. +A concurrent function that calculates the sum of two numbers is executed by TaskPool and returns the result. Example: @@ -111,9 +113,9 @@ struct Index { } ``` -#### Promise returned by concurrent functions +#### Concurrent Functions Returning Promises -Pay attention to the performance of returning Promise in the concurrent function. The concurrent synchronous function processes and returns Promise with the result. +Pay attention to the behavior of returning Promises in concurrent functions. In the following example, concurrent functions like **testPromise** and **testPromise1** handle these Promises and return results. Example: @@ -222,9 +224,9 @@ struct Index { } ``` -#### Using a User-Defined Class or Function in a Concurrent Function +#### Using Custom Classes or Functions in Concurrent Functions -User-defined classes or functions used in concurrent functions must be defined in different files. Otherwise, they will be considered as closures, as shown in the following example. +Custom classes or functions used in concurrent functions must be defined in separate files. Otherwise, they will be considered as closures, as shown in the following example. Example: @@ -251,21 +253,21 @@ class TestB { @Concurrent function TestFunc() { - // Case 1: Directly call a class or function defined in the same file in a concurrent function. + // Case 1: Directly call a class or function defined in the same file within a concurrent function. - // Directly call the add () function defined in the same file. The error message "Only imported variables and local variables can be used in @Concurrent decorated functions. " is displayed in red. + // Directly call the add() function defined in the same file. The following error message is displayed: "Only imported variables and local variables can be used in @Concurrent decorated functions. " // add(1); - // Use the TestA defined in the same file. The error message "Only imported variables and local variables can be used in @Concurrent decorated functions. " is displayed. + // Directly use the TestA constructor defined in the same file. The following error message is displayed: "Only imported variables and local variables can be used in @Concurrent decorated functions. " // let a = new TestA("aaa"); - // Directly access the nameStr member of TestB defined in the same file. The error message "Only imported variables and local variables can be used in @Concurrent decorated functions. " is displayed in red. + // Directly access the nameStr member of TestB defined in the same file. The following error message is displayed: "Only imported variables and local variables can be used in @Concurrent decorated functions. " // console.info("TestB name is: " + TestB.nameStr); - // Case 2: In the concurrent function, call the class or function defined in the Test.ets file and import the current file. + // Case 2: In the concurrent function, call classes or functions defined in the Test.ets file and imported into the current file. - // Output result: res1 is: 2 + // Output: res1 is: 2 console.info("res1 is: " + testAdd(1)); let tmpStr = new MyTestA("TEST A"); - // Output result: res2 is: TEST A + // Output: res2 is: TEST A console.info("res2 is: " + tmpStr.name); // Output: res3 is: MyTestB console.info("res3 is: " + MyTestB.nameStr); @@ -321,9 +323,9 @@ export class MyTestB { } ``` -#### Using Promise in a Concurrent Asynchronous Function +#### Using Promises in Concurrent Asynchronous Functions -If Promise is used in the concurrent asynchronous function, you are advised to use await to capture exceptions that may occur in Promise. A recommended example is provided below. +If Promise is used in concurrent asynchronous functions, you are advised to use await to enable TaskPool to capture any exceptions that may occur within the Promise. The recommended usage is shown in the following example. Example: diff --git a/en/application-dev/arkts-utils/taskpool-vs-worker.md b/en/application-dev/arkts-utils/taskpool-vs-worker.md index b12c707d679b1f93b3a3c2979ab5f0f9089ec099..cb0163e2e5ee603c9a02365e798f381a7f907d30 100644 --- a/en/application-dev/arkts-utils/taskpool-vs-worker.md +++ b/en/application-dev/arkts-utils/taskpool-vs-worker.md @@ -1,49 +1,49 @@ # Comparison Between TaskPool and Worker -**TaskPool** and **Worker** provide a multithreaded environment for applications to process time-consuming computing tasks or resource intensive tasks, preventing these tasks from blocking the host thread. This maximizes system utilization, reduces overall resource consumption, and improves overall system performance. +TaskPool and Worker provide a multithreaded runtime environment for applications, allowing them to handle time-consuming computing tasks or resource intensive tasks. This setup effectively prevents these tasks from blocking the host thread, maximizing resource utilization and improving overall system performance. - +This topic compares TaskPool and Worker based on their implementation characteristics and suitable use cases. -## Implementation Feature Comparison +## Implementation Characteristics Comparison -**Table 1** Comparison between TaskPool and Worker in implementation features +**Table 1** Comparison between TaskPool and Worker in implementation characteristics | Item| TaskPool | Worker | | -------- | -------- | -------- | | Memory model| Threads are isolated from each other, and memory is not shared.| Threads are isolated from each other, and memory is not shared.| | Parameter passing mechanism| The structured clone algorithm is used for serialization and deserialization.
ArrayBuffer and SharedArrayBuffer are used for parameter passing and sharing.| The structured clone algorithm is used for serialization and deserialization.
ArrayBuffer and SharedArrayBuffer are used for parameter passing and sharing.| -| Parameter passing| Parameters are passed in without being encapsulated.| Only one parameter can be carried in a message object. Therefore, you must encapsulate excess parameters.| -| Method invocation| Methods are directly passed in and called.| Methods are called after corresponding messages have been passed in and parsed in the worker thread.| -| Return value| A value is returned by default after asynchronous calling.| Messages proactively sent must be parsed and assigned by calling **onmessage()**.| -| Lifecycle| The task pool manages its own lifecycle, without considering the load.| You are required to manage the number and lifecycle of worker threads.| -| Maximum number of tasks| The number is automatically managed, rather than being manually configured.| A maximum of 64 worker threads can run simultaneously in the same process. The actual number is determined by the process memory.| -| Maximum task execution duration| 3 minutes (excluding the time used for Promise or async/await asynchronous call, for example, the time consumed by I/O tasks such as network download and file read/write). There is no upper limit on the execution duration of continuous tasks. | There is no restriction.| -| Task priority setting| Supported.| Not supported.| +| Parameter passing| Parameters are directly passed without being encapsulated, and the transfer method is used by default.| The message object should be encapsulated as a unique parameter.| +| Method invocation| Methods are directly called.| Messages are parsed in the Worker thread to invoke the corresponding methods.| +| Return value| Results are returned asynchronously by default.| Messages must be proactively sent and parsed by calling **onmessage()** for value assignment.| +| Lifecycle management| TaskPool manages its own lifecycle, without considering task load.| Developers are required to manage the number and lifecycle of Worker threads.| +| Maximum number of tasks| The number is automatically managed, rather than being manually configured.| A maximum of 64 Worker threads can run simultaneously in the same process. The actual number is determined by the process memory.| +| Maximum task duration| 3 minutes (excluding time spent on Promise and async/await calls, such as network downloads and file read/write operations). There is no upper limit on the duration of continuous tasks.| There is no limit.| +| Task priority setting| Setting the task priority is supported.| Not supported.| | Task cancellation| Supported.| Not supported.| | Thread reuse| Supported.| Not supported.| | Delayed task execution| Supported.| Not supported.| -| Setting task dependencies| Supported.| Not supported.| -| Queue| Supported.| Not supported.| +| Task dependency setting| Supported.| Not supported.| +| Serial queue| Supported.| Not supported.| | Task group| Supported.| Not supported.| ## Use Case Comparison -Both **TaskPool** and **Worker** support multithreaded concurrency. **TaskPool** worker threads are bound to the system scheduling priority and support load balancing (automatic scaling). **Worker** threads are manually created and do not support scheduling priority setting. Therefore, **TaskPool** provides better performance than **Worker** and is recommended in most scenarios. +Both TaskPool and Worker support multithreaded concurrency. However, TaskPool worker threads are bound to the system scheduling priority and support load balancing (automatic scaling), making it more efficient than Worker, which requires manual creation and may incur delays. In addition, Worker does not support scheduling priority setting. Therefore, TaskPool is recommended for most scenarios. -**TaskPool** is oriented to independent tasks, which are executed in threads. You do not need to care about the thread lifecycle, because non-continuous tasks are automatically reclaimed by the system if they are running for more than 3 minutes. On the contrary, **Worker** is oriented to threads and supports thread execution for a long time. You need to manage the thread lifecycle. +TaskPool is oriented to independent tasks, which are executed within threads. You do not need to care about the thread lifecycle, because long-running tasks (over 3 minutes and not classified as continuous tasks) are automatically reclaimed by the system. On the contrary, Worker is oriented to threads, supports long-running operations, and requires active lifecycle management. Common use cases are as follows: -- Use **Worker** for a task that runs for more than 3 minutes (excluding the time used for Promise or async/await asynchronous call, for example, I/O tasks such as network download and file read/write). For example, use **Worker** for a 1-hour prediction algorithm training job in the background. For details about the scenario example, see [Resident Task Development](./resident-task-guide.md). +- Tasks exceeding 3 minutes: For tasks that run longer than 3 minutes (excluding time spent on Promise and async/await calls, such as network downloads and file I/O operations), use Worker. For example, use Worker for a background CPU-intensive prediction algorithm that runs for an hour. For details about the scenario example, see [Resident Task Development](./resident-task-guide.md). -- Use **Worker** for a series of associated synchronous tasks. For example, in scenarios where handles are used, if different handles are created each time and they must be stored permanently for subsequent operation, use **Worker**. For details, see [Using Worker to Process Associated Synchronous Tasks](./sync-task-development.md#using-worker-to-process-associated-synchronous-tasks). +- Associated synchronous tasks: In scenarios where a series of synchronous tasks is required, such as when creating and using handles that must be permanently stored, Worker is recommended to ensure proper management of these handles. For details, see [Using Worker for Interdependent Synchronous Tasks](./sync-task-development.md#using-worker-for-interdependent-synchronous-tasks). -- Use **TaskPool** for a task for which the priority needs to be set. For example, in the histogram rendering scenario in Gallery, histogram data calculated in the background is used for UI display on the foreground. Therefore, histogram data calculation must be treated with high priority. In this case, use **TaskPool**. +- Tasks requiring priority setting: For example, in a Gallery histogram rendering scenario, background calculations for histogram data that affect user experience should be prioritized. This requires the use of TaskPool. -- Use **TaskPool** for a task that is subject to cancellation at any time. For example, in the large image browsing scenario in Gallery, two images before and after the current image are cached. When the user swipes one side, the image cache task on the other side needs to be canceled. In this case, use **TaskPool**. +- Frequently canceled tasks: For tasks that need to be canceled often, such as in a Gallery viewing scenario where images on either side of the current image are cached, TaskPool is recommended to efficiently manage the cancellation of a cache task when swiping to the next image. -- Use **TaskPool** for a large number of tasks or tasks with scattered scheduling points. For example, a large application with multiple modules may have multiple time-consuming tasks, and it is inconvenient to use worker threads to manage load. In this case, **TaskPool** is recommended. For details about the scenario example, see [Batch Data Writing to the Database](./batch-database-operations-guide.md). +- Numerous or dispersed tasks: For applications with multiple modules containing numerous time-consuming tasks, using Worker for load management may be inconvenient. TaskPool is recommended in such cases. For details about the scenario example, see [Batch Database Operations](./batch-database-operations-guide.md). diff --git a/en/application-dev/arkts-utils/taskpool-waterflow.md b/en/application-dev/arkts-utils/taskpool-waterflow.md new file mode 100644 index 0000000000000000000000000000000000000000..195397305baca1c886a2f30901661f03407727fe --- /dev/null +++ b/en/application-dev/arkts-utils/taskpool-waterflow.md @@ -0,0 +1,285 @@ +# ArkUI Waterfall Rendering + +This topic describes how to use [TaskPool](../reference/apis-arkts/js-apis-taskpool.md) to improve the rendering performance of the [WaterFlow](../reference/apis-arkui/arkui-ts/ts-container-waterflow.md) component. When the UI thread queries large volumes of data from the database and renders the data to the **WaterFlow** component, the UI may become unresponsive, negatively impacting user experience. To address this, we can offload data query to child threads and return the data to the UI thread using TaskPool APIs. + +This example describes the following scenarios: +- A child thread [queries data from the database](batch-database-operations-guide.md) and returns the data to the UI thread. +- The UI thread detects data updates and renders the data returned from the child thread to the **WaterFlow** component. + +1. Define an interface for the child thread to query data from the database and return the data to the UI thread. + + ```ts + // Mock.ets + import { taskpool } from '@kit.ArkTS'; + import { fillImg } from './Index'; + + @Concurrent + function query() { + console.info("TaskPoolTest-this is query"); + let result = new Array(33); + for (let i = 0; i < 33; i++) { + result[i] = 'Image' + i; + } + taskpool.Task.sendData(result); + } + + export function getImgFromDB() { + // Simulate the operation of querying the database and returning data. + let task = new taskpool.Task(query); + task.onReceiveData(fillImg); + taskpool.execute(task); + } + ``` + +2. Encapsulate a waterfall data source for loading data to the **WaterFlow** component. + + ```ts + // WaterFlowDataSource.ets + + // An object that implements the IDataSource interface, which is used by the WaterFlow component to load data. + export class WaterFlowDataSource implements IDataSource { + private dataArray: number[] = []; + private listeners: DataChangeListener[] = []; + + constructor() { + for (let i = 0; i < 100; i++) { + this.dataArray.push(i); + } + } + + // Obtain the data corresponding to the specified index. + public getData(index: number): number { + return this.dataArray[index]; + } + + // Notify the controller that data has been reloaded. + notifyDataReload(): void { + this.listeners.forEach(listener => { + listener.onDataReloaded(); + }) + } + + // Notify the controller that data has been added. + notifyDataAdd(index: number): void { + this.listeners.forEach(listener => { + listener.onDataAdd(index); + }) + } + + // Notify the controller that data has changed. + notifyDataChange(index: number): void { + this.listeners.forEach(listener => { + listener.onDataChange(index); + }) + } + + // Notify the controller that data has been deleted. + notifyDataDelete(index: number): void { + this.listeners.forEach(listener => { + listener.onDataDelete(index); + }) + } + + // Notify the controller that the data position has changed. + notifyDataMove(from: number, to: number): void { + this.listeners.forEach(listener => { + listener.onDataMove(from, to); + }) + } + + //Notify the controller that data has been deleted in batch. + notifyDatasetChange(operations: DataOperation[]): void { + this.listeners.forEach(listener => { + listener.onDatasetChange(operations); + }) + } + + // Obtain the total number of data records. + public totalCount(): number { + return this.dataArray.length; + } + + // Register a controller for data changes. + registerDataChangeListener(listener: DataChangeListener): void { + if (this.listeners.indexOf(listener) < 0) { + this.listeners.push(listener); + } + } + + // Unregister the controller for data changes. + unregisterDataChangeListener(listener: DataChangeListener): void { + const pos = this.listeners.indexOf(listener); + if (pos >= 0) { + this.listeners.splice(pos, 1); + } + } + + // Add data. + public add1stItem(): void { + this.dataArray.splice(0, 0, this.dataArray.length); + this.notifyDataAdd(0); + } + + // Add an element to the end of the data. + public addLastItem(): void { + this.dataArray.splice(this.dataArray.length, 0, this.dataArray.length); + this.notifyDataAdd(this.dataArray.length - 1); + } + + // Add an element at the specified index. + public addItem(index: number): void { + this.dataArray.splice(index, 0, this.dataArray.length); + this.notifyDataAdd(index); + } + + // Delete the first element. + public delete1stItem(): void { + this.dataArray.splice(0, 1); + this.notifyDataDelete(0); + } + + // Delete the second element. + public delete2ndItem(): void { + this.dataArray.splice(1, 1); + this.notifyDataDelete(1); + } + + // Delete the last element. + public deleteLastItem(): void { + this.dataArray.splice(-1, 1); + this.notifyDataDelete(this.dataArray.length); + } + + // Delete an element at the specified index. + public deleteItem(index: number): void { + this.dataArray.splice(index, 1); + this.notifyDataDelete(index); + } + + // Reload the data. + public reload(): void { + this.dataArray.splice(1, 1); + this.dataArray.splice(3, 2); + this.notifyDataReload(); + } + } + ``` + +3. During cold start of the application, call the **getImgFromDB()** interface to offload the data query operation to a child thread. After the img receives data from the child thread, render the data to the **WaterFlow** component. + + ```ts + // Index.ets + import { WaterFlowDataSource } from './WaterFlowDataSource'; + import { getImgFromDB } from './Mock'; + + // Simulate an image array. + let img = new Array(33); + export function fillImg(imgArr : Array) { + img = imgArr; + } + + @Entry + @Component + struct WaterFlowDemo { + @State minSize: number = 80; + @State maxSize: number = 180; + @State fontSize: number = 24; + @State colors: number[] = [0xFFC0CB, 0xDA70D6, 0x6B8E23, 0x6A5ACD, 0x00FFFF, 0x00FF7F]; + scroller: Scroller = new Scroller(); + dataSource: WaterFlowDataSource = new WaterFlowDataSource(); + private itemWidthArray: number[] = []; + private itemHeightArray: number[] = []; + // Calculate the width and height of a flow item. + getSize() { + let ret = Math.floor(Math.random() * this.maxSize); + return (ret > this.minSize ? ret : this.minSize); + } + + // Set the width and height array of the flow item. + setItemSizeArray() { + for (let i = 0; i < 100; i++) { + this.itemWidthArray.push(this.getSize()); + this.itemHeightArray.push(this.getSize()); + } + } + + aboutToAppear() { + this.setItemSizeArray(); + } + + @Builder + itemFoot() { + Column() { + Text(`Footer`) + .fontSize(10) + .backgroundColor(Color.Red) + .width(50) + .height(50) + .align(Alignment.Center) + .margin({ top: 2 }); + } + } + + build() { + Column({ space: 2 }) { + Text("ArkUI WaterFlow Demo") + .onAppear(()=>{ + getImgFromDB(); + }) + WaterFlow() { + LazyForEach(this.dataSource, (item: number) => { + FlowItem() { + Column() { + Text("N" + item) + .fontSize(12) + .height('16') + .onClick(()=>{ + + }); + // To simulate image loading, use the Text component. For actual JPG loading, use the Image component directly. Example: Image(this.img[item % 33]).objectFit(ImageFit.Contain).width('100%').layoutWeight(1) + if (img[item % 33] == null) { + Text('Loading image...') + .width('100%') + .layoutWeight(1); + } + Text(img[item % 33]) + .width('100%') + .layoutWeight(1); + } + } + .onAppear(() => { + // Pre-load more data when approaching the bottom. + if (item + 20 == this.dataSource.totalCount()) { + for (let i = 0; i < 100; i++) { + this.dataSource.addLastItem(); + } + } + }) + .width('100%') + .height(this.itemHeightArray[item % 100]) + .backgroundColor(this.colors[item % 5]) + }, (item: string) => item) + } + .columnsTemplate("1fr 1fr") + .columnsGap(10) + .rowsGap(5) + .backgroundColor(0xFAEEE0) + .width('100%') + .height('100%') + .onReachStart(() => { + console.info('TaskPoolTest-waterFlow reach start'); + }) + .onScrollStart(() => { + console.info('TaskPoolTest-waterFlow scroll start'); + }) + .onScrollStop(() => { + console.info('TaskPoolTest-waterFlow scroll stop'); + }) + .onScrollFrameBegin((offset: number, state: ScrollState) => { + console.info('TaskPoolTest-waterFlow scrollFrameBegin offset: ' + offset + ' state: ' + state.toString()); + return { offsetRemain: offset }; + }) + } + } + } + ``` \ No newline at end of file diff --git a/en/application-dev/arkts-utils/thread_communication.md b/en/application-dev/arkts-utils/thread_communication.md index 3b409f7d1f148af67a93bd296b3106aaf71822d3..81c0bb6872d6e8d1b203102d73729e9c5c62b39d 100644 --- a/en/application-dev/arkts-utils/thread_communication.md +++ b/en/application-dev/arkts-utils/thread_communication.md @@ -1,27 +1,27 @@ # Communication Between Threads -## Introduction +## Overview -During application development, some time-consuming tasks are executed in subthreads to prevent the main thread from being blocked, delivering a better user experience. Generally, a subthread can independently complete its task. However, in most cases, data needs to be transferred from the main thread to the subthread, or the task execution result needs to be returned from the subthread to the main thread. Therefore, communication between the main thread and subthread is necessary. This topic describes several example scenarios to show how to implement data communication between the main thread and subthreads in OpenHarmony application development. +During application development, some time-consuming tasks are executed in child threads to prevent the UI main thread from being blocked, delivering a better user experience. Generally, a child thread can independently complete its task. However, in most cases, data needs to be transferred from the host thread to the child thread, or the task execution result needs to be returned from the child thread to the host thread. Therefore, communication between the host thread and child thread is necessary. This topic describes several example scenarios to show how to implement data communication between the host thread and child threads in OpenHarmony application development. ## Independent Execution of a Task -If a time-consuming task can be executed independently by a subthread, the subthread only needs to return the execution result to the main thread after the task is executed. You can perform the following operations to implement this scenario. +If a time-consuming task can be executed independently by a child thread, the child thread only needs to return the execution result to the host thread after the task is executed. You can perform the following operations to implement this scenario. First, import the TaskPool module. ```typescript import { taskpool } from '@kit.ArkTS'; ``` -Then, implement the task that the subthread needs to perform. +Then, implement the task that the child thread needs to perform. ```typescript @Concurrent // Methods executed in the task must be decorated by @Concurrent. Otherwise, they cannot be called. export function loadPicture(count: number): IconItemSource[] { let iconItemSourceList: IconItemSource[] = []; - // Traverse and add six IconItem data records. + // Add six IconItem data records. for (let index = 0; index < count; index++) { const numStart: number = index * 6; - // Six images are used cyclically. + // Use six images in the loop. iconItemSourceList.push(new IconItemSource($r('app.media.nearby'), `item${numStart + 1}`)); iconItemSourceList.push(new IconItemSource($r('app.media.scan'), `item${numStart + 2}`)); iconItemSourceList.push(new IconItemSource($r('app.media.shop'), `item${numStart + 3}`)); @@ -39,7 +39,7 @@ Finally, call **execute** in the **TaskPool** class to execute the task. let lodePictureTask: taskpool.Task = new taskpool.Task(loadPicture, 30); // Execute the task and return the result. taskpool.execute(lodePictureTask).then((res: IconItemSource[]) => { - // Execution result of the loadPicture API. + // Execution result of the loadPicture method. this.iconItemSourceList = res; }) ...... @@ -47,7 +47,7 @@ taskpool.execute(lodePictureTask).then((res: IconItemSource[]) => { ## Simultaneous Execution of Multiple Tasks -If multiple tasks are executed simultaneously, their execution time and result return time vary according to the task complexity. If the main thread requires the execution results of all tasks, you can use the following code snippet: +When multiple tasks are executed concurrently, their execution times can vary due to differences in complexity, and the timing of their completion is unpredictable. If the host thread requires the execution results of all tasks, you can use the following code snippet: ```typescript ...... let taskGroup: taskpool.TaskGroup = new taskpool.TaskGroup(); @@ -63,30 +63,30 @@ taskpool.execute(taskGroup).then((ret: IconItemSource[][]) => { }) ...... ``` -In this scenario, all the tasks to be executed are placed in a task group. After all the tasks in the task group are executed, the execution result of each task is placed in an array and returned to the main thread. The main thread can obtain all task execution results at a time. +In this scenario, all the tasks to be executed are placed in a task group. After all the tasks in the task group are executed, the execution result of each task is placed in an array and returned to the host thread. The host thread can obtain all task execution results at a time. -In addition, if a task needs to process a large amount of data (for example, a list contains 10,000 data records), it is time-consuming to process all the data in one task. In this case, you can split the data into multiple sublists, allocate one task for each sublist, and combine the results of all the tasks. This pattern reduces the processing time and improves user experience. +In addition, if a task needs to process a large amount of data (for example, a list contains 10,000 data records), it is time-consuming to process all the data in one task. Instead, you can split the original data into multiple sublists and assign each sublist to an independent task. After all tasks are completed, you can combine the results into a complete dataset. This approach can reduce processing time and enhance user experience. -## Communication with the Main Thread During Task Execution +## Communication Between the Task and Host Thread -If a subthread needs to periodically notify the main thread of the task status and data changes, or needs to return a large amount of data by segment (for example, a large amount of data read from the database), you can perform the following operations: +When a task needs to do more than just return a final result—such as periodically updating the host thread on its status, reporting data changes, or returning large volumes of data in segments (for example, fetching large datasets from a database)—you can use the approach described in this topic. -First, implement a method to receive messages sent by the task. +Implement a method to receive messages sent by the task. ```typescript function notice(data: number): void { - console.info("The subthread task has been executed. Total images loaded:", data) + console.info("Child thread task completed. Total images loaded:", data) } ``` -Then, add **sendData()** to the task to enable the subthread to send messages to the main thread. +Then, add **sendData()** to the task to enable the child thread to send messages to the host thread. ```typescript -// Use sendData to notify the main thread of information in real time. +// Use sendData to notify the host thread of information in real time. @Concurrent export function loadPictureSendData(count: number): IconItemSource[] { let iconItemSourceList: IconItemSource[] = []; - // Traverse and add six IconItem data records. + // Add six IconItem data records. for (let index = 0; index < count; index++) { const numStart: number = index * 6; - // Six images are used cyclically. + // Use six images in the loop. iconItemSourceList.push(new IconItemSource($r('app.media.nearby'), `item${numStart + 1}`)); iconItemSourceList.push(new IconItemSource($r('app.media.scan'), `item${numStart + 2}`)); iconItemSourceList.push(new IconItemSource($r('app.media.shop'), `item${numStart + 3}`)); @@ -98,37 +98,37 @@ export function loadPictureSendData(count: number): IconItemSource[] { return iconItemSourceList; } ``` -Finally, use **onReceiveData()** to enable the main thread to receive messages. +In the host thread, use **onReceiveData()** to receive messages. ```typescript ...... let lodePictureTask: taskpool.Task = new taskpool.Task(loadPictureSendData, 30); -// Use notice to receive messages sent by the task. +// Use notice to receive messages from the task. lodePictureTask.onReceiveData(notice); taskpool.execute(lodePictureTask).then((res: IconItemSource[]) => { this.iconItemSourceList = res; }) ...... ``` -In this way, the main thread can receive the data sent by the task through **notice()**. +This allows the host thread to receive data sent by the task through **notice()**. -## Instant Communication Between the Worker Thread and Main Thread +## Real-Time Communication Between the Worker Thread and Host Thread -In ArkTS, Worker provides a limited number of threads that exist for a longer time than TaskPool threads. Multiple tasks may be executed in one [Worker thread](https://docs.openharmony.cn/pages/v4.0/en/application-dev/arkts-utils/worker-introduction.md/), and the execution duration or returned result of each task may be different. The host thread needs to call different methods in the Worker thread according to the actual situation, and the Worker thread needs to return the result to the host thread in time. You can perform the following operations to implement this scenario. +In ArkTS, Worker differ from TaskPool in that it has a limited number of threads but can run for extended periods. Multiple tasks may be executed in one [Worker thread](https://docs.openharmony.cn/pages/v4.0/en/application-dev/arkts-utils/worker-introduction.md/), and the execution duration or returned result of each task may be different. The host thread needs to call different methods in the Worker thread according to the actual situation, and the Worker thread needs to return the result to the host thread in time. You can perform the following operations to implement this scenario. First, create a Worker thread to execute different tasks based on parameters. ```typescript import { worker, MessageEvents, ThreadWorkerGlobalScope } from '@kit.ArkTS'; const workerPort: ThreadWorkerGlobalScope = worker.workerPort; -// The Worker thread receives messages from the main thread and calls the corresponding method based on the data type. +// The Worker thread receives messages from the host thread and calls the corresponding method based on the data type. workerPort.onmessage = (e: MessageEvents): void => { if (typeof e.data === "string") { try { - // The method to call does not carry an input parameter. + // Call the method without parameters. let res: string = workerPort.callGlobalCallObjectMethod("picData", "setUp", 0) as string; console.error("worker: ", res); } catch (error) { - // Exception handling. + // Handle exceptions. console.error("worker: error code is " + error.code + " error message is " + error.message); } } else if (e.data instanceof Array) { @@ -137,7 +137,7 @@ workerPort.onmessage = (e: MessageEvents): void => { } } ``` -Then, create a **Worker** object in the main thread. When the button is touched, **postMessage** is called to send a message to the Worker thread, and **onmessage** of the **Worker** class is used to receive data returned by the Worker thread. +Then, create a **Worker** object in the host thread. When the button is touched, **postMessage** is called to send a message to the Worker thread, and **onmessage** of the **Worker** class is used to receive data returned by the Worker thread. ```typescript import { worker, MessageEvents } from '@kit.ArkTS'; ...... @@ -149,7 +149,7 @@ aboutToAppear() { this.initWorker(); for (let index = 0; index < 20; index++) { const numStart: number = index * 6; - // Six images are used cyclically. + // Use six images in the loop. this.iconItemSourceList.push(new IconItemSource($r('app.media.nearby'), `item${numStart + 1}`)); this.iconItemSourceList.push(new IconItemSource($r('app.media.scan'), `item${numStart + 2}`)); this.iconItemSourceList.push(new IconItemSource($r('app.media.shop'), `item${numStart + 3}`)); @@ -182,13 +182,13 @@ Button ('Change the number of images to five', { type: ButtonType.Normal, stateE }) ...... ``` -In the sample code, the Worker thread performs two different processing. When the input data is of the string type, it calls **callGlobalCallObjectMethod** to synchronously call the method in the main thread. When the input data is of the array type, it returns the first four data records of the array to the main thread. In this way, instant communication between the main thread and Worker thread can be implemented. +In the sample code, the Worker thread performs two different processing. When the input data is of the string type, it calls **callGlobalCallObjectMethod** to synchronously call the method in the host thread (which is the UI main thread in this case). When the input data is of the array type, it returns the first four data records of the array to the host thread. This enables real-time communication between the host thread and the Worker thread, allowing the host thread to conveniently use the execution results of the Worker. -## Worker Thread Synchronously Calls a Method of the Main Thread +## Worker Thread Synchronously Calls a Method of the Host Thread -If the Worker thread needs to call the method that has been implemented in the main thread, you can perform the following operations: +If an interface is already implemented in the host thread and needs to be called by Worker, you can achieve this by using the approach described in this topic. -First, implement the method in the main thread, create a **Worker** object, and register the method on the **Worker** object. +Implement the interface in the host thread and create a Worker object. Register the interface to be called on the Worker object. ```typescript import { worker } from '@kit.ArkTS'; // Create a Worker object. @@ -200,7 +200,7 @@ class PicData { public setUp(): string { for (let index = 0; index < 20; index++) { const numStart: number = index * 6; - // Six images are used cyclically. + // Use six images in the loop. this.iconItemSourceList.push(new IconItemSource($r('app.media.nearby'), `item${numStart + 1}`)); this.iconItemSourceList.push(new IconItemSource($r('app.media.scan'), `item${numStart + 2}`)); this.iconItemSourceList.push(new IconItemSource($r('app.media.shop'), `item${numStart + 3}`)); @@ -213,7 +213,7 @@ class PicData { } let picData = new PicData(); -// Register the method on the Worker object. +// Register the object to be called on the Worker object. workerInstance.registerGlobalCallObject("picData", picData); workerInstance.postMessage("run setUp in picData"); ``` @@ -221,14 +221,13 @@ Then, use [callGlobalCallObjectMethod](../reference/apis-arkts/js-apis-worker.md ```typescript ...... try { - // The method to call does not carry an input parameter. + // Call the method without parameters. let res: string = workerPort.callGlobalCallObjectMethod("picData", "setUp", 0) as string; console.error("worker: ", res); } catch (error) { - // Exception handling. + // Handle exceptions. console.error("worker: error code is " + error.code + " error message is " + error.message); } ...... ``` - diff --git a/en/application-dev/arkts-utils/time-consuming-task-overview.md b/en/application-dev/arkts-utils/time-consuming-task-overview.md index 370fa1f13bbe41e16e3d2c7e32976f00f5bac5a9..5d60d9cf47e7a01aef9188eb7254ebb47b8a6339 100644 --- a/en/application-dev/arkts-utils/time-consuming-task-overview.md +++ b/en/application-dev/arkts-utils/time-consuming-task-overview.md @@ -1,17 +1,17 @@ -# Concurrent Time-Consuming Task Scenarios +# Overview of Concurrency in Time-Consuming Tasks -Time-consuming tasks refer to tasks that need to be executed for a long time. If a time-consuming task is executed in the main thread of the UI, problems such as frame freezing, frame loss, and slow response may occur. Typical time-consuming tasks include CPU-intensive tasks, I/O-intensive tasks, and synchronization tasks. +Time-consuming tasks are those that take a long time to complete. If executed in the UI main thread, they can cause application lag, frame drops, and slow response times. Typical examples include CPU intensive tasks, I/O intensive tasks, and synchronous tasks. -Common service scenarios of time-consuming tasks are as follows: +The following describes typical service scenarios for time-consuming tasks. -| Common Service Scenario| Description| CPU-Intensive Task| I/O-Intensive Task| Synchronize Task| +| Service Scenario| Description| CPU Intensive Task| I/O intensive Task| Synchronous Task| | -------- | -------- | -------- | -------- | -------- | -| Image/Video encoding and decoding| Encodes and decodes images or videos before displaying them.| √ | √ | × | -| Compression and decompression| Decompresses a local package or compresses a local file.| √ | √ | × | -| JSON parsing| Serializes and deserializes JSON strings.| √ | × | × | -| Model computation| Performs model operations and analysis on data.| √ | × | × | -| Network download| Downloads resources, images, and files on an intensive network.| × | √ | × | -| Database operation| Saves chat records, page layout, and music list information to the database, or reads the database to display related information when the application is started for the second time.| × | √ | × | +| Image/Video encoding and decoding| Encoding or decoding images or videos for display.| Supported| Supported| Not supported| +| Compression and decompression| Decompressing local archives or compressing local files.| Supported| Supported| Not supported| +| JSON parsing| Serializing and deserializing JSON strings.| Supported| Not supported| Not supported| +| Model computation| Performing data analysis using models.| Supported| Not supported| Not supported| +| Network download| Downloading resources, images, and files via intensive network requests.| Not supported| Supported| Not supported| +| Database operations| Saving data like chat records, page layouts, or music lists to the database, or reading from the database on application restart.| Not supported| Supported| Not supported| diff --git a/en/application-dev/arkts-utils/tool-disassembler.md b/en/application-dev/arkts-utils/tool-disassembler.md index 0f1f785857572dbdbb4c22ad21a93ab77c807b10..5b12f3e9eba6a54d24029755f8d92981b39cf66e 100644 --- a/en/application-dev/arkts-utils/tool-disassembler.md +++ b/en/application-dev/arkts-utils/tool-disassembler.md @@ -1,42 +1,42 @@ # Disassembler -## Introduction +## Overview -Disassembler is an ArkTS disassembly tool. If you need to analyze issues related to Ark bytecode files (\*.abc), you can use Disassembler to disassemble byte data into readable assembly instructions. +Disassembler is a utility in the ArkTS toolchain designed to convert Ark bytecode files (*.abc) into human-readable assembly instructions. It is particularly useful when you want to analyze or debug issues related to Ark bytecode files. -The tool is released with the DevEco Studio SDK. Take the Windows platform as an example. The Disassembler tool is stored in [DevEco Studio installation directory]\sdk\[SDK version]\openharmony\toolchains\ark_disasm.exe. +Disassembler is released with the DevEco Studio SDK. For instance, on Windows, the tool can be found at: [DevEco Studio installation directory]\sdk\[SDK version]\openharmony\toolchains\ark_disasm.exe. -## Commands +## Command-Line Instructions -Disassembly command: +To use Disassembler, run the following command: ``` ark_disasm.exe [options] input_file output_file ``` -Parameter description +Parameters -| Option| Left Unspecified Allowed| Description| +| Parameter| Optional| Description| | -------- | -------- | -------- | -| [options] | This parameter can be left unspecified.| Command option. For details, see the following description of options.| -| input_file | No| Path of the ARK bytecode file to be disassembled.| -| output_file | No| Output file path of the disassembled content.| +| [options] | Yes| Command options. For details, see **Description of options** below.| +| input_file | No| Path of the Ark bytecode file to be disassembled.| +| output_file | No| Path where the disassembled file will be saved.| -Description of options +Description of **options** -| Option| Left Unspecified Allowed| Argument Carried| Description| +| Option| Optional| Argument Carried| Description| | -------- | -------- | -------- | -------- | -| --debug | This parameter can be left unspecified.| No| Enables the function of outputting debugging information. By default, debugging information is output to the screen.| -| --debug-file | This parameter can be left unspecified.| Yes| Specifies the output file of debugging information if --debug is enabled.| -| --help | This parameter can be left unspecified.| No| Prints help information.| -| --skip-string-literals | This parameter can be left unspecified.| No| Skips disassembly of string literals.| -| --quiet | This parameter can be left unspecified.| No| Enables all options starting with '--skip-'.| -| --verbose | This parameter can be left unspecified.| No| Enables the output of additional information (byte position, ARK bytecode format, and operation code).| -| --version | This parameter can be left unspecified.| No| Displays the version number of the Ark bytecode file and the earliest supported Ark bytecode file version.| +| --debug | Yes| No| Enables the function of outputting debugging information. By default, debugging information is output to the screen.| +| --debug-file | Yes| Yes| Specifies the output file of debugging information if **--debug** is enabled.| +| --help | Yes| No| Displays help information.| +| --skip-string-literals | Yes| No| Skips disassembly of string literals.| +| --quiet | Yes| No| Enables all options prefixed with **--skip-**.| +| --verbose | Yes| No| Enables the output of additional information (byte position, ARK bytecode format, and operation code).| +| --version | Yes| No| Displays the version of the Ark bytecode file and the minimum supported version.| -## Samples +## Usage Example -Assume that the Ark bytecode file test.abc exists. The source code is as follows: +Assume that the Ark bytecode file **test.abc** exists, with the following source code: ``` let i = 99; @@ -45,28 +45,28 @@ show(); ``` -Run the following command to generate the disassembly file test.txt: The generated disassembly file contains information such as the operation code and format. +Run the following command to generate a disassembled file named **test.txt**, which contains information such as the operation code and format: ``` ark_disasm.exe test.abc test.txt ``` -View the content of the disassembly file. +Run the following command to view the content of the disassembled file: ``` cat test.txt ``` -Modify the file as follows: +The file content is as follows: ``` -# source binary: test.abc // Disassembled Ark bytecode file +# source binary: test.abc // Disassembled Ark bytecode file. .language ECMAScript # ==================== -# LITERALS // Literal data +# LITERALS // Literal data. 0 0x203 { 0 [ MODULE_REQUEST_ARRAY: { @@ -74,60 +74,60 @@ Modify the file as follows: ]} # ==================== -# RECORDS // Module definition data +# RECORDS // Module definition data. -The data starts with .record _ESConcurrentModuleRequestsAnnotation { // _ and is fixed module data. +.record _ESConcurrentModuleRequestsAnnotation { // Data prefixed with _ is fixed module data. } -.record test { // One JS file corresponds to one module data, including the module information (location in the ARK bytecode file, whether it is commonjs...). +.record test { // One JS file corresponds to one module. It contains the module information, for example, location in the ARK bytecode file and whether it is CommonJS. u8 isCommonjs = 0x0 u32 moduleRecordIdx = 0x203 ...... } # ==================== -# METHODS // Method definition data +# METHODS // Method definition data. L_ESSlotNumberAnnotation: u32 slotNumberIdx { 0x0 } -The show method in the source code of the .function any test.#*#show(any a0, any a1, any a2) { // method belongs to the test module. +.function any test.#*#show(any a0, any a1, any a2) { // The show method in the source code. It belongs to the test module. ldlexvar 0x0, 0x0 ...... } L_ESSlotNumberAnnotation: u32 slotNumberIdx { 0x3 } -The .function any test.func_main_0(any a0, any a1, any a2) { // method is automatically generated. The entire JS file can be regarded as a method. The method name is func_main_0. +.function any test.func_main_0(any a0, any a1, any a2) { // The method is automatically generated. The entire JS file can be regarded as a method named func_main_0. newlexenv 0x1 ...... } # ==================== -# STRING // Symbol table information +# STRING // Symbol table information [offset:0x88, name_value:i] ``` -Use the --verbose parameter to print more details such as the offset. +Use the **--verbose** parameter to print more details such as the offset. ``` ark_disasm.exe --verbose test.abc test.txt ``` -Some examples are listed here. +Here are some examples of the output with **--verbose**: ``` -.record _ESSlotNumberAnnotation { # offset: 0x00cd, size: 0x0026 (38) //: Prints the specific position and size of the module in the ARK bytecode file. +.record _ESSlotNumberAnnotation { # offset: 0x00cd, size: 0x0026 (38) // This prints the location and size of the module within the ARK bytecode file. } -.record test {# offset: 0x00f3, size: 0x0098 (152) // The specific position of the module in the ARK bytecode file is displayed. - u32 moduleRecordIdx = 0x203 # offset: 0x0144 // Location where the module information is printed +.record test { # offset: 0x00f3, size: 0x0098 (152) // This prints the location of the module within the ARK bytecode file. + u32 moduleRecordIdx = 0x203 # offset: 0x0144 // This prints the location of the module information. } ...... -.function any test.#*#show(any a0, any a1, any a2) { # offset: 0x0153, code offset: 0x0245 //: indicates the specific location of the method information and the specific location of the instruction in the method. +.function any test.#*#show(any a0, any a1, any a2) { # offset: 0x0153, code offset: 0x0245 // This prints the location of the method information and the location of the instruction in the method. # CODE: - ldlexvar 0x0, 0x0 # offset: 0x0249, [IMM4_IMM4].........[0x3c 0x00] //: indicates the location of each command. + ldlexvar 0x0, 0x0 # offset: 0x0249, [IMM4_IMM4].........[0x3c 0x00] // This prints the location of each command. ...... } ``` diff --git a/en/application-dev/arkts-utils/transferabled-object.md b/en/application-dev/arkts-utils/transferabled-object.md index 6d87deef6f7953ec8c8bedf05331764eaaa2ce7e..c541153a0e72858595dbba267a431c41129b2689 100644 --- a/en/application-dev/arkts-utils/transferabled-object.md +++ b/en/application-dev/arkts-utils/transferabled-object.md @@ -1,33 +1,33 @@ # Transferable Object (NativeBinding Object) -A Transferable object (also called NativeBinding object) is a JS object that is bound to a C++ object and provides main functions by C++. During cross-thread transmission, the same C++ object can be directly reused. Compared with the JS object copy mode, the transmission efficiency is higher. Therefore, NativeBinding objects that can be shared or transferred are also called Transferable objects. +A Transferable object, also known as a NativeBinding object, is a JS object that is bound to a C++ object, with the primary functionality provided by C++. Its JS object wrapper is allocated in the local heap of the virtual machine. During cross-thread communication, the same C++ object can be reused directly. Compared with the pass-by-copy mode of JS objects, this method offers higher transfer efficiency. Therefore, NativeBinding objects that can be shared or transferred are also referred to as Transferable objects. -## Sharing Mode +## Shared Mode -If the C++ implementation can ensure thread security, the C++ part of the NativeBinding object can support shared transmission. In this case, after the NativeBinding object is transferred across threads, you only need to create a JS shell again to bridge the object to the same C++ object. The following figure shows the communication process. +If the C++ implementation can ensure thread safety, the C++ part of the NativeBinding object supports the shared mode. In this case, after the NativeBinding object is passed across threads, you only need to create a JS object wrapper again to bridge to the same C++ object. The following figure shows the communication process. ![nativeBinding](figures/nativeBinding.png) -A common shared NativeBinding object includes a context, and the context object includes context information of an application component. The context object provides a manner of accessing a system service and a resource, so that the application component can interact with the system. For details about how to obtain context information, see [Context (Stage Model)](../application-models/application-context-stage.md). +A typical shared-mode NativeBinding object includes context. A context object contains contextual information for application components and provides a way to access system services and resources, enabling the application components to interact with the system. For details about how to obtain context, see [Context (Stage Model)](../application-models/application-context-stage.md). -For details, see [Using TaskPool for Frequent Database Operations](./batch-database-operations-guide.md#using-taskpool-for-frequent-database-operations). +For details about the development example, see [Using TaskPool for Frequent Database Operations](./batch-database-operations-guide.md#using-taskpool-for-frequent-database-operations). ## Transfer Mode -If the C++ implementation contains data and thread security cannot be ensured, the C++ part of the NativeBinding object needs to be transferred in transfer mode. In this case, after the NativeBinding object is transferred across threads, you only need to create a JS shell again to bridge the object to the C++ object. However, the binding relationship of the original object needs to be removed. The following figure shows the communication process. +If the C++ implementation contains data and cannot ensure thread safe, the C++ part of the NativeBinding object should be passed by transfer. In this case, after the NativeBinding object is passed across threads, you only need to create a JS object wrapper again to bridge to the C++ object. However, the original object must remove its binding to this object. The following figure shows the communication process. ![nativeBinding_transfer](figures/nativeBinding_transfer.png) -Common NativeBinding objects include PixelMap. The [PixelMap object](../reference/apis-image-kit/js-apis-image.md#imagecreatepixelmap8) can be used to read or write image data and obtain image information. It is usually used to display images in applications or systems. +A typical transfer-mode NativeBinding object includes a PixelMap. The [PixelMap object](../reference/apis-image-kit/js-apis-image.md#imagecreatepixelmap8) can read or write image data and obtain image information, and is usually used to display images in applications or systems. -### Samples +### Usage Example -An example of passing a PixelMap object across threads is provided to help you better understand. Obtain the image resources in the rawfile folder, create a PixelMap object in the subthread, and transfer the object to the main thread. The implementation is as follows: +Here is an example of passing a PixelMap object across threads to help you better understand the process. First, obtain the image resource from the **rawfile** folder, and then create a PixelMap object in the child thread and pass it to the main thread. The specific implementation is as follows: ```ts // Index.ets @@ -43,13 +43,13 @@ struct Index { private loadImageFromThread(): void { const resourceMgr = getContext(this).resourceManager; - // startIcon.png is copied from the media directory to the rawfile folder. You need to replace it. Otherwise, the image source fails to be created and subsequent operations cannot be performed. + // startIcon.png is copied from the media directory to the rawfile folder. You need to replace it. Otherwise, the imageSource fails to be created and subsequent operations cannot be performed. resourceMgr.getRawFd('startIcon.png').then(rawFileDescriptor => { taskpool.execute(loadPixelMap, rawFileDescriptor).then(pixelMap => { if (pixelMap) { this.pixelMap = pixelMap as PixelMap; console.log('Succeeded in creating pixelMap.'); - // The main thread releases the pixelMap. Because setTransferDetached has been called when the child thread returns pixelMap, the pixelMap can be released immediately. + // The main thread releases the pixelMap. Because setTransferDetached has been called when the child thread returns the pixelMap, the pixelMap can be released immediately. this.pixelMap.release(); } else { console.error('Failed to create pixelMap.'); @@ -86,13 +86,13 @@ import { image } from '@kit.ImageKit'; @Concurrent export async function loadPixelMap(rawFileDescriptor: number): Promise { - // Create an ImageSource instance. + // Create an imageSource. const imageSource = image.createImageSource(rawFileDescriptor); // Create a pixelMap. const pixelMap = imageSource.createPixelMapSync(); - // Release the ImageSource instance. + // Release the imageSource. imageSource.release(); - // Disconnect the reference of the original thread after the cross-thread transfer of the pixelMap is complete. + // Detach the reference of the original thread after the cross-thread transfer of the pixelMap is complete. pixelMap.setTransferDetached(true); // Return the pixelMap to the main thread. return pixelMap; diff --git a/en/application-dev/arkts-utils/worker-communicates-with-mainthread.md b/en/application-dev/arkts-utils/worker-communicates-with-mainthread.md index f49558da08c8bf38d025635e9d2594d88dc3f4b2..cc3bff6e6a080850a2201b916edc4458e2869c58 100644 --- a/en/application-dev/arkts-utils/worker-communicates-with-mainthread.md +++ b/en/application-dev/arkts-utils/worker-communicates-with-mainthread.md @@ -1,20 +1,20 @@ -# Instant Communication Between the Worker Thread and Host Thread +# Real-Time Communication Between the Worker Thread and Host Thread -In ArkTS, Worker provides a limited number of threads that exist for a longer time than TaskPool threads. A [Worker](worker-introduction.md) may execute multiple tasks. The execution duration or returned result of each task may be different. The host thread needs to call different methods in the Worker based on the site requirements, the worker needs to return the result to the host thread in a timely manner. +In ArkTS, Worker differ from TaskPool in that it has a limited number of threads but can run for extended periods. A [Worker](worker-introduction.md) can execute multiple tasks, each with varying execution times and results. The host thread needs to call different methods in the Worker based on the situation, and the Worker must promptly return the results to the host thread. -The following uses an example in which the worker responds to the "hello world" request for description. +The following example demonstrates how a Worker can respond to a "hello world" request. -1. First, create a Worker for executing multiple tasks. +1. Create a Worker that executes multiple tasks. ```ts // Worker.ets import { ErrorEvent, MessageEvents, ThreadWorkerGlobalScope, worker } from '@kit.ArkTS'; const workerPort: ThreadWorkerGlobalScope = worker.workerPort; - // The worker receives the message from the host thread and performs corresponding processing. + // The Worker receives messages from the host thread and processes them accordingly. workerPort.onmessage = (e: MessageEvents): void => { if (e.data === 'hello world') { workerPort.postMessage('success'); @@ -22,7 +22,7 @@ The following uses an example in which the worker responds to the "hello world" } ``` -2. The host thread is the UI main thread. The worker object is created in the host thread. When the button is clicked, the postmessage function is called to send a message to the worker. The onmessage method of the worker is used to receive the data returned by the worker. +2. In the host thread (UI main thread), create a Worker object. Use the **postmessage** method to send a message to the Worker when a button is clicked, and use the **onmessage** method of Worker to receive the response. ```ts // Index.ets @@ -47,13 +47,13 @@ The following uses an example in which the worker responds to the "hello world" ss.onexit = () => { isTerminate = true; } - Receive messages sent by the worker thread. + // Receive messages sent by the Worker thread. ss.onmessage = (e) => { res = e.data; flag = true; console.info("worker:: res is " + res); } - // Send a message to the worker thread. + // Send a message to the Worker thread. ss.postMessage("hello world"); while (!flag) { await promiseCase(); @@ -87,4 +87,4 @@ The following uses an example in which the worker responds to the "hello world" ``` -In the preceding sample code, the worker receives a message from the host thread, processes the message, and sends the result back to the host thread. In this way, instant communication between the main thread and Worker thread can be implemented. +In this example, the Worker thread receives a message from the host thread, processes it, and sends a response back. This enables real-time communication between the host thread and the Worker thread, allowing the host thread to conveniently use the execution results of the Worker. diff --git a/en/application-dev/arkts-utils/worker-introduction.md b/en/application-dev/arkts-utils/worker-introduction.md index 788ad1a1459912deea99a4788ae0812939df0f41..ed12cc88ff562967fa77c038c5d3a3aa5a89c9e7 100644 --- a/en/application-dev/arkts-utils/worker-introduction.md +++ b/en/application-dev/arkts-utils/worker-introduction.md @@ -1,6 +1,6 @@ -# Worker Introduction +# Worker -With the Worker module, you can provide a multithreaded environment for an application, so that the application can perform a time-consuming operation in a background thread. This greatly prevents a computing-intensive or high-latency task from blocking the running of the main thread. For details about the APIs and their usage, see [Worker](../reference/apis-arkts/js-apis-worker.md). +Worker primarily provides a multithreaded runtime environment for applications, allowing them to separate from the host thread during execution. This enables scripts to run in background threads for time-consuming operations, significantly reducing the likelihood of blocking the host thread during compute-intensive or high-latency tasks. For details about the APIs and their usage, see [Worker](../reference/apis-arkts/js-apis-worker.md). ## Worker Operating Mechanism @@ -9,27 +9,26 @@ With the Worker module, you can provide a multithreaded environment for an appli ![worker](figures/worker.png) -The thread that creates the worker thread is referred to as the host thread (not necessarily the main thread, since a worker thread can also create another worker thread). A worker thread is also named an actor thread. Each worker thread has an instance independent from the host thread, including the infrastructure, objects, and code segments. Memory overhead exists when each worker thread is started, and therefore the number of worker threads needs to be limited. The worker thread communicates with the host thread by means of message exchange. They use the serialization technique to exchange commands and data. +When creating a Worker, the thread that initiates it is referred to as the host thread (not necessarily the main thread, as worker threads can also create child Workers). The Worker itself runs in its own thread, known as a Worker thread or actor thread. Each Worker thread operates independently, with its own infrastructure, objects, and code segments, which incurs some memory overhead for each Worker. Therefore, the number of Worker threads should be limited. The Worker thread communicates with the host thread by means of message exchange. They use the serialization technique to exchange commands and data. ## Precautions for Worker -- A worker thread can be created manually or automatically. In manual creation mode, you must also perform related configurations. For details, see [Precautions for Creating a Worker Thread](#precautions-for-creating-a-worker-thread). -- The URL of the worker thread file passed in to the constructor function varies according to the version in use. For details, see [Precautions for File URLs](#precautions-for-file-urls). -- After a worker thread is created, you must manually manage its lifecycle. A maximum of 64 worker threads can run simultaneously. For details, see [Lifecycle Precautions](#lifecycle-precautions). -- The context objects in different threads are different. Therefore, **Worker** threads can use only thread-safe libraries, rather than UI-related non-thread-safe libraries. +- A Worker can be created manually or automatically. In manual creation mode, you must also synchronize the related configuration. For details, see [Precautions for Creating a Worker](#precautions-for-creating-a-worker). +- When using Worker capabilities, the URL of the Worker thread file passed in the constructor varies by API version. For specifics, see [Precautions for File URLs](#precautions-for-file-urls). +- After a Worker is created, its lifecycle must be managed manually. A maximum of 64 Worker threads can run simultaneously. For details, see [Precautions for Lifecycle Management](#precautions-for-lifecycle-management). +- The context objects in different threads are different. Therefore, Worker threads can use only thread-safe libraries. For example, non-thread-safe UI-related libraries cannot be used. - A maximum of 16 MB data can be serialized. -- You must register the **onerror** API in the main thread to listen for worker thread errors, which might cause a JavaScript crash. +- When using the Worker module, register the **onerror** callback in the host thread. Otherwise, JS crash occurs when the Worker thread is abnormal. - Worker thread files cannot be used across HAPs. -- Before referencing the HAR or HSP, configure the dependency on the HAR or HSP. For details, see (https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V5/ide-har-import-V5). -- [AppStorage](../quick-start/arkts-appstorage.md) cannot be used in the worker thread. +- Before referencing a HAR or HSP, configure the dependency on the HAR or HSP. For details, see [Referencing a Shared Package](https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V14/ide-har-import-V14). +- [AppStorage](../quick-start/arkts-appstorage.md) cannot be used in Worker threads. +### Precautions for Creating a Worker -### Precautions for Creating a Worker Thread +The Worker thread file must be placed in the ***{moduleName}*/src/main/ets/** directory to be included in the application package. There are two ways to create Worker thread directories and files: manually and automatically. -The worker thread file must be stored in the ***{moduleName}*/src/main/ets/** directory. Otherwise, it will not be packed into the application. A worker thread can be created manually or automatically. - -- Manual creation: Manually create the directory and file, and configure the related field in **build-profile.json5** so that the file can be packed into the application. +- Manual creation: Manually create the directory and file, and configure the related field in **build-profile.json5** so that the Worker thread file can be packed into the application package. Stage model: @@ -55,15 +54,15 @@ The worker thread file must be stored in the ***{moduleName}*/src/main/ets/** di } ``` -- Automatic creation: DevEco Studio supports one-click generation of worker threads. Right-click any position in the {moduleName} directory and choose **New > Worker** to generate the template file and configuration information of the worker thread. You do not need to configure the field in **build-profile.json5**. +- Automatic creation: DevEco Studio supports one-click generation of Workers. Right-click any position in the {moduleName} directory and choose **New > Worker** to generate the Worker template file and configuration information. There is no need to configure the fields in **build-profile.json5**. ### Precautions for File URLs - Before calling an API of the Worker module, you must create a **Worker** instance. The constructor function varies in different API versions, and the URL of the worker thread file must be passed in to **scriptURL** of the function. +Before calling an API of the Worker module, you must create a Worker object. The constructor is related to the API version and requires the URL to the Worker thread file to be passed in **scriptURL**. ```ts -// Import the worker module. +// Import the module. import { worker } from '@kit.ArkTS'; // Use the following function in API version 9 and later versions: @@ -73,97 +72,194 @@ const worker2: worker.Worker = new worker.Worker('entry/ets/workers/worker.ets') ``` -#### File URL Rules in the Stage Model +#### File URL Rules in Stage Model -The requirements for **scriptURL** in the constructor function are as follows: +The requirements for **scriptURL** in the constructor are as follows: - **scriptURL** consists of {moduleName}/ets and {relativePath}. -- {relativePath} is the relative path of the worker thread file to the ***{moduleName}*/src/main/ets/** directory. +- {relativePath} is the relative path of the Worker thread file to the ***{moduleName}*/src/main/ets/** directory. -(1) Loading a worker thread file of an ability +(1) Loading a Worker thread file of an ability -To load the worker thread file of an ability, use the URL {moduleName}/ets/{relativePath}. +To load the Worker thread file of an ability, use the URL {moduleName}/ets/{relativePath}. ```ts import { worker } from '@kit.ArkTS'; -// URL of the worker thread file: "entry/src/main/ets/workers/worker.ets" +// URL of the Worker thread file: "entry/src/main/ets/workers/worker.ets" const workerStage1: worker.ThreadWorker = new worker.ThreadWorker('entry/ets/workers/worker.ets'); -// URL of the worker thread file: "phone/src/main/ets/ThreadFile/workers/worker.ets" -const workerStage2: worker.ThreadWorker = new worker.ThreadWorker('phone/ets/ThreadFile/workers/worker.ets'); +// URL of the Worker thread file: "testworkers/src/main/ets/ThreadFile/workers/worker.ets" +const workerStage2: worker.ThreadWorker = new worker.ThreadWorker('testworkers/ets/ThreadFile/workers/worker.ets'); ``` -(2) Loading a worker thread file in [HSP](../quick-start/in-app-hsp.md) +(2) Loading a Worker thread file from an [HSP](../quick-start/in-app-hsp.md) -To load the worker thread file in HSP, use the URL {moduleName}/ets/{relativePath}. +To load the Worker thread file from an HSP, use the URL {moduleName}/ets/{relativePath}. ```ts import { worker } from '@kit.ArkTS'; -// URL of the worker thread file: "hsp/src/main/ets/workers/worker.ets" +// URL of the Worker thread file: "hsp/src/main/ets/workers/worker.ets" const workerStage3: worker.ThreadWorker = new worker.ThreadWorker('hsp/ets/workers/worker.ets'); ``` -(3) Loading a worker thread file in [HAR](../quick-start/har-package.md) +(3) Loading a Worker thread file from an [HAR](../quick-start/har-package.md) -The worker thread file in the HAR may be loaded in either of the following cases: +There are two scenarios for loading a Worker thread file from an HAR: -- @ path loading mode: All types of modules load the worker thread file in the local HAR. The URL is @{moduleName}/ets/{relativePath}. +- @ path loading: All types of modules load the Worker thread file from the local HAR. The URL is @{moduleName}/ets/{relativePath}. -- Relative path loading mode: The local HAR loads the worker thread file in the package. The URL is the relative path of the file where the Worker object is created to the worker thread file. +- Relative path loading: The local HAR loads the Worker thread file within the same package. The URL is the relative path of the file where the Worker object is created to the Worker thread file. >**NOTE** > ->When **useNormalizedOHMUrl** is enabled (the **useNormalizedOHMUrl** field of the **strictMode** attribute in the **build-profile.json5** file at the same level as the entry in the project directory is set to **true**) or the HAR is packed into a third-party package, the worker thread file in the HAR can be loaded using a relative path. +>When **useNormalizedOHMUrl** is enabled (the **useNormalizedOHMUrl** field of the **strictMode** property in the application-level **build-profile.json5** file at the same level as the entry in the project directory is set to **true**) or when the HAR is used as a third-party package, the Worker thread file contained the HAR can be loaded using a relative path. ```ts import { worker } from '@kit.ArkTS'; -// @ Path loading mode -// URL of the worker thread file: "har/src/main/ets/workers/worker.ets" +// @ path loading: +// URL of the Worker thread file: "har/src/main/ets/workers/worker.ets" const workerStage4: worker.ThreadWorker = new worker.ThreadWorker('@har/ets/workers/worker.ets'); -// Relative path loading mode: -// URL of the worker thread file: "har/src/main/ets/workers/worker.ets" +// Relative path loading: +// URL of the Worker thread file: "har/src/main/ets/workers/worker.ets" // URL of the file where the Worker object is created: "har/src/main/ets/components/mainpage/MainPage.ets" const workerStage5: worker.ThreadWorker = new worker.ThreadWorker('../../workers/worker.ets'); ``` -#### File URL Rules in the FA Model +#### File URL Rules in FA Model - **scriptURL** in the constructor function is the relative path between the worker thread file and "{moduleName}/src/main/ets/MainAbility". +**scriptURL** in the constructor is the relative path from the Worker thread file to "{moduleName}/src/main/ets/MainAbility". ```ts import { worker } from '@kit.ArkTS'; // The following three scenarios are involved. -// Scenario 1: URL of the worker thread file: "{moduleName}/src/main/ets/MainAbility/workers/worker.ets" +// Scenario 1: URL of the Worker thread file: "{moduleName}/src/main/ets/MainAbility/workers/worker.ets" const workerFA1: worker.ThreadWorker = new worker.ThreadWorker("workers/worker.ets", {name:"first worker in FA model"}); -// Scenario 2: URL of the worker thread file: "{moduleName}/src/main/ets/workers/worker.ets" +// Scenario 2: URL of the Worker thread file: "{moduleName}/src/main/ets/workers/worker.ets" const workerFA2: worker.ThreadWorker = new worker.ThreadWorker("../workers/worker.ets"); -// Scenario 3: URL of the worker thread file: "{moduleName}/src/main/ets/MainAbility/ThreadFile/workers/worker.ets" +// Scenario 3: URL of the Worker thread file: "{moduleName}/src/main/ets/MainAbility/ThreadFile/workers/worker.ets" const workerFA3: worker.ThreadWorker = new worker.ThreadWorker("ThreadFile/workers/worker.ets"); ``` -### Lifecycle Precautions +### Precautions for Lifecycle Management + +- Creating and destroying Worker consume system resources. Therefore, you are advised to manage created Workers efficiently and reuse them when possible. Idle Workers continue to run. When a Worker is no longer needed, call [terminate()](../reference/apis-arkts/js-apis-worker.md#terminate9) or [close()](../reference/apis-arkts/js-apis-worker.md#close9) to destroy it actively. If a Worker is in a non-running state such as destroyed or being destroyed, calling its functional interfaces will throw corresponding errors. + + +- The number of Workers is determined by the memory management policy, with a set memory threshold being the smaller of 1.5 GB and 60% of the device's physical memory. Under memory constraints, a maximum of 64 Workers can run simultaneously. If an attempt is made to create more Workers than this limit, the system displays the error message "Worker initialization failure, the number of Workers exceeds the maximum." The actual number of running Workers will be dynamically adjusted based on current memory usage. Once the cumulative memory usage of all Workers and the main thread exceeds the set threshold, Out of Memory (OOM) error occurs, and applications may crash. + + +## Basic Usage Example of Worker + +1. In DevEco Studio, right-click any position in the {moduleName} directory and choose **New > Worker** to automatically generate the Worker template file and configuration information. This section uses the creation of "worker" as an example. + + You can also manually create Worker thread files. For specific methods and related considerations, see [Precautions for Creating a Worker](#precautions-for-creating-a-worker). + +2. Import the Worker module. + + ```ts + // Index.ets + import { ErrorEvent, MessageEvents, worker } from '@kit.ArkTS' + ``` + +3. In the host thread, call [constructor()](../reference/apis-arkts/js-apis-worker.md#constructor9) of **ThreadWorker** to create a Worker object, and register callback functions. The calling thread is the host thread. + + ```ts + // Index.ets + @Entry + @Component + struct Index { + @State message: string = 'Hello World'; + + build() { + RelativeContainer() { + Text(this.message) + .id('HelloWorld') + .fontSize(50) + .fontWeight(FontWeight.Bold) + .alignRules({ + center: { anchor: '__container__', align: VerticalAlign.Center }, + middle: { anchor: '__container__', align: HorizontalAlign.Center } + }) + .onClick(() => { + // Create a Worker object. + let workerInstance = new worker.ThreadWorker('entry/ets/workers/worker.ets'); -- Creating and terminating worker threads consume performance. Therefore, you are advised to manage available workers and reuse them. The worker threads keep running even when they are idle. When a worker thread is not required, call [terminate()](../reference/apis-arkts/js-apis-worker.md#terminate9) or [close()](../reference/apis-arkts/js-apis-worker.md#close9) to terminate it. If a worker thread is terminated or being terminated, an error is thrown when it is called. + // Register the onmessage callback. When the host thread receives a message from the Worker thread through the workerPort.postMessage interface, this callback is invoked and executed in the host thread. + workerInstance.onmessage = (e: MessageEvents) => { + let data: string = e.data; + console.info("workerInstance onmessage is: ", data); + } + // Register the onerror callback to capture exceptions generated during the execution of the Worker thread. This callback is executed in the host thread. + workerInstance.onerror = (err: ErrorEvent) => { + console.info("workerInstance onerror message is: " + err.message); + } -- The number of worker threads is determined by the memory management policy. The required memory threshold is the smaller one between 1.5 GB and 60% of the physical memory of the device. If the memory is sufficient, a maximum of 64 worker threads can run simultaneously. If excess worker threads are to be created, the system displays the error message "Worker initialization failure, the number of workers exceeds the maximum." The number of actually running worker threads is dynamically adjusted based on the memory usage. Once the accumulated memory usage of all worker threads and main threads exceeds the threshold, Out of Memory (OOM) error occurs, and applications may crash. + // Register the onmessageerror callback. When the Worker object receives a message that cannot be serialized, this callback is invoked and executed in the host thread. + workerInstance.onmessageerror = () => { + console.info('workerInstance onmessageerror'); + } + + // Register the onexit callback. When the Worker object is destroyed, this callback is invoked and executed in the host thread. + workerInstance.onexit = (e: number) => { + // When the Worker object exits normally, the code is 0. When the Worker object exits abnormally, the code is 1. + console.info("workerInstance onexit code is: ", e); + } + + // Send a message to the Worker thread. + workerInstance.postMessage('1'); + }) + } + .height('100%') + .width('100%') + } + } + ``` + +4. Register the callback functions in the Worker thread file. + + ```ts + // worker.ets + import { ErrorEvent, MessageEvents, ThreadWorkerGlobalScope, worker } from '@kit.ArkTS'; + + const workerPort: ThreadWorkerGlobalScope = worker.workerPort; + + // Register the onmessage callback. When the Worker thread receives a message from the host thread through the postMessage interface, this callback is invoked and executed in the Worker thread. + workerPort.onmessage = (e: MessageEvents) => { + let data: string = e.data; + console.info('workerPort onmessage is: ', data); + + // Send a message to the main thread. + workerPort.postMessage('2'); + } + + // Register the onmessageerror callback. When the Worker object receives a message that cannot be serialized, this callback is invoked and executed in the Worker thread. + workerPort.onmessageerror = () => { + console.info('workerPort onmessageerror'); + } + + // Register the onerror callback. When an exception occurs during the execution of the Worker thread, this callback is invoked and executed in the Worker thread. + workerPort.onerror = (err: ErrorEvent) => { + console.info('workerPort onerror err is: ', err.message); + } + ``` -## Cross-HAR package loading worker +## Loading Worker Across HARs -1. For details about how to create a har, see [Developing a Static Shared Package](../quick-start/har-package.md). +1. Create an HAR. For details, see [HAR](../quick-start/har-package.md). -2. Create the Worker thread file in the har file. +2. Create the Worker thread file in the HAR. ```ts // worker.ets @@ -173,10 +269,10 @@ const workerFA3: worker.ThreadWorker = new worker.ThreadWorker("ThreadFile/worke } ``` -3. Configure the dependency of the HAR package in the oh-package.json5 file of the entry module. +3. Configure the dependency of the HAR in the **oh-package.json5** file of the entry module. ```ts - // Configure the dependency of the HAR package in the entry module. + // Configure the dependency of the HAR in the entry module. { "name": "entry", "version": "1.0.0", @@ -190,7 +286,7 @@ const workerFA3: worker.ThreadWorker = new worker.ThreadWorker("ThreadFile/worke } ``` -4. Load the worker thread file in the HAR package in the entry module. +4. Load the Worker thread file from the HAR in the entry module. ```ts // Index.ets @@ -212,7 +308,7 @@ const workerFA3: worker.ThreadWorker = new worker.ThreadWorker("ThreadFile/worke middle: { anchor: '__container__', align: HorizontalAlign.Center } }) .onClick(() => { - // Use @ to identify the path loading mode and load the Worker thread file in the har. + // Use @ path loading mode and load the Worker thread file from the HAR. let workerInstance = new worker.ThreadWorker('@har/ets/workers/worker.ets'); workerInstance.onmessage = () => { console.info('main thread onmessage'); @@ -227,64 +323,64 @@ const workerFA3: worker.ThreadWorker = new worker.ThreadWorker("ThreadFile/worke ``` -## Multi-level worker lifecycle management -Multi-level Workers can be created (that is, a hierarchical thread relationship is formed by creating child Workers through the parent Worker), and the lifecycle of Worker threads is managed by users. Therefore, the lifecycle of multi-level Workers must be correctly managed. If the child Worker is not stopped when the parent Worker is destroyed, unexpected results may occur. You are advised to ensure that the lifecycle of the child Worker is always within the lifecycle of the parent Worker and destroy all child Workers before destroying the parent Worker. +## Multi-Level Worker Lifecycle Management +Multi-level Workers can be created (a hierarchical thread relationship is formed by the mechanism of creating child Workers through parent Workers), and the lifecycle of Worker threads should be manually managed. Therefore, it is important to properly manage the lifecycle of multi-level Workers. If a parent Worker is destroyed without terminating its child Workers, unpredictable results may occur. It is recommended that you ensure the lifecycle of child Workers always remains within the lifecycle of the parent Worker and that all child Workers are terminated before destroying the parent Worker. -### Recommended Example +### Recommended Usage Example ```ts -// Create a worker thread (parent worker) in the main thread and create a worker thread (child worker) in the worker thread. +// Create a Worker thread (parent Worker) in the main thread, and create a Worker thread (child Worker) in the parent Worker. // main thread import { worker, MessageEvents, ErrorEvent } from '@kit.ArkTS'; -// Create a Worker instance in the main thread. +// Create a parent Worker object in the main thread. const parentworker = new worker.ThreadWorker("entry/ets/workers/parentworker.ets"); parentworker.onmessage = (e: MessageEvents) => { - console.info ("The main thread receives the parent worker thread information" + e.data); + console.info("The main thread receives a message from the parent Worker" + e.data); } parentworker.onexit = () => { - console.info ("The parent worker exits."); + console.info("The parent Worker exits"); } parentworker.onerror = (err: ErrorEvent) => { - console.info ("The main thread receives an error from the parent worker." + err); + console.info("The main thread receives an error from the parent Worker" + err); } -parentworker.postMessage ("The main thread sends a message to the parentworker. Recommended example"); +parentworker.postMessage("The main thread sends a message to the parent Worker - recommended example"); ``` ```ts // parentworker.ets import { ErrorEvent, MessageEvents, ThreadWorkerGlobalScope, worker } from '@kit.ArkTS'; -// Create an object in the worker thread for communicating with the main thread. +// Create an object in the parent Worker for communicating with the main thread. const workerPort: ThreadWorkerGlobalScope = worker.workerPort; workerPort.onmessage = (e : MessageEvents) => { - if (e.data = = "The main thread sends a message to the parent worker.-Recommended example") { + if (e.data == "The main thread sends a message to the parent Worker - recommended example") { let childworker = new worker.ThreadWorker("entry/ets/workers/childworker.ets"); childworker.onmessage = (e: MessageEvents) => { - console.info ("The parent Worker receives information from the child Worker" + e.data); - if (e.data = = "The child worker sends information to the parent worker.") { - workerPort.postMessage ("The parent worker sends information to the main thread."); + console.info("The parent Worker receives a message from the child Worker" + e.data); + if (e.data == "The child Worker sends information to the parent Worker") { + workerPort.postMessage("The parent Worker sends a message to the main thread"); } } childworker.onexit = () => { - console.info ("The child worker exits."); + console.info("The child Worker exits"); // Destroy the parent Worker after the child Worker exits. workerPort.close(); } childworker.onerror = (err: ErrorEvent) => { - console.info ("An error occurred on the child Worker." + err); + console.info("An error occurred on the child Worker" + err); } - childworker.postMessage ("The parent Worker sends information to the child Worker. Recommended example"); + childworker.postMessage("The parent Worker sends a message to the child Worker - recommended example"); } } ``` @@ -293,20 +389,20 @@ workerPort.onmessage = (e : MessageEvents) => { // childworker.ets import { ErrorEvent, MessageEvents, ThreadWorkerGlobalScope, worker } from '@kit.ArkTS'; -// Create an object in the worker thread for communicating with the main thread. +// Create an object in the child Worker for communicating with the parent Worker. const workerPort: ThreadWorkerGlobalScope = worker.workerPort; workerPort.onmessage = (e: MessageEvents) => { - if (e.data = = "The parent Worker sends information to the child Worker. Recommended example.") { - // Service logic of the sub-worker thread... - console.info ("The service execution is complete, and the child Worker is destroyed."); + if (e.data == "The parent Worker sends a message to the child Worker - recommended example") { + // Service logic of the child Worker... + console.info("The service execution is complete, and the child Worker is destroyed"); workerPort.close(); } } ``` -### Examples Not Recommended +### Not Recommended Example It is not recommended that a child Worker send messages to the parent Worker after the parent Worker is destroyed. @@ -317,18 +413,18 @@ import { worker, MessageEvents, ErrorEvent } from '@kit.ArkTS'; const parentworker = new worker.ThreadWorker("entry/ets/workers/parentworker.ets"); parentworker.onmessage = (e: MessageEvents) => { - console.info("The main thread receives the parent worker information" + e.data); + console.info("The main thread receives a message from the parent Worker" + e.data); } parentworker.onexit = () => { - console.info("The parent worker exits."); + console.info("The parent Worker exits"); } parentworker.onerror = (err: ErrorEvent) => { - console.info("The main thread receives an error from the parent worker." + err); + console.info("The main thread receives an error from the parent Worker" + err); } -parentworker.postMessage ("The main thread sends a message to the parent worker."); +parentworker.postMessage("The main thread sends a message to the parent Worker"); ``` ```ts @@ -338,24 +434,24 @@ import { ErrorEvent, MessageEvents, ThreadWorkerGlobalScope, worker } from '@kit const workerPort: ThreadWorkerGlobalScope = worker.workerPort; workerPort.onmessage = (e : MessageEvents) => { - console.info("The parent worker receives information from the main thread." + e.data); + console.info("The parent Worker receives a message from the main thread" + e.data); let childworker = new worker.ThreadWorker("entry/ets/workers/childworker.ets") childworker.onmessage = (e: MessageEvents) => { - console.info("The parent Worker receives information from the child Worker" + e.data); + console.info("The parent Worker receives a message from the child Worker" + e.data); } childworker.onexit = () => { - console.info("The child worker exits."); - workerPort.postMessage("The parent worker sends information to the main thread."); + console.info("The child Worker exits"); + workerPort.postMessage("The parent Worker sends a message to the main thread"); } childworker.onerror = (err: ErrorEvent) => { - console.info("An error occurred on the child Worker." + err); + console.info("An error occurred on the child Worker" + err); } - childworker.postMessage("The parent worker sends information to the child worker."); + childworker.postMessage("The parent Worker sends a message to the child Worker"); // Destroy the parent Worker after the child Worker is created. workerPort.close(); @@ -369,17 +465,17 @@ import { ErrorEvent, MessageEvents, ThreadWorkerGlobalScope, worker } from '@kit const workerPort: ThreadWorkerGlobalScope = worker.workerPort; workerPort.onmessage = (e: MessageEvents) => { - console.info("The child Worker receives the message" + e.data); + console.info("The child Worker receives a message" + e.data); - // After the parent Worker is destroyed, the child Worker sends information to the parent Worker. The behavior is unpredictable. - workerPort.postMessage("The child Worker sends information to the parent Worker."); + // After the parent Worker is destroyed, the child Worker sends a message to the parent Worker. The behavior is unpredictable. + workerPort.postMessage("The child Worker sends a message to the parent Worker"); setTimeout(() => { - workerPort.postMessage("The child Worker sends information to the parent Worker."); + workerPort.postMessage("The child Worker sends a message to the parent Worker"); }, 1000); } ``` -You are not advised to create a child Worker in the parent Worker thread before and after the parent Worker initiates the synchronous call of the destruction operation. You are not advised to create a child Worker in the parent Worker thread if you are not sure whether the parent Worker initiates a destruction operation. That is, ensure that the parent Worker thread is always alive before the child Worker thread is successfully created. +You are not advised to create a child Worker in the parent Worker before and after a synchronous call that clearly triggers the destruction of the parent Worker. Furthermore, avoid creating a child Worker in the parent Worker if there is any uncertainty about whether the parent Worker is being destroyed. Ensure that the parent Worker remains active before the child Worker is successfully created. ```ts // main thread @@ -388,18 +484,18 @@ import { worker, MessageEvents, ErrorEvent } from '@kit.ArkTS'; const parentworker = new worker.ThreadWorker("entry/ets/workers/parentworker.ets"); parentworker.onmessage = (e: MessageEvents) => { - console.info("The main thread receives the parent worker information" + e.data); + console.info("The main thread receives a message from the parent Worker" + e.data); } parentworker.onexit = () => { - console.info("The parent worker exits."); + console.info("The parent Worker exits"); } parentworker.onerror = (err: ErrorEvent) => { - console.info("The main thread receives an error from the parent worker." + err); + console.info("The main thread receives an error from the parent Worker" + err); } -parentworker.postMessage("The main thread sends a message to the parent worker."); +parentworker.postMessage("The main thread sends a message to the parent Worker"); ``` ```ts @@ -409,30 +505,30 @@ import { ErrorEvent, MessageEvents, ThreadWorkerGlobalScope, worker } from '@kit const workerPort: ThreadWorkerGlobalScope = worker.workerPort; workerPort.onmessage = (e : MessageEvents) => { - console.info("The parent worker receives information from the main thread." + e.data); + console.info("The parent Worker receives a message from the main thread" + e.data); // Create a child Worker after the parent Worker is destroyed. The behavior is unpredictable. workerPort.close(); let childworker = new worker.ThreadWorker("entry/ets/workers/childworker.ets"); - // Destroy the parent Worker before the child Worker thread confirms that the creation is successful. The behavior is unpredictable. + // Destroy the parent Worker before it is confirmed that the child Worker is successfully created. The behavior is unpredictable. // let childworker = new worker.ThreadWorker("entry/ets/workers/childworker.ets"); // workerPort.close(); childworker.onmessage = (e: MessageEvents) => { - console.info("The parent Worker receives information from the child Worker" + e.data); + console.info("The parent Worker receives a message from the child Worker" + e.data); } childworker.onexit = () => { - console.info("The child worker exits."); - workerPort.postMessage("The parent worker sends information to the main thread."); + console.info("The child Worker exits"); + workerPort.postMessage("The parent Worker sends a message to the main thread"); } childworker.onerror = (err: ErrorEvent) => { - console.info("An error occurred on the child Worker." + err); + console.info("An error occurred on the child Worker" + err); } - childworker.postMessage("The parent worker sends information to the child worker."); + childworker.postMessage("The parent Worker sends a message to the child Worker"); } ``` @@ -443,6 +539,6 @@ import { ErrorEvent, MessageEvents, ThreadWorkerGlobalScope, worker } from '@kit const workerPort: ThreadWorkerGlobalScope = worker.workerPort; workerPort.onmessage = (e: MessageEvents) => { - console.info("The child Worker receives the message" + e.data); + console.info("The child Worker receives a message" + e.data); } ``` diff --git a/en/application-dev/arkts-utils/worker-invoke-mainthread-interface.md b/en/application-dev/arkts-utils/worker-invoke-mainthread-interface.md index a74d600fac092c7bd5db3d256d62624bdf493fb9..dab7823b1050b67aa3530e2cb845e1190a5ac9f9 100644 --- a/en/application-dev/arkts-utils/worker-invoke-mainthread-interface.md +++ b/en/application-dev/arkts-utils/worker-invoke-mainthread-interface.md @@ -1,10 +1,10 @@ -# Worker Thread Synchronously Calling Methods of the Host Thread +# Synchronous Calls to Host Thread Interfaces from Worker -If the Worker thread needs to call the method that has been implemented in the main thread, you can perform the following operations: +If an interface is already implemented in the host thread and needs to be called by Worker, you can achieve this by using the approach described in this topic. -The following uses an example in which the worker synchronously calls the host thread interface for description. +The following example demonstrates how Worker can synchronously call an interface implemented in the host thread. -1. First, implement the method in the host thread, create a **Worker** object, and register the method on the **Worker** object. +1. Implement the interface in the host thread and create a Worker object. Register the interface to be called on the Worker object. ```ts // IconItemSource.ets @@ -33,7 +33,7 @@ The following uses an example in which the worker synchronously calls the host t public setUp(): string { for (let index = 0; index < 20; index++) { const numStart: number = index * 6; - // Six images are used cyclically. + // Use six images in the loop. this.iconItemSourceList.push(new IconItemSource('$media:startIcon', `item${numStart + 1}`)); this.iconItemSourceList.push(new IconItemSource('$media:background', `item${numStart + 2}`)); this.iconItemSourceList.push(new IconItemSource('$media:foreground', `item${numStart + 3}`)); @@ -47,23 +47,23 @@ The following uses an example in which the worker synchronously calls the host t } let picData = new PicData(); - // Register the method on the Worker object. + // Register the object to be called on the Worker object. workerInstance.registerGlobalCallObject("picData", picData); workerInstance.postMessage("run setUp in picData"); ``` -2. Then, the setUp () method in the host thread can be called through the callGlobalCallObjectMethod interface in the worker. +2. In Worker, use the **callGlobalCallObjectMethod** interface to call the **setUp()** method implemented in the host thread. ```ts // Worker.ets import { ErrorEvent, MessageEvents, ThreadWorkerGlobalScope, worker } from '@kit.ArkTS'; const workerPort: ThreadWorkerGlobalScope = worker.workerPort; try { - // The method to call does not carry an input parameter. + // Call the method without parameters. let res: string = workerPort.callGlobalCallObjectMethod("picData", "setUp", 0) as string; console.error("worker: ", res); } catch (error) { - // Exception handling. + // Handle exceptions. console.error("worker: error code is " + error.code + " error message is " + error.message); } ``` diff --git a/en/application-dev/arkts-utils/xml-conversion.md b/en/application-dev/arkts-utils/xml-conversion.md index d1cb6bd5d96f77494bf7c8b418d30792186c8edb..c0cd9bfef412d80c4d30507951def28b07c5d79d 100644 --- a/en/application-dev/arkts-utils/xml-conversion.md +++ b/en/application-dev/arkts-utils/xml-conversion.md @@ -1,10 +1,10 @@ # XML Conversion -Converting XML text into JavaScript objects makes it easier to process and manipulate data. In addition, JavaScript objects are more suitable than XML text for JavaScript applications. +Converting XML text into JavaScript objects can simplify data handling and manipulation, making it more suitable for use in JavaScript applications. -The common library provides the **ConvertXML** class to convert XML text into JavaScript objects. The input is XML strings and conversion options, and the output is a JavaScript object. For details about the conversion options, see [@ohos.convertxml (XML-to-JavaScript Conversion)](../reference/apis-arkts/js-apis-convertxml.md). +The ArkTS common library provides the **ConvertXML** class to convert XML text into JavaScript objects. The input is the XML string to be converted and conversion options, and the output is the resulting JavaScript object. For details about the conversion options, see [@ohos.convertxml (XML-to-JavaScript Conversion)](../reference/apis-arkts/js-apis-convertxml.md). ## Precautions @@ -14,15 +14,19 @@ To ensure successful XML parsing and conversion, the input XML data must comply ## How to Develop -To convert an XML file into a JavaScript object to obtain the tag values, proceed as follows: +To convert an XML document into a JavaScript object and obtain the tag values, proceed as follows: -1. Import the **convertxml** module. +1. Import the module. ```ts import { convertxml } from '@kit.ArkTS'; ``` -2. Enter the XML file to be converted and set conversion options. For details about the supported conversion options and their meanings, see [ConvertOptions](../reference/apis-arkts/js-apis-convertxml.md#convertoptions). +2. Input the XML document to be converted and set conversion options. For details about the supported conversion options and their meanings, see [ConvertOptions](../reference/apis-arkts/js-apis-convertxml.md#convertoptions). + + > **NOTE** + > + > If the XML text to convert contains the ampersand (&), replace it with the entity reference **\&**. ```ts let xml: string = diff --git a/en/application-dev/arkts-utils/xml-generation.md b/en/application-dev/arkts-utils/xml-generation.md index 16c571988e028239b5aa623d145cdd82b53ec135..8f73c869cd1c6276aa6b0ebcd23b6df7c2b43ce7 100644 --- a/en/application-dev/arkts-utils/xml-generation.md +++ b/en/application-dev/arkts-utils/xml-generation.md @@ -1,78 +1,84 @@ # XML Generation -XML can be used as a data exchange format, which is supported by a wealth of systems and applications. For example, web services can transfer structured data in XML format. +XML is a widely supported data exchange format used by various systems and applications. For example, web services often transmit structured data in XML format. -XML can also be used as a message passing format for communication between nodes in a distributed system. +XML can also serve as a messaging format for communication between nodes in distributed systems. ## Precautions -- XML tags must appear in pairs: one start tag and one end tag. +- XML tags must always appear in pairs: one start tag and one end tag. -- XML tags are case sensitive. The start tag and end tag must use the same case. +- XML tags are case sensitive, meaning that the case of the start and end tags must match. ## How to Develop -The **xml** module provides the **XmlSerializer** class to generate XML files. The input is an object of the ArrayBuffer or DataView type with a fixed length, which is used to store the output XML data. +The XML module provides the **XmlSerializer** class to generate XML data. This class takes a fixed-length ArrayBuffer or DataView object as input, which is used to store the generated XML data. -You can call different methods to write different types of content. For example, call **startElement(name: string)** to write a start tag and **setText(text: string)** to write a tag value. +You can call various methods to write different content. For example, call **startElement(name: string)** to write the start tag of an element and **setText(text: string)** to write the tag value. -For details about the APIs of the **XML** module, see [@ohos.xml (XML Parsing and Generation)](../reference/apis-arkts/js-apis-xml.md).
To generate an XML file, proceed as follows: +For details about the APIs of the XML module, see [@ohos.xml (XML Parsing and Generation)](../reference/apis-arkts/js-apis-xml.md). By calling the appropriate functions as needed, you can generate a complete XML document. -1. Import the modules. +1. Import the module. ```ts import { xml, util } from '@kit.ArkTS'; ``` -2. Create a buffer and construct an **XmlSerializer** object, either based on an object of the ArrayBuffer or DataView type. +2. Create a buffer and construct an XmlSerializer object, either based on an ArrayBuffer or a DataView object. ```ts - // Method 1: Create an XmlSerializer object based on an object of the ArrayBuffer type. - let arrayBuffer: ArrayBuffer = new ArrayBuffer(2048); // Create a 2048-byte object of the ArrayBuffer type. - let thatSer: xml.XmlSerializer = new xml.XmlSerializer(arrayBuffer); // Create an XmlSerializer object based on the object of the ArrayBuffer type. + // Method 1: Create an XmlSerializer object based on ArrayBuffer. + let arrayBuffer: ArrayBuffer = new ArrayBuffer(2048); // Create a 2048-byte ArrayBuffer. + let serializer: xml.XmlSerializer = new xml.XmlSerializer(arrayBuffer); // Create an XmlSerializer object based on the ArrayBuffer. - // Method 2: Create an XmlSerializer object based on an object of the DataView type. + // Method 2: Create an XmlSerializer object based on DataView. // let arrayBuffer: ArrayBuffer = new ArrayBuffer(2048); // let dataView: DataView = new DataView(arrayBuffer); - // let thatSer: xml.XmlSerializer = new xml.XmlSerializer(dataView); + // let serializer: xml.XmlSerializer = new xml.XmlSerializer(dataView); ``` -3. Call the functions to generate an XML file. +3. Call the functions to generate XML data. ```ts - thatSer.setDeclaration(); // Write the XML file declaration. - thatSer.startElement('bookstore'); // Write the start tag of an element. - thatSer.startElement('book'); // Write the start tag of a nested element. - thatSer.setAttributes('category', 'COOKING'); // Write the attributes and attribute values. - thatSer.startElement('title'); - thatSer.setAttributes('lang', 'en'); - thatSer.setText('Everyday'); // Write the tag value. - thatSer.endElement(); // Write the end flag. - thatSer.startElement('author'); - thatSer.setText('Giana'); - thatSer.endElement(); - thatSer.startElement('year'); - thatSer.setText('2005'); - thatSer.endElement(); - thatSer.endElement(); - thatSer.endElement(); + serializer.setDeclaration(); // Write the XML declaration. + serializer.startElement('bookstore'); // Write the start tag of an element. + serializer.startElement('book'); // Write the start tag of a nested element. + serializer.setAttributes('category', 'COOKING'); // Write attributes and attribute values. + serializer.startElement('title'); + serializer.setAttributes('lang', 'en'); + serializer.setText('Everyday'); // Write the tag value. + serializer.endElement(); // Write the end flag. + serializer.startElement('author'); + serializer.setText('Giana'); + serializer.endElement(); + serializer.startElement('year'); + serializer.setText('2005'); + serializer.endElement(); + serializer.endElement(); + serializer.endElement(); ``` -4. Use **Uint8Array** to operate the object of the ArrayBuffer type, and use **TextDecoder** to decode the Uint8Array. +4. Use **Uint8Array** to manipulate the ArrayBuffer, use **TextDecoder** to decode the Uint8Array, and output it. ```ts - let view: Uint8Array = new Uint8Array(arrayBuffer); // Use Uint8Array to read data from the object of the ArrayBuffer type. + let uint8Array: Uint8Array = new Uint8Array(arrayBuffer); // Use Uint8Array to read data from the ArrayBuffer. let textDecoder: util.TextDecoder = util.TextDecoder.create(); // Call the TextDecoder class of the util module. - let res: string = textDecoder.decodeToString(view); // Decode the view. - console.info(res); + let result: string = textDecoder.decodeToString(uint8Array); // Decode the Uint8Array. + console.info(result); ``` The output is as follows: ``` - \r\n \r\n Everyday\r\n Giana\r\n 2005\r\n \r\n + + + Everyday + Giana + 2005 + + ``` diff --git a/en/application-dev/arkts-utils/xml-overview.md b/en/application-dev/arkts-utils/xml-overview.md index b2c9bf1ca650b496f3ab754f3f51bd11cde6406a..f40f24a438818aebb538cbc9973c164182cd2385 100644 --- a/en/application-dev/arkts-utils/xml-overview.md +++ b/en/application-dev/arkts-utils/xml-overview.md @@ -1,32 +1,32 @@ # XML Overview -Extensible Markup Language (XML) is a markup language used to describe data. It aims to provide a common way to transmit and store data, especially data frequently used in web applications. XML does not predefine tags. As a result, it is more flexible and widely used. +Extensible Markup Language (XML) is a versatile markup language used to describe data, offering a flexible way to transport and store information, particularly in web applications. Unlike predefined markup languages like HTML, XML allows users to define their own tags, making it highly adaptable for various applications. -An XML file consists of elements, attributes, and content. +An XML document is composed of the following components: -- An element refers to a tag pair that contains text, attributes, or other elements. +- Elements: tag pairs that can enclose text, attributes, or other elements. -- Attributes provide additional information about an element. +- Attributes: additional details about the elements. -- Content is the data or sub-element contained in an element. +- Content: data or nested elements within an element. -XML supports the use of XML Schema Definition (XSD) or Document Type Definition (DTD) for defining the document structure. This allows you to customize rules to verify whether an XML document is in the expected format. +XML also supports the use of XML Schema Definition (XSD) or Document Type Definition (DTD) to define the structure of documents. This allows you to create custom validation rules to ensure that XML documents adhere to their intended format. -XML also supports features such as namespaces, entity references, comments, and processing instructions, making it easy to adapt to diverse data requirements. +Additional features of XML include namespaces, entity references, comments, and processing instructions, which enhance its flexibility and applicability across different data scenarios. -The common library provides XML-related basic capabilities, including [XML generation](xml-generation.md), [XML parsing](xml-parsing.md), and [XML conversion](xml-conversion.md). +The ArkTS common library provides essential XML functionalities such as [XML generation](xml-generation.md), [XML parsing](xml-parsing.md), and [XML conversion](xml-conversion.md). -The following is a simple XML example and the corresponding description. For more XML interfaces and their usage, see [@ohos.xml](../reference/apis-arkts/js-apis-xml.md). +The following is a simple XML example with explanations. For details about more XML interfaces and their usage, see [@ohos.xml](../reference/apis-arkts/js-apis-xml.md). ```XML + diff --git a/en/application-dev/arkts-utils/xml-parsing.md b/en/application-dev/arkts-utils/xml-parsing.md index ba0508cbc8fdb9cd5b003c4555c46fe8ce0f3e04..d3c5e988dce7cd806734b2460de0d1c8a2a14be8 100644 --- a/en/application-dev/arkts-utils/xml-parsing.md +++ b/en/application-dev/arkts-utils/xml-parsing.md @@ -1,20 +1,19 @@ # XML Parsing -Data transferred in XML format must be parsed before being put in use. Generally, three types of elements in XML files need to be parsed: [XML tags and tag values](#parsing-xml-tags-and-tag-values), [XML attributes and attribute values](#parsing-xml-attributes-and-attribute-values), and [XML event types and element depths](#parsing-xml-event-types-and-element-depths). +When using XML as a data carrier, it is necessary to parse relevant nodes in practice. This typically includes three types of operations: [parsing XML tags and their values](#parsing-xml-tags-and-values), [parsing XML attributes and their values](#parsing-xml-attributes-and-values), and [parsing XML event types and element depths](#parsing-xml-event-types-and-element-depths). For example, in web services, XML is the foundation of the Simple Object Access Protocol (SOAP). SOAP messages, which are usually encapsulated in XML format and contain request and response parameters, are parsed by web services to process client requests and generate corresponding responses. -The **xml** module provides the **XmlPullParser** class to parse XML files. The input is an object of the ArrayBuffer or DataView type containing XML text, and the output is the parsed information. +The XML module provides the **XmlPullParser** class to parse XML documents. The input is an ArrayBuffer or DataView containing XML text, and the output is the parsed information. - - **Table 1** XML parsing options +**Table 1** XML parsing options (see [ParseOptions](../reference/apis-arkts/js-apis-xml.md#parseoptions) for detailed descriptions) | Name| Type| Mandatory| Description| | -------- | -------- | -------- | -------- | | supportDoctype | boolean | No| Whether to ignore the document type. The default value is **false**, indicating that the document type is not parsed.| | ignoreNameSpace | boolean | No| Whether to ignore the namespace. The default value is **false**, indicating that the namespace is parsed.| -| tagValueCallbackFunction | (name: string, value: string) => boolean | No| Callback used to return **tagValue**, which consists of a tag and its value. The default value is **null**, indicating that XML tags and tag values are not parsed.| -| attributeValueCallbackFunction | (name: string, value: string) => boolean | No| Callback used to return **attributeValue**, which consists of an attribute and its value. The default value is **null**, indicating that XML attributes and attribute values are not parsed.| +| tagValueCallbackFunction | (name: string, value: string) => boolean | No| Callback used to return **tagValue**, which consists of a tag and its value. The default value is **null**, indicating that XML tags and values are not parsed.| +| attributeValueCallbackFunction | (name: string, value: string) => boolean | No| Callback used to return **attributeValue**, which consists of an attribute and its value. The default value is **null**, indicating that XML attributes and values are not parsed.| | tokenValueCallbackFunction | (eventType: EventType, value: ParseInfo) => boolean | No| Callback used to return **tokenValue**, which consists of the event type and the attributes of **parseInfo**. The default value is **null**, indicating that the event type and the attributes of **parseInfo** are not parsed.| @@ -25,17 +24,17 @@ The **xml** module provides the **XmlPullParser** class to parse XML files. The - Currently, parsing a given node is not supported. -## Parsing XML Tags and Tag Values +## Parsing XML Tags and Values -1. Import the modules. +1. Import the module. ```ts import { xml, util } from '@kit.ArkTS'; // Use the API provided by the util module to encode the file. ``` -2. Create an **XmlPullParser** object. +2. Create an XmlPullParser object. - The **XmlPullParser** object can be created based on an object of the ArrayBuffer or DataView type. + You can construct an XmlPullParser object based on ArrayBuffer or DataView. Both methods yield the same results. ```ts let strXml: string = @@ -46,21 +45,27 @@ The **xml** module provides the **XmlPullParser** class to parse XML files. The ''; let textEncoder: util.TextEncoder = new util.TextEncoder(); let arrBuffer: Uint8Array = textEncoder.encodeInto(strXml); // Encode the data to prevent garbled characters. - // 1. Create an XmlPullParser object based on an object of the ArrayBuffer type. + // Method 1: Create an XmlPullParser object based on ArrayBuffer. let that: xml.XmlPullParser = new xml.XmlPullParser(arrBuffer.buffer as object as ArrayBuffer, 'UTF-8'); - // 2. Create an XmlPullParser object based on an object of the DataView type. + // Method 2: Create an XmlPullParser object based on DataView. // let dataView: DataView = new DataView(arrBuffer.buffer as object as ArrayBuffer); // let that: xml.XmlPullParser = new xml.XmlPullParser(dataView, 'UTF-8'); ``` -3. Customize a callback function. In this example, the tag and tag value are directly printed. +3. Customize a callback function. In this example, the callback function directly prints the tags and their values. ```ts - let str: string = ''; function func(name: string, value: string): boolean { - str = name + value; - console.info(str); + if (name == 'note') { + console.info(name); + } + if (value == 'Play' || value == 'Work') { + console.info(' ' + value); + } + if (name == 'title' || name == 'lens') { + console.info(' ' + name); + } return true; // The value true means to continue parsing, and false means to stop parsing. } ``` @@ -76,27 +81,27 @@ The **xml** module provides the **XmlPullParser** class to parse XML files. The ``` note - title - Play - title - lens - Work - lens + title + Play + title + lens + Work + lens note ``` -## Parsing XML Attributes and Attribute Values +## Parsing XML Attributes and Values -1. Import the modules. +1. Import the module. ```ts import { xml, util } from '@kit.ArkTS'; // Use the API provided by the util module to encode the file. ``` -2. Create an **XmlPullParser** object. +2. Create an XmlPullParser object. ```ts let strXml: string = @@ -111,7 +116,7 @@ The **xml** module provides the **XmlPullParser** class to parse XML files. The let that: xml.XmlPullParser = new xml.XmlPullParser(arrBuffer.buffer as object as ArrayBuffer, 'UTF-8'); ``` -3. Customize a callback function. In this example, the attribute and attribute value are directly printed. +3. Customize a callback function. In this example, the callback function directly prints the attributes and their values. ```ts let str: string = ''; @@ -131,19 +136,19 @@ The **xml** module provides the **XmlPullParser** class to parse XML files. The The output is as follows: ``` - importance high logged true // Attributes and attribute values of the note node + importance high logged true // Attributes and values of the note node ``` ## Parsing XML Event Types and Element Depths -1. Import the modules. +1. Import the module. ```ts import { xml, util } from '@kit.ArkTS'; // Use the API provided by the util module to encode the file. ``` -2. Create an **XmlPullParser** object. +2. Create an XmlPullParser object. ```ts let strXml: string = @@ -156,7 +161,7 @@ The **xml** module provides the **XmlPullParser** class to parse XML files. The let that: xml.XmlPullParser = new xml.XmlPullParser(arrBuffer.buffer as object as ArrayBuffer, 'UTF-8'); ``` -3. Customize a callback function. In this example, the event type and element depth are directly printed. +3. Customize a callback function. In this example, the callback function directly prints the event types and element depths. ```ts let str: string = ''; @@ -191,7 +196,7 @@ The **xml** module provides the **XmlPullParser** class to parse XML files. The ## Example Scenario -In the following example, all parsing options are invoked to parse XML tags, attributes, and event types. +This example demonstrates how to use all parsing options to parse XML tags, attributes, and event types. ```ts diff --git a/en/application-dev/basic-services/common-event/Readme-EN.md b/en/application-dev/basic-services/common-event/Readme-EN.md index 8af60589d76f253dbfb515dc9c66d9c536e6b607..3db117c3121fe6898be6755373486e574746f0b4 100644 --- a/en/application-dev/basic-services/common-event/Readme-EN.md +++ b/en/application-dev/basic-services/common-event/Readme-EN.md @@ -1,19 +1,15 @@ -# Common Events +# Process and Thread Communication -- IPC +- Using Common Events for IPC - [Common Event Overview](common-event-overview.md) - - Common Event Subscription - - - [Common Event Subscription Overview](common-event-subscription-overview.md) - - - [Subscribing to Common Events in Dynamic Mode](common-event-subscription.md) - - - [Subscribing to Common Events in Static Mode (for System Applications Only)](common-event-static-subscription.md) - - - [Unsubscribing from Common Events in Dynamic Mode](common-event-unsubscription.md) + - [Subscribing to Common Events in Dynamic Mode](common-event-subscription.md) + + - [Subscribing to Common Events in Static Mode (for System Applications Only)](common-event-static-subscription.md) + + - [Unsubscribing from Common Events in Dynamic Mode](common-event-unsubscription.md) - [Publishing Common Events](common-event-publish.md) - [Removing Sticky Common Events (for System Applications Only)](common-event-remove-sticky.md) -- Inter-Thread Communication (FA Model) - - [Using Emitter for Inter-Thread Communication](itc-with-emitter.md) +- [Using Emitter for Inter-Thread Communication](itc-with-emitter.md) + diff --git a/en/application-dev/basic-services/common-event/common-event-overview.md b/en/application-dev/basic-services/common-event/common-event-overview.md index a1aeca0d2e442f46bfc1296d7027e0f99a8a932c..186bf72e22d0e9b9cec28e84c5d43329ad1bca48 100644 --- a/en/application-dev/basic-services/common-event/common-event-overview.md +++ b/en/application-dev/basic-services/common-event/common-event-overview.md @@ -21,6 +21,14 @@ Common events are also classified into unordered, ordered, and sticky common eve ## Working Principles Each application can subscribe to common events as required. After your application subscribes to a common event, the system sends it to your application every time the event is published. Such an event may be published by the system, other applications, or your own application. + +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 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). + + **Figure 1** Common events ![common-event](figures/common-event.png) diff --git a/en/application-dev/basic-services/common-event/common-event-subscription-overview.md b/en/application-dev/basic-services/common-event/common-event-subscription-overview.md deleted file mode 100644 index 262f30c87e6018fed4e417a196dcaeeb58e42ae2..0000000000000000000000000000000000000000 --- a/en/application-dev/basic-services/common-event/common-event-subscription-overview.md +++ /dev/null @@ -1,7 +0,0 @@ -# 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. - -- 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). diff --git a/en/application-dev/basic-services/common-event/figures/emitter.png b/en/application-dev/basic-services/common-event/figures/emitter.png new file mode 100644 index 0000000000000000000000000000000000000000..9c7d065519b26198b0836e72fc5341ea0bf9c4d0 Binary files /dev/null and b/en/application-dev/basic-services/common-event/figures/emitter.png differ diff --git a/en/application-dev/basic-services/common-event/itc-with-emitter.md b/en/application-dev/basic-services/common-event/itc-with-emitter.md index d9b4a63bc1fe1971839536ffd69b26f6a7d532a9..850ae618265b708247df36926988720686bf59ba 100644 --- a/en/application-dev/basic-services/common-event/itc-with-emitter.md +++ b/en/application-dev/basic-services/common-event/itc-with-emitter.md @@ -1,51 +1,79 @@ # Using Emitter for Inter-Thread Communication -[Emitter](../../reference/apis-basic-services-kit/js-apis-emitter.md) provides APIs for sending and processing events between threads, including the APIs for processing events that are subscribed to in persistent or one-shot manner, unsubscribing from events, and emitting events to the event queue. -To develop the Emitter mode, perform the following steps: +Emitter is an event processing mechanism used in a process. It provides the capabilities of subscribing to, publishing, and unsubscribing from events for applications. -1. Subscribe to an event. +## When to Use +Emitter is used to process events of the same thread or different threads in the same process in an asynchronous manner. To use this mechanism, you need to subscribe to an event and publish it, after which the Emitter distributes the published event to the subscriber, and the subscriber executes the callback method set during event subscription. Unsubscribe from the event in time to release the Emitter resources when the event does not need to be subscribed to. + +## Working Principles +Emitter distributes tasks by maintaining an internal event queue. An application needs to subscribe to an event and set the callback method of the event. After the application publish the event, an event is inserted into the queue. The task queue executes the tasks in serial mode, during which the callback method of the task subscriber is called to process the event. + +![emitter](figures/emitter.png) + +## Available APIs +For details, see [@ohos.events.emitter (Emitter)](../../reference/apis-basic-services-kit/js-apis-emitter.md). +| API | Capability | Description | +| ------- | ------ | -------- | +| on | Event subscription| Continuously subscribes to an event until the event is unsubscribed from.| +| once | Event subscription| Subscribes to an event once.| +| emit | Event publishing| Publishes an event once.| +| off | Event unsubscription.| Unsubscribes from the event and subsequent notifications of this event will not be received.| + +## How to Develop + +To enable Emitter's capabilities mentioned above, perform the following steps: + +1. Import the Emitter module. + ```ts import { emitter } from '@kit.BasicServicesKit'; - import { promptAction } from '@kit.ArkUI'; - import { hilog } from '@kit.PerformanceAnalysisKit'; + ``` + +2. Subscribe to an event. - const TAG: string = 'ThreadModel'; - const DOMAIN_NUMBER: number = 0xFF00; + Use **on()** for continuous subscription or **once()** for one-time subscription. Set the events to subscribe to and the callback function after the events are received. + ```ts + // Define an event with eventId 1. + let event: emitter.InnerEvent = { + eventId: 1 + }; + + // Use on() to subscribe to the event. After the event whose eventId is 1 is received, the callback function is executed. + emitter.on(event, () => { + console.info('on callback'); + }); ``` + ```ts - // Define an event with eventId 1. - let event: emitter.InnerEvent = { - eventId: 1 - }; - - // Trigger the callback after the event with eventId 1 is received. - let callback = (eventData: emitter.EventData): void => { - promptAction.showToast({ - message: JSON.stringify(eventData) - }); - hilog.info(DOMAIN_NUMBER, TAG, 'event callback:' + JSON.stringify(eventData)); - }; - - // Subscribe to the event with eventId 1. - emitter.on(event, callback); - promptAction.showToast({ - message: JSON.stringify('emitter subscribe success') + // Execute the callback after receiving the event whose eventId is 1. + // Note that the event is received only once using once(), while the event is received until the subscription is canceled using on(). + emitter.once(event, () => { + console.info('once callback'); }); ``` -2. Emit the event. +3. Emit the event. + + Use **emit()** to send events and set the events to send and the parameters to pass. ```ts // Define an event with eventId 1 and priority Low. let event: emitter.InnerEvent = { eventId: 1, priority: emitter.EventPriority.LOW }; - + + // Subscribes to the event and receive eventData. + emitter.once(event, (eventData : emitter.EventData) => { + console.info('enter callback, eventData-content:' + eventData?.data?.content); + console.info('enter callback, eventData-id:' + eventData?.data?.id); + console.info('enter callback, eventData-isEmpty:' + eventData?.data?.isEmpty); + }); + let eventData: emitter.EventData = { data: { - content: 'c', + content: 'emitter', id: 1, isEmpty: false } @@ -54,3 +82,14 @@ To develop the Emitter mode, perform the following steps: // Emit the event with eventId 1 and event content eventData. emitter.emit(event, eventData); ``` + +4. Unsubscribe from the event. + > **NOTE** + > + > If an event does not need to be subscribed to, cancel the subscription in a timely manner to prevent memory leakage. + + Use **off()** to unsubscribe from the event and set the corresponding event ID. + ```ts + // Unsubscribe from the event with eventId 1. + emitter.off(1); + ``` diff --git a/en/application-dev/basic-services/compress/Readme-EN.md b/en/application-dev/basic-services/compress/Readme-EN.md new file mode 100644 index 0000000000000000000000000000000000000000..15b5a11482626f610c80842e50248a543aaa82e0 --- /dev/null +++ b/en/application-dev/basic-services/compress/Readme-EN.md @@ -0,0 +1,3 @@ +# Compression and Decompression + +- [Compressing and Decompressing Files](deflate-and-inflate.md) diff --git a/en/application-dev/basic-services/compress/deflate-and-inflate.md b/en/application-dev/basic-services/compress/deflate-and-inflate.md new file mode 100644 index 0000000000000000000000000000000000000000..98b54ad12db2c85b8110c1412b4e7f022f979a46 --- /dev/null +++ b/en/application-dev/basic-services/compress/deflate-and-inflate.md @@ -0,0 +1,349 @@ +# Compressing and Decompressing Files + +This topic describes how to use functions in common compression and decompression scenarios. + +## Available APIs + +For details about more APIs and their usage, see [Zip](../../reference/apis-basic-services-kit/js-apis-zlib.md). + +| API | Description | +| ------------------------------------------------------------ | ---------------------------- | +| compressFile(inFile: string, outFile: string, options: Options): Promise<void> | Compresses a file. | +| decompressFile(inFile: string, outFile: string, options?: Options): Promise<void> | Decompresses a file. | +| compress(dest: ArrayBuffer, source: ArrayBuffer, sourceLen?: number): Promise<ZipOutputInfo> | Compresses the source buffer into the destination buffer. | +| compressBound(sourceLen: number): Promise<number> | Calculates the upper limit of the compression size to return. | +| uncompress(dest:ArrayBuffer, source: ArrayBuffer, sourceLen?: number): Promise<ZipOutputInfo> | Decompresses the compressed data into an original uncompressed one. | +| deflate(strm: ZStream, flush: CompressFlushMode): Promise<ReturnStatus> | Deflates data. | +| inflate(strm: ZStream, flush: CompressFlushMode): Promise<ReturnStatus> | Inflates data.| + +## How to Develop + +### Environment Preparations + +Create a test file **data.txt** in the application sandbox directory and write data for testing. The sample code is as follows: + + ```ts + import { fileIo as fs} from '@kit.CoreFileKit' + import { BusinessError, zlib } from '@kit.BasicServicesKit' + + @Entry + @Component + struct Index { + @State dataSize: number = 0; + + build() { + Row() { + Column() { + // Create the data.txt file and write test data. + Button('Create a test file data.txt').onClick(() => { + let path = getContext(this).filesDir; + // Create the data.txt file. + let inFile = fs.openSync(path + '/data.txt', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); + // Write test data. + for (let index = 0; index < 100; index++) { + fs.writeSync(inFile.fd, index + ': hello world, hello world, hello world, hello world, hello world.\n'); + } + // Obtain the original size of the test data and save it to dataSize. + let stat = fs.statSync(inFile.path); + this.dataSize = stat.size; + console.info('dataSize: ' + this.dataSize); + // Close the file. + fs.closeSync(inFile); + }) + } + } + .height('100%') + .width('100%') + } + } + ``` + +### Compressing and Decompressing .zip Files + +Use [zlib.compressFile()](../../reference/apis-basic-services-kit/js-apis-zlib.md#zlibcompressfile9-1) to compress the **data.txt** into to the **data.zip** file, and use [zlib.decompressFile()](../../reference/apis-basic-services-kit/js-apis-zlib.md#zlibdecompressfile9-1) to decompress the .zip file to the application sandbox directory. The sample code is as follows: + + ```ts + import { fileIo as fs} from '@kit.CoreFileKit' + import { BusinessError, zlib } from '@kit.BasicServicesKit' + + @Entry + @Component + struct Index { + build() { + Row() { + // Example 1: Compress the data.txt file into the data.zip file. + Button('compressFile').onClick(() => { + let path = getContext(this).filesDir; + let inFile = path + '/data.txt'; + let outFile = path + '/data.zip'; + let options: zlib.Options = {}; + zlib.compressFile(inFile, outFile, options).then((data: void) => { + console.info('compressFile success, data: ' + JSON.stringify(data)); + }).catch((errData: BusinessError) => { + console.error(`compressFile errCode: ${errData.code}, message: ${errData.message}`); + }) + }) + + // Example 2: Decompress the data.zip file to the application sandbox directory. + Button('decompressFile').onClick(() => { + let path = getContext(this).filesDir; + let inFile = path + '/data.zip'; + let outFile = path; + let options: zlib.Options = {}; + zlib.decompressFile(inFile, outFile, options).then((data: void) => { + console.info('decompressFile success, data: ' + JSON.stringify(data)); + }).catch((errData: BusinessError) => { + console.error(`decompressFile errCode: ${errData.code}, message: ${errData.message}`); + }) + }) + } + .height('100%') + .width('100%') + } + } + ``` + +### Compressing and Decompressing Buffers of Known Sizes + +For data in a buffer with a known size, use [compress()](../../reference/apis-basic-services-kit/js-apis-zlib.md#compress12) to compress the data into a destination buffer, [compressBound()](../../reference/apis-basic-services-kit/js-apis-zlib.md#compressbound12) to calculate the upper limit of the compression size of the destination buffer, and [uncompress()](../../reference/apis-basic-services-kit/js-apis-zlib.md#uncompress12) to decompress the buffer that stores the compressed data. To check the size of the destination buffer after decompression, obtain and save the original data size before compression. The sample code is as follows: + + ```ts + import { fileIo as fs} from '@kit.CoreFileKit' + import { BusinessError, zlib } from '@kit.BasicServicesKit' + + @Entry + @Component + struct Index { + @State dataSize: number = 0; // Size of the original data. + + build() { + Row() { + // Example 1: Read the data.txt file and save it to a buffer. Call the compress API to compress the data in the source buffer to the destination buffer and write the content in the destination buffer to the data.bin file. + Button('compress buffer').onClick(() => { + let path = getContext(this).filesDir; + let inFile = fs.openSync(path + '/data.txt', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); + let outFile = fs.openSync(path + '/data.bin', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); + // Read the content of the data.txt file and save the content to the buffer inBuf. + let stat = fs.statSync(inFile.path); + let inBuf = new ArrayBuffer(stat.size); + let readLen = fs.readSync(inFile.fd, inBuf); + console.info(`original size: ${stat.size}, read len: ${readLen}`); + // Obtain the size of the original data and save it. + this.dataSize = stat.size; + // Create a compressed object instance. + let zip = zlib.createZipSync(); + // Obtain the upper limit of a destination buffer. + zip.compressBound(stat.size).then((data) => { + console.info(`the max dest buf len is ${data}`); + // Destination buffer outBuf. + let outBuf = new ArrayBuffer(data); + // Compress the data in inBuf to outBuf. + zip.compress(outBuf, inBuf, readLen).then((zipOutInfo) => { + console.info(`compress success, status ${zipOutInfo.status}, destLen ${zipOutInfo.destLen}`); + // Write the data in outBuf to the data.bin file. + let writeLen = fs.writeSync(outFile.fd, outBuf, { length: zipOutInfo.destLen }); + console.info(`write destBuf to data.bin, writeLen ${writeLen}`); + // Close the file. + fs.closeSync(inFile.fd); + fs.closeSync(outFile.fd); + }).catch((errData: BusinessError) => { + console.error(`errData is errCode:${errData.code} message:${errData.message}`); + }) + }).catch((errData: BusinessError) => { + console.error(`errData is errCode:${errData.code} message:${errData.message}`); + }) + }) + + // Example 2: Read the compressed data in the data.bin file and save it to a buffer. Call the uncompress API to decompress the data in the source buffer to the destination buffer and write the content in the destination buffer to the data.txt file. + Button('uncompress buffer').onClick(() => { + let path = getContext(this).filesDir; + let inFile = fs.openSync(path + '/data.bin', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); + let outFile = fs.openSync(path + '/data.txt', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); + // Read the compressed data in the data.bin file and save the data to the buffer inBuf. + let stat = fs.statSync(inFile.path); + let inBuf = new ArrayBuffer(stat.size); + let readLen = fs.readSync(inFile.fd, inBuf); + console.info(`compressed data size: ${stat.size}, read len: ${readLen}`); + // Create a destination buffer. dataSize indicates the original size of the data saved before compression. + let outBuf = new ArrayBuffer(this.dataSize); + console.info(`the dest buf size is ${this.dataSize}`); + // Create a compressed object instance. + let zip = zlib.createZipSync(); + // Decompress the data in inBuf to outBuf. + zip.uncompress(outBuf, inBuf, readLen).then((zipOutInfo) => { + console.info(`uncompress success, status ${zipOutInfo.status}, destLen ${zipOutInfo.destLen}`); + // Write the data in outBuf to the data.txt file. + let writeLen = fs.writeSync(outFile.fd, outBuf, { length: zipOutInfo.destLen }); + console.info(`write destBuf to data.txt, writeLen ${writeLen}`); + // Close the file. + fs.closeSync(inFile.fd); + fs.closeSync(outFile.fd); + }).catch((errData: BusinessError) => { + console.error(`errData is errCode:${errData.code} message:${errData.message}`); + }) + }) + } + .height('100%') + .width('100%') + } + } + ``` + +### Compressing and Decompressing Buffers of Unknown Sizes + +For data in a buffer with an unknown size, use [deflate()](../../reference/apis-basic-services-kit/js-apis-zlib.md#deflate12) to compress the data read from an original input stream and [inflate()](../../reference/apis-basic-services-kit/js-apis-zlib.md#inflate12) to decompress the data read from a compressed input stream. The sample code is as follows: + + ```ts + import { fileIo as fs} from '@kit.CoreFileKit' + import { BusinessError, zlib } from '@kit.BasicServicesKit' + + @Entry + @Component + struct Index { + build() { + Row() { + // Example 1: Continuously read data from a file for compression. + Button('deflateFile').onClick(() => { + let path = getContext(this).filesDir; + let inFile = fs.openSync(path + '/data.txt', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); + let outFile = fs.openSync(path + '/data.bin', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); + deflateFile(inFile, outFile).then(() => { + console.info('deflateFile success'); + fs.closeSync(inFile.fd); + fs.closeSync(outFile.fd); + }) + }) + + // Example 2: Continuously read compressed data from the file for decompression. + Button('inflateFile').onClick(() => { + let path = getContext(this).filesDir; + let inFile = fs.openSync(path + '/data.bin', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); + let outFile = fs.openSync(path + '/data.txt', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); + inflateFile(inFile, outFile).then(() => { + console.info('deflateFile success'); + fs.closeSync(inFile.fd); + fs.closeSync(outFile.fd); + }) + }) + } + .height('100%') + .width('100%') + } + } + + // Continuously read data from a file, compress the data, and write the data to another file. + async function deflateFile(src: fs.File, dest: fs.File) { + let flush = zlib.CompressFlushMode.NO_FLUSH; + let strm: zlib.ZStream = {}; // Initialize a compression stream. + const BUFLEN = 4096; + let inBuf = new ArrayBuffer(BUFLEN); // Initialize an input buffer. + let outBuf = new ArrayBuffer(BUFLEN); // Initialize an output buffer. + // Create a compressed object instance. + let zip = zlib.createZipSync(); + // Initialize the stream status. + let initStatus = zip.deflateInit(strm, zlib.CompressLevel.COMPRESS_LEVEL_BEST_SPEED); + console.info('deflateInit ret: ' + (await initStatus).valueOf()); + do { + // Read data from a file to a buffer. + let readLen = fs.readSync(src.fd, inBuf); + console.info("readSync readLen: " + readLen); + flush = readLen == 0 ? zlib.CompressFlushMode.FINISH : zlib.CompressFlushMode.NO_FLUSH; + // Set the input buffer. + strm.availableIn = readLen; + strm.nextIn = inBuf; + do { + // Set the output buffer. + strm.availableOut = BUFLEN; + strm.nextOut = outBuf; + try { + // Compress the data in the input buffer to the output buffer. + let deflateStatus = zip.deflate(strm, flush); + console.info('deflate ret: ' + (await deflateStatus).valueOf()); + // Update the stream status. + let innerStrm = zip.getZStream(); + strm.availableIn = (await innerStrm).availableIn; + strm.nextIn = (await innerStrm).nextIn; + strm.availableOut = (await innerStrm).availableOut; + strm.nextOut = (await innerStrm).nextOut; + strm.totalIn = (await innerStrm).totalIn; + strm.totalOut = (await innerStrm).totalOut; + + if (strm.availableOut != undefined) { + // Write the compressed data to the output file. + let have = BUFLEN - strm.availableOut; + let writeLen = fs.writeSync(dest.fd, outBuf, { length: have }); + console.info(`writeSync writeLen: ${writeLen}`); + } + } catch (err) { + console.error('deflate err: ' + JSON.stringify(err)); + } + } while (strm.availableOut == 0); // Compress the remaining data in the input buffer cyclically until all data is compressed. + } while (flush != zlib.CompressFlushMode.FINISH); // Read data from the file cyclically until all data is read. + // Release resources. + zip.deflateEnd(strm); + } + + // Continuously read compressed data from a file, decompress the data, and write the data to another file. + async function inflateFile(src: fs.File, dest: fs.File) { + let status: zlib.ReturnStatus = zlib.ReturnStatus.OK; + let strm: zlib.ZStream = {}; // Initialize a compression stream. + const BUFLEN = 4096; + let inBuf = new ArrayBuffer(BUFLEN); // Initialize an input buffer. + let outBuf = new ArrayBuffer(BUFLEN); // Initialize an output buffer. + // Create a compressed object instance. + let zip = zlib.createZipSync(); + // Initialize the stream status. + let initStatus = zip.inflateInit(strm); + console.info('inflateInit ret: ' + (await initStatus).valueOf()); + do { + // Read the compressed data from the file to the buffer. + let readLen = fs.readSync(src.fd, inBuf); + console.info("readSync readLen: " + readLen); + if (readLen == 0) { + break; + } + // Set the input buffer. + strm.availableIn = readLen; + strm.nextIn = inBuf; + do { + // Set the output buffer. + strm.availableOut = BUFLEN; + strm.nextOut = outBuf; + try { + // Decompress the data in the input buffer to the output buffer. + let inflateStatus = zip.inflate(strm, zlib.CompressFlushMode.NO_FLUSH); + console.info('inflate ret: ' + (await inflateStatus).valueOf()); + // Update the stream status. + let innerStrm = zip.getZStream(); + strm.availableIn = (await innerStrm).availableIn; + strm.nextIn = (await innerStrm).nextIn; + strm.availableOut = (await innerStrm).availableOut; + strm.nextOut = (await innerStrm).nextOut; + strm.totalIn = (await innerStrm).totalIn; + strm.totalOut = (await innerStrm).totalOut; + + if (strm.availableOut != undefined) { + // Write the decompressed data to the output file. + let have = BUFLEN - strm.availableOut; + let writeLen = fs.writeSync(dest.fd, outBuf, { length: have }); + console.info(`writeSync writeLen: ${writeLen}`); + } + } catch (err) { + console.error('inflate err: ' + JSON.stringify(err)); + } + } while (strm.availableOut == 0) // Decompress the remaining data in the input buffer cyclically until all data is decompressed. + } while (status != zlib.ReturnStatus.STREAM_END.valueOf()) // Read data from the file cyclically until all data is read. + // Release resources. + zip.inflateEnd(strm); + } + ``` + +## FAQs + +1. 17800005 Incorrect Input Data + + For details about the possible causes and solution, see [error code 17800005](../../reference/apis-basic-services-kit/errorcode-zlib.md#17800005-incorrect-input-data). + +2. 17800007 Incorrect Input Buffer + + For details about the possible causes and solution, see [error code 17800007](../../reference/apis-basic-services-kit/errorcode-zlib.md#17800007-incorrect-input-buffer). diff --git a/en/application-dev/basic-services/pasteboard/Readme-EN.md b/en/application-dev/basic-services/pasteboard/Readme-EN.md index e439e9a41c7fff1a4c3d8c9be0238bab420d86fb..687e13712a723f53799f82c21250ef0549080da9 100644 --- a/en/application-dev/basic-services/pasteboard/Readme-EN.md +++ b/en/application-dev/basic-services/pasteboard/Readme-EN.md @@ -2,4 +2,5 @@ - [Using the Pasteboard to Copy and Paste](use_pasteboard_to_copy_and_paste.md) - [Using the Delayed Copy and Paste Function of the Pasteboard](pasteboard-time-lapse-copy-and-paste.md) +- [Using the Pasteboard to Copy and Paste (C/C++)](native-use-pasteboard.md) - [Requesting Permissions to Access the Pasteboard](get-pastedata-permission-guidelines.md) diff --git a/en/application-dev/basic-services/pasteboard/get-pastedata-permission-guidelines.md b/en/application-dev/basic-services/pasteboard/get-pastedata-permission-guidelines.md index 428dcb23bb9979d6e0c579538424c8dc4c5ceef1..17cdbec660cf44a1c77830c636211f9736a30fcd 100644 --- a/en/application-dev/basic-services/pasteboard/get-pastedata-permission-guidelines.md +++ b/en/application-dev/basic-services/pasteboard/get-pastedata-permission-guidelines.md @@ -11,6 +11,9 @@ Related APIs: | getData( callback: AsyncCallback<PasteData>): void | Reads a **PasteData** object from the pasteboard. This API uses an asynchronous callback to return the result.| | getData(): Promise<PasteData> | Reads a **PasteData** object from the pasteboard. This API uses a promise to return the result.| | getDataSync(): PasteData | Reads data from the system pasteboard. This API returns the result synchronously.| +| getUnifiedData(): Promise\ | Reads the data of a unified data object from the system pasteboard.| +| getUnifiedDataSync(): udc.UnifiedData | Reads the data of a unified data object from the system pasteboard. This API returns the result synchronously.| +| OH_UdmfData * OH_Pasteboard_GetData (OH_Pasteboard *pasteboard, int *status) | Obtains data from the pasteboard.| ## Accessing Pasteboard Content @@ -18,118 +21,19 @@ Applications can access the pasteboard content in either of the following ways: - Using security components - Applications that use the [security components](../../../application-dev/security/AccessToken/pastebutton.md) to access the pasteboard content do not need to request the permission. + Applications that use the [security components](../../security/AccessToken/pastebutton.md) to access the pasteboard content do not need to request the permission. Applications that use the security components can access the pasteboard content without any adaptation. - Requesting the **ohos.permission.READ_PASTEBOARD** permission - **READ_PASTEBOARD** is a user_grant permission. Applications that use customized components can request the **ohos.permission.READ_PASTEBOARD** permission to access the pasteboard content with user authorization. + **ohos.permission.READ_PASTEBOARD** is a restricted user_grant permission. Applications that use customized components can request the **ohos.permission.READ_PASTEBOARD** permission to access the pasteboard content with user authorization. - To request the **ohos.permission.READ_PASTEBOARD** permission, perform the following steps: - - 1. Configure the required permission in **module.json5**. For details, see [Requesting Application Permissions](../../../application-dev/security/AccessToken/determine-application-mode.md). - ```ts - "requestPermissions": [ - { - "name": "ohos.permission.READ_PASTEBOARD", - } - ] - ``` - - 2. Add a user authorization dialog box before the call to **getData**. - ```ts - import { hilog } from '@kit.PerformanceAnalysisKit'; - import { abilityAccessCtrl, common, Permissions, UIAbility, bundleManager } from '@kit.AbilityKit'; - import { window } from '@kit.ArkUI'; - import { BusinessError, pasteboard } from '@kit.BasicServicesKit'; - - async function checkAccessToken(permission: Permissions): Promise { - let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager(); - let grantStatus: abilityAccessCtrl.GrantStatus = abilityAccessCtrl.GrantStatus.PERMISSION_DENIED; - - // Obtain the token ID of the application. - let tokenId: number = 0; - try { - let bundleInfo: bundleManager.BundleInfo = await bundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION); - let appInfo: bundleManager.ApplicationInfo = bundleInfo.appInfo; - tokenId = appInfo.accessTokenId; - } catch (error) { - let err: BusinessError = error as BusinessError; - console.error(`Failed to get bundle info for self. Code is ${err.code}, message is ${err.message}`); - } - - // Check whether the user has granted the permission. - try { - grantStatus = await atManager.checkAccessToken(tokenId, permission); - } catch (error) { - let err: BusinessError = error as BusinessError; - console.error(`Failed to check access token. Code is ${err.code}, message is ${err.message}`); - } - - return grantStatus; - } - - @Entry - @Component - struct Index { - @State message: string = 'Hello World'; - @State msgList: Array = []; - // @State oaid: string = ''; - @State permission_state: boolean = true; - - reqPermissionsFromUser(permissions: Array): void { - let context = getContext(this) as common.UIAbilityContext; - let atManager = abilityAccessCtrl.createAtManager(); - // The return value of requestPermissionsFromUser determines whether to display a dialog box to request user authorization. - atManager.requestPermissionsFromUser(context, permissions).then((data) => { - let grantStatus: Array = data.authResults; - let length: number = grantStatus.length; - for (let i = 0; i < length; i++) { - if (grantStatus[i] === 0) { - // If the user grants the permission, the application can continue to access the target operation. - this.permission_state = true; - this.msgList.push ('Permission requested successfully.'); - } - else { - // If the user denies the permission, display a message indicating that user authorization is required, and direct the user to set the permission in the Settings page. - // openPermissionsInSystemSettings(); - console.error("user did not grant!") - this.permission_state = false; - this.msgList.push ('Failed to request the permission.'); - } - } - // Authorization successful. - }).catch((err: String) => { - }) - } - - async getPaste() { - const permissions: Array = ['ohos.permission.READ_PASTEBOARD']; - let grantStatus1: abilityAccessCtrl.GrantStatus = await checkAccessToken(permissions[0]); + How to request permissions: + + 1. Apply for high-level permissions through [ACL](../../security/AccessToken/declare-permissions-in-acl.md). - if (grantStatus1 === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) { - try { - let systemPasteboard: pasteboard.SystemPasteboard = pasteboard.getSystemPasteboard(); - systemPasteboard.getData((err: BusinessError, pasteData: pasteboard.PasteData) => { - if (err) { - console.error('Failed to get PasteData. Cause: ' + err.message); - return; - } - let text: string = pasteData.getPrimaryText(); - this.msgList.push ('Pasteboard content: '+text); - }); - } catch (err) { - hilog.error(0x0000, 'testTag', '%{public}s', `get oaid by promise catch error: ${err.code} ${err.message}`); - } - } else { - // Request the permission. - if(this.permission_state) { - this.reqPermissionsFromUser(permissions) - }else{ + 2. [Declare permissions](../../security/AccessToken/declare-permissions.md) in the **module.json5** configuration file. - } - } - } - } - ``` + 3. [Request user authorization](../../security/AccessToken/request-user-authorization.md) in a dialog box. + diff --git a/en/application-dev/basic-services/pasteboard/native-use-pasteboard.md b/en/application-dev/basic-services/pasteboard/native-use-pasteboard.md index 3cbfe3a53e2f0a5d08020de3e3a28ea1c48d048f..c0cf423e2a00e2e8959fa64e2728ae3967273bb9 100644 --- a/en/application-dev/basic-services/pasteboard/native-use-pasteboard.md +++ b/en/application-dev/basic-services/pasteboard/native-use-pasteboard.md @@ -14,7 +14,7 @@ The pasteboard allows you to copy and paste data of the plain text, hypertext, a - The size of data written to the pasteboard at a time cannot exceed 128 MB. - To ensure the accuracy of the pasteboard data, only one copy can be performed at a time. -- Currently, supported data types include **OH_UdsPlainText** (plain text), **OH_UdsHtml** (hypertext markup language), **OH_UdsFileUri** (file URI). **OH_UdsPixelMap** (pixel map), **OH_UdsHyperlink** (hyperlink), **OH_UdsAppItem** (application icon), and custom type. +- Currently, supported data types include **OH_UdsPlainText** (plain text), **OH_UdsHtml** (hypertext markup language), **OH_UdsFileUri** (file URI). **OH_UdsPixelMap** (pixel map), **OH_UdsHyperlink** (hyperlink), **OH_UdsAppItem** (application icon), and custom type. The data types supported by JS APIs are different from those supported by NDK APIs. You need to match the data types with the corresponding APIs during usage. For details, see [Using the Pasteboard to Copy and Paste](../pasteboard/use_pasteboard_to_copy_and_paste.md). - When you copy and paste data of a custom type, the specified type name cannot be the same as an existing one. - Since API version 12, [permission control](get-pastedata-permission-guidelines.md) is added to the pasteboard reading API to enhance user privacy protection. - The copy and paste APIs, [setUnifiedData](../../reference/apis-basic-services-kit/js-apis-pasteboard.md#setunifieddata12) and [getUnifiedData](../../reference/apis-basic-services-kit/js-apis-pasteboard.md#getunifieddata12), added in API version 12 are independent of the **OH_Pasteboard_SetData** and **OH_Pasteboard_GetData** APIs mentioned in this topic. Use the corresponding APIs when writing and reading data. diff --git a/en/application-dev/basic-services/request/app-file-upload-download.md b/en/application-dev/basic-services/request/app-file-upload-download.md index eace38c948e40b830420c73e79bee20a4a24e841..ee7e18e5cd347fec73cc250a40cf091b2dadb311 100644 --- a/en/application-dev/basic-services/request/app-file-upload-download.md +++ b/en/application-dev/basic-services/request/app-file-upload-download.md @@ -31,9 +31,6 @@ fs.writeSync(file.fd, 'upload file test'); fs.closeSync(file); // Configure the upload task. -let header = new Map(); -header.set('key1', 'value1'); -header.set('key2', 'value2'); let files: Array = [ // "internal://cache" in uri corresponds to the cacheDir directory. { filename: 'test.txt', name: 'test', uri: 'internal://cache/test.txt', type: 'txt' } @@ -41,7 +38,10 @@ let files: Array = [ let data: Array = [{ name: 'name', value: 'value' }]; let uploadConfig: request.UploadConfig = { url: 'https://xxx', - header: header, + header: { + 'key1':'value1', + 'key2':'value2' + }, method: 'POST', files: files, data: data @@ -95,6 +95,10 @@ let config: request.agent.Config = { mode: request.agent.Mode.FOREGROUND, overwrite: true, method: "POST", + headers: { + 'key1':'value1', + 'key2':'value2' + }, data: attachments, saveas: "./" }; @@ -110,6 +114,8 @@ request.agent.create(getContext(), config).then((task: request.agent.Task) => { }) task.on('completed', async() => { console.warn(`/Request upload completed`); + // This method requires the user to manage the task lifecycle. After the task is complete, call the remove method to release the task object. + request.agent.remove(task.tid); }) }).catch((err: BusinessError) => { console.error(`Failed to create a upload task, Code: ${err.code}, message: ${err.message}`); @@ -168,18 +174,21 @@ try { // pages/xxx.ets // Download the network resource file to the local application file directory, and read data from the file. import { BusinessError, request } from '@kit.BasicServicesKit'; +let context = getContext(this) as common.UIAbilityContext; +let filesDir = context.filesDir; let config: request.agent.Config = { action: request.agent.Action.DOWNLOAD, url: 'https://xxxx/test.txt', + saveas: 'xxxx.txt', gauge: true, overwrite: true, network: request.agent.Network.WIFI, }; -request.agent.create(getContext(), config).then((task: request.agent.Task) => { +request.agent.create(context, config).then((task: request.agent.Task) => { task.start((err: BusinessError) => { if (err) { - console.error(`Failed to start the upload task, Code: ${err.code} message: ${err.message}`); + console.error(`Failed to start the download task, Code: ${err.code} message: ${err.message}`); return; } }); @@ -188,6 +197,14 @@ request.agent.create(getContext(), config).then((task: request.agent.Task) => { }) task.on('completed', async() => { console.warn(`/Request download completed`); + let file = fs.openSync(filesDir + '/xxxx.txt', fs.OpenMode.READ_WRITE); + let arrayBuffer = new ArrayBuffer(1024); + let readLen = fs.readSync(file.fd, arrayBuffer); + let buf = buffer.from(arrayBuffer, 0, readLen); + console.info(`The content of file: ${buf.toString()}`); + fs.closeSync(file); + // This method requires the user to manage the task lifecycle. After the task is complete, call the remove method to release the task object. + request.agent.remove(task.tid); }) }).catch((err: BusinessError) => { console.error(`Failed to create a download task, Code: ${err.code}, message: ${err.message}`); diff --git a/en/application-dev/basic-services/usb/faqs-usb.md b/en/application-dev/basic-services/usb/faqs-usb.md new file mode 100644 index 0000000000000000000000000000000000000000..da0939c4341597632c75c9d6079eae5c2ca001a8 --- /dev/null +++ b/en/application-dev/basic-services/usb/faqs-usb.md @@ -0,0 +1,24 @@ +# FAQs + +## What should I do if the device list obtained by using usbManager.getDevices is empty when the device is connected to a PC using a USB cable? + +### Symptom + +After a device is connected to a PC using a USB cable, the device list obtained by **usbManager.getDevices** is empty, and the PC is not identified as a USB device. + +### Possible Causes + +USB devices are classified into two types: USB host and USB device. The USB host takes charge of data transmission and USB port management, and USB devices are managed by the USB host. + +If the current device functions as the USB host, the **usbManager.getDevices** API can be used to obtain the list of connected USB devices. + +Based on the preceding description: + +- When a device, for example, a phone, is connected to a PC using a USB cable, the PC is the USB host by default, and the phone is a USB device. +It is normal if the device list obtained by calling **usbManager.getDevices** on the phone is empty. +- When a device, for example, a phone, is connected to a mouse or keyboard using a USB cable, the phone is the USB host by default, and the mouse or keyboard is the USB device. +In this case, you can call the **usbManager.getDevices** API on the phone to obtain the device list. + +### Solution + +Ensure that the current device is the USB host and the connected device is the USB device. (Some devices can serve both as the USB host and USB device. In this case, you need to set such devices as USB devices so that the device list can be obtained by the USB host.) diff --git a/en/application-dev/calendarmanager/calendarmanager-calendar-developer.md b/en/application-dev/calendarmanager/calendarmanager-calendar-developer.md index 9ebc03f067f085348abc94860a4f29efebc732ec..5850f361569af30ee275e154e9c852176ed328f2 100644 --- a/en/application-dev/calendarmanager/calendarmanager-calendar-developer.md +++ b/en/application-dev/calendarmanager/calendarmanager-calendar-developer.md @@ -11,15 +11,15 @@ You can create an application-specific calendar, and add, delete, update, and qu The table below lists the main APIs used for calendar management. For details about more APIs and their usage, see [@ohos.calendarManager](../reference/apis-calendar-kit/js-apis-calendarManager.md). | API | Description | -| ------------------------------------------------------------ | ------------------------------------------------------------ | -| getCalendarManager(context : Context): CalendarManager | Obtains the **CalendarManager** object based on the context to manage calendars. | +| ----------------------------------------------------------- | ------------------------------------------------------------ | +| getCalendarManager(context: Context): CalendarManager | Obtains the **CalendarManager** object based on the context to manage calendars. | | createCalendar(calendarAccount: CalendarAccount): Promise\ | Creates a **Calendar** object based on the calendar account information. This API uses a promise to return the result.| | getCalendar(calendarAccount?: CalendarAccount): Promise\ | Obtains the default or specified **Calendar** object. This API uses a promise to return the result.
The default **Calendar** object is created when the data storage runs for the first time. You can call this API instead of **createCalendar()** to use the default calendar for a new event.| -| getAllCalendars(): Promise\ | Obtains the created and default **Calendar** objects of the current application. This API uses a promise to return the result.| -| deleteCalendar(calendar: Calendar): Promise\ | Deletes a specified **Calendar** object. This API uses a promise to return the result. | -| getConfig(): CalendarConfig | Obtains the calendar configuration information. | -| setConfig(config: CalendarConfig): Promise\ | Sets the calendar configuration information. This API uses a promise to return the result. | -| getAccount(): CalendarAccount | Obtains the calendar account information. | +| getAllCalendars(): Promise\ | Obtains the created and default **Calendar** objects of the current application. This API uses a promise to return the result.| +| deleteCalendar(calendar: Calendar): Promise\ | Deletes a specified **Calendar** object. This API uses a promise to return the result. | +| getConfig(): CalendarConfig | Obtains the calendar configuration information. | +| setConfig(config: CalendarConfig): Promise\ | Sets the calendar configuration information. This API uses a promise to return the result. | +| getAccount(): CalendarAccount | Obtains the calendar account information. | ## How to Develop @@ -28,7 +28,7 @@ The table below lists the main APIs used for calendar management. For details ab ```ts // EntryAbility.ets - import {abilityAccessCtrl,AbilityConstant, common, PermissionRequestResult, Permissions, UIAbility, Want } from '@kit.AbilityKit'; + import { abilityAccessCtrl, AbilityConstant, common, PermissionRequestResult, Permissions, UIAbility, Want } from '@kit.AbilityKit'; import { BusinessError } from '@kit.BasicServicesKit'; import { calendarManager } from '@kit.CalendarKit'; import { window } from '@kit.ArkUI'; @@ -122,7 +122,7 @@ The table below lists the main APIs used for calendar management. For details ab }); ``` -5. After a calendar is created, it is displayed in black. You need to call the **setConfig()** API to set calendar configuration information, including event reminder and calendar color. +5. After a calendar is created, it is displayed in black. You need to call **setConfig()** to set calendar configuration information, including event reminder and calendar color. ```ts // Index.ets diff --git a/en/application-dev/calendarmanager/calendarmanager-event-developer.md b/en/application-dev/calendarmanager/calendarmanager-event-developer.md index 47c592b12309fd6330e40e1e3eed7af409949a60..e2f3dfa217d98324a656cd7f8a5c0e7d1501aaab 100644 --- a/en/application-dev/calendarmanager/calendarmanager-event-developer.md +++ b/en/application-dev/calendarmanager/calendarmanager-event-developer.md @@ -10,14 +10,14 @@ After obtaining the **Calendar** object, you can create, delete, modify and quer The table below lists the main APIs used for event management. For details about more APIs and their usage, see [@ohos.calendarManager](../reference/apis-calendar-kit/js-apis-calendarManager.md). -| API | Description | -| ------------------------------------------------------------ | ------------------------------------------------------------ | -| getCalendarManager(context : Context): CalendarManager | Obtains a **CalendarManager** object based on the context. | +| API | Description | +| ----------------------------------------- | ------------------------------------------------------------ | +| getCalendarManager(context: Context): CalendarManager | Obtains a **CalendarManager** object based on the context. | | createCalendar(calendarAccount: CalendarAccount): Promise\ | Creates a **Calendar** object based on the calendar account information. This API uses a promise to return the result.| -| addEvent(event: Event): Promise\ | Creates an event, with no event ID specified in **Event**. This API uses a promise to return the result. | -| editEvent(event: Event): Promise\ | Creates a single event. If the input parameter **Event** is not set to the event ID, the event creation screen is displayed when this API is called. This API uses a promise to return the result.| -| deleteEvent(id: number): Promise\ | Deletes an event with the specified ID. This API uses a promise to return the result. | -| updateEvent(event: Event): Promise\ | Updates an event. This API uses a promise to return the result. | +| addEvent(event: Event): Promise\ | Creates an event, with no event ID specified in **Event**. This API uses a promise to return the result. | +| editEvent(event: Event): Promise\ | Creates a single event. If the input parameter **Event** is not set to the event ID, the event creation screen is displayed when this API is called. This API uses a promise to return the result.| +| deleteEvent(id: number): Promise\ | Deletes an event with the specified ID. This API uses a promise to return the result. | +| updateEvent(event: Event): Promise\ | Updates an event. This API uses a promise to return the result. | | getEvents(eventFilter?: EventFilter, eventKey?: (keyof Event)[]): Promise\ | Obtains all events in a calendar that match the filter criteria. This API uses a promise to return the result. | ## How to Develop @@ -26,7 +26,7 @@ The table below lists the main APIs used for event management. For details about ```ts // entry/src/main/ets/entryability/EntryAbility.ets - import {abilityAccessCtrl,AbilityConstant, common, PermissionRequestResult, Permissions, UIAbility, Want } from '@kit.AbilityKit'; + import { abilityAccessCtrl, AbilityConstant, common, PermissionRequestResult, Permissions, UIAbility, Want } from '@kit.AbilityKit'; import { BusinessError } from '@kit.BasicServicesKit'; import { calendarManager } from '@kit.CalendarKit'; import { window } from '@kit.ArkUI'; @@ -138,9 +138,9 @@ The table below lists the main APIs used for event management. For details about Currently, you can create an event in either of the following methods: - Method 1: Use the **addEvent()** or **addEvents()** API to create an event in the calendar. You can use the **addEvent()** API to create a single event or use the **addEvents()** API to create events in batches. The following describes how to create a single event. + Method 1: Use **addEvent()** to create a single event or **addEvents()** to create events in batches. The following describes how to create a single event. - Method 2: After obtaining the **calendarManager** object, you can use the **editEvent()** API to create a single event. In this case, the event creation page is displayed, where you can perform related operations to create an event. Note that **editEvent()** does not support the creation of custom periodic events. + Method 2: After obtaining the **calendarManager** object, you can use **editEvent()** to create a single event. In this case, the event creation page is displayed, where you can perform related operations to create an event. Note that **editEvent()** does not support the creation of custom periodic events. ```ts // Index.ets @@ -190,7 +190,7 @@ The table below lists the main APIs used for event management. For details about console.error(`Failed to addEvent. Code: ${err.code}, message: ${err.message}`); }); // Method 2 - const eventInfo: calendarManager.Event = { + const eventInfo: calendarManager.Event = { // Event title. title: 'title', // Event type. @@ -265,7 +265,7 @@ The table below lists the main APIs used for event management. For details about }); ``` -8. Delete a specified event by event ID. You can use the **deleteEvent()** API to create a single event or use the **deleteEvents()** API to delete events in batches. The following describes how to delete a single event. +8. Delete a specified event by event ID. You can use **deleteEvent()** to create a single event or use **deleteEvents()** to delete events in batches. The following describes how to delete a single event. ```ts // Index.ets diff --git a/en/application-dev/calendarmanager/calendarmanager-overview.md b/en/application-dev/calendarmanager/calendarmanager-overview.md index 33285a2375bd67f7df4bfc3e78b9860cfd4e1d74..bc1a2c9f3f4336378fbc97d9cdfd3dd575c4873d 100644 --- a/en/application-dev/calendarmanager/calendarmanager-overview.md +++ b/en/application-dev/calendarmanager/calendarmanager-overview.md @@ -1,19 +1,51 @@ # Introduction to Calendar Kit -## Key Concepts +Calendar Kit provides calendar and event management capabilities, which usually refer to APIs that can be used to access and operate calendar data. These APIs allow you to integrate time-related event services (such as travel, catering, sports, and entertainment) in other applications with the system calendar to implement functions such as event management, creation, and query. -Calendar: a tool used to record dates, holidays, and important events. +## Available Capabilities -## Introduction +Calendar Kit provides management capability for accounts and events. -Calendar Kit provides calendar and event management capabilities, including capabilities to obtain and create calendar events. A **CalendarManager** object is used to manage **Calendar** objects. A **Calendar** object contains the account information (**CalendarAccount**) and configuration information (**CalendarConfig**). Calendars and events are in the one-to-many relationship. That is, a calendar can have multiple events, but an event belongs to only one calendar. +- Create a calendar account. + + You can create a calendar account specific to your application, after which an account ID is returned. The account ID is the auto-increment primary key of the data table and is used as the unique identifier of the account. + +- Obtain the calendar account. + + You can obtain information about a specified calendar account or all calendar accounts created by the current application. + +- Delete a calendar account. + + You can delete a specified calendar account, after which all events associated with the calendar account will be deleted. + +- Create a calendar event. + + After obtaining the calendar account information, you can create an event under the obtained calendar account. When creating an event, you can set an event reminder and its notification is displayed when the set time arrives. + + After a calendar account is created, an account ID is returned. The account ID is the auto-increment primary key of the data table and is used as the unique identifier of the account. + +- Delete an event. + + You can delete one or more events with specified event IDs at a time. + +- Update an event. + + You can update event information based on the event ID, including the event title, location, start time, end time, and reminder time. + +- Query events. + + You can query events by event ID, event title, event start time, and event end time. + +## Features + +**One-click event service**: With the permanent authorization mechanism, after the user allows your application to read and write the system calendar, the corresponding event service can be written into the calendar in the form of deeplink. According to the reminder rules set by yourself, when an event is about to expire or expires, the corresponding service button will be displayed in the calendar application, notification, and widgets. Users can tap the button to redirect to the service landing page in one step. ## Working Principles -Calendar Kit provides a set of APIs for obtaining calendar accounts and writing calendar events to the obtained accounts. If an event has a reminder time set, the system sends a reminder to the user when the set time arrives. +Calendar Kit provides a set of APIs for obtaining calendar accounts, and writing calendar events to or reading events from the obtained accounts. If an event has a reminder time set, the system sends a reminder to the user when the set time arrives. ## Constraints -- Calendar Kit requires manual authorization from the user for the permissions to read and write calendar events. +- To use the capabilities of Calendar Kit, you need to obtain the **ohos.permission.READ_CALENDAR** and **ohos.permission.WRITE_CALENDAR** permissions to read or write calendars and events. For details, see [Declaring Permissions](../security/AccessToken/declare-permissions.md). -- Calendar Kit is only available in the stage model. +- Currently, the capabilities and APIs of Calendar Kit can be used only in the stage model. diff --git a/en/application-dev/connectivity/connectivity-kit-intro.md b/en/application-dev/connectivity/connectivity-kit-intro.md index 99dc6b935c017c96680b0b41e56102872c676b26..748ad0b760ff592713f9b31fedb90b39ae1e215e 100644 --- a/en/application-dev/connectivity/connectivity-kit-intro.md +++ b/en/application-dev/connectivity/connectivity-kit-intro.md @@ -4,7 +4,7 @@ Mobile devices have become an integral part of every life. For example, people listen to music with Bluetooth headphones, surf the Internet over Wi-Fi, and use their mobile phone as a transit pass or credit card. In these applications, NFC implements short-range interactions like payments and access control, Bluetooth provides basic wireless connections for devices, such as headphones, wearables, and peripheral devices, and Wi-Fi provides high-speed Internet access. -You can use Connectivity Kit to design mobile applications to meet different user requirements. +You can use Connectivity Kit to design mobile applications to meet diverse user needs in their daily lives. ### Bluetooth @@ -85,5 +85,3 @@ Connectivity Kit provides basic communication services for applications. Before Device capabilities can be used only after the related switch is enabled after user authorization. Otherwise, the system does not provide services for third-party applications. - - diff --git a/en/application-dev/connectivity/nfc/nfc-tag-access-guide.md b/en/application-dev/connectivity/nfc/nfc-tag-access-guide.md index cf9955b816cec0223ad0150a2bbf70d83db26670..e4b587deff2c67c27d0ace2cd2a7213b7d5ca27a 100644 --- a/en/application-dev/connectivity/nfc/nfc-tag-access-guide.md +++ b/en/application-dev/connectivity/nfc/nfc-tag-access-guide.md @@ -121,7 +121,7 @@ async function readerModeCb(error : BusinessError, tagInfo : tag.TagInfo) { return; } } - // Use other technologies to access this NFC tag if necessary. + // use other technology to access this nfc tag if necessary. } if (isoDep == undefined) { hilog.error(0x0000, 'testTag', 'readerModeCb getIsoDep is invalid'); @@ -241,7 +241,7 @@ export default class EntryAbility extends UIAbility { { "type":"tag-tech/IsoDep" } - // Add other technologies if neccessary, + // Add other technologies if necessary, // such as: NfcB/NfcF/NfcV/Ndef/MifareClassic/MifareUL/NdefFormatable ] } @@ -301,7 +301,7 @@ export default class EntryAbility extends UIAbility { return; } } - // Use other technologies to access this NFC tag if necessary. + // use other technology to access this nfc tag if necessary. } if (isoDep == undefined) { hilog.error(0x0000, 'testTag', 'getIsoDep is invalid'); diff --git a/en/application-dev/database/data-encryption.md b/en/application-dev/database/data-encryption.md index 62b81948c8c308bb88f5ae361d2a30cb256dda21..e452190b83c7f0a87c71910abf1e4c7e4b41f445 100644 --- a/en/application-dev/database/data-encryption.md +++ b/en/application-dev/database/data-encryption.md @@ -71,7 +71,7 @@ if (kvStore !== undefined) { The **encrypt** property in [StoreConfig](../reference/apis-arkdata/js-apis-data-relationalStore.md#storeconfig) specifies whether to encrypt the RDB store. The value **true** means to encrypt the RDB store, and **false** means the opposite. -If **encrypt** is **true**, you can set parameters such as the key and algorithm used for encryption/decryption in **cryptoParam**. +If **encrypt** is **true**, you can set parameters such as the key and algorithm used for encryption/decryption in **cryptoParam** in ArkTS APIs. This configuration is not supported in C/C++. The **cryptoParam** parameter is optional. @@ -113,12 +113,12 @@ for (let i = 0; i < 32; i++) { // Initialize the encryption algorithm. const CRYPTO_PARAM : relationalStore.CryptoParam = { - encryptionKey: key, // (Mandatory) Key used to open the encrypted database. If this parameter is not specified, the database generates and saves the key and uses the generated key to open the database file. - iterationCount: 25000, // (Optional) Number of iterations. The value must be greater than or equal to 0. If this parameter is not specified or is set to 0, the default value 10000 and the default encryption algorithm are used. + encryptionKey: key, // (Mandatory) Key used to open the encrypted database. If this parameter is not specified, the database generates and saves the key and uses the generated key to open the database file. + iterationCount: 25000, // (Optional) Number of iterations. The value must be greater than or equal to 0. If this parameter is not specified or is set to 0, the default value 10000 and the default encryption algorithm are used. encryptionAlgo: relationalStore.EncryptionAlgo.AES_256_CBC, // (Optional) Encryption/Decryption algorithm. If this parameter is not specified, the default algorithm AES_256_GCM is used. - hmacAlgo: relationalStore.HmacAlgo.SHA256, // (Optional) HMAC algorithm. If this parameter is not specified, the default value SHA256 is used. + hmacAlgo: relationalStore.HmacAlgo.SHA256, // (Optional) HMAC algorithm. If this parameter is not specified, the default value SHA256 is used. kdfAlgo: relationalStore.KdfAlgo.KDF_SHA512, // (Optional) KDF algorithm. If this parameter is not specified, the default value (same as the HMAC algorithm) is used. - cryptoPageSize: 2048 // (Optional) Page size used for encryption/decryption. The value must be an integer within the range of 1024 to 65536 and a power of 2. The default value is 1024. + cryptoPageSize: 2048 // (Optional) Page size used for encryption/decryption. The value must be an integer within the range of 1024 to 65536 and a power of 2. The default value is 1024. } const STORE_CONFIG : relationalStore.StoreConfig = { @@ -143,4 +143,3 @@ run(); ``` If you do not care about the algorithm and other parameters used for encryption, leave **cryptoParam** unspecified. In this case, the default encryption configuration is used. If you want to customize the encryption configuration or open an encrypted database that is not configured by default, set **cryptoParam**. - diff --git a/en/application-dev/database/encrypted_estore_guidelines.md b/en/application-dev/database/encrypted_estore_guidelines.md index ea82f39375221e380859d700d78fe4d54ef2425f..471a6404d26a3ec13e11d1669e14a03eb756692b 100644 --- a/en/application-dev/database/encrypted_estore_guidelines.md +++ b/en/application-dev/database/encrypted_estore_guidelines.md @@ -3,9 +3,9 @@ ## When to Use -An [EL5](../reference/apis-ability-kit/js-apis-app-ability-contextConstant.md#areamode) database is created in the **el5/** directory to store the application's sensitive information. When the device screen is locked and certain conditions are met, the key used to encrypt the sensitive information will be destroyed and the database cannot be operated. After the screen is unlocked, the key is restored and the read and write operations on the database are restored. This mechanism can effectively protect the user data. For details about how to manage the encryption directories, see [Obtaining and Modifying Encryption Levels](../application-models/application-context-stage.md#obtaining-and-modifying-encryption-levels). +An [EL5](../reference/apis-ability-kit/js-apis-app-ability-contextConstant.md#areamode) database is created in the **el5/** directory to store the application's sensitive information. When the device screen is locked and certain conditions are met, the key used to encrypt the sensitive information will be destroyed and the encrypted database cannot be read or written. After the screen is unlocked, the key is restored and the read and write operations on the database are restored. This mechanism can effectively protect the user data. For details about how to manage the encryption directories, see [Obtaining and Modifying Encryption Levels](../application-models/application-context-stage.md#obtaining-and-modifying-encryption-levels). -However, the application may write data when the screen is locked. Data loss will be caused if the EL5 database cannot be operated when data is written. A solution is provided to solve this problem. When the screen is locked, incremental data is stored in an [EL2](../reference/apis-ability-kit/js-apis-app-ability-contextConstant.md#areamode) database. The data temporarily stored in the EL2 database will be moved to the EL5 database when the EL5 database is unlocked. This ensures data security and consistency when the screen is locked. +However, the application may write data when the screen is locked. Data loss will be caused if the EL5 database cannot be operated when data is written. A solution is provided to solve this problem. When the screen is locked, incremental data is stored in an [EL2](../reference/apis-ability-kit/js-apis-app-ability-contextConstant.md#areamode) database. The data temporarily stored in the EL2 database will be moved to the EL5 database when the EL5 database is unlocked. This ensures data security and integrity when the screen is locked. Both the KV store and RDB store can be used as an EL5 database. @@ -14,7 +14,9 @@ Both the KV store and RDB store can be used as an EL5 database. The following classes are encapsulated to implement the data operations and transfer between EL2 and EL5 databases: - **Mover** class: provides APIs for moving data from an EL2 database to an EL5 database after the screen is unlocked. -- **Store** class: provides APIs for accessing and operating the currently operable database. + +- **Store** class: provides APIs for obtaining a database instance, adding, deleting, and updating data, and obtaining the data count in the database. + - **SecretKeyObserver** class: provides APIs for obtaining the key status. After the key is destroyed, the EL5 database will be closed. - **ECStoreManager** class: provides APIs for managing the EL2 and EL5 databases. @@ -225,7 +227,7 @@ export let lockObserve = new SecretKeyObserver(); ### ECStoreManager -Use the APIs provided by the **ECStoreManager** class to manage the EL2 and EL5 databases. Specifically, you can use the APIs to configure a database, set the function used to move data, provide the database handle for the application based on the key status, close an EL5 database, and destroy an El2 database after the data is moved. +Use the APIs provided by the **ECStoreManager** class to manage the EL2 and EL5 databases. You can configure database information and migration function information, provide database handles for applications based on the key status, close EL5 databases, and destroy EL2 databases after data migration. ```ts // ECStoreManager.ts @@ -701,7 +703,7 @@ export let lockObserve = new SecretKeyObserver(); ### ECStoreManager -Use the APIs provided by the **ECStoreManager** class to manage the EL2 and EL5 databases. Specifically, you can use the APIs to configure a database, set the function used to move data, provide the database handle for the application based on the key status, close an EL5 database, and destroy an El2 database after the data is moved. +Use the APIs provided by the **ECStoreManager** class to manage the EL2 and EL5 databases. You can configure database information and migration function information, provide database handles for applications based on the key status, close EL5 databases, and destroy EL2 databases after data migration. ```ts // ECStoreManager.ts diff --git a/en/application-dev/database/native-unified-data-management-framework-guidelines.md b/en/application-dev/database/native-unified-data-management-framework-guidelines.md index 5a883d75256c192834c09129b334de67d895d3cd..43e4e06a470c006e0dfefd4f077c5126267e52fa 100644 --- a/en/application-dev/database/native-unified-data-management-framework-guidelines.md +++ b/en/application-dev/database/native-unified-data-management-framework-guidelines.md @@ -8,9 +8,9 @@ The Unified Data Management Framework (UDMF) defines the language and data stand ## Basic Concepts -- UTD
A Uniform Type Descriptor (UTD) defines data of the same type to eliminate data type ambiguity. It contains the data type ID and types to which the current data type belongs. The UTD is generally used to filter or identify the data type in scenarios such as file preview and file sharing. +- UTD
A Uniform Type Descriptor (UTD) defines data of the same type to eliminate data type ambiguity. It contains the data type ID and types to which the current data type belongs. The UTD is generally used to filter or identify the data type in scenarios, such as file preview and file sharing. -- UDS
A uniform data struct (UDS) defines the data of a certain type (specified by a UTD). Uniform data structs allow unified parsing standards to be used in data interaction, which minimizes the adaptation workload. Uniform data structs are used for data interaction across applications and devices, such as, the drag-and-drop operations. +- UDS
A uniform data struct (UDS) defines the data of a certain type (specified by a UTD). Uniform data structs allow unified parsing standards to be used in data interaction, which minimizes the adaptation workload. Uniform data structs are used for data interaction across applications and devices, such as, the drag-and-drop operations. - Unified record
A unified record is abstract definition of a piece of data supported by the UDMF, for example, a text record or an image record. @@ -31,36 +31,36 @@ The Unified Data Management Framework (UDMF) defines the language and data stand For details about the APIs, see [UDMF](../reference/apis-arkdata/_u_d_m_f.md). -| API | Description | -| ------------------------------------------------------------ | ------------------------------------------------------------ | -| OH_Utd* OH_Utd_Create(const char* typeId) | Creates a pointer to an **OH_Utd** instance. | -| void OH_Utd_Destroy(OH_Utd* pThis) | Destroys the pointer to an **OH_Utd** instance. | -| const char** OH_Utd_GetTypesByFilenameExtension(const char* extension, unsigned int* count) | Obtains the uniform data types by file name extension. | -| const char** OH_Utd_GetTypesByMimeType(const char* mimeType, unsigned int* count) | Obtains the uniform data types by MIME type. | -| bool OH_Utd_Equals(OH_Utd* utd1, OH_Utd* utd2) | Checks whether two UTDs are the same. | -| void OH_Utd_DestroyStringList(const char** list, unsigned int count) | Destroys a UTD list. | -| OH_UdsHyperlink* OH_UdsHyperlink_Create() | Creates a pointer to an **OH_UdsHyperlink** instance. | -| void OH_UdsHyperlink_Destroy(OH_UdsHyperlink* pThis) | Destroys the pointer to an **OH_UdsHyperlink** instance. | -| const char* OH_UdsHyperlink_GetType(OH_UdsHyperlink* pThis) | Obtains the UTD ID from an **OH_UdsHyperlink** instance. | -| const char* OH_UdsHyperlink_GetUrl(OH_UdsHyperlink* pThis) | Obtains the URL from an **OH_UdsHyperlink** instance. | -| const char* OH_UdsHyperlink_GetDescription(OH_UdsHyperlink* pThis) | Obtains the link description from an **OH_UdsHyperlink** instance. | -| int OH_UdsHyperlink_SetUrl(OH_UdsHyperlink* pThis, const char* url) | Sets the URL for an **OH_UdsHyperlink** instance. | -| int OH_UdsHyperlink_SetDescription(OH_UdsHyperlink* pThis, const char* description) | Sets the link description for an **OH_UdsHyperlink** instance. | -| OH_UdmfData* OH_UdmfData_Create() | Creates a pointer to an **OH_UdmfData** instance. | -| void OH_UdmfData_Destroy(OH_UdmfData* pThis) | Destroys the pointer to an **OH_UdmfData** instance. | -| int OH_UdmfData_AddRecord(OH_UdmfData* pThis, OH_UdmfRecord* record) | Add an **OH_UdmfRecord** to an **OH_UdmfData** instance. | -| bool OH_UdmfData_HasType(OH_UdmfData* pThis, const char* type) | Checks whether the specified type exists in an **OH_UdmfData** instance. | -| OH_UdmfRecord** OH_UdmfData_GetRecords(OH_UdmfData* pThis, unsigned int* count) | Obtains all data records from an **OH_UdmfData** instance. | -| OH_UdmfRecord* OH_UdmfRecord_Create() | Creates a pointer to an **OH_UdmfRecord** instance. | -| void OH_UdmfRecord_Destroy(OH_UdmfRecord* pThis) | Destroys the pointer to an **OH_UdmfRecord** instance. | -| int OH_UdmfRecord_AddHyperlink(OH_UdmfRecord* pThis, OH_UdsHyperlink* hyperlink) | Adds hyperlink data to an **OH_UdmfRecord** instance. | -| char** OH_UdmfRecord_GetTypes(OH_UdmfRecord* pThis, unsigned int* count) | Obtains all data types in an **OH_UdmfRecord** instance. | -| int OH_UdmfRecord_GetHyperlink(OH_UdmfRecord* pThis, OH_UdsHyperlink* hyperlink) | Obtains the hyperlink data from an **OH_UdmfRecord** instance. | -| int OH_Udmf_GetUnifiedData(const char* key, Udmf_Intention intention, OH_UdmfData* unifiedData) | Obtains data from the UDMF database. | -| int OH_Udmf_SetUnifiedData(Udmf_Intention intention, OH_UdmfData* unifiedData, char* key, unsigned int keyLen) | Sets data in the UDMF database. | -| OH_UdmfRecordProvider* OH_UdmfRecordProvider_Create() | Creates a pointer to the unified data provider instance. | -| int OH_UdmfRecordProvider_SetData(OH_UdmfRecordProvider* provider, void* context, const OH_UdmfRecordProvider_GetData callback, const UdmfData_Finalize finalize) | Sets a callback for the unified data provider. | -| int OH_UdmfRecord_SetProvider(OH_UdmfRecord* pThis, const char* const* types, unsigned int count, OH_UdmfRecordProvider* provider) | Sets the unified data provider in an **OH_UdmfRecord** instance. | +| API | Description | +| ------------------------------------------------------------ | ----------------------------------------------------------- | +| OH_Utd* OH_Utd_Create(const char* typeId) | Creates a pointer to an **OH_Utd** instance. | +| void OH_Utd_Destroy(OH_Utd* pThis) | Destroys the pointer to an **OH_Utd** instance. | +| const char** OH_Utd_GetTypesByFilenameExtension(const char* extension, unsigned int* count) | Obtains the uniform data types by file name extension. | +| const char** OH_Utd_GetTypesByMimeType(const char* mimeType, unsigned int* count) | Obtains the uniform data types by MIME type. | +| bool OH_Utd_Equals(OH_Utd* utd1, OH_Utd* utd2) | Checks whether two UTDs are the same. | +| void OH_Utd_DestroyStringList(const char** list, unsigned int count) | Destroys a UTD list. | +| OH_UdsHyperlink* OH_UdsHyperlink_Create() | Creates a pointer to an **OH_UdsHyperlink** instance.| +| void OH_UdsHyperlink_Destroy(OH_UdsHyperlink* pThis) | Destroys the pointer to an **OH_UdsHyperlink** instance. | +| const char* OH_UdsHyperlink_GetType(OH_UdsHyperlink* pThis) | Obtains the UTD ID from an **OH_UdsHyperlink** instance. | +| const char* OH_UdsHyperlink_GetUrl(OH_UdsHyperlink* pThis) | Obtains the URL from an **OH_UdsHyperlink** instance. | +| const char* OH_UdsHyperlink_GetDescription(OH_UdsHyperlink* pThis) | Obtains the link description from an **OH_UdsHyperlink** instance. | +| int OH_UdsHyperlink_SetUrl(OH_UdsHyperlink* pThis, const char* url) | Sets the URL for an **OH_UdsHyperlink** instance. | +| int OH_UdsHyperlink_SetDescription(OH_UdsHyperlink* pThis, const char* description) | Sets the link description for an **OH_UdsHyperlink** instance. | +| OH_UdmfData* OH_UdmfData_Create() | Creates a pointer to an **OH_UdmfData** instance. | +| void OH_UdmfData_Destroy(OH_UdmfData* pThis) | Destroys the pointer to an **OH_UdmfData** instance. | +| int OH_UdmfData_AddRecord(OH_UdmfData* pThis, OH_UdmfRecord* record) | Add an **OH_UdmfRecord** to an **OH_UdmfData** instance. | +| bool OH_UdmfData_HasType(OH_UdmfData* pThis, const char* type) | Checks whether the specified type exists in an **OH_UdmfData** instance. | +| OH_UdmfRecord** OH_UdmfData_GetRecords(OH_UdmfData* pThis, unsigned int* count) | Obtains all data records from an **OH_UdmfData** instance. | +| OH_UdmfRecord* OH_UdmfRecord_Create() | Creates a pointer to an **OH_UdmfRecord** instance. | +| void OH_UdmfRecord_Destroy(OH_UdmfRecord* pThis) | Destroys the pointer to an **OH_UdmfRecord** instance. | +| int OH_UdmfRecord_AddHyperlink(OH_UdmfRecord* pThis, OH_UdsHyperlink* hyperlink) | Adds hyperlink data to an **OH_UdmfRecord** instance. | +| char** OH_UdmfRecord_GetTypes(OH_UdmfRecord* pThis, unsigned int* count) | Obtains all data types in an **OH_UdmfRecord** instance. | +| int OH_UdmfRecord_GetHyperlink(OH_UdmfRecord* pThis, OH_UdsHyperlink* hyperlink) | Obtains the hyperlink data from an **OH_UdmfRecord** instance. | +| int OH_Udmf_GetUnifiedData(const char* key, Udmf_Intention intention, OH_UdmfData* unifiedData) | Obtains data from the UDMF database. | +| int OH_Udmf_SetUnifiedData(Udmf_Intention intention, OH_UdmfData* unifiedData, char* key, unsigned int keyLen) | Sets data in the UDMF database. | +| OH_UdmfRecordProvider* OH_UdmfRecordProvider_Create() | Creates a pointer to the unified data provider instance. | +| int OH_UdmfRecordProvider_SetData(OH_UdmfRecordProvider* provider, void* context, const OH_UdmfRecordProvider_GetData callback, const UdmfData_Finalize finalize) | Sets a callback for the unified data provider. | +| int OH_UdmfRecord_SetProvider(OH_UdmfRecord* pThis, const char* const* types, unsigned int count, OH_UdmfRecordProvider* provider) | Sets the unified data provider in an **OH_UdmfRecord** instance. | ## Adding Dynamic Link Libraries @@ -84,7 +84,7 @@ libudmf.so ``` ## Obtaining Plaintext Data in Different Ways -To use the UTD to obtain plaintext data, perform the following steps: +The following walks you through on how to use the UTD to obtain plaintext data. 1. Obtain **typeId** of the UTD based on the file name extension **.txt**. 2. Obtain **typeId** of the UTD based on the MIME type **text/plain**. 3. Use the **typeId**s obtained to create two UTD instances. diff --git a/en/application-dev/database/share-data-by-datashareextensionability.md b/en/application-dev/database/share-data-by-datashareextensionability.md index 88ac95bb94d69ba55c8966c167bb3a33ad88ed9d..b3de68a61fd9c54cc0d6f5013b95e18df6e20c72 100644 --- a/en/application-dev/database/share-data-by-datashareextensionability.md +++ b/en/application-dev/database/share-data-by-datashareextensionability.md @@ -16,8 +16,7 @@ There are two roles in **DataShare**: - Data consumer: accesses the data provided by the provider using [createDataShareHelper()](../reference/apis-arkdata/js-apis-data-dataShare-sys.md#datasharecreatedatasharehelper). -**Figure 1** Data sharing mechanism - +**Figure 1** Data sharing mechanism ![dataShare](figures/dataShare.jpg) - The **DataShareExtensionAbility** module, as the data provider, implements services related to data sharing between applications. @@ -144,11 +143,11 @@ Before implementing a **DataShare** service, you need to create a **DataShareExt | Field| Description| Mandatory| | -------- | -------- | -------- | | name | Ability name, corresponding to the **ExtensionAbility** class name derived from **Ability**.| Yes| - | type | Ability type. The value **dataShare** indicates the development is based on the **datashare** template.| Yes| + | type | Ability type. The value **dataShare** indicates that the development is based on the **datashare** template.| Yes| | uri | Unique identifier for the data consumer to access the data provider.| Yes| | exported | Whether it is visible to other applications. Data sharing is allowed only when the value is **true**.| Yes| - | readPermission | Permission required for data access. If this parameter is not set, read permission verification is not performed by default.| No| - | writePermission | Permission required for data modification. If this parameter is not set, write permission verification is not performed by default.| No| + | readPermission | Permission required for accessing data. If this parameter is not set, read permission verification is not performed by default.| No| + | writePermission | Permission required for modifying data. If this parameter is not set, write permission verification is not performed by default.| No| | metadata | Silent access configuration, which includes the following:
- **name**: identifies the configuration, which has a fixed value of **ohos.extension.dataShare**.
- **resource**: has a fixed value of **$profile:data_share_config**, which indicates that the profile name is **data_share_config.json**.| **metadata** is mandatory when the ability launch type is **singleton**. For details about the ability launch type, see **launchType** in the [Internal Structure of the abilities Attribute](../quick-start/module-structure.md#internal-structure-of-the-abilities-attribute).| **module.json5 example** @@ -308,7 +307,4 @@ Before implementing a **DataShare** service, you need to create a **DataShareExt // Close the DataShareHelper instance. (dsHelper as dataShare.DataShareHelper).close(); } - ``` - - - + ``` \ No newline at end of file diff --git a/en/application-dev/database/share-data-by-silent-access.md b/en/application-dev/database/share-data-by-silent-access.md index 6eef9bdff740e7d99295bf19dfe853950c22c97f..6fc7a1679e48f29f07737310ccdcc26f46209048 100644 --- a/en/application-dev/database/share-data-by-silent-access.md +++ b/en/application-dev/database/share-data-by-silent-access.md @@ -3,9 +3,13 @@ ## When to Use -In a typical cross-application data access scenario, the data provider may be started multiple times. To minimize the startup times of the data provider and speed up the access, OpenHarmony provides the silent access feature, which allows access to the database without starting the data provider. +In a typical cross-application data access scenario, the data provider may be started multiple times. -In silent access, **DatamgrService** accesses and modifies data without starting the data provider. However, **DatamgrService** supports basic database access and data hosting only. If service processing is required, the service processing logic must be encapsulated into APIs for the data consumer to call. +To minimize the startup times of the data provider and speed up the access, OpenHarmony provides the silent access feature, which allows access to the database without starting the data provider. + +In silent access, **DatamgrService** accesses and modifies data without starting the data provider. + +However, **DatamgrService** supports basic database access and data hosting only. If service processing is required, the service processing logic must be encapsulated into APIs for the data consumer to call. If the service processing is too complex to be encapsulated, use [DataShareExtensionAbility](../reference/apis-arkdata/js-apis-application-dataShareExtensionAbility-sys.md) to start the data provider. @@ -27,7 +31,7 @@ If the service processing is too complex to be encapsulated, use [DataShareExten | ----- | --------- | ----------- | ------------ | --------------------------------- | | Persistent data| Sandbox directory of the data provider | Database tables | Permanent | RDB data used for schedules and meetings. | | Process data | DatamgrService sandbox directory| JSON or byte| Automatically deleted 10 days after no subscription| Time-sensitive data in simple format used for step count, weather, and heart rate monitoring.| -| Dynamic data | DatamgrService memory| KV pair| Automatically deleted after the device is restarted| Data generated when silent access is dynamically disabled or enabled. For example, to ensure data accuracy, silent access needs to be disabled in upgrade and enabled after the upgrade by using APIs. The "enabled" or "disabled" status generated by using the API is cleared after the device is restarted.
The dynamic data refers to only the data set by **enableSilentProxy** and **disableSilentProxy**. | +| Dynamic data | DatamgrService memory| KV pair| Automatically deleted after the device is restarted| Data generated when silent access is dynamically disabled or enabled. For example, to ensure data accuracy, silent access needs to be disabled in upgrade and enabled after the upgrade by using APIs. The "enabled" or "disabled" status generated by using the API is cleared after the device is restarted.
The dynamic data refers to only the data set by **enableSilentProxy** and **disableSilentProxy**.| @@ -45,13 +49,13 @@ If the service processing is too complex to be encapsulated, use [DataShareExten - You can add parameters to the URI to specify the access mode and target object. When adding parameters to a URI, note that the URI must be in the **datashareproxy://{*bundleName*}/{*dataPath*}?{*arg1*}&{*arg2*}** format. Otherwise, the parameters do not take effect. - The parameters to add start with a question mark (?) and separated by an ampersand (&). Consecutive symbols (for example, ???? or &&&) are considered as one. Currently, only **Proxy** and **appIndex** can be added. If the URI contains multiple question marks (?), the parameter following the question mark (?) must be **Proxy**. Otherwise, the parameter does not take effect. + The parameters to add start with a question mark (?) and separated by an ampersand (&). Consecutive symbols (for example, ???? or &&&) are considered as one. Currently, only **Proxy** and **appIndex** can be added. If the URI contains multiple question marks (?), the parameter following the question mark (?) must be **Proxy**. Otherwise, this parameter does not take effect. - **Proxy** specifies the data access mode used by the data consumer. The value can be **true** or **false**. The value **true** indicates the silent access mode, and **false** indicates the non-silent access mode. - **appIndex** specifies the index of an application clone. The value must be an integer starting from 1. This parameter takes effect only for cloned applications. For details about **appIndex**, see [BundleInfo](../reference/apis-ability-kit/js-apis-bundleManager-bundleInfo.md). If **appIndex** is **0** or left empty, the data consumer accesses the data provider application. - Currently, cloned applications can be accessed only in silent access mode. When setting the URI and parameters for accessing an application clone, both **Proxy** and **appIndex** are mandatory. For example, **datashareproxy://{bundleName}/{dataPath}?Proxy=true&appIndex=1** indicates that the data consumer accesses the first clone of the application in silent access mode. + Currently, cloned applications can be accessed only in silent mode. When setting the URI and parameters for accessing an application clone, both **Proxy** and **appIndex** are mandatory. For example, **datashareproxy://{bundleName}/{dataPath}?Proxy=true&appIndex=1** indicates that the data consumer accesses the first clone of the application in silent access mode. ## Constraints @@ -86,7 +90,7 @@ Most of the APIs for silent access are executed asynchronously in callback or pr | API | Description | | ---------------------------------------- | ------------------ | -| publish(data: Array<PublishedItem>, bundleName: string, version: number, callback: AsyncCallback<Array<OperationResult>>): void | Publishes data to **DatamgrService**. | +| publish(data: Array<PublishedItem>, bundleName: string, version: number, callback: AsyncCallback<Array<OperationResult>>): void | Publishes data to **DatamgrService**.| | on(type: 'publishedDataChange', uris: Array<string>, subscriberId: string, callback: AsyncCallback<PublishedDataChangeNode>): Array<OperationResult> | Subscribes to changes of the published data. | ### APIs for Accessing Dynamic Data @@ -94,7 +98,7 @@ Most of the APIs for silent access are executed asynchronously in callback or pr | API | Description | | ---------------------------------------- | ------------------ | | enableSilentProxy(context: Context, uri?: string): Promise<void> | Enables silent access by the data provider dynamically.
When the data consumer calls the **DataShare** API through silent access, the system verifies the silent access status.
If silent access is enabled, the **DataShare** API will be executed.| -| disableSilentProxy(context: Context, uri?: string): Promise<void> | Disables silent access by the data provider dynamically.
When the data consumer calls the **DataShare** API through silent access, the system verifies the silent access status.
If silent access is disabled, the **DataShare** API will be denied.| +| disableSilentProxy(context: Context, uri?: string): Promise<void> | Disables silent access by the data provider dynamically.
When the data consumer calls the **DataShare** API through silent access, the system verifies the silent access status.
If silent access is disabled, the **DataShare** API cannot be executed.| @@ -111,8 +115,8 @@ The following walks you through on how to share an RDB store. | Name | Description | Mandatory | | ----------------------- | ---------------------------------------- | ---- | | uri | URI of the data proxy, which is the unique identifier for cross-application data access. | Yes | - | requiredReadPermission | Permission required for reading data from the data proxy. If this parameter is not set, other applications are not allowed to access data. For details about the permissions, see [Permissions for All Applications](../security/AccessToken/permissions-for-all.md). | No | - | requiredWritePermission | Permission required for writing data to the data proxy. If this parameter is not set, other applications are not allowed to write data to the data proxy. For details about the permissions, see [Permissions for All Applications](../security/AccessToken/permissions-for-all.md). | No | + | requiredReadPermission | Permission required for reading data from the data proxy. If this parameter is not set, other applications are not allowed to access data. For details about the permissions, see [Application Permissions](../security/AccessToken/app-permissions.md). | No | + | requiredWritePermission | Permission required for writing data to the data proxy. If this parameter is not set, other applications are not allowed to write data to the data proxy. For details about the permissions, see [Application Permissions](../security/AccessToken/app-permissions.md). | No | | metadata | Metadata of the data source, including the **name** and **resource** fields.
The **name** field identifies the configuration, which has a fixed value of **dataProperties**.
The value of **resource** is **$profile:{fileName}**, indicating that the name of the configuration file is **{fileName}.json**.| Yes | **module.json5 example** @@ -184,7 +188,7 @@ The following walks you through on how to share an RDB store. } ``` -4. Use **DataShareHelper** APIs to access the services provided by the provider, for example, adding, deleting, modifying, and querying data. +4. Use the **DataShareHelper** APIs to access the services provided by the provider, for example, adding, deleting, modifying, and querying data. ```ts // Construct a piece of data. @@ -255,7 +259,7 @@ The following walks you through on how to share an RDB store. bundleNameOfOwner: "com.acts.ohos.data.datasharetestclient" } if(dsHelper != undefined) { - // When the DatamgrService modifies data, onCallback is invoked to return the data queried based on the rules in the template. + // When DatamgrService modifies data, onCallback is invoked to return the data queried based on the rules in the template. let result: Array = (dsHelper as dataShare.DataShareHelper).on("rdbDataChange", [dseUri], templateId, onCallback); } ``` @@ -279,8 +283,8 @@ In the **module.json5** file, set the data to be hosted in **proxyData**. For de | Name | Description | Mandatory | | ----------------------- | ----------------------------- | ---- | | uri | URI of the data proxy, which is the unique identifier for cross-application data access. | Yes | -| requiredReadPermission | Permission required for reading data from the data proxy. If this parameter is not set, other applications are not allowed to access data. For details about the permissions, see [Permissions for All Applications](../security/AccessToken/permissions-for-all.md).| No | -| requiredWritePermission | Permission required for writing data to the data proxy. If this parameter is not set, other applications are not allowed to write data to the dta proxy. For details about the permissions, see [Permissions for All Applications](../security/AccessToken/permissions-for-all.md).| No | +| requiredReadPermission | Permission required for reading data from the data proxy. If this parameter is not set, other applications are not allowed to access data. For details about the permissions, see [Application Permissions](../security/AccessToken/app-permissions.md).| No | +| requiredWritePermission | Permission required for writing data to the data proxy. If this parameter is not set, other applications are not allowed to write data to the dta proxy. For details about the permissions, see [Application Permissions](../security/AccessToken/app-permissions.md).| No | **module.json5 example** @@ -393,5 +397,3 @@ The data provider calls the **enableSilentProxy** API to dynamically enable sile } } ``` - - diff --git a/en/application-dev/database/uniform-data-structure.md b/en/application-dev/database/uniform-data-structure.md index 0c924365fccb7c6be3f535917ec2b68c20fc6678..5fb9204e287fbcdd7ede8374c5337e18d49e19e5 100644 --- a/en/application-dev/database/uniform-data-structure.md +++ b/en/application-dev/database/uniform-data-structure.md @@ -11,12 +11,13 @@ Applications can directly use the uniform data structs in certain scenarios. For The following table lists the uniform data structs provided by the UDMF. -| Data Struct | Data Type | Description | -| ----------------------- | :-------------------: | ---------- | -| [PlainText](../reference/apis-arkdata/js-apis-data-uniformDataStruct.md#plaintext) | 'general.plain-text' | Plain text | -| [Hyperlink](../reference/apis-arkdata/js-apis-data-uniformDataStruct.md#hyperlink) | 'general.hyperlink' | Hyperlink | -| [HTML](../reference/apis-arkdata/js-apis-data-uniformDataStruct.md#html) | 'general.html' | HyperText Markup Language (HTML) | -| [OpenHarmonyAppItem](../reference/apis-arkdata/js-apis-data-uniformDataStruct.md#openharmonyappitem) | 'openharmony.app-item' | Icon | +| Data Struct | Data Type | Description | +|-----------------------------------------------------------------------------------------------------| :-------------------: |------| +| [PlainText](../reference/apis-arkdata/js-apis-data-uniformDataStruct.md#plaintext) | 'general.plain-text' | Plain text | +| [Hyperlink](../reference/apis-arkdata/js-apis-data-uniformDataStruct.md#hyperlink) | 'general.hyperlink' | Hyperlink | +| [HTML](../reference/apis-arkdata/js-apis-data-uniformDataStruct.md#html) | 'general.html' | HyperText Markup Language (HTML) | +| [OpenHarmonyAppItem](../reference/apis-arkdata/js-apis-data-uniformDataStruct.md#openharmonyappitem) | 'openharmony.app-item' | Icon | +| [ContentForm](../reference/apis-arkdata/js-apis-data-uniformDataStruct.md#contentform14) | 'general.content-form' | Content widget| ## How to Develop @@ -88,4 +89,4 @@ The following describes how to use the uniform data structs to define a hyperlin } } } - ``` \ No newline at end of file + ``` diff --git a/en/application-dev/database/uniform-data-type-list.md b/en/application-dev/database/uniform-data-type-list.md index e77631474614507d82d892299718466bff6f3fb2..e79255723f6bbdbe6be0ce03af10ebd315f45560 100644 --- a/en/application-dev/database/uniform-data-type-list.md +++ b/en/application-dev/database/uniform-data-type-list.md @@ -43,15 +43,14 @@ Generic UTDs define universal data types that can be identified by a majority of | general.xwindowdump-image | general.image | .xwd | image/x-xwindowdump | X Window dump (XWD) image format. | | general.heif | general.image | .heif, .heifs, .hif | image/heif | High Efficiency Image File (HEIF) format. | | general.heic | general.image | .heic, .heics | image/heic | High Efficiency Image Container (HEIC) format. | -| general.jpeg-2000 | general.image | .jp2, .jpg2, .jpx, .jpf, .jpm | image/jp2, image/jpx, image/jpm | JPEG 2000 (JP2) file format.| -| general.ief-image | general.image | .ief | image/ief | Image exchange file format.| -| com.aol.art-image | general.image | .art | image/x-jg | ART file format| -| general.video | general.media | - | - | Generic video type. | +| general.jpeg-2000 | general.image | .jp2, .jpg2, .jpx, .jpf, .jpm | image/jp2, image/jpx, image/jpm | JPEG 2000 (JP2) file format.| +| general.ief-image | general.image | .ief | image/ief | Image exchange file format.| +| general.video | general.media | - | - | Generic video type. | | general.avi | general.video | .avi, .vfw | video/avi, video/msvideo, video/x-msvideo | Audio Video Interleave (AVI) video format. | | general.mpeg | general.video | .mpg, .mpeg, .m75, .m15,.mpe | video/mpg, video/mpeg, video/x-mpg, video/x-mpeg | MPEG-1 or MPEG-2 video format. | -| general.mpeg-4 | general.video | .mp4, .mpeg4 | video/mp4, video/mp4v | MPEG-4 video format. | +| general.mpeg-4 | general.video | .mp4, .mp4v, .mpeg4 | video/mp4, video/mp4v | MPEG-4 video format. | | general.3gpp | general.video | .3gp, .3gpp | video/3gpp | 3GPP video format. | -| general.3gpp2 | general.video | .3g2, .3gp2, .3gpp2 | video/3gpp2 | 3GPP2 video format. | +| general.3gpp2 | general.video | .3g2, .3gp2, .3gpp2 | video/3gpp2 | 3GPP2 video format. | | general.vob | general.video | .vob | video/mpeg, video/x-ms-vob | Video Object (VOB) format, a container format in DVD video media. | | general.dif-video | general.video | .dif | video/dv | DIF video format. | | general.dv-video | general.video | .dv | video/dv | DV video format. | @@ -59,13 +58,13 @@ Generic UTDs define universal data types that can be identified by a majority of | general.mng | general.video | .mng | video/x-mng | Multiple Network Graphics (NMG) format. | | general.mpegurl-video | general.video | .mxu, .m4u | video/vnd.mpegurl | Multimedia (video) playlist format. | | general.ts | general.video | .ts | video/mp2ts, video/mp2t | Video stream format using MPEG. | -| general.mp2t | general.video | .m2ts, .mts, .m2t | video/mp2t | Blu-ray Budav video in Ophil format.| -| general.mpeg-2 | general.video | .mpeg2, .mpv2, .mp2v, .m2v, .mpv | video/mpeg | MPEG-2 video format.| -| general.mpeg-1 | general.video | .mpeg1, .mpv1, .mp1v, .m1v | video/mpeg | MPEG-1 video format.| -| general.divx-video | general.video | .divx | video/divx | DivX-encoded video format.| -| general.ogv | general.video | .ogv | video/ogg | Ogg video format.| -| general.h264-video | general.video | .h264 | video/H264 | H.264 video format.| -| general.audio | general.media | - | - | Generic audio type. | +| general.mp2t | general.video | .m2ts, .mts, .m2t | video/mp2t | Blu-ray Disc Audio-Video (BDAV) format.| +| general.mpeg-2 | general.video | .mpeg2, .mpv2, .mp2v, .m2v, .mpv | video/mpeg | MPEG-2 video format.| +| general.mpeg-1 | general.video | .mpeg1, .mpv1, .mp1v, .m1v | video/mpeg | MPEG-1 video format.| +| general.divx-video | general.video | .divx | video/divx | DivX-encoded video format.| +| general.ogv | general.video | .ogv | video/ogg | Ogg video format.| +| general.h264-video | general.video | .h264 | video/H264 | H.264 video format.| +| general.audio | general.media | - | - | Generic audio type. | | general.ogg | general.audio | .ogg | audio/ogg | OGG audio format. | | general.aiff | general.audio | .aiff | audio/aiff | AIFF audio format. | | general.pcm | general.audio | .pcm | audio/pcm | PCM audio format. | @@ -134,6 +133,9 @@ Generic UTDs define universal data types that can be identified by a majority of | general.p7r | general.text | .p7r | application/x-pkcs7-certreqresp | Format of the file containing the response to a certificate request. | | general.pem | general.text | .pem | application/x-pem-file | Privacy-Enhanced Mail (PEM) format. | | general.log | general.text | .log | text/plain | Log file format. | +| general.tel | general.text | .tel | | Schematic information file type, such as files containing device packaging diagram, network topology, encoding information, and more. | +| general.ion | general.text | .ion | text/plain | File content description type. | +| general.conf | general.text | .conf | text/plain | Generic configuration file type. | | general.calendar | general.text | - | - | Generic calendar data type. | | general.vcs | general.calendar | .vcs | text/calendar | vCalendar format. | | general.ics | general.calendar | .ics | text/calendar | iCalendar format. | @@ -168,6 +170,8 @@ Generic UTDs define universal data types that can be identified by a majority of | general.json | general.script | .json | application/json | JSON format. | | general.yaml | general.script | .yaml, .yml | application/yaml | YAML format. | | general.shell-script | general.script | .sh, .command | text/x-shellscript | Shell script. | +| general.ets | general.script | .ets | | extended TypeScript source code format. | +| general.json5 | general.script | .json5 | | JSON5 file format. | | general.csh-script | general.shell-script | .csh | text/x-csh | C-shell script. | | general.perl-script | general.shell-script | .pl, .pm | text/x-perl-script | Perl script. | | general.python-script | general.shell-script | .py | text/x-python-script | Python script. | @@ -211,15 +215,17 @@ The system-specific UTDs are closely related to a platform or an operating syste | openharmony.atomic-service | general.object | - |- | Atomic service defined for OpenHarmony. | | openharmony.package | general.directory | - |- | Package defined for OpenHarmony. | | openharmony.hap | openharmony.package | .hap |- | Harmony Ability Package (HAP) defined for OpenHarmony. | +| openharmony.app | openharmony.package | .app |- | Application package type defined by the system. | | openharmony.hdoc | general.composite-object | .hdoc |- | Notepad file format defined for OpenHarmony. | | openharmony.hinote | general.composite-object | .hinote |- | Note file format defined for OpenHarmony. | | openharmony.styled-string | general.composite-object | - |- | String type defined for OpenHarmony. | | openharmony.moving-photo | general.media | - |- | Moving photo defined for OpenHarmony.| | openharmony.pixel-map | general.image | - |- | Pixel Map defined for OpenHarmony. | -| macos.dmg | general.disk-image | .dmg |- application/x-apple-diskimage | Installation package format defined by MacOS. | -| debian.deb | general.archive | .deb,.udeb | application/x-debian-package,application/vnd.debian.binary-package | Software package format defined by Debian. | -| com.android.apk | general.archive | .apk, .apks, .aab, .xapk, .apkm, .akp | application/vnd.android.package-archive | Android application installation package format. | -| redhat.rpm-archive | general.archive | .rpm | application/x-rpm | RedHat application installation package format. | +| macos.dmg | general.disk-image | .dmg | application/x-apple-diskimage | Installation package format defined by MacOS. | +| debian.deb | general.archive | .deb,.udeb | application/x-debian-package,application/vnd.debian.binary-package | Software package format defined by Debian. | +| com.android.apk | general.archive | .apk, .apks, .aab, .xapk, .apkm, .akp | application/vnd.android.package-archive | Android application installation package format. | +| redhat.rpm-archive | general.archive | .rpm | application/x-rpm | RedHat application installation package format. | +| com.huawei.hmos.settings.wifi | general.text | .hmoswifi | | Wi-Fi sharing configuration file format of HarmonyOS. | ## Application-specific UTDs Application-specific UTDs are defined and maintained by a specific application or organization, and the data interaction is identified by the specific application. The IDs of these type of UTDs are in the **com.***company-name*.xxx or **org.***organization-name*.xxx format. The following table lists the application-specific UTDs prebuilt in the system. @@ -394,6 +400,7 @@ Application-specific UTDs are defined and maintained by a specific application o | org.aomedia.avif-image | general.image | .avif | image/avif | AVIF image file format. | | com.google.webp | general.image | .webp | image/webp | WebP image file format. | | org.gimp.xcf | general.image | .xcf | application/x-xcf,image/x-xcf | GIMP image file format. | +| com.aol.art-image | general.image | .art | image/x-jg | ART file format| | com.real.realmedia | general.video | .rm | application/vnd.rn-realmedia | RealMedia file format. | | com.real.realmedia-vbr | general.video | .rmvb | application/vnd.rn-realmedia-vbr | RealMedia Variable Bitrate (RMVB) format.| | com.real.realvideo | general.video | .rv | video/x-pn-realvideo | RealVideo format.| @@ -457,12 +464,26 @@ Application-specific UTDs are defined and maintained by a specific application o | org.mozilla.xpinstall | general.archive | .xpi | application/x-xpinstall | Compressed archive format. | | com.ezbsystems.zipped-iso | general.disk-image | .isz | - | Format of the compressed ISO image in ZIP format. | | com.dbase.dbf | general.database | .dbf | application/dbf, application/dbase | Database file format. | -| com.youtube.video | general.video | .yt, .vt | video/vnd.youtube.yt | YouTube video format.| -| com.cisco.webex-video | general.video | .wrf | video/x-webex | WebEx Recording file format.| -| org.csiro.annodex | general.video | .axv | video/annodex | Annodex video format.| -| com.fujifilm.raf-raw-image | general.raw-image | .raf | image/x-fuji-raf | Fujifilm raw image format.| -| com.panasonic.rw2-raw-image | general.raw-image | .rw2, .raw | image/x-panasonic-raw | Panasonic raw image format.| -| com.pentax.pef-raw-image | general.raw-image | .pef | image/x-pentax-pef | Pentax Electronic format (PEF).| -| com.sumsung.srw-raw-image | general.raw-image | .srw | image/x-samsung-srw | Samsung raw image format.| -| com.epson.erf-raw-image | general.raw-image | .erf | image/x-epson-erf | Epson raw image format.| -| com.olympus.orf-raw-image | general.raw-image | .orf | image/x-olympus-orf | Olympus raw image format.| +| com.youtube.video | general.video | .yt, .vt | video/vnd.youtube.yt | YouTube video format.| +| com.cisco.webex-video | general.video | .wrf | video/x-webex | WebEx Recording file format.| +| org.csiro.annodex | general.video | .axv | video/annodex | Annodex video format.| +| com.fujifilm.raf-raw-image | general.raw-image | .raf | image/x-fuji-raf | Fujifilm raw image format.| +| com.panasonic.rw2-raw-image | general.raw-image | .rw2, .raw | image/x-panasonic-raw | Panasonic raw image format.| +| com.pentax.pef-raw-image | general.raw-image | .pef | image/x-pentax-pef | Pentax Electronic format (PEF).| +| com.sumsung.srw-raw-image | general.raw-image | .srw | image/x-samsung-srw | Samsung raw image format.| +| com.epson.erf-raw-image | general.raw-image | .erf | image/x-epson-erf | Epson raw image format.| +| com.olympus.orf-raw-image | general.raw-image | .orf | image/x-olympus-orf | Olympus raw image format.| +| org.w3.woff | general.font | .woff | font/woff | Web Open Font Format (WOFF).| +| org.sqlite.database | general.database | .sqlite, .sqlite3, .db, .db3, .s3db, .sl3 | application/vnd.sqlite3 | SQLite database format.| +| com.microsoft.pdb | general.database | .pdb | application/x-ms-pdb | Program database format.| +| com.monkeysaudio.ape-audio | general.audio | .pdb | audio/x-monkeys-audio | Monkey's audio format.| +| org.xiph.opus-audio | general.audio | .opus | audio/opus | Opus lossy audio encoding format.| +| com.microsoft.tlb | general.object | .tlb | | OLE library file format.| +| com.microsoft.catalog | general.object | .cat | | Windows catalog file format.| +| com.microsoft.vbscript | general.script | .vbs | application/x-vbs | VBScript format.| +| com.microsoft.sys | general.object | .sys | | Windows system file format.| +| com.microsoft.powershell-script | general.script | .ps1 | | Windows PowerShell script format.| +| com.microsoft.registry | general.database | .reg | | DOS batch file format.| +| com.microsoft.dos-batch | general.script | .bat | application/x-bat | Windows registry format.| +| com.microsoft.inf | general.text | .inf | text/plain | Setup information file format.| +| com.microsoft.sccd | general.xml | .sccd | | Signed Custom Capability Descriptor (SCCD) file format.| diff --git a/en/application-dev/device/driver/externaldevice-faqs.md b/en/application-dev/device/driver/externaldevice-faqs.md index 455d38bf83dabfbcd8ad04e23ccd39a85547ee24..4d918650b2b68e5c3a08ae8b155cd1e432d19c54 100644 --- a/en/application-dev/device/driver/externaldevice-faqs.md +++ b/en/application-dev/device/driver/externaldevice-faqs.md @@ -39,4 +39,4 @@ The message "code:9568347 error: install parse native so failed" is displayed du ### Solution -Configure the value of `abiFilters` in `buildOption/externalNativeOptions` in the `build-profile.json5` file. For details, see [Application Debugging] (https://developer.huawei.com/consumer/en/doc/harmonyos-faqs-V5/faqs-app-debugging-14-V5). +Configure the value of `abiFilters` in `buildOption/externalNativeOptions` in the `build-profile.json5` file. For details, see [Application Debugging](https://developer.huawei.com/consumer/en/doc/harmonyos-faqs-V5/faqs-app-debugging-14-V5). diff --git a/en/application-dev/device/driver/externaldevice-guidelines.md b/en/application-dev/device/driver/externaldevice-guidelines.md index 30bd692f6277a9584cfec6ed7d61748f5bb65b52..039a7158fb8b73b3710bf850cb327dae9a58e649 100644 --- a/en/application-dev/device/driver/externaldevice-guidelines.md +++ b/en/application-dev/device/driver/externaldevice-guidelines.md @@ -63,7 +63,7 @@ You can use the APIs to query and bind peripheral devices so as to use the custo The following sample code is a demo that illustrates how to develop both the client and server and implement IPC. -1. Create an OpenHarmony project. For details, see [Creating a Project] (https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V13/ide-create-new-project-V13). +1. Create an OpenHarmony project. For details, see [Creating a Project](https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V13/ide-create-new-project-V13). **NOTE** diff --git a/en/application-dev/device/input/interceptor-guidelines.md b/en/application-dev/device/input/interceptor-guidelines.md index fba28c7a64cc5f800b471c053e19ca951e904bc5..ae07ba750e1d58155a58ac702c747639d718afd4 100644 --- a/en/application-dev/device/input/interceptor-guidelines.md +++ b/en/application-dev/device/input/interceptor-guidelines.md @@ -22,7 +22,7 @@ The following table lists the APIs for event interception. For details, see [Inp Before calling interception-related APIs, you need to link the related dynamic library. You can do this by editing the **CMakeList.txt** file as follows: ```txt - target_link_libraries(entry PUBLIC libohinput.so) +target_link_libraries(entry PUBLIC libohinput.so) ``` ### Applying for Required Permissions diff --git a/en/application-dev/device/input/monitor-guidelines.md b/en/application-dev/device/input/monitor-guidelines.md index 5811871c50a2b13e8f02b5059ca6388bb542d905..5f274e29d05d54bdf0a13484f1c170b33d506831 100644 --- a/en/application-dev/device/input/monitor-guidelines.md +++ b/en/application-dev/device/input/monitor-guidelines.md @@ -28,7 +28,7 @@ The following table lists the APIs for event listening. For details, see [Input] Before calling interception-related APIs, you need to link the related dynamic library. You can do this by editing the **CMakeList.txt** file as follows: ```txt - target_link_libraries(entry PUBLIC libohinput.so) +target_link_libraries(entry PUBLIC libohinput.so) ``` ### Applying for Required Permissions diff --git a/en/application-dev/device/location/fenceExtensionAbility.md b/en/application-dev/device/location/fenceExtensionAbility.md new file mode 100644 index 0000000000000000000000000000000000000000..2ddbfac77ba8abc70f0d2a6612b3b439b1ed6490 --- /dev/null +++ b/en/application-dev/device/location/fenceExtensionAbility.md @@ -0,0 +1,93 @@ +# FenceExtensionAbility + +## Overview +[FenceExtensionAbility](../../reference/apis-location-kit/js-apis-app-ability-FenceExtensionAbility.md) is an ExtensionAbility of the geofence type. It enables you to efficiently implement geofencing functionalities. + +## When to Use + +1. Subscribe to geofence status change events through the [geoLocationManager.on('gnssFenceStatusChange')](../../reference/apis-location-kit/js-apis-geoLocationManager.md#geolocationmanagerongnssfencestatuschange) API of the location service, and pass the FenceExtensionAbility parameters in the **want** parameter. +2. After the event is triggered, the system reports the geofence event and data through the **onFenceStatusChange** API. Based on the event received, the application can perform corresponding service processing, for example, sending notifications. + +## Available APIs +For details about the APIs, see [FenceExtensionAbility](../../reference/apis-location-kit/js-apis-app-ability-FenceExtensionAbility.md). +| Available APIs| Description| +| ---- | ---- | +| onFenceStatusChange(transition: geoLocationManager.GeofenceTransition, additions: Record<string, string>): void | Callback invoked when a geofence status change event is received. Service processing is then performed based on the event type and data.| +| onDestroy(): void | Callback invoked when a FenceExtensionAbility destruction event is received.| + +## How to Develop + +### Implementing a FenceExtensionAbility + +Implement the capability of the [FenceExtensionAbility](../../reference/apis-location-kit/js-apis-app-ability-FenceExtensionAbility.md) provider. + +To manually create a FenceExtensionAbility in a project in DevEco Studio, perform the following steps: + +1. In the **ets** directory of a module in the project, right-click and choose **New > Directory** to create a directory named **fenceextensionability**. +2. Right-click the **fenceextensionability** directory, and choose **New > File** to create a file named **MyFenceExtensionAbility.ets**. +3. Open the **MyFenceExtensionAbility.ets** file and import its dependencies. Customize a class that inherits from **FenceExtensionAbility** and implement the **onFenceStatusChange** and **onDestroy** APIs. + +The sample code is as follows: + +```ts +import { FenceExtensionAbility, geoLocationManager } from '@kit.LocationKit'; +import { notificationManager } from '@kit.NotificationKit'; +import { Want, wantAgent } from '@kit.AbilityKit'; + +export class MyFenceExtensionAbility extends FenceExtensionAbility { + onFenceStatusChange(transition: geoLocationManager.GeofenceTransition, additions: Record): void { + // Receive the geofence status change event and process the service logic. + console.info(`on geofence transition,id:${transition.geofenceId},event:${transition.transitionEvent},additions:${JSON.stringify(additions)}`); + + // Send a geofence notification. + let wantAgentInfo: wantAgent.WantAgentInfo = { + wants: [ + { + bundleName: 'com.example.myapplication', + abilityName: 'EntryAbility', + parameters: + { + "geofenceId": transition?.geofenceId, + "transitionEvent": transition?.transitionEvent, + } + } as Want + ], + actionType: wantAgent.OperationType.START_ABILITY, + requestCode: 100 + }; + wantAgent.getWantAgent(wantAgentInfo).then((wantAgentMy) => { + let notificationRequest: notificationManager.NotificationRequest = { + id: 1, + content: { + notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT, + normal: { + title: `Geofence Notification`, + text: `on geofence transition,id:${transition.geofenceId},event:${transition.transitionEvent},additions:${JSON.stringify(additions)}`, + } + }, + notificationSlotType: notificationManager.SlotType.SOCIAL_COMMUNICATION, + wantAgent: wantAgentMy + }; + notificationManager.publish(notificationRequest); + }); + } +} +``` + +4. Register the FenceExtensionAbility in the [module.json5 file](../../quick-start/module-configuration-file.md) of the module in the project. Set **type** to **"fence"** and **srcEntry** to the code path of the FenceExtensionAbility component. + +```json +{ + "module": { + "extensionAbilities": [ + { + "name": "MyFenceExtensionAbility", + "srcEntry": "./ets/fenceExtensionability/MyFenceExtensionAbility.ets", + "description": "MyFenceExtensionAbility", + "type": "fence", + "exported": true + }, + ] + } +} +``` diff --git a/en/application-dev/device/location/location-guidelines.md b/en/application-dev/device/location/location-guidelines.md index d6e313cfdbe00e973998e82179d669a271565a79..9c70e7bff59b3bcc3e0b2e839b223991184c29fd 100644 --- a/en/application-dev/device/location/location-guidelines.md +++ b/en/application-dev/device/location/location-guidelines.md @@ -10,6 +10,8 @@ Real-time location of the device is recommended for location-sensitive services. The following table lists the APIs used to obtain the device location information. For details, see (../../reference/apis-location-kit/js-apis-geoLocationManager.md). +This module supports only the WGS-84 coordinate system. + **Table 2** APIs for obtaining device location information | API| Description| @@ -19,6 +21,7 @@ The following table lists the APIs used to obtain the device location informatio | [getCurrentLocation(request: CurrentLocationRequest | SingleLocationRequest, callback: AsyncCallback<Location>): void](../../reference/apis-location-kit/js-apis-geoLocationManager.md#geolocationmanagergetcurrentlocation) | Obtains the current location. This API uses an asynchronous callback to return the result. | | [getCurrentLocation(request?: CurrentLocationRequest | SingleLocationRequest): Promise<Location>](../../reference/apis-location-kit/js-apis-geoLocationManager.md#geolocationmanagergetcurrentlocation-2) | Obtains the current location. This API uses a promise to return the result. | | [getLastLocation(): Location](../../reference/apis-location-kit/js-apis-geoLocationManager.md#geolocationmanagergetlastlocation) | Obtains the last known device location.| +| [isLocationEnabled(): boolean](../../reference/apis-location-kit/js-apis-geoLocationManager.md#geolocationmanagerislocationenabled) | Checks whether the location switch is enabled.| ## How to Develop @@ -29,7 +32,20 @@ The following table lists the APIs used to obtain the device location informatio ```ts import { geoLocationManager } from '@kit.LocationKit'; ``` -3. Obtain the current location of the device. It is mainly used in scenarios such as viewing of the current location, signing in/out, and service recommendation. +3. Call **isLocationEnabled** to check whether the location switch is enabled. + The return result is a Boolean value. The value **true** indicates that the location switch is enabled, and the value **false** indicates the opposite. + + ```ts + import { geoLocationManager } from '@kit.LocationKit'; + try { + let locationEnabled = geoLocationManager.isLocationEnabled(); + } catch (err) { + console.error("errCode:" + err.code + ", message:" + err.message); + } + ``` + If the location switch is not enabled, launch a dialog box asking the user to enable the switch. For details, see [Setting the Global Switch](../../reference/apis-ability-kit/js-apis-abilityAccessCtrl.md#requestglobalswitch12). + +4. Obtain the current location of the device. It is mainly used in scenarios such as viewing of the current location, signing in/out, and service recommendation. - Method 1: Obtain the latest location in the system cache.
If the system does not have a cached location, an error code is returned.
Using this API to obtain the device location can reduce the system power consumption.
@@ -74,7 +90,11 @@ The following table lists the APIs used to obtain the device location informatio console.error("errCode:" + JSON.stringify(err)); } ``` -4. Obtain the device location continuously. It is mainly used in scenarios such as navigation, movement track, and travel.
+ The coordinates obtained by this module are in the WGS-84 coordinate system. If you need to use coordinates in other coordinate systems, perform a coordinate system conversion. + + You can use the SDK capabilities provided by a third-party map to implement coordinate system conversion. + +5. Obtain the device location continuously. It is mainly used in scenarios such as navigation, movement track, and travel.
Instantiate a [ContinuousLocationRequest](../../reference/apis-location-kit/js-apis-geoLocationManager.md#continuouslocationrequest12) object to notify the system of the type of location service to be provided for applications and the interval for reporting location information.
- Set the location scenario by using **locationScenario**.
You are advised to set **locationScenario** based on the application scenario. For details about the enum values of this parameter, see [UserActivityScenario](../../reference/apis-location-kit/js-apis-geoLocationManager.md#useractivityscenario12). For example, if **locationScenario** is set to **NAVIGATION**, the application will obtain the device location in both the indoor and outdoor scenarios for navigation.
diff --git a/en/application-dev/dfx/Readme-EN.md b/en/application-dev/dfx/Readme-EN.md index 1e6ff23a313e18af61594731d2e685a97c7f6d8e..c80b33810b2c00bc502084882ad0992ecb9e5ee5 100644 --- a/en/application-dev/dfx/Readme-EN.md +++ b/en/application-dev/dfx/Readme-EN.md @@ -47,13 +47,13 @@ - [Using HiDebug (ArkTS)](hidebug-guidelines-arkts.md) - [Using HiDebug (C/C++)](hidebug-guidelines-ndk.md) - HiCollie - - [Using HiCollie (C/C++)](hicollie-guidelines-ndk.md) + - [Using HiCollie to Detect Service Thread Stuck and Jank Events](hicollie-guidelines-ndk.md) - Error Management - [Development of Error Manager](errormanager-guidelines.md) - [Development of Application Recovery](apprecovery-guidelines.md) - Fault Analysis - - [Analyzing JSCrash](jscrash-guidelines.md) - - [Analyzing CppCrash](cppcrash-guidelines.md) + - [Analyzing JS Crash](jscrash-guidelines.md) + - [Analyzing CPP Crash](cppcrash-guidelines.md) - [Analyzing AppFreeze](appfreeze-guidelines.md) - Command Line Tools - [hdc](hdc.md) @@ -65,3 +65,4 @@ - [hisysevent](hisysevent.md) - [uinput](uinput.md) + diff --git a/en/application-dev/dfx/appfreeze-guidelines.md b/en/application-dev/dfx/appfreeze-guidelines.md index de94c98719446b39bcf25b235629fb20ec3dacb2..3be38bab852313df906ccd27f1141755e2c72561 100644 --- a/en/application-dev/dfx/appfreeze-guidelines.md +++ b/en/application-dev/dfx/appfreeze-guidelines.md @@ -83,7 +83,7 @@ Version:1.0.0 Pid:1561 Uid:20010039 Reason:LIFECYCLE_TIMEOUT -sysfreeze: LIFECYCLE_TIMEOUT LIFECYCLE_TIMEOUT at 20230317170653 +sysfreeze:LIFECYCLE_TIMEOUT LIFECYCLE_TIMEOUT at 20230317170653 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DOMAIN:AAFWK STRINGID:LIFECYCLE_TIMEOUT @@ -102,12 +102,12 @@ General information is present in all the aforementioned logs. It contains the f | Field| Description| | -------- | -------- | | EVENTNAME | One or more fault events that constitute the cause of main thread freeze event.| -| TIMESTAMP | Time when the fault event reported. You can narrow down the time range to view HiLog logs based on the timeout duration described in [AppFreeze Detection](#appfreeze-detection).| +| TIMESTAMP | Time when the fault event is reported. You can narrow down the time range to view HiLog logs based on the timeout duration described in [AppFreeze Detection](#appfreeze-detection).| | PID | PID of the failed process, which can be used with the timestamp and timeout duration to search for related process information in the Hilog logs.| | PACKAGE_NAME | Application process package name.| | MSG | Dump information or description of the fault.| | BinderCatcher | Information about IPC calls between a process and other system processes, such as the call waiting time.| -| PeerBinder Stacktrace | Information about stack trace of the peer process.| +| PeerBinder Stacktrace | Stack trace information of the peer process.| | cpuusage | CPU usage of the device.| | memory | Memory usage of the process.| @@ -130,12 +130,12 @@ The task information in the main thread queue includes: Locate the application stack information by searching for the **PID**. In the following stack, the window stays in the IPC communication phase when it sends events to the system through the IPC. ``` -OpenStacktraceCatcher -pid==1561 packageName is com.ohos.huawei.myapplication +OpenStacktraceCatcher -pid==1561 packageName is com.example.myapplication Result: 0 ( no error ) Timestamp:2017-08-0817:06:53.000 Pid:1561 Uid:20010039 -Process name:com.ohos.huawei.myapplication +Process name:com.example.myapplication Tid:1561,Name:i.myapplication #00 pc 0017888c /system/lib/libark_jsruntime.so #01 pc 00025779 /system/lib/platformsdk/libipc_core.z.so(OHOS:BinderConnector:WriteBinder(unsigned Long,void*)+56) @@ -155,7 +155,7 @@ Tid:1561,Name:i.myapplication #15 pc 0045dd4b /system/lib/libace.z.so #16 pc 00d24fef /system/lib/libace.z.so #17 pc 0041e6e9 /system/lib/libace.z.so -#18 pc 0000b4d9 /system/lib/platformsdk/libeventhandler.z.so(OHOS:AppExecFwk:EventHandler:DistributeEvent(std::__h:unique_ptr<0 #19 pc 00012829 /system/lib/platformsdk/libeventhandler.z.so +#18 pc 0000b4d9 /system/lib/platformsdk/libeventhandler.z.so(OHOS:AppExecFwk:EventHandler:DistributeEvent(std::__h:unique_ptr<0 #19 pc 00012829 /system/lib/platformsdk/libeventhandler.z.so)) #20 pc 00011841 /system/lib/platformsdk/libeventhandler.z.so(OHOS:AppExecFwk:EventRunner:Run()+64) #21 pc 00054a8b /system/lib/libappkit_native.z.so(OHOS:AppExecFwk:MainThread:Start()+278) #22 pc 00011503 /system/bin/appspawn @@ -174,7 +174,8 @@ PeerBinderCatcher -pid==1561 Layer_==0 BinderCatcher -- - 1561::1561t0685:0c0de0Wait:10.366245919s 1329::1376t0487:794c0de0Wait:0.12070041s + 1561:1561 to 685:0 code 0 Wait:10.366245919 s + 1329:1376 to 487:794 code 0 Wait:0.12070041 s pid context request started max ready free_async_space 1561 binder 0 3 16 4 520192 @@ -209,7 +210,7 @@ Tid:658,Name:wifi_manager_service #08 pc 0002666f /system/lib/platformsdk/libipc_core.z.so(OHOS:BinderInvoker:StartWorkLoop()+18) #09 pc 000270a9 /system/lib/platformsdk/libipc_core.z.so(OHOS:BinderInvoker:JoinThread(bool)+32) #10 pc 00023783 /system/lib/platformsdk/libipc_core.z.so(OHOS:IPCWorkThread:ThreadHandler(void*)+290) -#11 pc 0007b4d9 /system/lib/platformsdk/libeventhandler.z.so(OHOS:AppExecFwk:EventHandler:DistributeEvent(std::__h:unique_ptr,panda + #02 pc 0024b4bb /system/lib/libark_jsruntime.so #03 pc 00fbed23 /system/lib/libace.z.so #04 pc 00d8208f /system/lib/libace.z.so ... @@ -317,8 +318,8 @@ TIMESTAMP = 2017/08/08-17:06:27:292 PID = 1561 UID = 20010039 TID = 1566 -PACKAGE_NAME com.ohos.huawei.myapplication -PROCESS NAME com.ohos.huawei.myapplication eventLog_action cmd:c,cmd:m,tr,k:SysRqFile +PACKAGE_NAME com.example.myapplication +PROCESS NAME com.example.myapplication eventLog_action cmd:c,cmd:m,tr,k:SysRqFile eventLog_interval 10 MSG = App main thread is not response!EventHandler dump begin curTime:2017-08-08 05:06:27.291 Event runner (Thread name =Thread ID =1561)is running @@ -338,9 +339,9 @@ MSG = App main thread is not response!EventHandler dump begin curTime:2017-08-08 Timestamp:2017-08-0817:0k:27,4142447784 Pid:1561 Uid:20010039 -Process name:com.ohos.huawei.myapplication +Process name:com.example.myapplication Tid:1561 Name:i.myapplication - at anonymous (D:/project/OpenHarmony0S/MyApplication_test/entry/build/default/intermediates/loader_out/default/ets/pages/Index_.js:0:1) + at anonymous entry (D:/project/MyApplication_test/entry/build/default/intermediates/loader_out/default/ets/pages/Index_.js:0:1) #00 pc 00178dcc /system/lib/libark_jsruntime.so #01 pc 00177ebb /system/lib/libark_jsruntime.so #02 pc 0024b4bb /system/lib/libark_jsruntime.so(panda:FunctionRef:Call(panda:ecmascript:EcmaVM const*,panda:Local,par @@ -351,7 +352,7 @@ Tid:1561 Name:i.myapplication Check the code being executed on the application side based on the Hilog log. -Generally, you can view the [General Information in the Log Body](#general-information-in-the-log-body) to determine the cause of an appfreeze event, including peer communication suspension, high CPU usage, memory leakage, or a large amount of memory. +Generally, you can view the [General Information in the Log Body](#general-information-in-the-log-body) to determine the cause of an appfreeze event, including peer communication suspension, high CPU usage, memory leaks, or a large amount of memory. ### Specific Information in the Log Body (User Input Response Timeout) @@ -363,7 +364,7 @@ For details, see [General Information in the Log Body](#general-information-in-t ### Specific Information in the Log Body (Lifecycle Switching Timeout) -Similar to **THREAD_BLOCK**, **LIFECYCLE_TIMEOUT** consists of two parts, namely **LIFECYCLE_HALF_TIMEOUT** and **LIFECYCLE_TIMEOUT**. +**LIFECYCLE_TIMEOUT** consists of two events, namely **LIFECYCLE_HALF_TIMEOUT** and **LIFECYCLE_TIMEOUT**. **MSG** indicates the lifecycle that encounters a timeout. @@ -377,8 +378,8 @@ STRINGID:LIFECYCLE TIMEOUT TIMESTAMP:2023/03/10-17:06:53:65 PID:1561 UID:20010039 -PACKAGE_NAME:com.ohos.huawei.myapplication -PROCESS_NAME:com.ohos.huawei.myapplication +PACKAGE_NAME:com.example.myapplication +PROCESS_NAME:com.example.myapplication MSG:ability:EntryAbility background timeout ``` @@ -400,7 +401,7 @@ To locate an appfreeze event, you need to obtain related logs such as fault logs ### Obtaining the Log -The appfreeze log is managed together with the native process crash, JS application crash, and system process crash logs in the FaultLogger module. You can obtain the log in any of the following ways. +The appfreeze log is managed together with the native process crash, JS application crash, and system process crash logs in the FaultLog module. You can obtain the log in any of the following ways. - Method 1: DevEco Studio @@ -420,17 +421,17 @@ The appfreeze log is managed together with the native process crash, JS applicat ### Confirming Basic Information -#### Obtain basic information such as the process ID of the freeze application and whether the application is in the foreground +#### Obtain basic information such as the process ID of the freeze application and whether the application is in the foreground. ``` Generated by HiviewDFX@OpenHarmony ============================================================ Device info:HUAWEI Mate 60 Pro Build info:ALN-AL00 x.x.x.xx(XXXXXXX) -Fingerprint: ef8bd28f8b57b54656d743b546efa73764c77866a65934bd96f2678f886813b7 +Fingerprint:ef8bd28f8b57b54656d743b546efa73764c77866a65934bd96f2678f886813b7 Module name:com.xxx.xxx Version:1.2.2.202 -VersionCode: 1002002202 +VersionCode:1002002202 PreInstalled:Yes Foreground:No --> Indicates that the application is not in the foreground. Pid:15440 @@ -464,9 +465,12 @@ Detection durations for different faults in different scenarios: |Foreground application: 6s
Background application: 3s * 5 + 6s = 21s| 5s | Load: 10s
Active: 5s
Inactive: 0.5s
Terminate: 10s
Connect: 3s
Disconnect: 0.5s
Restart: 5s
Foreground: 5s
Background: 3s| **NOTE** -1. The detection duration of **THREAD_BLOCK_3S** or **LIFECYCLE_HALF_TIMEOUT** is half of that of **THREAD_BLOCK_6S** or **LIFECYCLE_TIMEOUT**. **THREAD_BLOCK_3S** and **LIFECYCLE_HALF_TIMEOUT** are warnings and do not report logs independently. **THREAD_BLOCK_6S** and **LIFECYCLE_TIMEOUT** are errors and report logs with the corresponding warning. -2. If **THREAD_BLOCK_3S** occurs in the foreground application, **THREAD_BLOCK_6S** will be triggered. -3. The value of **backgroundReportCount_** is **0**. When **THREAD_BLOCK_3S** occurs for five consecutive times (the count is not cleared), the **THREAD_BLOCK_6S** event is reported. Consequently, the detection durations of **THREAD_BLOCK_3S** and **THREAD_BLOCK_6S** are 18s and 21s respectively. + +1. The detection duration of **THREAD_BLOCK_3S** is half that of **THREAD_BLOCK_6S**, while **LIFECYCLE_HALF_TIMEOUT** is half that of **LIFECYCLE_TIMEOUT**. **THREAD_BLOCK_3S** and **LIFECYCLE_HALF_TIMEOUT** are warnings and do not report logs independently. **THREAD_BLOCK_6S** and **LIFECYCLE_TIMEOUT** are errors and report logs with the corresponding warning. + +2. When **THREAD_BLOCK_3S** occurs in the foreground application, **THREAD_BLOCK_6S** will be triggered. + +3. In the background application, when **THREAD_BLOCK_3S** occurs for five consecutive times (the value of **backgroundReportCount_** is **5**), the **THREAD_BLOCK_6S** event is reported. Consequently, the detection durations of **THREAD_BLOCK_3S** and **THREAD_BLOCK_6S** are 18s and 21s respectively. The fault occurrence time can be obtained based on the detection duration and the fault reporting time. @@ -485,7 +489,9 @@ mainHandler dump is: ``` Running duration of the current task = dump begin curTime – trigger time. In this example, the running duration of the current task is 27s. + If the task running duration is longer than the fault detection duration, the running task causes the application freeze event. In this case, you need to check the task. + If the current task running duration is short, the task is only one of the tasks running in the main thread within the detection duration and may not be the task that consumes most time. You are advised to check the task that consumes the longest time recently (in **History event queue information**). In this case, the watchdog cannot be scheduled because the thread is busy. 2. History event queue information @@ -540,6 +546,7 @@ To ensure timely response to the user, all tasks in the user input event propaga The watchdog task is in the priority queue, which is sent every 3 seconds. Compare the movements of the watchdog task in the queue of the warning and block events. + warning: ``` High priority event queue information: @@ -627,7 +634,7 @@ Tid:14727, Name:xxx # 10 pc 00000000000b4214 /system/lib64/platformsdk/libnative_rdb.z.so(OHOS::NativeRdb::SqliteSharedResultSet::ExecuteForSharedBlock(OHOS::AppDataFwk::SharedBlock*, int, int, bool)+236)(5e8443def4695e8c791e5f847035ad9f) ``` -Based on the trace information, check whether the called function of stack top times out. +Based on [Analyzing Trace Logs](#analyzing-trace logs), check whether the execution of the function at stack top times out. 4. The stack is a temporary stack, and the warning stack is not the same as the error stack. @@ -665,11 +672,11 @@ Tid:3108, xxx # 10 pc 00000000002d6e14 /system/lib64/module/arkcompiler/stub.an(RTStub_AsmInterpreterEntry+208) ``` -In this case, the stacks are irregular because they are captured during thread running, which indicates that the thread is not suspended. If the thread is busy, analyze and optimize the application based on the trace and hilog logs. +In this case, the stacks are irregular because they are captured during thread running, which indicates that the thread does not freezes. If the thread is busy, analyze and optimize the application based on [Analyzing Trace Logs](#analyzing-trace logs) and hilog logs. ### Viewing Binder Information -Obtain the Binder information after the warning event if it occurs, otherwise, obtain the Binder information after the block event. +Obtain the binder information after the warning event if it occurs, otherwise, obtain the binder information after the block event. 1. Obtain the Binder information. @@ -719,10 +726,10 @@ In this case, you can check the following items: 4. Check whether there is no calling relationship and whether the stack is an IPC stack. -Check whether the stack is a temporary stack, that is, whether the warning stack is the same as the error stack. It is possible that the warning stack is an IPC stack, and the block stack is a temporary stack because the IPC request has ended when the binder is captured, and the IPC request takes a short time. +Check whether the stack is a temporary stack, that is, whether the warning stack is the same as the block stack. It is possible that the warning stack is an IPC stack, and the block stack is a temporary stack because the IPC request has ended when the binder is captured, and the IPC request takes a short time. It should be noted that binder information is not obtained in real time when a fault occurs and is delayed. For faults that require half-period detection, binder information is accurately captured because most binder information can be collected within the fault period. For other faults, the off-site binder information may be captured when the reporting is delayed. -You can view the execution duration of the binder based on the trace. +You can view the execution duration of binder based on [Analyzing Trace Logs](#analyzing-trace logs). ### Analyzing Hilog logs @@ -750,7 +757,7 @@ You can view the execution duration of the binder based on the trace. #### Procedure -View [Obtain the fault occurrence time](#obtain-the-fault-occurrence-time), and determine the fault occurrence time based on the fault type. Analyze the hilog log in the specific period to obtain the status of the running thread. +View [Obtain the fault occurrence time](#obtain-the-fault-occurrence-time), and determine the fault occurrence time based on the fault type. Analyze the HiLog logs in the specific period to obtain the status of the running thread. - If no application log is printed, the application is frozen when the logging API is invoked. @@ -774,13 +781,13 @@ View [Obtain the fault occurrence time](#obtain-the-fault-occurrence-time), and The possible causes are as follows: -1. The duration of each service is not long, but the number of services is too large.Therefore, the process runs intensively in a long period of time and occupies the main thread. +1. The duration of each service is not long, but the number of services is too large. Therefore, the process runs intensively in a long period of time and occupies the main thread. ![appfreeze_2024061409](figures/appfreeze_2024061409.png) ![appfreeze_2024061410](figures/appfreeze_2024061410.png) -In the preceding figure, the **ohos.animator** in **PriviewArea::updateShotComponent** is executed for 9.2s. +In the preceding figure, the **animator** in **PriviewArea::updateShotComponent** is executed for 9.2s. The thread is busy executing a service cyclically and analyzing each service segment. @@ -800,7 +807,7 @@ In the preceding figure, the execution duration of **OHOS::AppExecFwk::FormMgrAd #### Background -The xxx service reports the appfreeze crash **THREAD_BLOCK_6S**. +The xxx service reports the appfreeze problem **THREAD_BLOCK_6S**. #### Error Codes @@ -821,18 +828,18 @@ int xxx() #### Impact -The background application is suspended and related functions are unavailable, but it is imperceptible to the user. +The background application freezes and related functions are unavailable, but it is imperceptible to the user. #### Fault Locating Extract the key fault logs. ``` -appfreeze: com.huawei.hmsapp.xxx THREAD_BLOCK_6S at 20240408082432 +appfreeze: com.example.hmsapp.xxx THREAD_BLOCK_6S at 20240408082432 DisplayPowerInfo:powerState:AWAKE ``` -The value of **Foreground** indicates that **hiai** is a background application. Therefore, it can be inferred that when the 3s event is reported, the background application is suspended for **18s**. +The value of **Foreground** indicates that the application is a background application. Therefore, it can be inferred that when the 3s event is reported, the background application is frozen for 18s. ``` Module name:com.xxx.xxx.xxx @@ -868,7 +875,7 @@ PACKAGE_NAME = com.xxx.xxx.xxx PROCESS_NAME = com.xxx.xxx.xxx ``` -When the **THREAD_BLOCK_3S** event is reported, the **EventHandler** is captured at **08:24:29.413**. The cause is as expected: "App main thread is not response!" The main thread does not respond. The running task is send at **08:24:01.514**. +When the **THREAD_BLOCK_3S** event is reported, the **EventHandler** is captured at **08:24:29.413**. The cause is as expected: "App main thread is not response!" The main thread does not respond. The running task is sent at **08:24:01.514**. ``` MSG = @@ -880,11 +887,11 @@ mainHandler dump is: Current Running: start at 2024-04-08 08:24:01.514, Event { send thread = 43675, send time = 2024-04-08 08:24:01.514, handle time = 2024-04-08 08:24:01.514, task name = uvLoopTask } ``` -The watchdog task is in the high priority event queue. As shown in the following figure, a task is thrown to the main thread every 3 seconds, which is as expected. +The watchdog task is in **High priority event queue**. As shown in the following figure, a task is thrown to the main thread every 3 seconds, which is as expected. The queue of **THREAD_BLOCK_3S** is similar to that of **THREAD_BLOCK_6S**, with one more event in the queue of **THREAD_BLOCK_6S**. -The earliest event is send at **08:24:11.388**, which is 18s earlier than the report time **08:24:29:612** as expected. +The earliest event is sent at **08:24:11.388**, which is 18s earlier than the report time **08:24:29:612** as expected. ``` High priority event queue information: @@ -897,11 +904,11 @@ The earliest event is send at **08:24:11.388**, which is 18s earlier than the re No.7 : Event { send thread = 43679, send time = 2024-04-08 08:24:29.412, handle time = 2024-04-08 08:24:29.412, id = 1, caller = [watchdog.cpp(Timer:139)] } ``` -To sum up, the main thread of the application starts to run this task at **08:24:01.514**. The first **THREAD_BLOCK_3S** event occurs at **08:24:11.388**, and the application is suspended at about **08:24:11**. +To sum up, the main thread of the application starts to run this task at **08:24:01.514**. The first **THREAD_BLOCK_3S** event occurs at **08:24:11.388**, and the application freezes at about **08:24:11**. View the main thread stack at **xxx_request_client.so -> libsamgr_proxy.z.so -> libipc_core.z.so(OHOS::BinderConnector::WriteBinder)**. -The main thread initiates an IPC request, but the peer process does not response. As a result, the process is suspended, as shown in the following stack. +The main thread initiates an IPC request, but the peer process does not respond. As a result, the process freezes, as shown in the following stack. ``` Tid:43675, Name:xxx @@ -927,7 +934,7 @@ Tid:43675, Name:xxx # 19 pc 0000000000002944 xxx_rpc_client.so(xxx::xxx::RpcRequestClient::RpcRequestClient()+224)(02343ed2fff69759d408b23eaf69fcde) ``` -Check the binderCatcher. The main thread **43675** is communicating with process **979** and the **BinderCatcher** is suspended for 27s. +Check **BinderCatcher**. The main thread **43675** is communicating with process **979** and the **BinderCatcher** waits for 27s. ``` PeerBinderCatcher -- pid==43675 layer_ == 1 @@ -973,7 +980,7 @@ Tid:979, Name:xxxserver # 13 pc 00000000000a3b58 /system/lib/ld-musl-aarch64.so.1(libc_start_main_stage2+64)(91b804d2409a13f27463debe9e19fb5d) ``` -The error code can be located by decompiling, and the use of the lock can be checked based on the context. +Decompile the code to locate the error line and check the lock based on the context. #### Solution @@ -1009,15 +1016,15 @@ Adjust the lock properly based on the context. #### Suggestions -1. Pay special attention to the timing and deadlock events during multi-thread interaction. +1. Pay special attention to the timing and deadlock issues during multi-thread interaction. ### Typical Case of **APP_INPUT_BLOCK** - Full Component Update #### Background -When the theme is switched, the system is suspended, and the appfreeze fault of the sceneboard is reported. +When the theme is switched, the system freezes, and the appfreeze problem of sceneboard is reported. -This appfreeze fault occurs when the thread is busy. +This appfreeze problem occurs because the thread is too busy. #### Error Codes @@ -1043,7 +1050,7 @@ which severely affect user experience. Extract the key fault logs. ``` -appfreeze: com.ohos.sceneboard APP_INPUT_BLOCK at 20240319022527 +appfreeze: com.example.sceneboard APP_INPUT_BLOCK at 20240319022527 DisplayPowerInfo:powerState:AWAKE ``` @@ -1055,12 +1062,12 @@ STRINGID:APP_INPUT_BLOCK TIMESTAMP:2024/03/14-14:40:59:440 --> Fault report time. PID:2918 UID:20020017 -PACKAGE_NAME:com.ohos.sceneboard -PROCESS_NAME:com.ohos.sceneboard +PACKAGE_NAME:com.example.sceneboard +PROCESS_NAME:com.example.sceneboard ``` -The reported cause: "User input does not respond!" There is no response to the user input event. -The running task of the main thread (TID = PID) starts at **14:40:53.499** and is not complete until the **Fault time** **14:40:58**. +The reported cause is "User input does not respond!". +The running task of the main thread (Thread ID == PID) starts at **14:40:53.499** and is not complete until the **Fault time** **14:40:58**. ``` MSG = @@ -1072,9 +1079,9 @@ mainHandler dump is: Current Running: start at 2024-03-14 02:40:53.499, Event { send thread = 2918, send time = 2024-03-14 02:40:53.499, handle time = 2024-03-14 02:40:53.499, task name = } ``` -User input events need to be responded immediately. Therefore, user input events are in the high priority event queue, together with the watchdog tasks. +User input events need to be responded immediately. Therefore, they are in the high priority event queue, together with the watchdog tasks. -In the following example, more than 200 input events are blocked in the queue and are not processed. +In the following example, more than 200 input events are blocked in the queue. ``` High priority event queue information: @@ -1108,10 +1115,10 @@ In the following example, more than 200 input events are blocked in the queue an The input event triggers the main thread task of the application. However, the execution is not complete within 6 seconds and no response is returned. As a result, the ANR times out. In this case, you only need to find out the task that the input triggers and why the task execution times out. -In the running main thread stack, the **ark_jsruntime GetCurrentThreadId** function at the stack top is not lock blocking or time-consuming. The captured stack is a transient stack that is useless for analysis. +In the running main thread stack, the **ark_jsruntime GetCurrentThreadId** function at the stack top does not hold a lock or is time-consuming. The captured stack is a transient stack that is useless for analysis. ``` -Tid:2918, Name:ohos.sceneboard +Tid:2918, Name:example.sceneboard # 00 pc 000000000009f73c /system/lib/ld-musl-aarch64.so.1(8fa55898166cd804dad43d909b5319cc) # 01 pc 000000000054b7b4 /system/lib64/platformsdk/libark_jsruntime.so(panda::os::thread::GetCurrentThreadId()+12)(7715646e48f750f3dc31e660b056eb43) # 02 pc 00000000002107a4 /system/lib64/platformsdk/libark_jsruntime.so(panda::ecmascript::EcmaVM::CheckThread() const+200)(7715646e48f750f3dc31e660b056eb43) @@ -1132,7 +1139,7 @@ Tid:2918, Name:ohos.sceneboard Check the Hilog logs. -The **APP_INPUT_BLOCK** event is reported at about **13:40:59.448**, and then the DFX kills the suspended SCB. +The **APP_INPUT_BLOCK** event is reported at about **13:40:59.448**, and then DFX kills the freezed SCB. ![appfreeze_2024061412](figures/appfreeze_2024061412.png) @@ -1140,7 +1147,7 @@ The **APP_INPUT_BLOCK** event is reported at about **13:40:59.448**, and then th ![appfreeze_2024061413](figures/appfreeze_2024061413.png) -Within the 6 seconds, a large number of SCB logs are printed, showing that the SCB is re-rendering. +Within the 6 seconds, a large number of SCB logs are printed, showing that the SCB is re-rendered. ![appfreeze_2024061414](figures/appfreeze_2024061414.png) @@ -1168,9 +1175,9 @@ Trigger the home screen component refresh only when the home screen component st #### Suggestions -The scope of page refresh triggered by a click event needs to be properly controlled. Avoid scenarios such as a large number of components need to be refreshed or a page needs to be refreshed frequently. +Minimize the scope of page refresh triggered by a click event. Avoid scenarios where a large number of components need to be refreshed or a page needs to be refreshed frequently. -### Typical Case of **LIFECYCLE_TIMEOUT** - Loading a Cloud Diagram +### Typical Case of **LIFECYCLE_TIMEOUT** - Loading a Cloud Image #### Background @@ -1178,7 +1185,7 @@ When a user opens a cloud note, the application freezes and then crashes. #### Error Codes -The cloud images are obtained synchronously in a loop. +The cloud image is obtained synchronously in a loop. ```ts public static xxxFunction(fileUris: string[]): void { @@ -1203,7 +1210,7 @@ The following example extracts the key fault logs of **LIFECYCLE_TIMEOUT** that sysfreeze: LIFECYCLE_TIMEOUT LIFECYCLE_TIMEOUT at 20240201100459 ``` -The **MSG** information indicates that the timeout is in the foreground, and the duration is 5s. +The **MSG** information indicates that the timeout occurs in the foreground, and the duration is 5s. ``` MSG = @@ -1225,8 +1232,8 @@ STRINGID:LIFECYCLE_TIMEOUT TIMESTAMP:2024/02/01-10:04:59:965 PID:18083 UID:20020041 -PACKAGE_NAME:com.huawei.hmos.notepad -PROCESS_NAME:com.huawei.hmos.notepad +PACKAGE_NAME:com.example.notepad +PROCESS_NAME:com.example.notepad ******************************************* start time: 2024/02/01-10:04:57:555 DOMAIN = AAFWK @@ -1235,11 +1242,11 @@ TIMESTAMP = 2024/02/01-10:04:57:538 PID = 18083 UID = 20020041 TID = 17286 -PACKAGE_NAME = com.huawei.hmos.notepad -PROCESS_NAME = com.huawei.hmos.notepad +PACKAGE_NAME = com.example.notepad +PROCESS_NAME = com.example.notepad ``` -The task is started at **10:04:54.798**, and the interval between the start time and **LIFECYCLE_HALF_TIMEOUT** is about 2.5s, which is as expected. +The task starts at **10:04:54.798**, and the interval between the start time and **LIFECYCLE_HALF_TIMEOUT** is about 2.5s, which is as expected. ``` mainHandler dump is: @@ -1259,7 +1266,7 @@ mainHandler dump is: Check the stack information at **libfs.z.so -> libdatashare_consumer.z.so -> libipc_core.z.so**. ``` -Tid:18083, Name:ei.hmos.notepad +Tid:18083, Name:ei.example.notepad # 00 pc 00000000001617a4 /system/lib/ld-musl-aarch64.so.1(ioctl+180)(4ca73cff61bea7c4a687eb0f71c9df69) # 01 pc 000000000003e8a0 /system/lib64/platformsdk/libipc_core.z.so(OHOS::BinderConnector::WriteBinder(unsigned long, void*)+72)(3248fceb1fa676994734e0437430ce37) # 02 pc 0000000000049f38 /system/lib64/platformsdk/libipc_core.z.so(OHOS::BinderInvoker::TransactWithDriver(bool)+296)(3248fceb1fa676994734e0437430ce37) @@ -1277,7 +1284,7 @@ Tid:18083, Name:ei.hmos.notepad # 14 pc 0000000000132e48 /system/lib64/module/arkcompiler/stub.an ``` -The **BinderCatcher** shows that the communication with process **5235** takes more than 2.5s, which is as expected. +The **BinderCatcher** information shows that the communication with process **5235** takes more than 2.5s, which is as expected. ``` PeerBinderCatcher -- pid==18083 layer_ == 1 @@ -1287,7 +1294,7 @@ BinderCatcher -- 3462:3621 to 4956:4981 code 8 wait:273.550283291 s ``` -The **5235** is a media library process and stack information is not useful for analysis. +The **5235** process is a media library process and the stack information is not useful for analysis. ``` PeerBinder Stacktrace -- @@ -1296,7 +1303,7 @@ Result: 0 ( no error ) Timestamp:2024-02-01 10:04:57.000 Pid:5235 Uid:20020079 -Process name:com.ohos.medialibrary.medialibrarydata +Process name:com.medialibrary.medialibrarydata Tid:5235, Name:edialibrarydata # 00 pc 0000000000142d1c /system/lib/ld-musl-aarch64.so.1(epoll_wait+84)(4ca73cff61bea7c4a687eb0f71c9df69) # 01 pc 000000000000fb74 /system/lib64/chipset-pub-sdk/libeventhandler.z.so(OHOS::AppExecFwk::EpollIoWaiter::WaitFor(std::__h::unique_lock&, long)+224)(a4d21072c08fd3ac639d5cf5b8fb8b51) @@ -1319,9 +1326,9 @@ Tid:5235, Name:edialibrarydata # 18 pc 000000000001106c /system/bin/appspawn(_start_c+76)(7b715884c45cfe57b22df46fdaeeca88) ``` -The preceding information indicates that the application loads files synchronously using the URI through **Open::Sync** and calls the **datashare()** to obtain media library file data. +The preceding information indicates that the application loads files synchronously using the URI through **Open::Sync** and calls **datashare()** to obtain media library file data. -The log information shows that the process is suspended when calls the **datashare()** to load the cloud diagram, which is consistent with the stack information. +The log information shows that the process freezes when calling **datashare()** to load the cloud image, which is consistent with the stack information. ![appfreeze_2024061416](figures/appfreeze_2024061416.png) @@ -1360,6 +1367,6 @@ public static async xxxFunction(fileUris: string[]): void { #### Suggestions -1. Data on the cloud side must be fully verified in scenarios with good network, weak network, and no network. +1. Verify the requested cloud data in scenarios where the network is available, weak, or unavailable. 2. Do not perform time-consuming operations in the application lifecycle function. diff --git a/en/application-dev/dfx/figures/appfreeze_20230310105865.png b/en/application-dev/dfx/figures/appfreeze_20230310105865.png deleted file mode 100644 index 0082b4a012d79e2a407934abc6b3e45e580e20dd..0000000000000000000000000000000000000000 Binary files a/en/application-dev/dfx/figures/appfreeze_20230310105865.png and /dev/null differ diff --git a/en/application-dev/dfx/figures/appfreeze_20230310105866.png b/en/application-dev/dfx/figures/appfreeze_20230310105866.png deleted file mode 100644 index 87e25e01d01d5e039c1089ee7604d2e14403efee..0000000000000000000000000000000000000000 Binary files a/en/application-dev/dfx/figures/appfreeze_20230310105866.png and /dev/null differ diff --git a/en/application-dev/dfx/figures/appfreeze_20230310105867.png b/en/application-dev/dfx/figures/appfreeze_20230310105867.png deleted file mode 100644 index c77c4686a66c56dc051aaa3a1d7996a3cb93985b..0000000000000000000000000000000000000000 Binary files a/en/application-dev/dfx/figures/appfreeze_20230310105867.png and /dev/null differ diff --git a/en/application-dev/dfx/figures/appfreeze_20230310105868.png b/en/application-dev/dfx/figures/appfreeze_20230310105868.png deleted file mode 100644 index 7c1f36e709e4b07908567a7124df5e45fbd9bad1..0000000000000000000000000000000000000000 Binary files a/en/application-dev/dfx/figures/appfreeze_20230310105868.png and /dev/null differ diff --git a/en/application-dev/dfx/figures/appfreeze_20230310105869.png b/en/application-dev/dfx/figures/appfreeze_20230310105869.png deleted file mode 100644 index a55b3373405f2f4db972507e2f35102021c7f92a..0000000000000000000000000000000000000000 Binary files a/en/application-dev/dfx/figures/appfreeze_20230310105869.png and /dev/null differ diff --git a/en/application-dev/dfx/figures/appfreeze_20230310105870.png b/en/application-dev/dfx/figures/appfreeze_20230310105870.png deleted file mode 100644 index 73c0549142e49e233b3ea38f8e1b6e44c642a30e..0000000000000000000000000000000000000000 Binary files a/en/application-dev/dfx/figures/appfreeze_20230310105870.png and /dev/null differ diff --git a/en/application-dev/dfx/figures/appfreeze_20230310105871.png b/en/application-dev/dfx/figures/appfreeze_20230310105871.png deleted file mode 100644 index ea8fe6bb1156255571e45e4e22d69cea70ae474f..0000000000000000000000000000000000000000 Binary files a/en/application-dev/dfx/figures/appfreeze_20230310105871.png and /dev/null differ diff --git a/en/application-dev/dfx/figures/appfreeze_20230310105872.png b/en/application-dev/dfx/figures/appfreeze_20230310105872.png deleted file mode 100644 index 43406b804f9c981e636f4ad6099ce1abd69fb3d1..0000000000000000000000000000000000000000 Binary files a/en/application-dev/dfx/figures/appfreeze_20230310105872.png and /dev/null differ diff --git a/en/application-dev/dfx/figures/appfreeze_20230310105873.png b/en/application-dev/dfx/figures/appfreeze_20230310105873.png deleted file mode 100644 index 71457fa6a49bf657a3b4527c7a000818c824ba94..0000000000000000000000000000000000000000 Binary files a/en/application-dev/dfx/figures/appfreeze_20230310105873.png and /dev/null differ diff --git a/en/application-dev/dfx/figures/hdc_image_001_en.PNG b/en/application-dev/dfx/figures/hdc_image_001_en.PNG deleted file mode 100644 index a6cffbe31e8698bd3a410ad63285b0c642d7e746..0000000000000000000000000000000000000000 Binary files a/en/application-dev/dfx/figures/hdc_image_001_en.PNG and /dev/null differ diff --git a/en/application-dev/dfx/figures/hdc_image_003_en.PNG b/en/application-dev/dfx/figures/hdc_image_003_en.PNG deleted file mode 100644 index 0b54e84b7334a78b06ec1075aee4a58358c90068..0000000000000000000000000000000000000000 Binary files a/en/application-dev/dfx/figures/hdc_image_003_en.PNG and /dev/null differ diff --git a/en/application-dev/dfx/figures/hdc_image_005.PNG b/en/application-dev/dfx/figures/hdc_image_005.PNG new file mode 100644 index 0000000000000000000000000000000000000000..9675746c48b65257a9e3c890ec562fb358692586 Binary files /dev/null and b/en/application-dev/dfx/figures/hdc_image_005.PNG differ diff --git a/en/application-dev/dfx/figures/hdc_img_002_en.PNG b/en/application-dev/dfx/figures/hdc_img_002_en.PNG deleted file mode 100644 index c0537ea0fde2ec4e3b9b405351da69a905b45f63..0000000000000000000000000000000000000000 Binary files a/en/application-dev/dfx/figures/hdc_img_002_en.PNG and /dev/null differ diff --git a/en/application-dev/dfx/figures/hiappevent_extend_so_inited.png b/en/application-dev/dfx/figures/hiappevent_extend_so_inited.png deleted file mode 100644 index 0425c3c0c6bdf5d48104b7df9a31f68f6cc55567..0000000000000000000000000000000000000000 Binary files a/en/application-dev/dfx/figures/hiappevent_extend_so_inited.png and /dev/null differ diff --git a/en/application-dev/dfx/figures/hiappevent_extend_so_report.png b/en/application-dev/dfx/figures/hiappevent_extend_so_report.png deleted file mode 100644 index 37e5ab5081e3b782a0f3045eb81c60636eecbc0c..0000000000000000000000000000000000000000 Binary files a/en/application-dev/dfx/figures/hiappevent_extend_so_report.png and /dev/null differ diff --git a/en/application-dev/dfx/figures/hiappevent_extend_so_stream.png b/en/application-dev/dfx/figures/hiappevent_extend_so_stream.png deleted file mode 100644 index d03b9913d3c8baadaa25b5371f925a5194bef94b..0000000000000000000000000000000000000000 Binary files a/en/application-dev/dfx/figures/hiappevent_extend_so_stream.png and /dev/null differ diff --git a/en/application-dev/dfx/figures/hiappevent_extend_so_verify.png b/en/application-dev/dfx/figures/hiappevent_extend_so_verify.png deleted file mode 100644 index ed9de00ae82f6f3296c11436ab41b6ba18a8ca5c..0000000000000000000000000000000000000000 Binary files a/en/application-dev/dfx/figures/hiappevent_extend_so_verify.png and /dev/null differ diff --git a/en/application-dev/dfx/figures/hidumper-cpuusage-pid.png b/en/application-dev/dfx/figures/hidumper-cpuusage-pid.png deleted file mode 100644 index 5e4532f91d271a3af8eba23948b6f3b9d6b8e130..0000000000000000000000000000000000000000 Binary files a/en/application-dev/dfx/figures/hidumper-cpuusage-pid.png and /dev/null differ diff --git a/en/application-dev/dfx/figures/hidumper-cpuusage.png b/en/application-dev/dfx/figures/hidumper-cpuusage.png deleted file mode 100644 index db800aafea2031e5f66e9917ad5ff48c2b26bdda..0000000000000000000000000000000000000000 Binary files a/en/application-dev/dfx/figures/hidumper-cpuusage.png and /dev/null differ diff --git a/en/application-dev/dfx/figures/hidumper-e.png b/en/application-dev/dfx/figures/hidumper-e.png deleted file mode 100644 index 778f328335405bec80469fe650b27f36a9e9ecc2..0000000000000000000000000000000000000000 Binary files a/en/application-dev/dfx/figures/hidumper-e.png and /dev/null differ diff --git a/en/application-dev/dfx/figures/hidumper-h.png b/en/application-dev/dfx/figures/hidumper-h.png deleted file mode 100644 index cfb4197db8c79ac688d5c108693b61bf50c194f5..0000000000000000000000000000000000000000 Binary files a/en/application-dev/dfx/figures/hidumper-h.png and /dev/null differ diff --git a/en/application-dev/dfx/figures/hidumper-ipc.png b/en/application-dev/dfx/figures/hidumper-ipc.png deleted file mode 100644 index 875cd452968fd7b03084616b08400bb8344c9a2c..0000000000000000000000000000000000000000 Binary files a/en/application-dev/dfx/figures/hidumper-ipc.png and /dev/null differ diff --git a/en/application-dev/dfx/figures/hidumper-jsheap.png b/en/application-dev/dfx/figures/hidumper-jsheap.png deleted file mode 100644 index f8c96465e4b6aea27669f61a213cfc6ba6311044..0000000000000000000000000000000000000000 Binary files a/en/application-dev/dfx/figures/hidumper-jsheap.png and /dev/null differ diff --git a/en/application-dev/dfx/figures/hidumper-ls.PNG b/en/application-dev/dfx/figures/hidumper-ls.PNG deleted file mode 100644 index 561b5e2c4e8e57c86ae7ff655dc10d105466e753..0000000000000000000000000000000000000000 Binary files a/en/application-dev/dfx/figures/hidumper-ls.PNG and /dev/null differ diff --git a/en/application-dev/dfx/figures/hidumper-mem-pid.png b/en/application-dev/dfx/figures/hidumper-mem-pid.png deleted file mode 100644 index 0ebfc41321e2b80d1ef03bb071f57a40c21fe2b1..0000000000000000000000000000000000000000 Binary files a/en/application-dev/dfx/figures/hidumper-mem-pid.png and /dev/null differ diff --git a/en/application-dev/dfx/figures/hidumper-mem-smaps.png b/en/application-dev/dfx/figures/hidumper-mem-smaps.png deleted file mode 100644 index 77aae302cfa1ca7921bda23f22f3ac405b04a077..0000000000000000000000000000000000000000 Binary files a/en/application-dev/dfx/figures/hidumper-mem-smaps.png and /dev/null differ diff --git a/en/application-dev/dfx/figures/hidumper-mem.png b/en/application-dev/dfx/figures/hidumper-mem.png deleted file mode 100644 index 3caf43894e4bea99bcde28bccdc5d73a240fb5b1..0000000000000000000000000000000000000000 Binary files a/en/application-dev/dfx/figures/hidumper-mem.png and /dev/null differ diff --git a/en/application-dev/dfx/figures/hidumper-net.png b/en/application-dev/dfx/figures/hidumper-net.png deleted file mode 100644 index 0184554741bb8005c199f051aa8d806dad21c97f..0000000000000000000000000000000000000000 Binary files a/en/application-dev/dfx/figures/hidumper-net.png and /dev/null differ diff --git a/en/application-dev/dfx/figures/hidumper-p.png b/en/application-dev/dfx/figures/hidumper-p.png deleted file mode 100644 index bf6a0382c7f4121bcbae32cad318d22234e29d5c..0000000000000000000000000000000000000000 Binary files a/en/application-dev/dfx/figures/hidumper-p.png and /dev/null differ diff --git a/en/application-dev/dfx/figures/hidumper-renderservice-fps.png b/en/application-dev/dfx/figures/hidumper-renderservice-fps.png deleted file mode 100644 index 677ceb275edf041c88cdbc86df1b2c43882440cf..0000000000000000000000000000000000000000 Binary files a/en/application-dev/dfx/figures/hidumper-renderservice-fps.png and /dev/null differ diff --git a/en/application-dev/dfx/figures/hidumper-renderservice-h.png b/en/application-dev/dfx/figures/hidumper-renderservice-h.png deleted file mode 100644 index 526e629afcf82652f8d07c83ecc78200cdc2de26..0000000000000000000000000000000000000000 Binary files a/en/application-dev/dfx/figures/hidumper-renderservice-h.png and /dev/null differ diff --git a/en/application-dev/dfx/figures/hidumper-s-3301.png b/en/application-dev/dfx/figures/hidumper-s-3301.png deleted file mode 100644 index 2c2fee31a8e3aefe446af9dbf965da25ae390b6e..0000000000000000000000000000000000000000 Binary files a/en/application-dev/dfx/figures/hidumper-s-3301.png and /dev/null differ diff --git a/en/application-dev/dfx/figures/hidumper-s.png b/en/application-dev/dfx/figures/hidumper-s.png deleted file mode 100644 index 2b2e51a075fcb5794caec6f975f9f845814546b1..0000000000000000000000000000000000000000 Binary files a/en/application-dev/dfx/figures/hidumper-s.png and /dev/null differ diff --git a/en/application-dev/dfx/hdc.md b/en/application-dev/dfx/hdc.md index 907d70c314e7d726b68697a53f843d547b6a9eb0..a3e2e6a52b97c8a6fcc04652256395f94753c719 100644 --- a/en/application-dev/dfx/hdc.md +++ b/en/application-dev/dfx/hdc.md @@ -2,763 +2,829 @@ OpenHarmony Device Connector (hdc) is a command line tool used for debugging. You can use it on a Windows, Linux, or macOS system to interact with devices. +hdc consists of three processes: + +**client**: the process running on the PC. This process is started when you run the hdc command and exits after the command is executed. + +**server**: the background server process running on the PC. It is used to manage data interaction between the **client** and **daemon** processes and discover devices. + +**daemon**: the daemon process running on the device. It is used to respond to the requests sent by **server**. + +The following figure shows the relationship. + +![hdc](figures/hdc_image_005.PNG) +> **NOTE** +> +> When **client** is started, it checks whether **server** is running by default. If not, a new hdc program is started as the** server** and runs in the background. +> +> When **server** is running, it listens for port 8710 of the PC by default. You can set the system environment variable **OHOS_HDC_SERVER_PORT** to listen for a port. + ## Environment Setup -Obtain hdc from the **toolchains** folder in OpenHarmony SDK. For first-time use, configure the environment variables as follows. +The hdc tool is obtained from the **toolchains** directory of OpenHarmony SDK. -### Setting the Environment Variable **HDC_SERVER_PORT** +### (Optional) Running the hdc Program on the CLI -**Windows** +You can go to the **toolchains** directory of SDK through the CLI and run the hdc command in the directory for debugging. +To facilitate the execution of the hdc program in the CLI, you can add the file path of the hdc program to the system environment variable that specifies the command search path. +For example, add it to **Path** on Windows. -1. Choose **This PC > Properties >Advanced system settings > Advanced > Environment Variables**, add the variable **HDC_SERVER_PORT**, and set its value to any port number not in use, such as **7035**. +### (Optional) Configuring the server Listening Port -![Create system variable](figures/hdc_image_001_en.PNG) +When the hdc server is started, it listens for port 8710 of the PC by default. The hdc client uses TCP to connect to the server through this port. If port 8710 of the PC has been used or you want to use another port, you can add the environment variable **OHOS_HDC_SERVER_PORT** to the system environment variable to listen for any unoccupied port when the server is started. +For example, set **OHOS_HDC_SERVER_PORT** to **18710**. + +> **NOTE** +> +> After the environment variable is configured, close and restart the CLI and other software that uses OpenHarmony SDK. -2. Restart DevEco Studio. +## hdc commands -**macOS** +### Global Parameters -1. Start the terminal tool and run the following command: +Global parameters are the parameters that follow **hdc** when some hdc commands are run. +For example, use the **-t** parameter to specify a device for command execution. ```shell - echo $SHELL + hdc -t connect-key shell echo "Hello world" ``` - - If the command output is **/bin/bash**, open the **.bash_profile** file. +| Parameter| Description| +| -------- | -------- | +| -t | Specifies a target device to connect. When one device is connected, this parameter is optional. When multiple devices are connected, it is mandatory.| +| -l | (Optional) Specifies the log level when the device is running. The value ranges from 0 to 6. The default value is **3** (**LOG_INFO**).| +| -s | (Optional) Specifies the IP and port for listening when the client connects to the server.| +| -p | (Optional) Executes a client command without querying the server process.| +| -m | (Optional) Starts the server process in the foreground.| + +### Commands +| Command| Description| +| -------- | -------- | +| list targets | Displays all connected target devices.| +| wait | Waits until the device is properly connected.| +| tmode usb | This command is invalid and cannot be used to enable the USB connection channel. You need to enable it on the device setting page.| +| tmode port | Enables the network connection channel of the device.| +| tmode port close | Disables the network connection channel of the device.| +| tconn | Specifies the device to connect based on the IP address and port number.| +| shell | Executes a single command on the device.| +| install | Installs an application.| +| uninstall | Uninstalls a specified application.| +| file send | Sends a local file to a remote device.| +| file recv | Sends a file from a remote device to the local device.| +| fport ls | Lists all port forwarding tasks.| +| fport | Sets up a local port forwarding, which forwards data from a local port to a remote port.| +| rport | Sets up a remote port forwarding, which forwards data from a remote port to a local port.| +| fport rm | Deletes a port forwarding task.| +| start | Starts the hdc server process.| +| kill | Terminates the hdc server process.| +| hilog | Obtains device log information.| +| jpid | Displays the PIDs of all applications that have enabled JDWP on the device.| +| track-jpid | Displays the PIDs and names of the applications that have enabled JDWP on the device in real time.| +| target boot| Restarts the target device.| +| target mount | Mounts the system partition in read/write mode. (This command is unavailable for non-root devices.)| +| smode | Grants the **root** permission to the background hdc server running on the device. You can use the **-r** option to revoke the granted permission. (This command is unavailable for non-root devices.)| +| keygen | Generates a new key pair.| +| version | Displays the hdc version information. You can also run the **hdc -v** command to display the version information.| +| checkserver | Obtains the version information about the client process and server process.| - ```shell - vi ~/.bash_profile - ``` +> **NOTE** +> +> Global parameters must be placed before commands. - - If the command output is **/bin/zsh**, open the **.zshrc** file. +## Basic Commands - ```shell - vi ~/.zshrc - ``` +Before using hdc, enable the USB debugging function on the device and connect the device to the PC using a USB cable. -2. Press **i** to enter **Insert** mode. -3. Enter the following content to add **HDC_SERVER_PORT** information to **PATH**. +### Displaying Connected Devices ```shell - HDC_SERVER_PORT=7035 - launchctl setenv HDC_SERVER_PORT $HDC_SERVER_PORT - export HDC_SERVER_PORT + hdc list targets ``` -4. Press **Esc** to exit **Insert** mode. Then enter **:wq** and press **Enter** to save the settings. -5. Run the following command for the environment variable to take effect. +### Running the Shell command - - If the **.bash_profile** file is opened in step 1, run the following command: + ```shell + hdc shell echo "Hello world" + ``` - ```shell - source ~/.bash_profile - ``` +### Obtaining the Help Information - - If the **.zshrc** file is opened in step 1, run the following command: +| Command| Description| +| -------- | -------- | +| -h [verbose] | Displays the hdc help information. The optional parameter **verbose** can be used to display detailed help information.| +| help | Displays the hdc help information.| - ```shell - source ~/.zshrc - ``` +Display hdc help information. -6. Restart DevEco Studio. + ```shell + hdc -h [verbose] + hdc help + ``` -### (Optional) Setting Global Environment Variables +**Return value** +| Return Value| Description| +| -------- | -------- | +| OpenHarmony device connector(HDC) ...
---------------------------------global commands:----------------------------------
-h/help [verbose]                     - Print hdc help, 'verbose' for more other cmds
..._(Detailed information is omitted here.)_| Help information for hdc commands.| -> **NOTE** -> If global environment variables are not set, you can run commands to go to the **toolchains** directory in the SDK and run hdc commands in the directory for debugging. +**Usage** -**Windows** +```shell +hdc -h +hdc help -Choose **This PC > Properties > Advanced system settings > Advances > Environment Variables**, add the **toolchains** path of the SDK to the value of **Path**. +// Display the detailed help information. +hdc -h verbose +``` -In the following example, the **toolchains** path of the local SDK is **/User/username/sdk/openharmony/10/toolchains**. +### NOTE -![System Variables](figures/hdc_img_002_en.PNG) +- If an exception occurs, run the **hdc kill -r** command to kill the hdc process and restart the hdc server. -![Edit Environment Variable](figures/hdc_image_003_en.PNG) +- If the **hdc list targets** command cannot obtain the device information, see [Failed to Identify the Target Device](#failed-to-identify-the-target-device). -**Linux/macOS** +## Managing Device Connections -1. Start the terminal tool and run the following command: +### Displaying Devices - ```shell - echo $SHELL - ``` +Run the **list targets** command to display all connected target devices. +You can add the **-v** parameter to display detailed device information. - - If the command output is **/bin/bash**, open the **.bash_profile** file. - ```shell - vi ~/.bash_profile - ``` +```shell +hdc list targets [-v] +``` - - If the command output is **/bin/zsh**, open the **.zshrc** file. +**Return value** +| Return Value| Description| +| -------- | -------- | +| Device ID list| List of connected device IDs. The ID is the value of **connect-key** used in the **-t** parameter.| +| [Empty] | No device is found.| - ```shell - vi ~/.zshrc - ``` +**Usage** -2. Press **i** to enter **Insert** mode. +```shell +hdc list targets +hdc list targets -v +``` -3. Enter the following content and add the SDK path to the **PATH**. +### Connecting to the Specified Target Device - In the following example, the **toolchains** path of the local SDK is **_/User/username/sdk/openharmony/10/toolchains_**. +When a single device is connected, you do not need to specify the device ID when running the command. +When multiple devices are connected, use the **-t** parameter to specify the target device ID each time you run the command. ```shell - HDC_SDK_PATH=/User/username/sdk/openharmony/10/toolchains - launchctl setenv HDC_SDK_PATH $HDC_SDK_PATH # This command needs to be executed only on macOS. - export PATH=$PATH:$HDC_SDK_PATH + hdc -t [connect-key] [command] ``` -4. Press **Esc** to exit **Insert** mode. Then enter **:wq** and press **Enter** to save the settings. - -5. Run the following command for the environment variable to take effect. + **Parameters** +| Name| Description| +| -------- | -------- | +| connect-key| Device ID, which is the return value of the **hdc list targets** command.| +| command | Command to be executed.| - - If the **.bash_profile** file is opened in step 1, run the following command: + > **NOTE** + > + > The *connect-key* uniquely identifies a device. If the device is connected over the network, the *connect-key* is the IP address and port number. If the device is connected through USB, the *connect-key* is the USB SN. - ```shell - source ~/.bash_profile - ``` + **Return value** +| Return Value| Description| +| -------- | -------- | +| Command output| Command execution result, which may vary with the command.| +| [Fail]Not match target founded, check connect-key please | No device matches the *connect-key*.| +| [Fail]Device not founded or connected | The device is not found or connected.| +| [Fail]ExecuteCommand need connect-key? please confirm a device by help info | You must specify one device if there are multiple devices available.| +| Unknown operation command... | The command is not supported.| - - If the **.zshrc** file is opened in step 1, run the following command: + > **NOTE** + > + > The error messages will be optimized in the future. Do not use them to determine the result of the automatic script or program. - ```shell - source ~/.zshrc - ``` - -**(Optional for Linux) Granting USB Operation Permission for Non-root Users** + **Usage** -- To temporarily grant the full operation permission on a USB device, run the following command: + This option must be used with a command. The following uses the **shell** command as an example. ```shell - sudo chmod -R 777 /dev/bus/usb/ + hdc list targets // Display connect-key of all connected devices. + hdc -t [connect-key] shell // Replace connect-key with the specified device ID. ``` -- To permanently change the operation permission on a USB device, do as follows: - - 1. Run the **lsusb** command to obtain the **vendorID** and **productID** of the USB device. +### Waiting for Device Connection - 2. Create an **udev** rule. +Run the following commands: - Edit the **udev** loading rule and replace the default **idVendor** and **idProduct** values of the device with the values obtained in the previous step. + ```shell + hdc wait // Wait for the device to connect. + hdc -t connect-key wait // Wait for the specified device to connect. Replace connect-key with the specified device ID. + ``` - **MODE="0666"** indicates the permissions of **GROUP** (the user group) for the USB device. Ensure that the login user is in the user group. + **Return value** +| Return Value| Description| +| -------- | -------- | +| None| The **hdc wait** command ends when a properly connected device is identified.| - ```shell - sudo vim /etc/udev/rules.d/90-myusb.rules - SUBSYSTEMS=="usb", ATTRS{idVendor}=="067b", ATTRS{idProduct}=="2303", GROUP="users", MODE="0666" - ``` + **Usage** - 3. Restart the computer or reload the **udev** rule. + ```shell + hdc wait + hdc -t connect-key wait + ``` - ```shell - sudo udevadm control --reload - ``` +### Common Connections -> **NOTE** -> A non-root user cannot find the device using hdc in Linux. Granting USB operation permission for non-root users can solve this problem. However, granting the full permission may pose potential security risks. You need to determine whether to grant the permission based on actual requirements. +#### USB Connection -## Precautions +- Checking the environment -- If an exception occurs, run the **hdc kill -r** command to kill the hdc process and restart the hdc service. +| Item| Normal| Exception Handling| +| -------- | -------- | -------- | +| USB debugging| USB debugging is enabled.| If the USB debugging mode is not automatically enabled, restart the device.| +| USB data cable connection| The PC used for debugging is connected to the device USB port using a USB cable.| If you use a USB cable with low bandwidth and no data communication function, the device may fail to be identified. You are advised to use an officially recommended USB cable.| +| USB port| A USB port on the mainboard (USB port on the rear panel of a desktop computer or USB port on a laptop computer) is used.| If you use a conversion adapter, docking station, or USB port on the front panel of a desktop computer, issues such as low bandwidth and USB sync problems may occur, which results in frequent disconnections. Therefore, direct connection between the PC and the device is recommended.| +| hdc environment variable| The help information is displayed after the **hdc -h** command is executed.| For details, see [Environment Setup](#environment-setup).| +| Driver| After the device is connected via hdc, **HDC Device** or **HDC Interface** is displayed in **Device Manager**.| For details, see [Failed to Identify the Target Device](#failed-to-identify-the-target-device).| -- If no device information is obtained after the **hdc list targets** command is executed, check whether the hdc process exists in the **Task Manager**. If the process exists, run the **hdc kill -r** command to kill the process and restart the hdc service. +- Procedure +1. Connect the PC to the device through a USB port. -## How to Use -> **NOTE** -> -> - The parameters enclosed in [] in a command are optional. -> - The parameters in italics are variables. Replace them with actual values when running the command. - +2. Check the connection. -### Global Option Commands + ```shell + hdc list targets + ``` -| Option | Description| -| -------- | -------- | -| -h/help | Displays hdc help information.| -| -v/version | Displays hdc version information.| -| -t [connect-key] [command] | Connects to the specified device. You can run the **hdc list targets** command to obtain the **connect-key**.| -| -l [level] | Sets the levels of the logs generated during the running of the tool. The default value is **LOG_INFO**.| -| wait | Waits for the device to be properly connected and checks whether the device is connected and ready to receive instructions.| -| checkserver | Obtains the **client-server** version.| + If the corresponding device ID is returned, the USB connection is successful. -1. Display hdc help information. +3. When the device is found, run the related commands to interact with the device. If you want to perform USB command operations without the device ID, ensure that the device is not in TCP connection mode (the device information displayed by running the **hdc list targets **command does not contain **IP:port**) and directly connect to the device. For example: ```shell - hdc -h/help + hdc shell ``` - **Return value** - | Return Value| Description| - | -------- | -------- | - | OpenHarmony device connector(HDC) ...
---------------------------------global commands:----------------------------------
-h/help [verbose]                     - Print hdc help, 'verbose' for more other cmds
..._(Detailed information is omitted here.)_| Help information for hdc commands.| +#### TCP Connection - **Usage** + > **NOTE** + > + > The TCP debugging function is not stable. Exercise caution when using this function for production. - ```shell - hdc -h or hdc help - ``` +- Checking the environment -2. Display hdc version information. +| Item| Normal| Exception Handling| +| -------- | -------- | -------- | +| Network connection| The PC and the device are on the same network.| Connect the PC and device to the same Wi-Fi network or enable the Wi-Fi hotspot on your device.| +| Network Status| Use **telnet IP:port** to check that the network connection between the PC and the device is normal.| Connect the PC and the device over a stable network.| +| hdc environment variable| The help information is displayed after the **hdc -h** command is executed.| For details, see [Environment Setup](#environment-setup).| - ```shell - hdc -v/version - ``` +- Procedure - **Return value** - | Return Value| Description| - | -------- | -------- | - | Ver: X.X.Xa | hdc (SDK) version information.| +1. Enable network debugging on the device setting page. - **Usage** +2. Record the port number displayed on the device as **PORT** for TCP connection. + +3. Run the following command to connect to the device through TCP (you need to know the device IP address and enabled port number): ```shell - hdc -v or hdc version + hdc tconn IP:PORT ``` + You can obtain the IP address from the device settings. The port number is displayed in the previous step. -3. Connect to a device. If there is only one device connected, you do not need to specify **connect-key**. If there are multiple devices connected, you must specify **connect-key** each time. +4. Check the connection. ```shell - hdc -t [connect-key] [command] + hdc list targets ``` - **Parameters** - | Name| Description| - | -------- | -------- | - | connect-key| Device ID.| - | command | Command to be executed.| + If the return value is in the *IP:PORT* format, the connection is successful. -> **NOTE** - > The **connect-key** uniquely identifies a device. If the device is connected over the network, the **connect-key** is the IP address. If the device is connected through USB, the **connect-key** is the USB SN. +5. To disable the TCP connection mode, disable network debugging on the device. - **Return value** -| Return Value| Description| -| -------- | -------- | -| Command output| Command execution result, which may vary with the command.| -| [Fail]Not match target founded, check connect-key please | No device matches the *connect-key*.| -| [Fail]Device not founded or connected | The device is not found or connected.| -| [Fail]ExecuteCommand need connect-key? please confirm a device by help info | You must specify one device if there are multiple devices available.| -| Unknown operation command... | The command is not supported.| +#### Remote Connection - **Usage** +In the remote connection scenario, the client remotely connects to the server through the network. The client and server run on different PCs, and the server connects to the device. +The following figure shows the remote connection. - This option must be used with a command. The following uses the **shell** command as an example. +![Remote connection structure](figures/hdc_image_004.PNG) - ```shell - hdc list targets // Display connect-key of all connected devices. - hdc -t [connect-key] shell // Replace connect-key with the specified device ID. - ``` +The hdc client runs on PC1, and the hdc server runs on PC2, which is connected to the device. + +- Connection command -4. Specify the runtime log level. The default value is **LOG_INFO**. + | Command| Description| + | -------- | -------- | + | -s | Specifies the IP address and port number of the current server process to listen for.| + + Use the **-s** parameter to specify the IP address and port number of the server. The setting is valid only when the current command is executed. ```shell - hdc -l [level] [command] + hdc -s [ip]:[port] [command] ``` **Parameters** | Parameter| Description| | -------- | -------- | - | [level] | Log level.
0: LOG_OFF
1: LOG_FATAL
2: LOG_WARN
3: LOG_INFO
4: LOG_DEBUG
5: LOG_ALL| + | ip | IP address to listen for. Both IPv4 and IPv6 addresses are supported.| + | port | Port to listen for. The value ranges from 1 to 65535.| | command | Command to be executed.| **Return value** | Return Value| Description| | -------- | -------- | - | Command output| Command execution result, which may vary with the command.| - | Log information| Logs of the specified level.| + | Connect server failed | Fails to connect to the server.| + | -s content port incorrect. | The port number is out of range (1 to 65535).| **Usage** ```shell - hdc -l 5 shell ls + # Run the command to obtain the device information in the server process of 127.0.0.1:8710: + hdc -s 127.0.0.1:8710 list targets ``` -5. Wait until the device is connected properly. - - ```shell - hdc wait // Wait for the device to connect. - hdc -t connect-key wait // Wait for the specified device to connect. Replace connect-key with the specified device ID. - ``` - - **Return value** - | Return Value| Description| - | -------- | -------- | - | None| After the **hdc wait** command is executed, the process ends when a properly connected device is identified.| + > **NOTE** + > + > If the **-s** parameter is used to specify a server port, the system ignores the port set in the **OHOS_HDC_SERVER_PORT** environment variable. - **Usage** +- Procedure - ```shell - hdc wait - hdc -t connect-key wait - ``` + 1. Configuring the server -6. Obtain the client-server version information. + Connect the server to the device using a USB cable and run the following commands: ```shell - hdc checkserver + hdc kill // Terminate the local hdc server. + hdc -s IP:8710 -m // Enable the hdc server for network forwarding. + // In the command, IP indicates the IP address of the server. To query the IP address, you can run the **ipconfig** command on Windows and run the **ifconfig** command on Unix. + // 8710 is the default port number. You can also set it to another port number, for example, 18710. + // After startup, the server prints logs. ``` - **Return value** - | Return Value| Description| - | -------- | -------- | - | Client version: Ver: X.X.Xa, Server version: Ver: X.X.Xa | Client-server version information.| + 2. Connecting to the client - **Usage** + Ensure that the client can connect to the server IP address, and then run the following command: ```shell - hdc checkserver + hdc -s IP:8710 [command] // IP indicates the IP address of the server, and 8710 indicates the port number set when the server is started in step 1. + // If the port number changes, change the port number accordingly. + // and command can be any available hdc command, for example, list targets. ``` -### Commands for Viewing Device List - -| Command| Description| -| -------- | -------- | -| list targets [-v] | Displays all connected devices. Use **-v** to display detailed device information.| - -Display all connected devices. - -```shell -hdc list targets[-v] -``` - -**Return value** -| Return Value| Description| -| -------- | -------- | -| Device information| A list of connected devices.| -| [Empty] | No device is found.| - -**Usage** +### Switching Between USB Debugging and Network Debugging -```shell -hdc list targets -hdc list targets -v -``` +The following table lists the commands for switching the connection mode. -### Service Process Commands +You are advised to enable or disable the USB debugging and network debugging on the device. | Command| Description| | -------- | -------- | -| target mount | Mounts the system partition in read/write mode (unavailable to user).| -| target boot [-bootloader\|-recovery] | Restarts a target device. You can use the **-bootloader** option to enter the fastboot mode and the **-recovery** option to enter the recovery mode.| -| target boot [MODE] | Restart a target device to enter the corresponding mode. **MODE** is an option supported by **reboot** in the **/bin/begetctl** command.| -| smode [-r] | Grants the **root** permission to the background hdc service running on the device. You can use the **-r** option to revoke the granted permission (unavailable to user).| -| kill [-r] | Terminates the hdc process. You can use the **-r** option to restart the process.| -| start [-r] | Starts the hdc process. You can use the **-r** option to restart the process.| +| tmode usb | This command is invalid and cannot be used to enable the USB connection channel. You need to enable it on the device setting page.| +| tmode port [port-number] | Enables the network connection channel of the device. Then the daemon process on the device restarts, and the USB connection is interrupted. You need to reconnect the device.| +| tmode port close | Disables the network connection channel of the device. Then the daemon process on the device restarts, and the USB connection is interrupted. You need to reconnect the device.| +| tconn [IP]:[port] [-remove] | Specifies a connection to a device in *IP address: port number* format. Use the **-remove** option to disconnect from the specified device.| -1. Mount the system partition in read/write mode. +1. Enable the network connection of the device. ```shell - hdc target mount + hdc tmode port [port-number] ``` + **Parameters** + | Parameter| Description| + | -------- | -------- | + | port-number | Port number of the connection. The value ranges from 1 to 65535.| + **Return value** | Return Value| Description| | -------- | -------- | - | Mount finish | Mounting succeeded.| - | [Fail]Mount failed | Mounting failed.| + | Set device run mode successful. | The network connection channel is enabled successfully.| + | [Fail]ExecuteCommand need connect-key | Failed to enable the network connection channel because no device exists in the list. | + | [Fail]Incorrect port range | The port number is out of range (1 to 65535).| **Usage** ```shell - hdc target mount - ``` - -2. Restart the target device. - - ```shell - target boot [-bootloader|-recovery] - target boot [MODE] + hdc tmode port 1234 ``` - **Parameters** - | Name| Description| - | -------- | -------- | - | Not specified| Restarts a device.| - | -bootloader| Restarts a device to enter the **fastboot** mode.| - | -recovery | Restarts a device to enter the **recovery** mode.| - | MODE | Restarts a device to enter the **MODE** mode. The **MODE** option is supported by **reboot** in the **/bin/begetctl** command. You can run the **hdc shell "/bin/begetctl -h \grep reboot"** command to obtain the options.| | - - **Usage** + > **NOTE** + > + > Before changing the connection mode, ensure that the remote device and the local PC are on the same network and the PC can ping the IP address of the remote device. + > + > Otherwise, do not run this command. - ```shell - hdc target boot -bootloader // Restart the device to enter the fastboot mode. - hdc target boot -recovery // Restart the device to enter the recovery mode. - hdc target boot shutdown // Shut down the device. - ``` + > **NOTE** + > + > After the command is executed, the remote daemon process exits and restarts, and the USB connection is disconnected. You need to reconnect the USB connection. -3. Grant the **root** permission to the background hdc service running on the device. +2. Disable the network connection channel of the device. ```shell - hdc smode [-r] + hdc tmode port close ``` **Return value** | Return Value| Description| | -------- | -------- | - | No return value| Permission granted.| - | [Fail]Error information| Failed to grant the permission.| + | [Fail]ExecuteCommand need connect-key | Failed to disable the network connection channel because no device exists in the list.| **Usage** ```shell - hdc smode - hdc smode -r // Revoke the root permission. + hdc tmode port close ``` + > **NOTE** + > After the command is executed, the remote daemon process exits and restarts, and the USB connection is disconnected. You need to reconnect the USB connection. -4. Terminate the hdc service. +3. Connect to the specified device through TCP. ```shell - hdc kill [-r] + hdc tconn [IP]:[port] [-remove] ``` + **Parameters** + | Parameter| Description| + | -------- | -------- | + | [IP]:[port] | IP address and port number of the device.| + | -remove | An optional parameter used to disconnect a specified device.| + **Return value** | Return Value| Description| | -------- | -------- | - | Kill server finish | The service is terminated successfully.| - | [Fail]Error information| Failed to terminate the service.| + | Connect OK | Device connected.| + | [Info]Target is connected, repeat operation| The device is already connected.| + | [Fail]Connect failed | Failed to connect the specified device.| **Usage** ```shell - hdc kill - hdc kill -r // Restart and terminate the service process. + hdc tconn 192.168.0.1:8888 + hdc tconn 192.168.0.1:8888 -remove // Disconnect from the specified device. ``` -5. Start the hdc service. +## Running the Interactive Command + +The command format is as follows: ```shell - hdc start [-r] + ``` + **Parameters** +| Parameter| Description| +| -------- | -------- | +| [command] | A single command to execute on the device. The command varies depending on the system type or version. You can run the **hdc shell ls /system/bin** command to obtain the supported command list. Currently, many commands are provided by [toybox](../tools/toybox.md). You can run the **hdc shell toybox --help** command to obtain the help information.| + **Return value** - | Return Value| Description| - | -------- | -------- | - | No return value| The service is started successfully.| - | [Fail]Error information| Failed to start the service process.| +| Return Value| Description| +| -------- | -------- | +| Command execution result| Execution result of the command. For details, see the corresponding command output.| +| /bin/sh: XXX : inaccessible or not found | The specified command is not supported.| **Usage** ```shell - hdc start - hdc start -r // Restart the service. + hdc shell ps -ef + hdc shell help -a // List all available commands. ``` -### Network Commands +## Managing Applications | Command| Description| | -------- | -------- | -| fport ls | Lists all port forwarding tasks.| -| fport _localnode remotenode_ | Sets up a local port forwarding, which forwards data from a local port to a remote port.| -| rport _remotenode localnode_ | Sets up a remote port forwarding, which forwards data from a remote port to a local port.| -| fport rm _taskstr_ | Removes a port forwarding task.| -| tmode usb | This command cannot be used to enable the USB connection channel. You need to enable it on the device setting page.| -| tmode port [port-number] | Enable the network connection channel of the device. Then the daemon process on the device restarts, and the USB connection is interrupted. You need to reconnect the device.| -| tmode port close | Disable the network connection channel of the device. Then the daemon process on the device restarts, and the USB connection is interrupted. You need to reconnect the device.| -| tconn [IP]:[port] [-remove] | Specifies a connection to a device in *IP address: port number* format. Use the **-remove** option to disconnect from the specified device.| +| install _src_ | Installs an application.| +| uninstall _packageName_ | Uninstalls an application.| -1. List all port forwarding tasks. +1. Install an app. ```shell - hdc fport ls + hdc install [-r|-s] src ``` + **Parameters** + | Name| Description| + | -------- | -------- | + | src| Installation package name.| + | -r | Replaces the existing app (.hap).| + | -s | Install a shared package (.hsp).| + **Return value** | Return Value| Description| | -------- | -------- | - | tcp:1234 tcp:1080 [Forward] | Local port forwarding.| - | tcp:2080 tcp:2345 [Reverse] | Remote port forwarding.| - | [empty] | No port forwarding.| + | AppMod finish | The installation is successful.| + | Error information| The installation fails.| **Usage** + For example, install **example.hap**. + ```shell - hdc fport ls + hdc install E:\example.hap ``` -2. Set up a local port forwarding, which forwards data from a local port to a remote port. +2. Uninstall the app. ```shell - hdc fport localnode remotenode + hdc uninstall [-k|-s] packageName ``` + **Parameters** + | Name| Description| + | -------- | -------- | + | packageName | Application installation package.| + | -k | Used to retain **/data** and **/cache**.| + | -s | Used to uninstall a shared package.| + **Return value** | Return Value| Description| | -------- | -------- | - | Forwardport result:OK | The port forwarding is set up properly.| - | [Fail]Incorrect forward command | Failed to set up the port forwarding due to parameter errors.| - | [Fail]TCP Port listen failed at XXXX | Failed to set up the port forwarding because the local port is in use.| + | AppMod finish | The uninstallation is successful.| + | Error information| The uninstallation fails.| **Usage** + For example, uninstall **com.example.hello**. + ```shell - hdc fport tcp:1234 tcp:1080 + hdc uninstall com.example.hello ``` +## Transferring Files -3. Set up a remote port forwarding, which forwards data from a remote port to a local port. +| Command| Description| +| -------- | -------- | +| file send _localpath remotepath_ | Sends a local file to a remote device.| +| file recv _remotepath localpath_ | Sends a file from a remote device to the local device.| + +1. Send a local file to a remote device. ```shell - hdc rport remotenode localnode + hdc file send [-a|-sync|-z|-m] localpath remotepath ``` - **Return value** - | Return Value| Description| + **Parameters** + | Name| Description| | -------- | -------- | - | Forwardport result:OK | The port forwarding is set up properly.| - | [Fail]Incorrect forward command | Failed to set up the port forwarding due to parameter errors.| - | [Fail]TCP Port listen failed at XXXX | Failed to set up the port forwarding because the local port is in use.| + | _localpath_ | Path of the file to send on the local device.| + | _remotepath_ | Destination path on the remote device.| + | -a | Used to retain the file timestamp.| + | -sync | Used to transfer only the files whose **mtime** is updated.| + | -z | Used to compress and transmit files in LZ4 format. This parameter is unavailable.| + | -m | Used to synchronize the DAC permission, UID, GID, and MAC permission during file transfer.| + + **Return value** + + A success message is displayed if the file is sent successfully. Error information is displayed if the file fails to be sent. **Usage** ```shell - hdc rport tcp:1234 tcp:1080 + hdc file send E:\example.txt /data/local/tmp/example.txt ``` -4. Remove the specified port forwarding. + + +2. Send a file from a remote device to the local device. ```shell - hdc fport rm taskstr + hdc file recv [-a|-sync|-z|-m] remotepath localpath ``` **Parameters** - | Parameter| Description| + | Name| Description| | -------- | -------- | - | _taskstr_ | Port forwarding task, in the format of tcp:XXXX tcp:XXXX.| + | _localpath_ | Destination path on the local device.| + | _remotepath_ | Path of the file to send on the remote device.| + | -a | Used to retain the file timestamp.| + | -sync | Used to transfer only the files whose **mtime** is updated.| + | -z | Used to compress and transmit files in LZ4 format. This parameter is unavailable.| + | -m | Used to synchronize the DAC permission, UID, GID, and MAC permission during file transfer.| **Return value** - | Return Value| Description| - | -------- | -------- | - | Remove forward ruler success, ruler:tcp:XXXX tcp:XXXX | The port forwarding is removed successfully.| - | [Fail]Remove forward ruler failed, ruler is not exist tcp:XXXX tcp:XXXX | Failed to remove the port forwarding because the specified forwarding does not exist.| + + A success message is displayed if the file is received successfully. Error information is displayed if the file fails to be received. **Usage** ```shell - hdc fport rm tcp:1234 tcp:1080 + hdc file recv /data/local/tmp/a.txt ./a.txt ``` +## Port Forwarding + +| Command| Description| +| -------- | -------- | +| fport ls | Lists all port forwarding tasks.| +| fport _localnode remotenode_ | Sets up a local port forwarding, which forwards data from a local port to a remote port.| +| rport _remotenode localnode_ | Sets up a remote port forwarding, which forwards data from a remote port to a local port.| +| fport rm _taskstr_ | Deletes a port forwarding task.| + +Port forwarding type supported by the PC: TCP. -5. Enable the USB connection channel of the device. +Port forwarding type supported by the device: TCP, DEV, localabstract, localfilesystem, JDWP, ark. + +1. List all port forwarding tasks. ```shell - hdc tmode usb + hdc fport ls ``` + **Return value** + | Return Value| Description| + | -------- | -------- | + | tcp:1234 tcp:1080 [Forward] | Local port forwarding.| + | tcp:2080 tcp:2345 [Reverse] | Remote port forwarding.| + | [empty] | No port forwarding.| + **Usage** ```shell - hdc tmode usb + hdc fport ls ``` - > **NOTE** - > This command cannot be used to enable the USB connection channel. You need to enable it on the device setting page. -6. Enable the network connection channel of the device. +2. Set up a local port forwarding, which forwards data from a local port to a remote port. ```shell - hdc tmode port [port-number] - ``` - - **Parameters** - | Parameter| Description| - | -------- | -------- | - | port-number | Port number of the connection. The value ranges from 1 to 65536.| + hdc fport localnode remotenode + ``` **Return value** | Return Value| Description| | -------- | -------- | - | Set device run mode successful. | The network connection channel is enabled successfully.| - | [Fail]ExecuteCommand need connect-key | Failed to enable the network connection channel because no device exists in the list. | - | [Fail]Incorrect port range | The port number is out of range (1 to 65536).| + | Forwardport result:OK | The port forwarding is set up properly.| + | [Fail]Incorrect forward command | Failed to set up the port forwarding due to parameter errors.| + | [Fail]TCP Port listen failed at XXXX | Failed to set up the port forwarding because the local port is in use.| **Usage** ```shell - hdc tmode port 1234 + hdc fport tcp:1234 tcp:1080 ``` - > **NOTE** - > Before changing the connection mode, ensure that the remote device and the local executor are on the same network, and the executor can ping the IP address of the remote device. - > - > Otherwise, do not run this command. - - > **NOTE** - > After the command is executed, the remote daemon process exits and restarts, and the USB connection is disconnected. You need to reconnect the USB connection. - -7. Disable the network connection channel of the device. +3. Set up a remote port forwarding, which forwards data from a remote port to a local port. ```shell - hdc tmode port close + hdc rport remotenode localnode ``` **Return value** | Return Value| Description| | -------- | -------- | - | [Fail]ExecuteCommand need connect-key | Failed to disable the network connection channel because no device exists in the list.| + | Forwardport result:OK | The port forwarding is set up properly.| + | [Fail]Incorrect forward command | Failed to set up the port forwarding due to parameter errors.| + | [Fail]TCP Port listen failed at XXXX | Failed to set up the port forwarding because the local port is in use.| **Usage** ```shell - hdc tmode port close + hdc rport tcp:1234 tcp:1080 ``` - > **NOTE** - > After the command is executed, the remote daemon process exits and restarts, and the USB connection is disconnected. You need to reconnect the USB connection. - -8. Connect to the specified device through TCP. +4. Delete a specified port forwarding task. ```shell - hdc tconn [IP]:[port] [-remove] + hdc fport rm taskstr ``` **Parameters** | Parameter| Description| | -------- | -------- | - | [IP]:[port] | Device IP address and port number.| - | -remove | (Optional) Disconnects from the specified device.| + | _taskstr_ | Port forwarding task, in the format of **tcp:XXXX tcp:XXXX**.| **Return value** | Return Value| Description| | -------- | -------- | - | Connect OK | Device connected.| - | [Info]Target is connected, repeat opration | The device is already connected.| - | [Fail]Connect failed | Failed to connect the specified device.| + | Remove forward ruler success, ruler:tcp:XXXX tcp:XXXX | The port forwarding is removed successfully.| + | [Fail]Remove forward ruler failed, ruler is not exist tcp:XXXX tcp:XXXX | Failed to remove the port forwarding because the specified forwarding does not exist.| **Usage** ```shell - hdc tconn 192.168.0.1:8888 - hdc tconn 192.168.0.1:8888 -remove // Disconnect from the specified device. + hdc fport rm tcp:1234 tcp:1080 ``` -### File Commands +## Managing Server Processes | Command| Description| | -------- | -------- | -| file send _localpath remotepath_ | Sends a local file to a remote device.| -| file recv _remotepath localpath_ | Sends a file from a remote device to the local device.| +| start [-r] | Starts the hdc process. You can use the **-r** option to restart the process.| +| kill [-r] | Terminates the hdc process. You can use the **-r** option to restart the process.| +| -p | Executes a client command without querying the server process.| +| -m | Starts a server process in the foreground.| -1. Send a local file to a remote device. + +1. Start the hdc server. ```shell - hdc file send localpath remotepath + hdc start [-r] ``` - **Parameters** - | Name| Description| - | -------- | -------- | - | _localpath_ | Path of the file to send on the local device.| - | _remotepath_ | Destination path on the remote device.| - **Return value** - - A success message is displayed if the file is sent successfully. Error information is displayed if the file fails to be sent. + | Return Value| Description| + | -------- | -------- | + | No return value | The server is started successfully. | **Usage** ```shell - hdc file send E:\example.txt /data/local/tmp/example.txt + hdc start + hdc start -r // Restart the server. ``` -2. Send a file from a remote device to the local device. + > **NOTE** + > + > When a hdc server is started and the system does not detect any running server, set the log level in the following sequence: If the **-l** parameter is specified and the **OHOS_HDC_LOG_LEVEL** environment variable is configured, use the log level configured by the environment variable. If only the **-l** parameter is specified, use the log level configured by this parameter. If both of them are not specified, the server starts with the default log level **LOG_INFO**. + +2. Terminate the hdc server. ```shell - hdc file recv remotepath localpath + hdc kill [-r] ``` - **Parameters** - | Name| Description| - | -------- | -------- | - | _localpath_ | Destination path on the local device.| - | _remotepath_ | Path of the file to send on the remote device.| - **Return value** - - A success message is displayed if the file is received successfully. Error information is displayed if the file fails to be received. + | Return Value| Description| + | -------- | -------- | + | Kill server finish | The server is terminated successfully.| + | [Fail]Error information| Failed to terminate the server.| **Usage** ```shell - hdc file recv /data/local/tmp/a.txt ./a.txt + hdc kill + hdc kill -r // Restart and terminate the server process. ``` -### App Commands - -| Command| Description| -| -------- | -------- | -| install _src_ | Installs an app.| -| uninstall _packageName_ | Uninstalls an app.| - -1. Install an app. +3. Execute a client command without querying the server. ```shell - hdc install [-r|-s] src + hdc -p [command] ``` **Parameters** - | Name| Description| + | Parameter| Description| | -------- | -------- | - | src| Installation package name.| - | -r | Replaces the existing app (.hap).| - | -s | Install a shared package (.hsp).| + | command | Command to be executed.| **Return value** | Return Value| Description| | -------- | -------- | - | AppMod finish | The installation is successful.| - | Error information| The installation fails.| + | Connect server failed | Fails to connect to the server.| **Usage** - For example, install **example.hap**. - ```shell - hdc install E:\example.hap + # Start a background server. + hdc start + # Execute the command directly without querying the server. + hdc -p list targets ``` -2. Uninstall the app. + > **NOTE** + > + > When a command is executed without the **-p** parameter specified, the client first checks whether a server is running locally. If the system does not detect a running server process, the client automatically starts a server process and sets up a connection to transfer commands. If the system detects a running server process, the client directly connects to the server process and transfers commands. + +4. Start the server process in the foreground. ```shell - hdc uninstall [-k|-s] packageName + hdc -m ``` - **Parameters** - | Name| Description| - | -------- | -------- | - | packageName | App installation package.| - | -k | Retains **/data** and **/cache**.| - | -s | Uninstalls a shared package.| - **Return value** | Return Value| Description| | -------- | -------- | - | AppMod finish | The uninstallation is successful.| - | Error information| The uninstallation fails.| + | Initial failed | The server process fails to be initialized.| + | [I][_1970-01-01 00:00:00.000_][_abcd_][_session.cpp:25_] _Program running. Ver: X.X.Xa Pid:12345_ | Logs of the corresponding level are printed to display the activity status of the server.| **Usage** - For example, uninstall **com.example.hello**. - ```shell - hdc uninstall com.example.hello + # Start a server process with the IP address and port number specified. + hdc -s 127.0.0.1:8710 -m ``` -### Debugging Commands + > **NOTE** + > + > 1. When using the **-m** parameter, you can add the **-s** parameter to specify the IP address and port number to be listened. If no IP address and port number are specified using the **-s** parameter and the environment variable **OHOS_HDC_SERVER_PORT** is not set, the system uses the default IP address and port number **127.0.0.1:8710**. + > 2. If the server process is started in the foreground, the default log output level is **LOG_DEBUG**. You can use the **-l** parameter to change the log level. + > 3. Only one server process instance can run at a time. If a background server process is running, a new server process instance cannot be started on the foreground. + +## Operating the Device | Command| Description| | -------- | -------- | +| hilog [-h] | Display the log information of the device. You can run the **hdc hilog -h** command to obtain the supported parameters. | | jpid | Displays the PIDs of all applications that have enabled JDWP on the device.| | track-jpid [-a\|-p] | Displays the PID and name of the application for which JDWP is enabled on the device in real time. If no parameter is specified, only the processes of the **debug** application are displayed. If the **-a** parameter is specified, the processes of the **debug** and **release** applications are displayed. If the **-p** parameter is specified, the **debug** and **release** labels are not displayed.| -| hilog [options] | Obtains the log information of the device. **options** indicates the parameters supported by HiLog. You can run the **hdc hilog -h** command to obtain the parameter information. | -| shell [command] | Runs a debugging command specified by *command*. The supported commands vary with the system type or version. You can run the **hdc shell ls /system/bin** command to view the supported commands. | +| target boot [-bootloader\|-recovery] | Restarts the target device. You can use the **-bootloader** option to enter the fastboot mode and the **-recovery** option to enter the recovery mode.| +| target boot [MODE] | Restart the target device to enter the corresponding mode. **MODE** is an option supported by **reboot** in the **/bin/begetctl** command.| +| target mount | Mounts the system partition in read/write mode. (This command is supported after the device has required the root permission.)| +| smode [-r] | Grants the root permission to the hdc background server process on the device. You can use the **-r** parameter to cancel the permission. (This command is supported after the device has required the root permission.)| -1. Obtain log information about the device. +1. Display the log information of the device. ```shell - hdc hilog [options] + hdc hilog [-h] ``` **Parameters** | Parameter| Description| | -------- | -------- | - | [options] | Parameters supported by HiLog. You can run the **hdc hilog -h** command to obtain the parameter list.| + | [-h] | Parameters supported by HiLog. You can run the **hdc hilog -h** command to obtain the parameter list.| **Return value** | Return Value| Description| @@ -768,8 +834,7 @@ hdc list targets -v **Usage** ```shell - hdc hilog - hdc shell "hilog -r" // Clear the cached logs. + hdc hilog ``` 2. Display the PIDs of all processes that enable JDWP. @@ -781,7 +846,7 @@ hdc list targets -v **Return value** | Return Value| Description| | -------- | -------- | - | PID list| PIDs of the applications that enable JDWP| + | PID list| PIDs of the applications that enable JDWP.| | [empty] | No process enables JDWP.| **Usage** @@ -799,9 +864,9 @@ hdc list targets -v **Parameters** | Parameter| Description| | -------- | -------- | - | Not specified| Displays only the PIDs, bundle names, and process names of debug applications.| - | -a | Displays the PIDs, bundle names, and process names of the debug and release applications. | - | -p | Displays the PIDs, bundle names, and process names of the debug and release applications, but does not display the **debug** and **release** labels.| + | Not specified| Used to display only the PIDs, bundle names, and process names of **debug** applications.| + | -a | Used to display the PIDs, bundle names, and process names of the **debug** and **release** applications. | + | -p | Used to display the PIDs, bundle names, and process names of the **debug** and **release** applications, but does not display the **debug** and **release** labels.| **Return value** | Return Value| Description| @@ -815,31 +880,78 @@ hdc list targets -v hdc track-jpid ``` -4. Run a command. +4. Restart the target device. ```shell - hdc shell [command] + target boot [-bootloader|-recovery] + target boot [MODE] ``` **Parameters** - | Parameter| Description| + | Name| Description| | -------- | -------- | - | [command] | Debugging command to be executed. You can run the **help** command to obtain all debugging commands.| + | Not specified| Used to restart a device.| + | -bootloader| Used to restart a device to enter the **fastboot** mode.| + | -recovery | Used to restart a device to enter the **recovery** mode.| + | MODE | Used to restart a device to enter the **MODE** mode. **MODE** is a parameter supported by **reboot** in the **/bin/begetctl** command.
For details, run the **hdc shell "/bin/begetctl -h \| grep reboot"** command.| | + + **Usage** + + ```shell + hdc target boot -bootloader // Restart the device to enter the fastboot mode. + hdc target boot -recovery // Restart the device to enter the recovery mode. + hdc target boot shutdown // Shut down the device. + ``` + + +5. Mount the system partition in read/write mode. + + ```shell + hdc target mount + ``` **Return value** | Return Value| Description| | -------- | -------- | - | Command execution result| Execution result of the debugging command.| - | /bin/sh: XXX : inaccessible or not found | The specified command is not supported.| + | Mount finish | Mounting succeeded.| + | [Fail]Mount failed | Mounting failed.| **Usage** ```shell - hdc shell ps -ef - hdc shell help -a // List all available commands. + hdc target mount + ``` + + > **NOTE** + > + > This command is supported only after the device has required the root permission. Exercise caution when running this command. + +6. Grant the **root** permission to the background hdc server running on the device. + + ```shell + hdc smode [-r] + ``` + + **Return value** + | Return Value| Description| + | -------- | -------- | + | No return value| Permission granted.| + | [Fail]Error information| Failed to grant the permission.| + + **Usage** + + ```shell + hdc smode + hdc smode -r // Revoke the root permission. ``` -### Security Command + > **NOTE** + > + > This command is supported only after the device has required the **root** permission. + + + +## Security Command | Command| Description| | -------- | -------- | @@ -862,125 +974,137 @@ hdc list targets -v hdc keygen key // Generate the key and key.pub files in the current directory. ``` +## Obtaining the Version Number -## When to Use - -### USB Connection - -**Checking the Environment** -| Item| Normal| Exception Handling| -| -------- | -------- | -------- | -| USB debugging| USB debugging is enabled.| If the USB debugging mode is not automatically enabled, restart the device.| -| USB data cable connection| The PC used for debugging is connected to the device USB port using a USB cable.| If you use a USB cable with low bandwidth and no data communication function, the device may fail to be identified. You are advised to use an officially recommended USB cable.| -| USB port| A USB port on the mainboard (USB port on the rear panel of a desktop computer or USB port on a laptop computer) is used.| If you use a conversion adapter, docking station, or USB port on the front panel of a desktop computer, issues such as low bandwidth and USB sync problems may occur, which results in frequent disconnections. Therefore, direct connection between the PC and the device is recommended.| -| hdc environment variable| The help information is displayed after the **hdc -h** command is executed.| For details, see "Environment Setup".| -| Driver| After the device is connected via hdc, **HDC Device** or **HDC Interface** is displayed in **Device Manager**.| Install the driver.| - -**Procedure** - -```shell -hdc shell // For USB direct connection, ensure that the device is not in TCP connection mode. -``` - -### TCP Connection - -**Checking the Environment** -| Item| Normal| Exception Handling| -| -------- | -------- | -------- | -| Network connection| The PC and the device are on the same network.| Connect the PC and device to the same Wi-Fi network or enable the Wi-Fi hotspot on your device.| -| Network Status| Use **telnet IP:port** to check that the network connection between the PC and the device is normal.| Connect the PC and the device over a stable network.| -| hdc environment variable| The help information is displayed after the **hdc** command is executed.| For details, see "Environment Setup".| +| Command| Description| +| -------- | -------- | +| -v/version | Displays hdc version information.| +| checkserver | Obtains the client and server process versions.| -**Procedure** +1. Display hdc version information. -1. Connect the PC to the device through a USB port. + ```shell + hdc -v/version + ``` + **Return value** + | Return Value| Description| + | -------- | -------- | + | Ver: X.X.Xa | hdc (SDK) version information.| -2. Change the connection mode from USB mode to the TCP mode. + **Usage** ```shell - hdc tmode port 8710// Add a port number after port. The default port number is 8710. + hdc -v or hdc version ``` -3. Connect to the device over TCP (the device IP address must be obtained in advance). +2. Obtain the client and server process versions. ```shell - hdc tconn IP:8710 + hdc checkserver ``` - You can view the IP address on the device. The port number is the one specified in the previous step. The default port number is 8710. + **Return value** + | Return Value| Description| + | -------- | -------- | + | Client version: Ver: X.X.Xa, Server version: Ver: X.X.Xa | The client and server versions.| -4. Check the connection. + **Usage** ```shell - hdc list targets + hdc checkserver ``` - If the return value is in the *IP:port* format, the connection is successful. +## hdc Debugging Logs -5. (Optional) Change the TCP mode to the USB mode. +### Server Logs + +#### Log level + +Specify the hdc log level. The default value is **LOG_INFO**. ```shell - hdc tmode usb + hdc -l [level] [command] ``` - The USB mode is restored. + **Parameters** +| Parameter| Description| +| -------- | -------- | +| [level] | Log level.
0: LOG_OFF
1: LOG_FATAL
2: LOG_WARN
3: LOG_INFO
4: LOG_DEBUG
5: LOG_ALL
6: LOG_LIBUSB| +| command | Command to be executed.| + + > **NOTE** + > + > 1. When the log level is set to 6 (**LOG_LIBUSB**), incremental logs related to libusb are generated. The incremental logs are detailed and contain a large amount of data, which helps accurately diagnose USB-related exceptions in server processes. USB-related operations are mainly performed by server processes. Therefore, incremental logs are available only for server processes. Accordingly, the client logs almost do not contain incremental log information. + > 2. You can change only the log levels of the current client and server processes. + + **Return value** +| Return Value| Description| +| -------- | -------- | +| Command output| Command execution result, which may vary with the command.| +| Log information| Logs of the specified level.| -### Remote Connection + **Usage** -The following figure illustrates a remote connection. + Run the **shell ls** command with the log level specified to **LOG_DEBUG**. -![Remote connection structure](figures/hdc_image_004.PNG) + ```shell + hdc -l 5 shell ls + ``` -**Server Configuration** + Run the **-m** command with the log level specify to **LOG_LIBUSB**. -Connect the server to the device using a USB cable and run the following commands: + ```shell + hdc kill && hdc -l 6 -m + ``` -```shell -hdc kill // Terminate the local hdc service. -hdc -s IP:8710 -m // Enable the hdc service for network forwarding. - // In the command, IP indicates the IP address of the server. To query the IP address, you can run the ipconfig command on Windows and run the ifconfig command on Unix. - // 8710 is the default port number. You can also set it to another port number, for example, 18710. - // After startup, the server prints logs. -``` + > **NOTE** + > The **-m** parameter is used to start the server process in the foreground. You can directly view the foreground log output and press **Ctrl+C **to exit the process. -**Client Connection** + Start the server process in the background with the log level set to **LOG_LIBUSB**. -Ensure that the client can connect to the server IP address, and then run the following command: -```shell -hdc -s IP:8710 [command] // IP indicates the IP address of the server, - // and command can be any available hdc command, for example, list targets. -``` + ```shell + hdc kill && hdc -l 6 start + ``` -### Obtaining Logs + > **NOTE** + > When the server process is started in the background, you can view the log output in **hdc.log**. For details about the log path, see **Obtaining Logs**. -**Server logs** +#### Obtaining Logs Obtain server logs. ```shell -hdc kill ​ +hdc kill hdc -l5 start ``` The collected logs are stored in the following path. -| OS| Path| Remarks| +| OS | Path | Remarks | | -------- | -------- | -------- | -| Windows | %temp%\hdc_logs | The following is an example. Replace *Username* with the actual one.
C:\Users\Username\AppData\Local\Temp\hdc_logs| -| Linux | /tmp/hdc_logs | - | -| MacOS | $TMPDIR/hdc_logs | - | +| Windows | %temp%\hdc.log | The following are examples. Replace *Username* with the actual one.
**
C:\Users\Username\AppData\Local\Temp\hdc.log** | +| Linux | /tmp/hdc.log | - | +| macOS | $TMPDIR/hdc.log | - | + +Log-related environment variables + +| Environment Variable | Default Value| Description | +|--------------------|-----|--------------------------------| +| OHOS_HDC_LOG_LEVEL | 5 | The log level of the server process.
For details, see [Server Logs](#server-logs). | + + +Configure environment variables as follows: -The hdc_logs folder contains the following types of logs: +The following shows how to set the **OHOS_HDC_LOG_LEVEL** environment variable to **5**. -|Type| Name Format| Function| Remarks| -| -------- | -------- | -------- | -------- | -| Real-time log| hdc.log | Records hdc server logs in real time.| Each time the hdc server is restarted, the original log is renamed and a new hdc.log is recorded.| -| Temporary historical log| hdc-%Y%m%d-%H%M%S.log | Dumps intermediate files generated during historical log archiving.| For example, **16:18:57.921 on September 19, 2024** is recorded as
**20240919-161857921**.
The generated temporary log file is stored in the format of **hdc-20240919-161857921.log**.| -| Archived historical logs| hdc-%Y%m%d-%H%M%S.log.tgz | Compresses and stores historical logs.| The archive file is a compressed file of the **.tgz** type. You can use a decompression tool to obtain the file.
For example, if the name of a temporary historical log file is **hdc-20240919-161857921.log**,
the name of the corresponding archived historical log file is **hdc-20240919-161857921.log.tgz**.
After an archived historical log file is generated, the corresponding temporary historical log file is automatically deleted.| -| Temporary real-time log| .hdc.cache.log | Records temporary caches generated by real-time logs.| | +| OS| Configuration Method| +|---|---| +| Windows | Choose **This PC >Properties >Advanced system settings >Advanced >Environment Variables**, add the environment variable **OHOS_HDC_LOG_LEVEL**, and set its value to **5**. After the configuration is complete, click **OK**. Restart the CLI or other software that uses OpenHarmony SDK for the new environment variable to take effect. | +| Linux | Add **export OHOS_HDC_LOG_LEVEL=5** to the end of the **~/.bash_profile** file, save the file, and run the **source ~/.bash_profile** command for the current environment variable to take effect.| +| macOS | Add **export OHOS_HDC_LOG_LEVEL=5** to the end of the **~/.zshrc** file, save the file, and run the **source ~/.zshrc** command for the current environment variable to take effect. After the environment variable is configured, restart the CLI or other software that uses OpenHarmony SDK for the new environment variable to take effect.| -**Device Logs** +### Device Logs Enable HiLog to obtain the corresponding logs. @@ -998,121 +1122,162 @@ hdc file recv /data/log/hilog // Obtain the stored HilLog logs After the **hdc list targets** command is executed, the command output is **[empty]**. +**Possible Causes and Solution** + Perform the following operations to locate the fault. - Case 1: Check whether the target device is displayed in **Device Manager**. - Windows: + Windows: - Check whether **HDC Device** (for a single-port device) or **HDC Interface** (for a composite device) exists under **Universal Serial Bus Controllers** in **Device Manager**. + Check whether **HDC Device** (for a single-port device) or **HDC Interface** (for a composite device) exists under **Universal Serial Bus Controllers** in **Device Manager**. - Linux: + Linux: - Run the **lsusb** command. Check whether **HDC Device** or **HDC Interface** is displayed in the command output. + Run the **lsusb** command. Check whether **HDC Device** or **HDC Interface** is displayed in the command output. - macOS: + macOS: - View USB devices in **System Information** or **System Overview**. + View USB devices in **System Information** or **System Overview**. - 1. Press and hold the **Option** key, and click **Menu**. + 1. Press and hold the **Option** key, and click **Menu**. - 2. Choose **System Information** or **System Overview**. + 2. Choose **System Information** or **System Overview**. - 3. Select **USB** on the left. + 3. Select **USB** on the left. - 4. Check whether **HDC Device** or **HDC Interface** exists in the device tree. + 4. Check whether **HDC Device** or **HDC Interface** exists in the device tree. - **Solution** + **Solution** - If the device is not displayed, it fails to be identified. You can use any of the following methods to resolve the problem: + If the device is not displayed, it fails to be identified. You can use any of the following methods to resolve the problem: - - Use another physical USB port. - - Replace the USB cable. - - Use another PC for debugging. - - Enable the USB debugging mode. - - Click **OK** to allow USB debugging. - - If a TCP connection can be set up, run the **hdc tmode usb** command to switch to the USB connection. - - Restore the factory settings of the device. + - Use another physical USB port. + - Replace the USB cable. + - Use another PC for debugging. + - Enable the USB debugging mode. + - Click **OK** to allow USB debugging. + - If a TCP connection can be set up, run the **hdc tmode usb** command to switch to the USB connection. + - Restore the factory settings of the device. - Case 2: A USB device exists, but the driver is damaged. **HDC Device** with a warning icon in yellow is displayed. - This problem usually occurs in Windows. In **Device Manager/Universal Serial Bus Device**, **HDC Device** is displayed with a yellow warning icon, indicating that the device cannot work properly. To resolve the problem, reinstall the driver. If the problem persists, use another USB cable, docking station, or USB port. + This problem usually occurs in Windows. In **Device Manager/Universal Serial Bus Device**, **HDC Device** is displayed with a yellow warning icon, indicating that the device cannot work properly. To resolve the problem, reinstall the driver. If the problem persists, use another USB cable, docking station, or USB port. - **Reinstalling the Driver** + **Reinstalling the Driver** - 1. Open **Device Manager**, and right-click the **HDC Device** with a warning icon. + 1. Open **Device Manager**, and right-click the **HDC Device** with a warning icon. - 2. In the displayed menu, choose **Update driver**. + 2. In the displayed menu, choose **Update driver**. - 3. In the first prompt window, select **Browse my computer for drivers**. + 3. In the first prompt window, select **Browse my computer for drivers**. - 4. In the second prompt window, select **Let me pick from a list of available drivers on my computer**. + 4. In the second prompt window, select **Let me pick from a list of available drivers on my computer**. - 5. In the third prompt window, deselect **Show compatible hardware**, select **WinUsb Device** for **Manufacture** and **WinUsb Device** for **Model**, and click **Next**. + 5. In the third prompt window, deselect **Show compatible hardware**, select **WinUsb Device** for **Manufacture** and **WinUsb Device** for **Model**, and click **Next**. - Case 3: "[Fail]Failed to communicate with daemon" is displayed when the device is connected. - When "[Fail]Failed to communicate with daemon" is displayed after a hdc command is executed. + When "[Fail]Failed to communicate with daemon" is displayed after a hdc command is executed. - Possible causes are as follows: + Possible causes are as follows: - - The hdc or SDK does not match the device. If the device is the latest version, update the hdc or SDK tool to the latest version. - - The port is occupied. + - The hdc or SDK does not match the device. If the device is the latest version, update the hdc or SDK tool to the latest version. + - The port is occupied. - This problem usually occurs when hdc and hdc_std use the same **HDC_SERVER_PORT** or the same default port **8710**. Ensure that either hdc or hdc_std is running. This problem also occurs when other software occupies the default hdc port. + This problem usually occurs when hdc and hdc_std use the same **OHOS_HDC_SERVER_PORT** or the same default port **8710**. Ensure that either hdc or hdc_std is running. This problem also occurs when other software occupies the default hdc port. - Case 4: "Connect server failed" is displayed when the device is connected. - The possible causes are as follows: + The possible causes are as follows: + + - **Port Preemption** + + Solution: + 1. Check the software processes that come with hdc, including software with built-in hdc, such as DevEco Studio and DevEco Testing. + + Stop these software processes and run hdc commands. + + 2. Check hdc port status. + + For example, if **OHOS_HDC_SERVER_PORT** is set to **8710**, run the following command to check the port status. + + Unix: + + ```shell + netstat -an |grep 8710 + ``` + + Windows: + + ```shell + netstat -an |findstr 8710 + ``` + + If the port is used by another software, stop the software process or change the **OHOS_HDC_SERVER_PORT** environment variable to another port number. + + 3. Check for and stop the hdc server of another version. + + Windows: + + Choose **Task Manager** > **Details**, right-click the **hdc.exe** process and choose **Open file location**. Check whether the location is the same as that configured in the environment variable. If not, stop the **hdc.exe** process by running the **hdc kill** command or terminating the process in **Task Manager**. Then, run the hdc command again. (The hdc server will be restarted by running the hdc command.) + + Unix: - - **Port Preemption** + Run the **ps -ef |grep hdc** command to query the hdc server process running in the background and check whether the process startup location is the hdc file location set by the environment variable **Path**. If not, stop the hdc process by running the **hdc kill** or **kill -9 hdc** *PID* command, and run the hdc command again. (The hdc server will be restarted by running the hdc command.) - Solution: - 1. Check the software processes that come with hdc, including software with built-in hdc, such as DevEco Studio and DevEco Testing. + - **Registry Exception** - Stop these software processes and run hdc commands. + Solution: Clear the registry. The procedure is as follows: - 2. Check hdc port status. + 1. Press **Win+R** to open the **Run** dialog box, and enter **regedit** to open the registry. + 2. Enter the following address in the address bar, and press **Enter** to access the registry of the USB device driver. - For example, if **HDC_SERVER_PORT** is set to **8710**, run the following command to check the port status. + ```shell + Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{88bae032-5a81-49f0-bc3d-a4ff138216d6} + ``` - Unix: + 3. Right-click **UpperFilters** and choose **Edit**. Back up and clear the value data. The backup data can be used to restore the value data if the problem persists. + 4. Refresh the **Device Manager**, remove and reconnect the USB cable to the USB port, or restart the PC. - ```shell - netstat -an |grep 8710 - ``` + + +**The non-root user cannot find the device using hdc in Linux** - Windows: +In Linux, you can enable the USB device operation permission for non-root users as follows: - ```shell - netstat -an |findstr 8710 - ``` +- To temporarily grant the full operation permission on a USB device, run the following command: - If the port is used by another software, stop the software process or change the **HDC_SERVER_PORT** environment variable to another port number. + ```shell + sudo chmod -R 777 /dev/bus/usb/ + ``` - 3. Check for and stop the hdc server of another version. +- To permanently change the operation permission on a USB device, do as follows: - Windows: + 1. Run the **lsusb** command to obtain the **vendorID** and **productID** of the USB device. - Choose **Task Manager** > **Details**, right-click the **hdc.exe** process and choose **Open file location**. Check whether the location is the same as that configured in the environment variable. If not, stop the **hdc.exe** process by running the **hdc kill** command or terminating the process in **Task Manager**. Then, run the hdc command again. (The hdc server will be restarted by running the hdc command.) + 2. Create an **udev** rule. - Unix: + Edit the **udev** loading rule and replace the default **idVendor** and **idProduct** values of the device with the values obtained in the previous step. - Run the **ps -ef |grep hdc** command to query the hdc server process running in the background and check whether the process startup location is the hdc file location set by the environment variable **Path**. If not, stop the hdc process by running the **hdc kill** or **kill -9 hdc** *PID* command, and run the hdc command again. (The hdc server will be restarted by running the hdc command.) + **MODE="0666"** indicates the permissions of **GROUP** (the user group) for the USB device. Ensure that the login user is in the user group. - - **Registry Exception** + ```shell + sudo vim /etc/udev/rules.d/90-myusb.rules + SUBSYSTEMS=="usb", ATTRS{idVendor}=="067b", ATTRS{idProduct}=="2303", GROUP="users", MODE="0666" + ``` - Solution: Clear the registry. The procedure is as follows: + 3. Restart the computer or reload the **udev** rule. - 1. Press **Win+R** to open the **Run** dialog box, and enter **regedit** to open the registry. - 2. Enter the following address in the address bar, and press **Enter** to access the registry of the USB device driver. + ```shell + sudo udevadm control --reload + ``` - ```shell - Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{88bae032-5a81-49f0-bc3d-a4ff138216d6} - ``` +> **NOTE** +> +> A non-root user cannot find the device using hdc in Linux. Granting USB operation permission for non-root users can solve this problem. However, granting the full permission may pose potential security risks. You need to determine whether to grant the permission based on actual requirements. - 3. Right-click **UpperFilters** and choose **Edit**. Back up and clear the value data. The backup data can be used to restore the value data if the problem persists. - 4. Refresh the **Device Manager**, remove and reconnect the USB cable to the USB port, or restart the PC. + ### Failed to Run hdc @@ -1124,11 +1289,11 @@ The **hdc.exe**/hdc binary file cannot be executed using the CLI. - Incorrect runtime environment. - Linux: Ubuntu 18.04 64-bit or later is recommended. If **libc++.so** reference errors are reported, run the **ldd** or **readelf** command to check library reference. + Linux: Ubuntu 18.04 64-bit or later is recommended. If **libc++.so** reference errors are reported, run the **ldd** or **readelf** command to check library reference. - macOS: macOS 11 or later is recommended. + macOS: macOS 11 or later is recommended. - Windows: Windows 10 or Windows 11 64-bit is recommended. If the WinUSB library or driver is missing in an earlier version, use [Zadig](https://github.com/pbatard/libwdi/releases) to update it. For Windows 10 or Windows 11 64-bit, use [Zadig](https://github.com/pbatard/libwdi/releases) to install the libusb-win32 driver. For details, see [Zadig](https://github.com/pbatard/libwdi/releases). + Windows: Windows 10 or Windows 11 64-bit is recommended. If the WinUSB library or driver is missing in an earlier version, use [Zadig](https://github.com/pbatard/libwdi/releases) to update it. For Windows 10 or Windows 11 64-bit, use [Zadig](https://github.com/pbatard/libwdi/releases) to install the libusb-win32 driver. For details, see [Zadig](https://github.com/pbatard/libwdi/releases). - Improper running mode: Use the correct command to run the hdc tool instead of double-clicking the file. @@ -1136,5 +1301,5 @@ The **hdc.exe**/hdc binary file cannot be executed using the CLI. 1. Run the **hdc list targets** command. 2. Check whether **HDC Device** exists in **Device Manager**. -3. Run the **hdc kill** command to terminate the server, and then run the **hdc -l5 start** command to collect logs. The **hdc.log** file is stored in the **hdc_logs** folder of the **TEMP** directory on the execution end. The specific directory varies with the OS. For details, see [Obtaining Logs](#obtaining-logs). +3. Run the **hdc kill** command to terminate the server, and then run the **hdc -l5 start** command to collect logs. (The **hdc.log** file is stored in the **TEMP** directory on the execution end. The directory location varies with the OS. For details, see [Server Logs](#server-logs).) 4. Locate the problem based on the **hdc.log** file. diff --git a/en/application-dev/dfx/hiappevent-watcher-app-events-arkts.md b/en/application-dev/dfx/hiappevent-watcher-app-events-arkts.md index e5e41fbd56f9e421f069afb7c2312a1524576b71..f712e398a0a0c51d85be051fcccd4cd2f8322f43 100644 --- a/en/application-dev/dfx/hiappevent-watcher-app-events-arkts.md +++ b/en/application-dev/dfx/hiappevent-watcher-app-events-arkts.md @@ -10,15 +10,15 @@ For details about how to use the APIs (such as parameter usage constraints and v | API | Description | | --------------------------------------------------- | -------------------------------------------- | -| write(info: AppEventInfo, callback: AsyncCallback\): void | Writes events to the event file through **AppEventInfo** objects. This API uses an asynchronous callback to return the result. | -| write(info: AppEventInfo): Promise\ | Writes events to the event file through **AppEventInfo** objects. This API uses a promise to return the result. | +| write(info: AppEventInfo, callback: AsyncCallback\): void | Writes events to the event file through **AppEventInfo** objects. This API uses an asynchronous callback to return the result.| +| write(info: AppEventInfo): Promise\ | Writes events to the event file through **AppEventInfo** objects. This API uses a promise to return the result.| **Subscription APIs** | API | Description | | --------------------------------------------------- | -------------------------------------------- | -| addWatcher(watcher: Watcher): AppEventPackageHolder | Adds a watcher to listen for application events. | -| removeWatcher(watcher: Watcher): void | Removes a watcher to unsubscribe from application events. | +| addWatcher(watcher: Watcher): AppEventPackageHolder | Adds a watcher to listen for application events.| +| removeWatcher(watcher: Watcher): void | Removes a watcher to unsubscribe from application events.| ## How to Develop diff --git a/en/application-dev/dfx/hiappevent-watcher-crash-events-arkts.md b/en/application-dev/dfx/hiappevent-watcher-crash-events-arkts.md index 93c2b84d7a37debeb50ea796eb901e131a4d44e4..311252e471472db6459f798b61ba6fdfc47fc927 100644 --- a/en/application-dev/dfx/hiappevent-watcher-crash-events-arkts.md +++ b/en/application-dev/dfx/hiappevent-watcher-crash-events-arkts.md @@ -111,7 +111,10 @@ The following describes how to subscribe to a crash event triggered by a button 5. In DevEco Studio, click the **Run** button to run the project. Then, click the **appCrash** button to trigger a crash event. After a crash occurs, the system uses different stack backtracking methods to generate crash logs based on the crash type (JsError or NativeCrash) and then invokes callback. The NativeCrash stack backtracking takes about 2s. In practice, the duration depends on the number of service threads and the duration of inter-process communication. JsError triggers in-process stack backtracking, and NativeCrash triggers out-of-process stack backtracking. Therefore, NativeCrash stack backtracking is more time-consuming than JsError stack backtracking. You can subscribe to crash events so that the stack backtracking result is asynchronously reported without blocking the current service. -6. When the application is restarted, HiAppEvent reports the crash event to the registered watcher. You can view the following event information in the **Log** window. +6. If the application does not capture the crash event, the application exits after the system crashes. When the application is restarted, HiAppEvent reports the crash event to the registered watcher. +
If the application captures the crash event. HiAppEvent reports the event before the application exits in the following scenarios: +
  Scenario 1: The application does not exit during exception handling. For example, when [errorManger.on](../reference/apis-ability-kit/js-apis-app-ability-errorManager.md#errormanageronerror) is used to capture JsError, the application registers the NativeCrash signal processing function and does not exit.
  Scenario 2: Exception handling takes a long time, and the application exit time is delayed. +
After HiAppEvent reports the event, you can view the processing logs of the system event data in the **Log** window. ```text HiAppEvent onReceive: domain=OS diff --git a/en/application-dev/dfx/hiappevent-watcher-crash-events-ndk.md b/en/application-dev/dfx/hiappevent-watcher-crash-events-ndk.md index 3ef89f18ae499da6c93491d1d5f1db39b1a515f0..8a8bb8503e656efcb1dc61215272ea9cd45b71f8 100644 --- a/en/application-dev/dfx/hiappevent-watcher-crash-events-ndk.md +++ b/en/application-dev/dfx/hiappevent-watcher-crash-events-ndk.md @@ -246,7 +246,10 @@ The following describes how to subscribe to the crash event triggered by a butto 8. In DevEco Studio, click the **Run** button to run the project. Then, click the **appCrash** button to trigger a crash event. After a crash occurs, the system uses different stack backtracking methods to generate crash logs based on the crash type (JsError or NativeCrash) and then invokes callback. The NativeCrash stack backtracking takes about 2s. In practice, the duration depends on the number of service threads and the duration of inter-process communication. JsError triggers in-process stack backtracking, and NativeCrash triggers out-of-process stack backtracking. Therefore, NativeCrash stack backtracking is more time-consuming than JsError stack backtracking. You can subscribe to crash events so that the stack backtracking result is asynchronously reported without blocking the current service. -9. When the application is started next time, HiAppEvent reports the crash event to the registered watcher. You can view the processing logs of system event data in the **Log** window. +9. If the application does not capture the crash event, the application exits after the system crashes. When the application is restarted, HiAppEvent reports the crash event to the registered watcher. +
If the application captures the crash event. HiAppEvent reports the event before the application exits in the following scenarios: +
  Scenario 1: The application does not exit during exception handling. For example, when [errorManger.on](../reference/apis-ability-kit/js-apis-app-ability-errorManager.md#errormanageronerror) is used to capture JsError, the application registers the NativeCrash signal processing function and does not exit.
  Scenario 2: Exception handling takes a long time, and the application exit time is delayed. +
After HiAppEvent reports the event, you can view the processing logs of the system event data in the **Log** window. ```text HiAppEvent eventInfo.domain=OS diff --git a/en/application-dev/dfx/hiappevent-watcher-crash-events.md b/en/application-dev/dfx/hiappevent-watcher-crash-events.md index 3cbff9fa698b8b1983037fa1ce0cffd77aade353..e50764634d91c3f1aed3fa303676520f172f43d8 100644 --- a/en/application-dev/dfx/hiappevent-watcher-crash-events.md +++ b/en/application-dev/dfx/hiappevent-watcher-crash-events.md @@ -20,9 +20,9 @@ The **params** parameter in the event information is described as follows. | uid | number | User ID of the application.| | uuid | string | Error ID.| | exception | object | Exception information. For details, see **exception**.
For details about the NativeCrash events, see **exception (NativeCrash)**. **exception** contains only brief fault information. For details, see the **external_log** file.| -| hilog | string[] | Log information.| +| hilog | string[] | Log information. A maximum of 100 lines of HiLog information can be displayed. More logs can be obtained from the error log file.| | threads | object[] | Full thread call stack. For details, see **thread**. This field applies only to NativeCrash events.| -| external_log12+ | string[] | Path of the error log file. If the directory files exceed the threshold (for details, see **log_over_limit**), new log files may fail to be written. Therefore, delete the log files immediately after they are processed.| +| external_log12+ | string[] | Path of the error log file. Error log files include **CPPCRASH** and **JSERROR**. You can use them for [Analyzing CPP Crash](cppcrash-guidelines.md) and [Analyzing JS Crash](jscrash-guidelines.md). If the directory files exceed the threshold (for details, see **log_over_limit**), new log files may fail to be written. Therefore, delete the log files immediately after they are processed.| | log_over_limit12+ | boolean | Whether the size of generated fault log files and existing log files exceeds the upper limit (5 MB). The value **true** indicates that the upper limit is exceeded and logs fail to be written. The value **false** indicates that the upper limit is not exceeded.| **exception** @@ -66,8 +66,8 @@ The **params** parameter in the event information is described as follows. | Name | Type | Description | | ------- | ------ | ------------------------- | | file | string | File name.| -| symbol | string | Function name.| -| buildId | string | Unique file ID.| +| symbol | string | Function name. | +| buildId | string | Unique file ID. | | pc | string | PC register address.| | offset | number | Function offset.| diff --git a/en/application-dev/dfx/hiappevent-watcher-freeze-events-arkts.md b/en/application-dev/dfx/hiappevent-watcher-freeze-events-arkts.md index 6afdb8fe997b3f46ed6327bd96eed763ea96ec77..93a850442fb5d752ce88e6b7c86264843f37e752 100644 --- a/en/application-dev/dfx/hiappevent-watcher-freeze-events-arkts.md +++ b/en/application-dev/dfx/hiappevent-watcher-freeze-events-arkts.md @@ -117,7 +117,7 @@ The following describes how to subscribe to the freeze event triggered by a butt }) ``` -5. In DevEco Studio, click the **Run** button to run the project. Then, click the **appfreeze** button to trigger a freeze event. +5. In DevEco Studio, click the **Run** button to run the project. Then, click the **appfreeze** button to trigger a freeze event. 6. The application crashes. After restarting the application, you can view the following event information in the **Log** window. diff --git a/en/application-dev/dfx/hiappevent-watcher-freeze-events-ndk.md b/en/application-dev/dfx/hiappevent-watcher-freeze-events-ndk.md index 80897cf983c7133c407b11366d7dd25c881487c9..2614ad988cbe2dd5b1cc26b3678f57e9fb95395e 100644 --- a/en/application-dev/dfx/hiappevent-watcher-freeze-events-ndk.md +++ b/en/application-dev/dfx/hiappevent-watcher-freeze-events-ndk.md @@ -266,7 +266,7 @@ The following describes how to subscribe to the freeze event triggered by a butt }) ``` -8. In DevEco Studio, click the **Run** button to run the project. Then, click the **appfreeze** button to trigger a freeze event. +8. In DevEco Studio, click the **Run** button to run the project. Then, click the **appfreeze** button to trigger a freeze event. 9. The application crashes. After restarting the application, you can view the following event information in the **Log** window. diff --git a/en/application-dev/dfx/hiappevent-watcher-mainthreadjank-events-arkts.md b/en/application-dev/dfx/hiappevent-watcher-mainthreadjank-events-arkts.md index d10af41e0bed18b059e0d8e41db0e3c4b44a2475..c4200b8d010fad80d131b8c59fce372534b3c42a 100644 --- a/en/application-dev/dfx/hiappevent-watcher-mainthreadjank-events-arkts.md +++ b/en/application-dev/dfx/hiappevent-watcher-mainthreadjank-events-arkts.md @@ -1,5 +1,9 @@ # Subscribing to Main Thread Jank Events (ArkTS) +## Main Thread Jank Event Specifications + +For details, see [Main Thread Jank Event Overview](./hiappevent-watcher-mainthreadjank-events.md). + ## Available APIs For details about how to use the APIs, see [Application Event Logging](../reference/apis-performance-analysis-kit/js-apis-hiviewdfx-hiappevent.md). @@ -11,7 +15,7 @@ For details about how to use the APIs, see [Application Event Logging](../refere ## How to Develop -The following describes how to subscribe to the main thread jank event, which is reported when a task running in the main thread times out. +The following describes how to subscribe to the main thread jank event in sampling stack, which is reported when a task running in the main thread times out. 1. Create an ArkTS application project. In the **entry/src/main/ets/entryability/EntryAbility.ets** file, import the dependent modules. @@ -45,11 +49,11 @@ The following describes how to subscribe to the main thread jank event, which is hilog.info(0x0000, 'testTag', `HiAppEvent eventInfo.eventType=${eventInfo.eventType}`); // Obtain the timestamp when the main thread jank event occurs. hilog.info(0x0000, 'testTag', `HiAppEvent eventInfo.params.time=${eventInfo.params['time']}`); - // Obtain the version information of the app. + // Obtain the version information of the application. hilog.info(0x0000, 'testTag', `HiAppEvent eventInfo.params.bundle_version=${eventInfo.params['bundle_version']}`); - // Obtain the bundle name of the app. + // Obtain the bundle name of the application. hilog.info(0x0000, 'testTag', `HiAppEvent eventInfo.params.bundle_name=${eventInfo.params['bundle_name']}`); - // Obtain the PID and UID of the app. + // Obtain the PID and UID of the application. hilog.info(0x0000, 'testTag', `HiAppEvent eventInfo.params.pid=${eventInfo.params['pid']}`); hilog.info(0x0000, 'testTag', `HiAppEvent eventInfo.params.uid=${eventInfo.params['uid']}`); // Obtain the begin time and end time on the main thread. @@ -64,23 +68,21 @@ The following describes how to subscribe to the main thread jank event, which is }); ``` +3. In the **entry > src > main > ets > pages> Index.ets** file, add the **timeOut500** button with **onClick()** to trigger a main thread jank event when the button is clicked. The sample code is as follows:. -3. In the **entry/src/main/ets/pages/Index.ets** file, add the **timeOut500** button with **onClick()** to trigger a main thread jank event when the button is clicked. The sample code is as follows: - ```ts + ```ts Button("timeOut350") .fontSize(50) - .fontWeight(FontWeight.Bold) - .onClick(() => { - let t = Date.now(); - while (Date.now() - t <= 350) {} - }) - ``` - -4. **If the nolog version is used and the developer mode is disabled**, the main thread checker will collect tracing data when a task times out. + .fontWeight(FontWeight.Bold) + .onClick(() => { + let t = Date.now(); + while (Date.now() - t <= 350) {} + }) + ``` -5. In DevEco Studio, click the **Run** button to run the application project. Click the **timeOut350** button twice consecutively to trigger a main thread jank event. +4. In DevEco Studio, click the **Run** button to run the application project. Click the **timeOut350** button twice consecutively to trigger a main thread jank event. -6. After the main thread jank event is reported, the system calls **onReceive()**. You can view the following event information in the **Log** window. +5. After the main thread jank event is reported, the system calls **onReceive()**. You can view the following event information in the **Log** window. Tracing data of the main thread jank event is as follows: @@ -100,115 +102,9 @@ The following describes how to subscribe to the main thread jank event, which is ``` The sampling stack of the main thread jank event is similar to the trace result. The differences are as follows: - - Stack: - external_log=["/data/storage/el2/log/watchdog/MAIN_THREAD_JANK_yyyyMMDDHHmmss_xxxx.txt"]. *xxxx* indicates the process ID. - - Trace: - external_log=[""/data/storage/el2/log/watchdog/MAIN_THREAD_JANK_unix timestamp_xxxx.trace"]. *xxxx* indicates the process ID. - -## Main Thread Jank Event Time Specifications -1. Begin time - - If the main thread processing time is greater than 150 ms but less than 450 ms, trigger a stack sampling. **Only one sampling stack can be triggered based on the PID of an app in its lifecycle.** - - If the main thread processing time exceeds 450 ms, trigger a trace sampling. **Only one sampling trace can be triggered based on the UID of an app in a day.** - -2. Stack capture time - - When the main thread jank event occurs, the main thread checker starts to check whether the jank event occurs again every 155 ms (1 ≤ number of check times ≤ 2). There are three cases: - - (1) If a jank event is detected during the first check, the main thread checker starts stack sampling every 155 ms for 10 times. The stack sampling data is collected and an event is reported at the next interval. Then the check ends. - - ![Stack capture time example 1](figures/dump-stack1.PNG) - - (2) If a jank event is detected during the second check, the main thread checker starts stack sampling every 155 ms for 10 times. The stack sampling data is collected and an event is reported at the next interval. Then the check ends. - - ![Stack capture time example 2](figures/dump-stack2.PNG) - - (3) If no jank event is detected in the two checks, the check ends. - - ![Stack capture time example 3](figures/dump-stack3.PNG) - -3. Trace capture time - - After the function is called to capture tracing data, the main thread checker checks for a main thread jank event every 150 ms for 20 times. If a main thread jank event occurs in any of the 20 checks, the check ends in 3s and the tracing data is stored. - - (1) No main thread jank event is detected. - ![Trace capture example](figures/dump-trace1.PNG) - - (2) At least one main thread jank event is detected. - - ![Trace capture example](figures/dump-trace2.PNG) - -## Main Thread Jank Event Specifications - -1. Log aging - - Generally, the size of a stack file is 7 KB to 10 KB, and the size of a trace file is 3 MB to 6 MB. The **watchdog** directory in the app sandbox can store a maximum of 10 MB files. If the total file size exceeds 10 MB, the user needs to manually delete files. The path to **watchdog** is **/data/app/el2/100/log/*app_bundle_name*/watchdog**. - -2. You can obtain the log path from **EXTERNAL_LOG**. - -3. Currently, stack capturing supports only the ARM64 architecture. The stack capture result contains both native frames and JS frames parsed. - - An example of the stack capture result is as follows: - ```text - 9 #00 pc 0000757c /system/bin/appspawn(55679d09bcdea35bb1e0d4e1d9a3e58f) - 9 #01 pc 000731c0 /system/lib/ld-musl-aarch64.so.1(add9e521e4eaf5cb009d4260f3b69ccd) - 9 #02 pc 000090a9 /system/bin/appspawn(main+396)(55679d09bcdea35bb1e0d4e1d9a3e58f) - 9 #03 pc 0000ab5d /system/bin/appspawn(AppSpawnRun+100)(55679d09bcdea35bb1e0d4e1d9a3e58f) - 9 #04 pc 0000e7f1 /system/lib/chipset-pub-sdk/libbegetutil.z.so(RunLoop_+200)(52ace27d827ad482439bf32cc75bb17b) - ...... - 9 #21 pc 00107aec /system/lib/ld-musl-aarch64.so.1(__pthread_cond_timedwait+628)(add9e521e4eaf5cb009d4260f3b69ccd) - 1 #00 pc 00032e67 /system/lib/platformsdk/libmmi-util.z.so(OHOS::MMI::UDSSocket::OnReadPackets(OHOS::MMI::CircleStreamBuffer&, std::__h::function)+158)(99e56bc765f9208f7b7ba8b268886a59) - 1 #01 pc 0000312e5 /system/lib/platformsdk/libmmi-client.z.so(OHOS::MMI::ClientMsgHandler::OnMsgHandler(OHOS::MMI::UDSClient const&, OHOS::MMI::NetPacket&)+340)(66ac85e964777ae89f0c26c339093cd1) - 1 #02 pc 0003016b /system/lib/platformsdk/libmmi-client.z.so(OHOS::MMI::ClientMsgHandler::OnPointerEvent(OHOS::MMI::UDSClient const&, OHOS::MMI::NetPacket&)+1222)(66ac85e964777ae89f0c26c339093cd1) - 1 #03 pc 0003b96b /system/lib/platformsdk/libmmi-client.z.so(OHOS::MMI::InputManagerImpl::OnPointerEvent(std::__h::shared_ptr)+1370)(66ac85e964777ae89f0c26c339093cd1) - 1 #04 pc 00095903 /system/lib/platformsdk/libwm.z.so(OHOS::Rosen::InputEventListener::OnInputEvent(std::__h::shared_ptr) const+478)(9c40c5f416d6f830435126998fbcad42) - ...... - 1 #21 pc 003f5c55 /system/lib/platformsdk/libark_jsruntime.so(4e6a2651ec80a7f639233f414d6486fe) - 1 #22 at anonymous (/entry/build/default/cache/default/default@CompileArkTS/esmodule/debug/entry/src/main/ets/pages/Index.js:67:17) - 1 #23 at wait2 (/entry/build/default/cache/default/default@CompileArkTS/esmodule/debug/entry/src/main/ets/pages/Index.js:16:12) - ...... - ``` - - Each stack capture records 16 KB call stack information of the main thread for stack unwinding. Therefore, each stack capture result contains a maximum of 16 KB invocation information of the process for 10 times. The captured data is displayed in a tree view, with repeated stack frames aggregated and different call layers distinguished by line indentation. If the stack fails to be captured (for example, the main thread is blocked in the kernel or signals are masked), the content of the **/proc/self/wchan** file is output. - - In the result, each row indicates a piece of stack information. The meaning of a row of stack frame information can be interpreted as follows: - - Native frame: - - ```text - 9 #02 pc 000090a9 /system/bin/appspawn(main+396)(55679d09bcdea35bb1e0d4e1d9a3e58f) - ^ ^ ^ ^ ^ ^ - 1 2 3 4 5 6 - - 1 indicates the number of times that the frame is sampled. - 2 indicates the invoking level of the frame. The line indentation size corresponds to this level. The number of sampling times of all frames at the same level cannot be greater than 10. The number of sampling times of #00 is 10 (set the sampling times). - 3 indicates the PC value of the native frame. - 4 indicates the path of the called file. - 5 indicates the name of the called function and code line offset (available in unstripped version, and may not available in stripped version). - 6 indicates the MD5 value of the .so file. - ``` - - JS frame: - - ```text - 1 #23 at wait2 (/entry/build/default/cache/default/XXX/entry/src/main/ets/pages/Index.js:16:12) - ^ ^ ^ ^ - 1 2 3 4 - - 1 indicates the number of times that the frame is sampled. The maximum value is the sampling times. - 2 indicates the invoking level of the frame, which is the same as that of the native frame. - 3 indicates the name of the called function, which is **wait2**. - 4 indicates the path, file, row number, and column number of the called function. - ``` - -4. Trace specifications - - The size of a trace file is 1 MB to 5 MB. You can parse the trace file using [SmartPerf](https://www.smartperf.host). - - After the trace file is imported, the page displays the time axis, CPU usage, CPU load, IPC method calling, and process, thread, and method calling information from the top down. In this way, the data is displayed from the event dimension. + Stack: + external_log=["/data/storage/el2/log/watchdog/MAIN_THREAD_JANK_yyyyMMDDHHmmss_xxxx.txt"]. xxxx indicates the process ID. - For details about how to use trace files, see [How to Load Trace Files on the Web Client](https://gitee.com/openharmony/developtools_smartperf_host/blob/master/ide/src/doc/md/quickstart_systemtrace.md). + Trace: + external_log=[""/data/storage/el2/log/watchdog/MAIN_THREAD_JANK_unix timestamp_xxxx.trace"]. xxxx indicates the process ID. diff --git a/en/application-dev/dfx/hiappevent-watcher-mainthreadjank-events-ndk.md b/en/application-dev/dfx/hiappevent-watcher-mainthreadjank-events-ndk.md index 1be960afd229138f3a3cb9e85c51e40b470befbc..5be045379bcc0de3a48b588cacf1d7e59dcd3003 100644 --- a/en/application-dev/dfx/hiappevent-watcher-mainthreadjank-events-ndk.md +++ b/en/application-dev/dfx/hiappevent-watcher-mainthreadjank-events-ndk.md @@ -1,5 +1,9 @@ # Subscribing to Main Thread Jank Events (C/C++) +## Main Thread Jank Event Specifications + +For details, see [Main Thread Jank Event Overview](./hiappevent-watcher-mainthreadjank-events.md). + ## Available APIs For details about how to use the APIs (such as parameter usage restrictions and value ranges), see [HiAppEvent](../reference/apis-performance-analysis-kit/_hi_app_event.md#hiappevent). @@ -9,10 +13,12 @@ For details about how to use the APIs (such as parameter usage restrictions and | API | Description | | ------------------------------------------------------------ | -------------------------------------------- | | int OH_HiAppEvent_AddWatcher(HiAppEvent_Watcher *watcher) | Adds a watcher to listen for application events.| -| int OH_HiAppEvent_RemoveWatcher(HiAppEvent_Watcher *watcher)| Removes a watcher to unsubscribe from application events.| +| int OH_HiAppEvent_RemoveWatcher(HiAppEvent_Watcher *watcher) | Removes a watcher to unsubscribe from application events.| ## How to Develop +The following describes how to subscribe to the main thread jank event in sampling stack, which is reported when a task running in the main thread times out. + 1. Create a native C++ project and import the **jsoncpp** file to the project. The directory structure is as follows: ```yml @@ -169,11 +175,9 @@ For details about how to use the APIs (such as parameter usage restrictions and }) ``` -8. If the nolog version is used and the developer mode is disabled, the main thread checker will collect tracing data when a task times out. +8. In DevEco Studio, click the **Run** button to run the application project. Click the **timeOut350** button twice consecutively to trigger a main thread jank event. -9. In DevEco Studio, click the **Run** button to run the application project. Click the **timeOut350** button twice consecutively to trigger a main thread jank event. - -10. After the main thread jank event is reported, you can view the following event information in the **Log** window. +9. After the main thread jank event is reported, you can view the following event information in the **Log** window. ```text HiAppEvent eventInfo.domain=OS @@ -190,10 +194,7 @@ For details about how to use the APIs (such as parameter usage restrictions and HiAppEvent eventInfo.params.log_over_limit=0 ``` - > **NOTE** - > For details, see [Main Thread Jank Event Time Specifications](./hiappevent-watcher-mainthreadjank-events-arkts.md#main-thread-jank-event-time-specifications) and [Main Thread Jank Event Specifications](./hiappevent-watcher-mainthreadjank-events-arkts.md#main-thread-jank-event-specifications). - -11. Remove the event watcher. +10. Remove the event watcher. ```c++ static napi_value RemoveWatcher(napi_env env, napi_callback_info info) { @@ -203,7 +204,7 @@ For details about how to use the APIs (such as parameter usage restrictions and } ``` -12. Destroy the event watcher. +11. Destroy the event watcher. ```c++ static napi_value DestroyWatcher(napi_env env, napi_callback_info info) { diff --git a/en/application-dev/dfx/hiappevent-watcher-mainthreadjank-events.md b/en/application-dev/dfx/hiappevent-watcher-mainthreadjank-events.md index 65d0b018841e952e39090250e36d1be315707cc6..6f769edc40eaed4969ef93491cbd17f608273b37 100644 --- a/en/application-dev/dfx/hiappevent-watcher-mainthreadjank-events.md +++ b/en/application-dev/dfx/hiappevent-watcher-mainthreadjank-events.md @@ -20,3 +20,120 @@ The **params** parameter in the event information is described as follows. | end_time | number | End time of a task in the main thread.| | external_log| string[] | Path of the generated log files. If the directory files exceed the threshold (for details, see **log_over_limit**), new log files may fail to be written. Therefore, delete the log files immediately after they are processed.| | log_over_limit| boolean | Whether the size of generated log files and existing log files exceeds the upper limit (10 MB). The value **true** indicates that the upper limit is exceeded and logs fail to be written. The value **false** indicates that the upper limit is not exceeded.| + +## Main Thread Jank Event Time Specifications + +1. Begin time + + Stack sampling triggered by main thread Jank (150 ms < Main thread processing time < 450 ms): For the processes with the same PID, the call stack sampling for a main thread jank event can be triggered only once.. + + Trace sampling triggered by main thread jank (Main thread processing time > 450 ms): For the processes with the same PID, the trace sampling for a main thread jank event can be triggered only once in a day. + + > **NOTE** + > + > To enable the main thread checker to collect tracing data when a task times out, ensure that the nolog version is used and **Developer Options** is disabled + > + > You can go to **Settings** > **About phone** to check the software version. The log version ends with **log**. + > + > When **Developer Options** is disabled, DevEco Studio may be unavailable. Therefore, you are advised to install the application before disabling **Developer Options**. + +2. Stack capture time + + When the main thread jank event occurs, the main thread checker starts to check whether the jank event occurs again every 155 ms (1 ≤ number of check times ≤ 2). There are three cases: + + (1) If a jank event is detected during the first check, the main thread checker starts stack sampling every 155 ms for 10 times. The stack sampling data is collected and an event is reported at the next interval. Then the check ends. + + ![Stack capture time example 1](figures/dump-stack1.PNG) + + (2) If a jank event is detected during the second check, the main thread checker starts stack sampling every 155 ms for 10 times. The stack sampling data is collected and an event is reported at the next interval. Then the check ends. + + ![Stack capture time example 2](figures/dump-stack2.PNG) + + (3) If no jank event is detected in the two checks, the check ends. + + ![Stack capture time example 3](figures/dump-stack3.PNG) + +3. Trace capture time + + After the function is called to capture tracing data, the main thread checker checks for a main thread jank event every 150 ms for 20 times. If a main thread jank event occurs in any of the 20 checks, the check ends in 3s and the tracing data is stored. + + (1) No main thread jank event is detected. + + ![Trace capture example](figures/dump-trace1.PNG) + + (2) At least one main thread jank event is detected. + + ![Trace capture example](figures/dump-trace2.PNG) + +## Main Thread Jank Event Specifications + +1. Log aging + + Generally, the size of a stack file is 7 KB to 10 KB, and the size of a trace file is 3 MB to 6 MB. The **watchdog** directory in the application sandbox can hold files up to10 MB. If the total file size exceeds the limit, the user needs to manually delete files. The path to **watchdog** is **/data/app/el2/100/log/*app_bundle_name*/watchdog**. + +2. You can obtain the log path from **external_logs**. + +3. Currently, stack capturing supports only the ARM64 architecture. The stack capture result contains both native frames and JS frames parsed. + + An example of the stack capture result is as follows: + + ```text + 9 #00 pc 0000757c /system/bin/appspawn(55679d09bcdea35bb1e0d4e1d9a3e58f) + 9 #01 pc 000731c0 /system/lib/ld-musl-aarch64.so.1(add9e521e4eaf5cb009d4260f3b69ccd) + 9 #02 pc 000090a9 /system/bin/appspawn(main+396)(55679d09bcdea35bb1e0d4e1d9a3e58f) + 9 #03 pc 0000ab5d /system/bin/appspawn(AppSpawnRun+100)(55679d09bcdea35bb1e0d4e1d9a3e58f) + 9 #04 pc 0000e7f1 /system/lib/chipset-pub-sdk/libbegetutil.z.so(RunLoop_+200)(52ace27d827ad482439bf32cc75bb17b) + ...... + 9 #21 pc 00107aec /system/lib/ld-musl-aarch64.so.1(__pthread_cond_timedwait+628)(add9e521e4eaf5cb009d4260f3b69ccd) + 1 #00 pc 00032e67 /system/lib/platformsdk/libmmi-util.z.so(OHOS::MMI::UDSSocket::OnReadPackets(OHOS::MMI::CircleStreamBuffer&, std::__h::function)+158)(99e56bc765f9208f7b7ba8b268886a59) + 1 #01 pc 0000312e5 /system/lib/platformsdk/libmmi-client.z.so(OHOS::MMI::ClientMsgHandler::OnMsgHandler(OHOS::MMI::UDSClient const&, OHOS::MMI::NetPacket&)+340)(66ac85e964777ae89f0c26c339093cd1) + 1 #02 pc 0003016b /system/lib/platformsdk/libmmi-client.z.so(OHOS::MMI::ClientMsgHandler::OnPointerEvent(OHOS::MMI::UDSClient const&, OHOS::MMI::NetPacket&)+1222)(66ac85e964777ae89f0c26c339093cd1) + 1 #03 pc 0003b96b /system/lib/platformsdk/libmmi-client.z.so(OHOS::MMI::InputManagerImpl::OnPointerEvent(std::__h::shared_ptr)+1370)(66ac85e964777ae89f0c26c339093cd1) + 1 #04 pc 00095903 /system/lib/platformsdk/libwm.z.so(OHOS::Rosen::InputEventListener::OnInputEvent(std::__h::shared_ptr) const+478)(9c40c5f416d6f830435126998fbcad42) + ...... + 1 #21 pc 003f5c55 /system/lib/platformsdk/libark_jsruntime.so(4e6a2651ec80a7f639233f414d6486fe) + 1 #22 at anonymous (/entry/build/default/cache/default/default@CompileArkTS/esmodule/debug/entry/src/main/ets/pages/Index.js:67:17) + 1 #23 at wait2 (/entry/build/default/cache/default/default@CompileArkTS/esmodule/debug/entry/src/main/ets/pages/Index.js:16:12) + ...... + ``` + + Each time a stack is sampled, 16 KB of the call stack information of the main thread is captured for backtrace analysis. Therefore, each stack capture result contains a maximum of 16 KB call information of the process. The stack sampling is performed 10 times in total. The captured data is displayed in a tree view, with repeated stack frames aggregated and different call layers distinguished by line indentation. If the stack fails to be captured (for example, the main thread is blocked in the kernel or signals are masked), the content of the **/proc/self/wchan** file is output. + + In the result, each row indicates a piece of stack information. The meaning of a row of stack frame information can be interpreted as follows: + + Native frame: + + ```text + 9 #02 pc 000090a9 /system/bin/appspawn(main+396)(55679d09bcdea35bb1e0d4e1d9a3e58f) + ^ ^ ^ ^ ^ ^ + 1 2 3 4 5 6 + + 1 indicates the number of times that the frame is sampled. + 2 indicates the call level of the frame. The line indentation size corresponds to this level. The number of sampling times of all frames at the same level cannot be greater than 10. The number of sampling times of #00 is 10 (sampling times specified). + 3 indicates the Program Counter (PC) value of the native frame. + 4 indicates the path of the called file. + 5 indicates the name of the called function and code line offset (available in unstripped version, and may not available in stripped version). + 6 indicates the MD5 value of the .so file. + ``` + + JS frame: + + ```text + 1 #23 at wait2 (/entry/build/default/cache/default/XXX/entry/src/main/ets/pages/Index.js:16:12) + ^ ^ ^ ^ + 1 2 3 4 + + 1 indicates the number of times that the frame is sampled. The maximum value is the sampling times. + 2 indicates the call level of the frame, which is the same as that of the native frame. + 3 indicates the name of the called function, which is **wait2**. + 4 indicates the path, file, row number, and column number of the called function. + ``` + +4. Trace specifications + + The size of a trace file is 1 MB to 5 MB. You can parse the trace file using [SmartPerf](https://www.smartperf.host). + + After a trace file is imported, the page displays the time axis, CPU usage, CPU load, IPC method calling, and process, thread, and method calling information from the top down. In this way, the data is displayed from the event dimension. + + For details about how to use trace files, see [How to Load Trace Files on the Web Client](https://gitee.com/openharmony/developtools_smartperf_host/blob/master/ide/src/doc/md/quickstart_systemtrace.md). + diff --git a/en/application-dev/dfx/hiappevent-watcher-resourceleak-events-arkts.md b/en/application-dev/dfx/hiappevent-watcher-resourceleak-events-arkts.md index 21bdde93feebe6bce1a5497209dc7d0da84c9eda..358279ee2835c9a3ab7a9c90cfc3c8d22be92116 100644 --- a/en/application-dev/dfx/hiappevent-watcher-resourceleak-events-arkts.md +++ b/en/application-dev/dfx/hiappevent-watcher-resourceleak-events-arkts.md @@ -48,7 +48,7 @@ The following describes how to subscribe to a memory leak event. ``` 3. In the **entry/src/main/ets/pages/index.ets** file, add the **memoryleak** button and construct a scenario for triggering a resource leak event in **onClick()**. - In this case, use [hidebug.setAppResourceLimit](../reference/apis-performance-analysis-kit/js-apis-hidebug.md#hidebugsetappresourcelimit12) to set the memory limit to trigger a memory leak event, and enable **System resource leak log** in **Developer options**. The sample code is as follows: + In this case, use [hidebug.setAppResourceLimit](../reference/apis-performance-analysis-kit/js-apis-hidebug.md#hidebugsetappresourcelimit12) to set the memory limit to trigger a memory leak event, and enable **System resource leak log** in **Developer options**. (Restart the device to enable or disable this function.) The sample code is as follows: ```ts import hidebug from "@ohos.hidebug"; @@ -56,23 +56,24 @@ The following describes how to subscribe to a memory leak event. @Entry @Component struct Index { - @State leakedArray: string[][] = []; - - build() { - Column() { - Row() { - Column() { - Button("pss leak") - .onClick(() => { - hidebug.setAppResourceLimit("pss_memory", 1024, true); - for (let i = 0; i < 20 * 1024; i++) { - this.leakedArray.push(new Array(1).fill("leak")); - } - }) + @State leakedArray: string[][] = []; + + build() { + Column() { + Row() { + Column() { + Button("pss leak") + .onClick(() => { + hidebug.setAppResourceLimit("pss_memory", 1024, true); + for (let i = 0; i < 20 * 1024; i++) { + this.leakedArray.push(new Array(1).fill("leak")); + } + }) + } } + .height('100%') + .width('100%') } - .height('100%') - .width('100%') } } ``` @@ -87,3 +88,26 @@ The following describes how to subscribe to a memory leak event. HiAppEvent eventName=RESOURCE_OVERLIMIT HiAppEvent eventInfo={"domain":"OS","name":"RESOURCE_OVERLIMIT","eventType":1,"params":{"bundle_name":"com.example.myapplication","bundle_version":"1.0.0","memory":{"pss":2100257,"rss":1352644,"sys_avail_mem":250272,"sys_free_mem":60004,"sys_total_mem":1992340,"vss":2462936},"pid":20731,"resource_type":"pss_memory","time":1502348798106,"uid":20010044,"external_log": ["/data/storage/el2/log/resourcelimit/RESOURCE_OVERLIMIT_1725614572401_6808.log", "/data/storage/el2/log/resourcelimit/RESOURCE_OVERLIMIT_1725614572412_6808.log"], "log_over_limit": false}} ``` + +6. Currently, in the nolog version of the commercial OS based on OpenHarmony, the function of subscribing to VM heap snapshots is enabled. The application needs to call **hidebug.setAppResourceLimit** and **hiAppEvent.addWatcher** in sequence, and configure the following environment variables in the **AppScope/app.json5** file: + + ```text + "appEnvironments": [ + { + "name": "DFX_RESOURCE_OVERLIMIT_OPTIONS", + "value": "oomdump:enable" + } + ] + ``` + + The size of a heap snapshot file ranges from 0.4 GB to 1.2 GB (about 50 MB to 100 MB after being compressed in ZIP format). Therefore, the system limits the number of times that heap snapshots are generated. The specifications are as follows: + - Device: The OOM heap snapshot file can be generated for five times a week. If this limit is exceeded, all applications cannot generate heap snapshots. + - Application: The OOM heap snapshot file can be generated only once a week. + - If the remaining storage space of the device is less than 30 GB, **oomdump** is not triggered. + During debugging, you can adjust the system time to seven days later and restart the device to reset the number of times that the application triggers **oomdump**, so that you can quickly complete function adaptation and verification. + + > **NOTE** + > + > After receiving the subscribed event, the application should obtain the path of the heap snapshot file from the **external_log** field of the event, move or upload the file to the cloud as soon as possible, and then delete the original heap snapshot file. Otherwise, the next heap snapshot file may fail to be generated due to insufficient storage space (up to 2 GB) of the application sandbox path directory.
+ > The value **field** in the JSON5 configuration file supports the key-value pair set **key1:value1;key2:value2;...**. Currently, the **oomdump** function can be enabled in the nolog version only for applications configured with the preceding key-value pairs.
+ > Change the extension of the .log file generated after subscription to **.rawheap**, use [rawheap-translator](../tools/rawheap-translator.md) to convert the file to a .heapsnapshot file, and open the file using DevEco Studio or a browser. For details, see [Importing Heap Snapshots Offline](https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V5/ide-snapshot-basic-operations-V5#section6760173514388). diff --git a/en/application-dev/dfx/hiappevent-watcher-resourceleak-events-ndk.md b/en/application-dev/dfx/hiappevent-watcher-resourceleak-events-ndk.md index 307c6ec8aab9d266b9e7ea70ba91bc95121f705c..59812255573e2aef93324c4a15b237a430686979 100644 --- a/en/application-dev/dfx/hiappevent-watcher-resourceleak-events-ndk.md +++ b/en/application-dev/dfx/hiappevent-watcher-resourceleak-events-ndk.md @@ -123,6 +123,9 @@ For details about how to use the APIs (such as parameter usage restrictions and In the **napi_init.cpp** file, define the methods related to the watcher of the OnTrigger type. ```c++ + // Define a variable to cache the pointer to the created watcher. + static HiAppEvent_Watcher *systemEventWatcher; + // Implement the callback function used to return the listened events. The content pointed to by the events pointer is valid only in this function. static void OnTake(const char *const *events, uint32_t eventLen) { Json::Reader reader(Json::Features::strictMode()); @@ -218,7 +221,7 @@ For details about how to use the APIs (such as parameter usage restrictions and ``` 7. In the **entry/src/main/ets/pages/index.ets** file, add the **memoryleak** button and construct a scenario for triggering a resource leak event in **onClick()**. - In this case, use [hidebug.setAppResourceLimit](../reference/apis-performance-analysis-kit/js-apis-hidebug.md#hidebugsetappresourcelimit12) to set the memory limit to trigger a memory leak event, and enable **System resource leak log** in **Developer options**. The sample code is as follows: + In this case, use [hidebug.setAppResourceLimit](../reference/apis-performance-analysis-kit/js-apis-hidebug.md#hidebugsetappresourcelimit12) to set the memory limit to trigger a memory leak event, and enable **System resource leak log** in **Developer options**. (Restart the device to enable or disable this function.) The sample code is as follows: ```ts import hidebug from "@ohos.hidebug"; @@ -226,23 +229,24 @@ For details about how to use the APIs (such as parameter usage restrictions and @Entry @Component struct Index { - @State leakedArray: string[][] = []; - - build() { - Column() { - Row() { - Column() { - Button("pss leak") - .onClick(() => { - hidebug.setAppResourceLimit("pss_memory", 1024, true); - for (let i = 0; i < 20 * 1024; i++) { - this.leakedArray.push(new Array(1).fill("leak")); - } - }) + @State leakedArray: string[][] = []; + + build() { + Column() { + Row() { + Column() { + Button("pss leak") + .onClick(() => { + hidebug.setAppResourceLimit("pss_memory", 1024, true); + for (let i = 0; i < 20 * 1024; i++) { + this.leakedArray.push(new Array(1).fill("leak")); + } + }) + } } + .height('100%') + .width('100%') } - .height('100%') - .width('100%') } } ``` diff --git a/en/application-dev/dfx/hichecker-guidelines-arkts.md b/en/application-dev/dfx/hichecker-guidelines-arkts.md index 6f3e439e7c2b97ca6accce9ba935fe1db855b49f..df2b9d048599d5aa3d8bb432230d831f664e9bf7 100644 --- a/en/application-dev/dfx/hichecker-guidelines-arkts.md +++ b/en/application-dev/dfx/hichecker-guidelines-arkts.md @@ -2,7 +2,7 @@ ## Overview -HiChecker is provided to check issues that may be easily ignored during application development. Such issues include time-consuming thread calling and ability resource leakage in application processes. The issues are recorded in logs or lead to process crashes so that you can find and rectify them. +HiChecker is provided to check issues that may be easily ignored during application development. Such issues include time-consuming thread calling and ability resource leakage in application processes. The issues are recorded in logs or lead to process crashes explicitly so that you can find and rectify them. ## Basic Concepts @@ -16,18 +16,18 @@ HiChecker is provided to check issues that may be easily ignored during applicat ## Constraints -- Currently, the alarm rules supports only logs (default) and app crashes. +- Currently, the alarm rules support only logs (default) and application crashes. - HiChecker supports stack unwinding in C but not in JavaScript. ## Available APIs The check APIs are provided by the HiChecker module. For details about the APIs, see [HiChecker](../reference/apis-performance-analysis-kit/js-apis-hichecker.md). -| API | Description | +| API| Description| | -------- | -------- | -| hichecker.addCheckRule(rule: bigint) | Adds a rule. | -| hichecker.removeCheckRule(rule: bigint) | Removes a rule. | -| hichecker.containsCheckRule(rule: bigint) | Queries a rule. | +| hichecker.addCheckRule(rule: bigint) | Adds a rule.| +| hichecker.removeCheckRule(rule: bigint) | Removes a rule.| +| hichecker.containsCheckRule(rule: bigint) | Queries a rule.| ## How to Develop diff --git a/en/application-dev/dfx/hicollie-guidelines-ndk.md b/en/application-dev/dfx/hicollie-guidelines-ndk.md index d5fe4d1e8539492a8556587e2aa16c7230927dde..1f729bde79eaa01a290fec2cb81b3437674e7c5e 100644 --- a/en/application-dev/dfx/hicollie-guidelines-ndk.md +++ b/en/application-dev/dfx/hicollie-guidelines-ndk.md @@ -1,8 +1,9 @@ -# Using HiCollie (C/C++) +# Using HiCollie to Detect Service Thread Stuck and Jank Events (C/C++) HiCollie provides APIs for detecting service thread stuck and jank events and reporting stuck events. -## Available APIs +## Availability APIs + | API | Description | | ------------------------------- | --------------------------------- | | OH_HiCollie_Init_StuckDetection | Registers a callback to periodically detect service thread stuck events. | @@ -13,12 +14,12 @@ HiCollie provides APIs for detecting service thread stuck and jank events and re > > The service thread stuck faultlog starts with **appfreeze-** and is generated in **Device/data/log/faultlog/faultlogger/**. The log files are named in the format of **appfreeze-application bundle name-application UID-time (seconds)**. For details, see [appfreeze Log Analysis](./appfreeze-guidelines.md#appfreeze-log-analysis). > -> For details about the specifications of service thread jank logs, see [Main Thread Jank Event Specifications](./hiappevent-watcher-mainthreadjank-events-arkts.md#main-thread-jank-event-specifications). - +> For details, see [Main Thread Jank Event Time Specifications](./hiappevent-watcher-mainthreadjank-events.md#main-thread-jank-event-time-specifications) and [Main Thread Jank Event Specifications](./hiappevent-watcher-mainthreadjank-events.md#main-thread-jank-event-specifications).. For details (such as parameter usage and value ranges), see [HiCollie](../reference/apis-performance-analysis-kit/_hi_hicollie.md). ## How to Develop + The following describes how to add a button in the application and click the button to call the HiCollie APIs. 1. Create a native C++ project and import the **jsoncpp** file to the project. The directory structure is as follows: @@ -208,7 +209,8 @@ The following describes how to add a button in the application and click the but 7. At the bottom of DevEco Studio, switch to the **Log** tab and set the filter criteria to **testTag**. (1) Wait for 10s and click the **testHiCollieJankNdk** button. (The jank event detection is not performed within 10s after the thread starts.) - The thread timeout information of the sampling stack obtained through **OH_HiCollie_Init_JankDetection()** is displayed in **/data/app/el2/100/log/application bundle name/watchdog/BUSSINESS_THREAD_JANK_XXX.txt.** - -(2) Click the **testHiCollieStuckNdk** button. + The thread timeout information of the sampling stack obtained through **OH_HiCollie_Init_JankDetection()** is displayed + in **/data/app/el2/100/log/application bundle name/watchdog/BUSSINESS_THREAD_JANK_XXX.txt.** + + (2) Click the **testHiCollieStuckNdk** button. The callback used for detecting stuck events is initialized through **OH_HiCollie_Init_StuckDetection()**. You can define the detection function for stuck events as required. diff --git a/en/application-dev/dfx/hidebug-guidelines-arkts.md b/en/application-dev/dfx/hidebug-guidelines-arkts.md index 9375527e85af5bcbb751a861bfe27e5a608967a9..55a800e7e326e670f93a337e4f914a2cc8e35f48 100644 --- a/en/application-dev/dfx/hidebug-guidelines-arkts.md +++ b/en/application-dev/dfx/hidebug-guidelines-arkts.md @@ -46,9 +46,14 @@ The following describes how to add a button in the application and click the but The following shows how to add **hidebug.getSystemCpuUsage()** to call the hidebug APIs. For details about how to use other APIs, see [API Reference](../reference/apis-performance-analysis-kit/js-apis-hidebug.md). ```ts - import { hidebug, hilog } from '@kit.PerformanceAnalysisKit'; + import { hidebug } from '@kit.PerformanceAnalysisKit'; + import { BusinessError } from '@kit.BasicServicesKit'; function testHidebug(event?: ClickEvent) { - hilog.info(0x0000, "testTag", `getCurrentCpuUsage ${hidebug.getSystemCpuUsage()}`); + try { + console.info(`getSystemCpuUsage: ${hidebug.getSystemCpuUsage()}`) + } catch (error) { + console.error(`error code: ${(error as BusinessError).code}, error msg: ${(error as BusinessError).message}`); + } } ``` @@ -80,7 +85,7 @@ The following describes how to add a button in the application and click the but 5. At the bottom of DevEco Studio, switch to the **Log** tab and set the filter criteria to **testTag**. Then, the CPU usage logs obtained using **hidebug.getSystemCpuUsage()** are displayed in the window. ```Text - 06-25 19:50:27.485 24645-24645/com.example.myapplication I A00000/testTag: getCurrentCpuUsage 0.10164512338425381 + 08-20 11:06:01.891 1948-1948 A03d00/JSAPP com.examp...lication I getSystemCpuUsage: 0.4722222222222222 ``` diff --git a/en/application-dev/dfx/hidumper.md b/en/application-dev/dfx/hidumper.md index efc137634e21b389f489d734a8c5c5dcb2c72235..7c199740973bd8d8d4822758d60d289440a8feff 100644 --- a/en/application-dev/dfx/hidumper.md +++ b/en/application-dev/dfx/hidumper.md @@ -409,6 +409,20 @@ HiDumper is a command-line tool used to export essential system information for hidumper -p ``` + > **Note** + > + > In the Release version, this command can be used to export the process information of the debugging applications. + > + > How to distinguish the Debug and Release versions: + > + > 1. Run the **hdc shell "param get|grep const.debuggable"** command to check whether the output is **0** or **1**. + > + > 2. Run the **hdc shell "param get|grep const.product.software.version"** command to check whether the current version contains the **log** string. + > + > The Release version outputs **0** and does not contain the **log** string. + > + > The Debug version outputs **1** and contain the **log** string. + **Example** ``` @@ -644,15 +658,7 @@ HiDumper is a command-line tool used to export essential system information for > > This command is available only in the Debug version and is unavailable in the Release version. > - > How to distinguish the Debug and Release versions: - > - > 1. Run the **hdc shell "param get|grep const.debuggable"** command to check whether the output is **0** or **1**. - > - > 2. Run the **hdc shell "param get|grep const.product.software.version"** command to check whether the current version contains the **log** string. - > - > The Release version outputs **0** and does not contain the **log** string. - > - > The Debug version outputs **1** and contain the **log** string. + > For details about how to distinguish the debug and release versions, see **hidumper -p**. **Example** @@ -714,7 +720,7 @@ HiDumper is a command-line tool used to export essential system information for > > In the Release version, this command can be used to export the snapshot information of the debugging applications. > - > For details about how to distinguish the Debug and Release versions, see the last example. + > For details about how to distinguish the debug and release versions, see **hidumper -p**. > > The path of the jsheap file: **/data/log/faultlog/temp or /data/log/reliability/resource_leak/memory_leak**. diff --git a/en/application-dev/dfx/hilog-guidelines-arkts.md b/en/application-dev/dfx/hilog-guidelines-arkts.md index 13dd7867ece3728db6efd388099c88d60b0a82dc..79720cbafd941ff7868a380057cf2430443c6440 100644 --- a/en/application-dev/dfx/hilog-guidelines-arkts.md +++ b/en/application-dev/dfx/hilog-guidelines-arkts.md @@ -15,7 +15,7 @@ HiLog defines five log levels (DEBUG, INFO, WARN, ERROR, and FATAL) and provides | -------- | -------- | | isLoggable(domain: number, tag: string, level: LogLevel) | Checks whether logs of the specified domain, tag, and level can be printed.| | debug(domain: number, tag: string, format: string, ...args: any[]) | Outputs DEBUG logs, which are used only for debugging applications and services.
To set the log level to **DEBUG**, run the **hdc shell hilogcat** command in the **Terminal** window of DevEco Studio or in the **cmd** window.| -| info(domain: number, tag: string, format: string, ...args: any[]) | Outputs INFO logs, which provide prevalent, highlighting events related to key service processes..| +| info(domain: number, tag: string, format: string, ...args: any[]) | Outputs INFO logs, which provide prevalent, highlighting events related to key service processes.| | warn(domain: number, tag: string, format: string, ...args: any[]) | Outputs WARN logs, which indicate issues that have little impact on the system.| | error(domain: number, tag: string, format: string, ...args: any[]) | Outputs ERROR logs, which indicate program or functional errors.| | fatal(domain: number, tag: string, format: string, ...args: any[]) | Outputs FATAL logs, which indicate program or functionality crashes that cannot be rectified.| @@ -94,7 +94,7 @@ Add a click event in a button, which prints a log when the button is clicked. .height('5%') // Add a onClick event with the button to print a log when the button is clicked. .onClick(() => { - hilog.isLoggable(0xFF00, "testTag", hilog.LogLevel.INFO); + hilog.isLoggable(0xFF00, "testTag", hilog.LogLevel.INFO); hilog.info(0xFF00, "testTag", "%{public}s World %{public}d", "hello", 3); }) } @@ -108,9 +108,9 @@ Add a click event in a button, which prints a log when the button is clicked. For example, output an INFO log in the following format: ```txt - "%{public}s World %{public}d" + %{public}s World %{public}d ``` - + *%{public}s* indicates a string, and *%{public}d* indicates an integer. Both of them are displayed in plaintext. 4. Run the project on a real device, and click the **Next** button on the app/service. @@ -118,7 +118,7 @@ Add a click event in a button, which prints a log when the button is clicked. 5. At the bottom of DevEco Studio, switch to the **Log** tab and set the filter criteria. Specifically, select the current device and process, set the log level to **Verbose**, and enter **testTag** in the search box. Then, only the logs that meet the filter criteria are displayed. - In this example, the printed log is "hello World 3". + In this example, the printed log is "hello World 3." diff --git a/en/application-dev/dfx/hilog-guidelines-ndk.md b/en/application-dev/dfx/hilog-guidelines-ndk.md index def23c0d09b6c69eb3c9ebe56d6ceb945909dca1..1f9a73a772e68cbf6dd081f53791434f6cefe6fa 100644 --- a/en/application-dev/dfx/hilog-guidelines-ndk.md +++ b/en/application-dev/dfx/hilog-guidelines-ndk.md @@ -6,7 +6,7 @@ HiLog is a subsystem that provides logging for the system framework, services, a ## Available APIs -HiLog defines five log levels (DEBUG, INFO, WARN, ERROR, and FATAL) and provides APIs to output logs of different levels. For details about the APIs, see [hilog](../reference/apis-performance-analysis-kit/_hi_log.md)). +HiLog defines five log levels (DEBUG, INFO, WARN, ERROR, and FATAL) and provides APIs to output logs of different levels. For details about the APIs, see [hilog](../reference/apis-performance-analysis-kit/_hi_log.md). | API/Macro| Description| | -------- | -------- | @@ -109,7 +109,7 @@ static void Test(void) // 1. Register a callback. OH_LOG_SetCallback(MyHiLog); - // 2. Call the hilog API to print logs. Logs are output to HiLog and returned to MyHiLog() through the registered callback. Then, MyHiLog() is called to process the logs. + // 2. Call the hilog API to print logs. Logs are output to HiLog and returned to **MyHiLog()** through the registered callback. Then, **MyHiLog()** is called to process the logs. HiLog::Info(LABEL, "hello world"); } ``` diff --git a/en/application-dev/dfx/hitracemeter-guidelines-arkts.md b/en/application-dev/dfx/hitracemeter-guidelines-arkts.md index a8675581d4a53e4e9eea6a35aaeb8e95333c32d2..702f2bacb728febb8f2da6b9048b153089149809 100644 --- a/en/application-dev/dfx/hitracemeter-guidelines-arkts.md +++ b/en/application-dev/dfx/hitracemeter-guidelines-arkts.md @@ -18,11 +18,11 @@ The performance tracing APIs are provided by the **hiTraceMeter** module. For details, see [Hitrace](../reference/apis-performance-analysis-kit/js-apis-hitracemeter.md). -| API | Description | +| API| Description| | -------- | -------- | -| hiTraceMeter.startTrace(name: string, taskId: number) | Starts an asynchronous time slice trace task. If multiple tracing tasks with the same name need to be performed at the same time, different task IDs must be specified through **taskId**. If the tracing tasks with the same name are not performed at the same time, the same task ID can be used. | +| hiTraceMeter.startTrace(name: string, taskId: number) | Starts an asynchronous time slice trace task. If multiple tracing tasks with the same name need to be performed at the same time, different task IDs must be specified through **taskId**. If the tracing tasks with the same name are not performed at the same time, the same task ID can be used.| | hiTraceMeter.finishTrace(name: string, taskId: number) | Stops an asynchronous time slice trace task. The values of **name** and **taskId** must be the same as those of **hiTraceMeter.startTrace**. | -| hiTraceMeter.traceByValue(name: string, value: number) | Traces the value changes of a numeric variable, which is an integer. | +| hiTraceMeter.traceByValue(name: string, value: number) | Traces the value changes of a numeric variable, which is an integer.| HiTraceMeter logging APIs are classified into three types by functionality/behavior: API for synchronous time slice tracing, API for asynchronous time slice tracing, and API for integer tracing. APIs for synchronous and asynchronous time slice tracing are synchronous and are used in the same thread. Cross-thread logging and analysis are not supported. diff --git a/en/application-dev/dfx/hitracemeter-view.md b/en/application-dev/dfx/hitracemeter-view.md index 8c311ba662abec595bdb643a1d2bd62f79098884..ed9e324f84eea9c7d0c728ffa5344b0982766953 100644 --- a/en/application-dev/dfx/hitracemeter-view.md +++ b/en/application-dev/dfx/hitracemeter-view.md @@ -1,12 +1,52 @@ # Viewing HiTraceMeter Logs - ## Viewing Logs on DevEco Studio -In the CPU Insight of DevEco Studio Profiler, you can view the CPU usage and thread running status of applications and services, and learn about the CPU consumption in the specified period and key logging of the system. For details, see [CPU Activity Analysis: CPU](https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V5/ide-insight-session-cpu-V5). +In CPU Insight of DevEco Studio Profiler, you can display HiTraceMeter logs for analyzing the CPU usage and thread running status of applications and services and viewing the CPU consumption in a specified period. For details, see [CPU Activity Analysis: CPU](https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V5/ide-insight-session-cpu-V5). ## Viewing Logs Using a Command Line Tool -1. Run the **hilog -b D** command to set the log level. +1. Set up the environment for OpenHarmony Device Connector (hdc). For details, see [Environment Setup](hdc.md#environment-setup). + +2. In the **Terminal** window of DevEco Studio or the CLI on the host, run the **hdc shell** command to connect to the device, and run the [hitrace](hitrace.md) command on the device to capture HiTraceMeter logs. + + ```shell + PS D:\xxx\xxx> hdc shell + # hitrace --trace_begin app + ``` + +3. Run the program that enables HiTraceMeter logging on the device. + +4. Dump the HiTraceMeter log file that contains the HiTraceMeter logging information in step 3. + + - Logs are printed in the window by default. + + ```shell + # hitrace --trace_dump + ``` + + - You can create a file to save logs in the **/data/local/tmp/** directory (other directories are unavailable). + + ```shell + # hitrace --trace_dump -o /data/local/tmp/trace.ftrace + ``` + +5. Run the **hitrace** command on the device to stop capturing HiTraceMeter logs. + + ```shell + # hitrace --trace_finish + ``` + +6. Exit the device, enter the host, and export the HiTraceMeter logs to the current directory. + + ```shell + # exit + PS D:\xxx\xxx> hdc file recv /data/local/tmp/trace.ftrace ./ + ``` + +7. You can search for keywords such as the logging name in the HiTraceMeter logs to check whether the logging is successful. + +8. Display and analyze the HiTraceMeter logs. -2. Run the **hilog |grep hitrace** command to view HiTrace logs. + - In DevEco Studio Profiler, select **Open File** to import the HiTraceMeter logs for analysis. For details, see [CPU Activity Analysis: CPU](https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V5/ide-insight-session-cpu-V5). + - Use [HiSmartPerf](https://gitee.com/openharmony/developtools_smartperf_host) for analysis. You can download the tool from [developertools_smartperf_host Release](https://gitee.com/openharmony/developtools_smartperf_host/releases). diff --git a/en/application-dev/displaymanager/Readme-EN.md b/en/application-dev/displaymanager/Readme-EN.md index 58692e589bebd444bc0689c6a6db567619ab5c88..686c46cc2f5903c5ec6ddb8991a154279f6df7c6 100644 --- a/en/application-dev/displaymanager/Readme-EN.md +++ b/en/application-dev/displaymanager/Readme-EN.md @@ -1,3 +1,8 @@ # Display Management +- [Display Management Overview](displayManager-overview.md) - [Using OH_DisplayManager to Obtain Basic Display Information and Listen for Status Changes (C/C++)](native-display-manager.md) +- [Using Display to Obtain Display Properties and Listen for Status Changes (ArkTS)](screenProperty-guideline.md) + +- [Creating and Using a Virtual Screen (ArkTS) (for System Applications Only)](virtualScreen-guideline.md) + diff --git a/en/application-dev/displaymanager/displayManager-overview.md b/en/application-dev/displaymanager/displayManager-overview.md new file mode 100644 index 0000000000000000000000000000000000000000..1b9117eba5c032f35b534d43c4c2293e41bc6cf2 --- /dev/null +++ b/en/application-dev/displaymanager/displayManager-overview.md @@ -0,0 +1,16 @@ +# Display Management Overview + +Display management is centered around the oversight of a device's displays, which includes physical, virtual, and foldable displays. It involves managing their properties and serving as a broadcaster to relay monitored information to services that have subscribed to display information. + +Display management includes the following capabilities: + +- Obtaining the display properties, such as resolution, physical pixel density, and dimensions. +- Listening for various display events, including rotation, resolution changes, refresh rate changes, and folding state changes. +- Creating and using virtual screens. This capability is available only for system applications. + +For details about how to obtain display properties and listen for status changes, see [Using OH_DisplayManager to Obtain Basic Display Information and Listen for Status Changes (C/C++)](native-display-manager.md) and [Using Display to Obtain Display Properties and Listen for Status Changes (ArkTS)](screenProperty-guideline.md). For details about how to use virtual screens, see [Creating and Using a Virtual Screen (ArkTS) (for System Applications Only)](virtualScreen-guideline.md). + +## Constraints + +- The Display and Screen APIs must be used in the system that supports the SystemCapability.Window.SessionManager capability. For details, see [SystemCapability](../reference/syscap.md). +- In multi-display implementation, the Screen API is available only for system applications only, and certain APIs require the ohos.permission.CAPTURE_SCREEN permission. diff --git a/en/application-dev/displaymanager/screenProperty-guideline.md b/en/application-dev/displaymanager/screenProperty-guideline.md new file mode 100644 index 0000000000000000000000000000000000000000..9e3dd3c2e9797b392862e7052408e1da85d31554 --- /dev/null +++ b/en/application-dev/displaymanager/screenProperty-guideline.md @@ -0,0 +1,178 @@ +# Using Display to Obtain Display Properties and Listen for Status Changes (ArkTS) + +## When to Use + +[Display](../reference/apis-arkui/js-apis-display.md) provides APIs for managing displays, such as obtaining information about the default display, obtaining information about all displays, and listening for the addition and removal of displays. Applications may adjust their UI in response to changes in the display information, display status, and folding states. + +Typical scenarios for utilizing display properties are as follows: + +- Display information query: You can query the display resolution, physical pixel density, logical pixel density, refresh rate, dimensions, rotation direction, and rotation angle. For details, see [Display Properties](../reference/apis-arkui/js-apis-display.md#properties). +- Display status monitoring: You can listen for changes in the rotation, resolution, and refresh rate of the display. +- Folding state monitoring: You can check whether the device is foldable and listen for changes in its folding state (whether it is unfolded or folded). + +## Available APIs + +The following table lists the common APIs related to display properties. For details, see [@ohos.display (Display)](../reference/apis-arkui/js-apis-display.md). + +| API | Description | +| ------------------------------------------------------------ | ------------------------------------------------------------ | +| getAllDisplays(): Promise> | Obtains all display objects. This API uses a promise to return the result. | +| getDefaultDisplaySync(): Display | Obtains the default display object. This API uses an asynchronous callback to return the result. | +| getDisplayByIdSync(displayId: number): Display | Obtains a display object based on the display ID. | +| on(type: 'add'\|'remove'\|'change', callback: Callback\): void | Subscribes to display change events. | +| off(type: 'add'\|'remove'\|'change', callback?: Callback\): void | Unsubscribes from display change events. | +| on(type: 'captureStatusChange', callback: Callback\): void | Subscribes to screen capture, casting, or recording status change events. | +| off(type: 'captureStatusChange', callback?: Callback\): void | Unsubscribes from screen capture, casting, or recording status change events. | +| on(type: 'availableAreaChange', callback: Callback\): void | Subscribes to change events of the available area on the display of the current device. This API uses an asynchronous callback to return the result.| +| off(type: 'availableAreaChange', callback?: Callback\): void | Unsubscribes from change events of the available area on the display of the current device. | +| isFoldable(): boolean | Checks whether the device is foldable. | +| on(type: 'foldStatusChange', callback: Callback\): void | Subscribes to fold status change events of the foldable device. | +| off(type: 'foldStatusChange', callback?: Callback\): void | Unsubscribes from fold status change events of the foldable device. | + +## Obtaining a Display Object + +The display object provides APIs to obtain display properties and listen for changes. You can use any of the following methods to obtain a display object, depending on your service requirements: + +- Use **getDefaultDisplaySync()** to obtain the default display object. +- Use **getAllDisplays()** to obtain all display objects. +- Use **getDisplayByIdSync()** to obtain a display object with a specific display ID. + +The following example demonstrates how to use **getDefaultDisplaySync()** to obtain the default display object: + +```ts +import { display } from '@kit.ArkUI'; + +let displayClass: display.Display | null = null; +displayClass = display.getDefaultDisplaySync(); +// Ensure that the display object, displayClass in this example, is obtained before the operations of querying the display properties and listening for events and status changes. +``` + +## Obtaining Display Properties + +1. After the display object is acquired, you can query the basic information about the display through its properties. + + ```ts + import { display } from '@kit.ArkUI'; + + let displayClass: display.Display | null = null; + displayClass = display.getDefaultDisplaySync(); + + // Obtain the display ID. + console.info(`The screen Id is ${displayClass.id}.`); + // Obtain the refresh rate. + console.info(`The screen is ${displayClass.refreshRate}.`); + // Obtain the display width. + console.info(`The screen width is ${displayClass.width}.`); + // Obtain the display height. + console.info(`The screen height is ${displayClass.height}.`); + // ... + ``` + +2. To enhance UI layout design, you can use **getCutoutInfo()** to obtain information about unusable areas of the display, including punch hole, notch, and curved area of a waterfall display. You can also use **getAvailableArea()** to obtain the available area of the display. + + ```ts + import { BusinessError } from '@kit.BasicServicesKit'; + + displayClass.getCutoutInfo().then((cutoutInfo: display.CutoutInfo) => { + console.info('Succeeded in getting cutoutInfo. Data: ' + JSON.stringify(cutoutInfo)); + }).catch((err: BusinessError) => { + console.error(`Failed to obtain all the display objects. Code: ${err.code}, message: ${err.message}`); + }); + + displayClass.getAvailableArea().then((availableArea) => { + console.info('Succeeded get the available area in this display. data: ' + JSON.stringify(availableArea)); + }).catch((err: BusinessError) => { + console.error(`Failed to get the available area in this display. Code: ${err.code}, message: ${err.message}`); + }); + ``` + +3. Call **display.isCaptured()** to determine whether the device is engaged in activities such as screen capture, casting, or recording. + + ```ts + console.info(`The screen is captured or not : ${display.isCaptured()}`); + ``` + +## Listening for Display Status Changes + +1. To listen for display changes, use **display.on('add'|'remove'|'change')** to subscribe to events such as the addition, removal, or alteration of displays. To unsubscribe from these events, call **display.off('add'|'remove'|'change')**. + + ```ts + import { display } from '@kit.ArkUI'; + import { Callback } from '@kit.BasicServicesKit'; + + let callback1: Callback = (data: number) => { + console.info('Listening enabled. Data: ' + JSON.stringify(data)); + }; + // The following uses the addition event as an example. + display.on("add", callback1); + + // Unregister all the callbacks that have been registered through on(). + display.off("add"); + // Unregister a single callback. + display.off('add', callback1); + ``` + +2. To listen for screen capture, casting, or recording status changes, call **display.on('captureStatusChange')**. To end the listening, call **display.off('captureStatusChange')**. + + ```ts + let callback2: Callback = (captureStatus: boolean) => { + // For captureStatus, the value true means that the device starts screen capture, casting, or recording, and false means that the device stops screen capture, casting, or recording. + console.info('Listening capture status: ' + captureStatus); + }; + // Listen for screen capture, casting, or recording status changes. + display.on('captureStatusChange', callback2); + + display.off('captureStatusChange', callback2); + ``` + +3. To listen for available area changes of the display, call **on('availableAreaChange')**. To end the listening, call **off('availableAreaChange')**. + + ```ts + import { Callback } from '@kit.BasicServicesKit'; + import { display } from '@kit.ArkUI'; + + let callback3: Callback = (data: display.Rect) => { + console.info('Listening enabled. Data: ' + JSON.stringify(data)); + }; + let displayClass: display.Display | null = null; + try { + displayClass = display.getDefaultDisplaySync(); + // Listen for changes of the available area on the display. + displayClass.on("availableAreaChange", callback3); + } catch (exception) { + console.error(`Failed to register callback. Code: ${exception.code}, message: ${exception.message}`); + } + // End the listening. + displayClass.off("availableAreaChange", callback3); + ``` + +## Listening for Folding State Changes + +1. Call **display.isFoldable()** to check whether the device is foldable. + + ``` + import { display } from '@kit.ArkUI'; + + let ret: boolean = false; + ret = display.isFoldable(); + ``` + +2. If the device is a foldable device, call **display.on('foldStatusChange')** to listen for folding state changes. To end the listening, call **display.off('foldStatusChange')**. + + ```ts + import { Callback } from '@kit.BasicServicesKit'; + + /** + * The callback parameter used for subscription must be passed as an object. + * If an anonymous function is used for registration, a new underlying object is created each time the function is called, causing memory leakage. + */ + let callback: Callback = (data: display.FoldStatus) => { + console.info('Listening enabled. Data: ' + JSON.stringify(data)); + }; + display.on('foldStatusChange', callback); + + // Unregister all the callbacks that have been registered through on(). + display.off('foldStatusChange'); + // Unregister a single callback. + display.off('foldStatusChange', callback); + ``` diff --git a/en/application-dev/displaymanager/virtualScreen-guideline.md b/en/application-dev/displaymanager/virtualScreen-guideline.md new file mode 100644 index 0000000000000000000000000000000000000000..087deaababff6aaa3f4eb9cce97206027aeb3978 --- /dev/null +++ b/en/application-dev/displaymanager/virtualScreen-guideline.md @@ -0,0 +1,148 @@ +# Creating and Using a Virtual Screen (ArkTS) (for System Applications Only) + +## When to Use + +A virtual screen serves as a conceptual representation in the system. It allows an application to create a virtual screen without depending on a physical screen. It provides a rendering target through the surface, allowing applications to render content such as images and videos onto the virtual screen. + +## Available APIs + +The following lists the common APIs available for the virtual screen. For details about the APIs, see [@ohos.screen (Screen) (System API)](../reference/apis-arkui/js-apis-screen-sys.md). + +| API | Description | +| ------------------------------------------------------------ | -------------------------------------------- | +| createVirtualScreen(options:VirtualScreenOption): Promise<Screen> | Creates a virtual screen. This API uses a promise to return the result. | +| setVirtualScreenSurface(screenId:number, surfaceId: string): Promise<void> | Sets the surface for a virtual screen. This API uses a promise to return the result.| +| makeMirror(mainScreen:number, mirrorScreen:Array<number>): Promise<number> | Sets screen mirroring. This API uses a promise to return the result. | +| stopMirror(mirrorScreen:Array<number>): Promise<void> | Stops screen mirroring. This API uses a promise to return the result. | +| destroyVirtualScreen(screenId:number): Promise<void> | Destroys a virtual screen. This API uses a promise to return the result. | + +## How to Develop + +1. Create a virtual screen. + + - Define the parameters used for creating the virtual screen. + + - Call **createVirtualScreen()** to create the virtual screen. + + The ohos.permission.CAPTURE_SCREEN permission is required for calling **createVirtualScreen()**. For details, see [Requesting Restricted Permissions](../security/AccessToken/declare-permissions-in-acl.md). + +2. Bind the surface ID of the rendering target to the virtual screen. + + To enable the virtual screen to accurately present the intended content, bind the surface ID of the rendering target to the virtual screen. The operations are as follows: + + - Call **getXComponentSurfaceId()** to obtain the surface ID. As a unique identifier, the surface ID carries important data related to the screen's image properties. It facilitates the acquisition and adjustable configuration of the image properties such as resolution and pixel format. + + - Call **setVirtualScreenSurface()** to associate the obtained surface ID with the virtual screen, ensuring that the virtual screen can properly receive and process the associated image data. + +3. Call **makeMirror()** to create a mirror of the physical screen and project it onto the virtual screen. + + After the virtual screen is created, the application can call **makeMirror()** to start mirroring of the physical screen based on service requirements. This API duplicates the content currently displayed on the physical screen and projects it onto the virtual screen created earlier, facilitating real-time synchronized viewing between the two screens. + +4. Stop mirroring. + + If synchronized mirroring between the physical and virtual screens is no longer needed, call **stopMirror()** to stop mirroring. This operation terminates the mirroring from the physical screen to the virtual screen, restoring the virtual screen to an autonomous state. + +5. Destroy the virtual screen. + + Upon completion of the service process and when the virtual screen is no longer needed, release the related resources in a timely manner to prevent memory leaks and unnecessary consumption of system resources. You can call **destroyVirtualScreen()** to destroy the virtual screen securely and effectively, thereby releasing the system resources occupied by the virtual screen. + +```ts +import { BusinessError } from '@kit.BasicServicesKit'; +import { screen } from '@kit.ArkUI'; + +@Entry +@Component +struct VirtualScreen { + xComponentController: XComponentController = new XComponentController(); + + build() { + RelativeContainer() { + Column() { + XComponent({ + type: XComponentType.SURFACE, + controller: this.xComponentController + }) + } + Button('Virtual screen') + .onClick(() => { + // screenVirtualScreen is used to store the created virtual screen object. + let screenVirtualScreen: screen.Screen | null = null; + class VirtualScreenOption { + name: string = ''; + width: number = 0; + height: number = 0; + density: number = 0; + surfaceId: string = ''; + } + // option defines the parameters required for creating the virtual screen. + let option: VirtualScreenOption = { + name: 'screen01', + width: 1080, + height: 2340, + density: 2, + surfaceId: '' + }; + // Create a virtual screen. + screen.createVirtualScreen(option, (err: BusinessError, data: screen.Screen) => { + const errCode: number = err.code; + if (errCode) { + console.error(`Failed to create the virtual screen. Code:${err.code},message is ${err.message}`); + return; + } + screenVirtualScreen = data; + console.info('Succeeded in creating the virtual screen. Data: ' + JSON.stringify(data)); + // Obtain the surface ID. + let surfaceId = this.xComponentController.getXComponentSurfaceId(); + screen.setVirtualScreenSurface(screenVirtualScreen.id, surfaceId, (err: BusinessError) => { + const errCode: number = err.code; + if (errCode) { + console.error(`Failed to set the surface for the virtual screen. Code:${err.code},message is ${err.message}`); + return; + } + console.info('Succeeded in setting the surface for the virtual screen.'); + }); + let mirrorScreenIds: Array = [screenVirtualScreen.id]; + // Obtain all screens. + screen.getAllScreens((err: BusinessError, data: Array) => { + const errCode: number = err.code; + if (errCode) { + console.error(`Failed to get all screens. Code:${err.code},message is ${err.message}`); + return; + } + // Call makeMirror to create a mirror for the physical screen and project it to the virtual screen. + let mainScreenId = data.find(item => item.sourceMode === 0)?.id; + screen.makeMirror(mainScreenId, mirrorScreenIds, (err: BusinessError, data: number) => { + const errCode: number = err.code; + if (errCode) { + console.error(`Failed to set screen mirroring. Code:${err.code},message is ${err.message}`); + return; + } + console.info('Succeeded in setting screen mirroring. Data: ' + JSON.stringify(data)); + }); + // Stop mirroring. + screen.stopMirror(mirrorScreenIds, (err: BusinessError) => { + const errCode: number = err.code; + if (errCode) { + console.error(`Failed to stop mirror screens. Code:${err.code},message is ${err.message}`); + return; + } + console.info('Succeeded in stopping mirror screens.'); + }); + // Destroy the virtual screen. + screen.destroyVirtualScreen(mirrorScreenIds[0], (err: BusinessError) => { + const errCode: number = err.code; + if (errCode) { + console.error(`Failed to destroy the virtual screen. Code:${err.code},message is ${err.message}`); + return; + } + console.info('Succeeded in destroying the virtual screen.'); + }); + }); + }); + }) + } + .height('100%') + .width('100%') + } +} +``` diff --git a/en/application-dev/distributedservice/devicemanager-guidelines.md b/en/application-dev/distributedservice/devicemanager-guidelines.md index 841aa6ae553f2b09881649a8fea776645a4c6f4d..d985f6a31138f21f1a1c223de70a59be805b9f4a 100644 --- a/en/application-dev/distributedservice/devicemanager-guidelines.md +++ b/en/application-dev/distributedservice/devicemanager-guidelines.md @@ -92,7 +92,7 @@ Discover nearby devices. ### Available APIs -startDiscovering(discoverParam: {[key: string]: Object} , filterOptions?: {[key: string]: Object} ): void; +startDiscovering(discoverParam: {[key: string]: Object;} , filterOptions?: {[key: string]: Object;} ): void; Starts to discover the devices that are in the same LAN or have Bluetooth enabled. For details, see [startDiscovering](../reference/apis-distributedservice-kit/js-apis-distributedDeviceManager.md#startdiscovering). @@ -160,7 +160,7 @@ Bind an untrusted device discovered to establish a trust relationship. ### Available APIs -bindTarget(deviceId: string, bindParam: {[key: string]: Object} , callback: AsyncCallback<{deviceId: string}>): void; +bindTarget(deviceId: string, bindParam: {[key: string]: Object;} , callback: AsyncCallback<{deviceId: string;}>): void; Binds a device. For details, see [bindTarget](../reference/apis-distributedservice-kit/js-apis-distributedDeviceManager.md#bindtarget). @@ -237,7 +237,7 @@ You can listen for the device online/offline status. The service will be notifie ### Available APIs -on(type: 'deviceStateChange', callback: Callback<{ action: DeviceStateChange, device: DeviceBasicInfo }>): void; +on(type: 'deviceStateChange', callback: Callback<{ action: DeviceStateChange; device: DeviceBasicInfo; }>): void; Listens for device online/offline status. For details, see [on('deviceStateChange')](../reference/apis-distributedservice-kit/js-apis-distributedDeviceManager.md#ondevicestatechange). diff --git a/en/application-dev/faqs/faqs-arkts-module.md b/en/application-dev/faqs/faqs-arkts-module.md new file mode 100644 index 0000000000000000000000000000000000000000..e0a0c4f7df23d6b70d0e010d585e8d04e8b8487a --- /dev/null +++ b/en/application-dev/faqs/faqs-arkts-module.md @@ -0,0 +1,332 @@ +# ArkTS Modular Loading + + +## Error Messages Related to Modular Loading Displayed at the Runtime of ArkTS Applications +### "Cannot find dynamic-import module 'xxxx'" + +This error indicates that the module to load is not compiled into the application package. + +**Possible cause** + +An expression is dynamically loaded as an input parameter, but the module path is incorrect. +``` typescript + import(module).then(m=>{m.foo();}).catch((e: Error)=>{console.info(e.message)}); +``` + +**Locating method** + +Print the path information of the module, and check whether the path is correct. + +### "Cannot find module 'xxxx' , which is application Entry Point" +This error indicates that the entry file is not found during application startup. + +**Possible cause** + +The entry file is not found during application startup. + +**Locating method** + +(1) Open the application's project-level build file **module.json5** in the **entry/src/main** directory. + + +The following is an example of some parameters in **module.json5**. +``` +{ + "module": { + "name": "entry", + "type": "entry", + ... + "abilities": [ + { + "name": "EntryAbility", // Module name. + "srcEntry": "./ets/entryability/EntryAbility.ts", // Relative path of the src directory to the project root directory. + "description": "$string:EntryAbility_desc", + "icon": "$media:icon", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:icon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ] + } +} +``` +(2) Check the value of **srcEntry** under **abilities** in **module.json5**. This parameter specifies the path of the entry file. + +### "No export named 'xxxx' which exported by 'xxxx'" +This error indicates that no specific object is found in the module when the .so file in the HAP or HAR of the application is being loaded. + +**Possible cause** + +The dependency between modules is pre-parsed in the static build phase of the module. If the imported variable name in the .ets file is incorrect, an error message is displayed in DevEco Studio. An error message is also displayed in the application build phase. Note that the dependency of native C++ modules in the application is checked only at runtime. + +**Locating method** + +Check whether the .so file in the application contains the exported variable that causes the error, and compare the exported variable with the imported variable in the .so file. If they are inconsistent, modify the variable. + + +## Failure in Loading .so Files + +If a .so file fails to be loaded, a JS error indicating loading failure is not explicitly thrown. You can check whether the exported object is **undefined** to determine the loading status of the .so file. + +**Loading failure symptom** + +| Loading Type| TS/JS Module| System Library/Application .so File| +| -------- | -------- | -------- | +| Static loading| The VM automatically throws an error and the process exits.| No error is thrown, and the loaded object is **undefined**.| +| Dynamic loading| No error is proactively thrown and the program reaches the reject branch. You can call the **catch** method to capture the error.| No error is proactively thrown and the program reaches the resolve branch. You can check whether the variable exported by the module is **undefined** in the branch.| + +**Example 1: Static loading of the system library/application .so file fails.** + +``` +import testNapi from 'libentry.so' + +if (testNapi == undefined) { + console.error('load libentry.so failed.'); +} +``` + +Command output: +``` +load libentry.so failed. +``` + +**Example 2: Dynamic loading of the system library/application .so file fails.** + +``` +import('libentry.so') + .then(m => { + if (typeof m.default === 'undefined') { + console.warn(`load libentry.so failed.`); + } else { + console.info('load libentry.so success:', m); + } + return m; + }) + .catch((e: Error) => { + console.error('load libentry.so error:', e); + }); +``` + +Command output: +``` +load libentry.so failed. +``` + +**Possible cause, locating method, and solution** + +For details, see [Node-API FAQs](https://gitee.com/openharmony/docs/blob/master/en/application-dev/napi/use-napi-faqs.md). + + +## Initialization Errors at Runtime Caused by Inter-Module Circular Dependency + +Inter-module circular dependencies are usually caused by these modules referencing each other's files. +```ts +// file1 + export {b} from './file2' + export {a} from './A' + +// file2 + import {a} from './file1' + export let b:number = a; + +// A + export let a:number = 50; +``` +The preceding code reports the following error: +``` +Error message:a is not initialized +``` + +If only the loading sequence of **file1** is changed: +```ts +// file1 + export {a} from './A' + export {b} from './file2' +// file2 + import {a} from './file1' + export let b:number = a; +// A + export let a:number = 50; +``` +The preceding code does not report an error. In this case, the execution order is as follows: (1) **file1** loads module A, and module A has no dependencies on other modules. (2) After execution, **file1** is returned. (3) **file2** is loaded. (4) When **file2** loads **file1**, it needs to access the variable a which is defined in **file1**. Since module A in **file1** has already been executed, **file2** can be loaded normally. +Note that modular build uses depth-first loading. + +### Solution to Circular Dependencies +[@security/no-cycle](https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V5/ide_no-cycle-V5) + + +## Example Error Scenarios Because ArkTS Symbols Are Not Initialized + +The ArkTS coding specification is a subset of the ECMAScript specification. When a symbol that has not been initialized is accessed, an error is thrown during runtime. The following common error scenarios are provided to help you locate and rectify source code errors: + +### Access Before const/let Declaration + +``` typescript +console.log(a); // Error: Variable 'a' is used before being assigned. +console.log(b); // Error: Variable 'b' is used before being assigned. + +let a = '1'; +const b = '2'; +``` +**Recommended** + +``` +let a = '1'; +const b = '2'; + +console.log(a); +console.log(b); +``` + + +### Instantiation Before Class Declaration + +``` typescript +let a = new A(); // Error: Class 'A' used before its declaration. + +class A {} +``` + +**Recommended** + +``` +class A {} + +let a = new A(); +``` + +### Accessing Static Properties of a Class Before Declaration + +``` typescript +let a = A.a; // Error: Class 'A' used before its declaration. + +class A { + static a = 1; +} +``` + +**Recommended** + +``` +class A { + static a = 1; +} + +let a = A.a; +``` + +### Accessing let and const That Are Not Declared in a Function + +``` typescript +foo(); // Error: Error message:a is not initialized + +let a = 1; +const b = 2; + +function foo() { + let v = a + b; +} +``` + +**Recommended** + +``` +let a = 1; +const b = 2; + +function foo() { + let v = a + b; +} + +foo(); +``` + +### Accessing Static Properties of a Class That Is Not Declared in a Function + +``` typescript +foo(); // Error: Error message:A is not initialized + +class A { + static a = 1; +} + +function foo() { + let v = A.a; + let w = new A(); +} +``` + +**Recommended** + +``` +class A { + static a = 1; +} + +function foo() { + let v = A.a; + let w = new A(); +} + +foo(); +``` + +### Inter-Module Circular Dependency - const/let + +``` typescript +// module1.ets +import { a, b } from './module2' + +export let i = 1; +export let m = a; +export const j = 2; +export const n = b; + +// --------------------- + +// module2.ets +import { i, j } from './module1' + +export let a = i; // Error: Error message:i is not initialized +export const b = j; // Error: Error message:j is not initialized +``` + +**Solution** + +For details, see [Solution to Circular Dependencies](#solution-to-circular-dependencies). + + +### Inter-Module Circular Dependency - Class + +``` typescript +// class1.ets +import { b } from './class2' + +export class A { + static a = b; +} + +// --------------------- + +// class2.ets +import { A } from './class1' +export let b = 1; + +const i = A.a; // Error: Error message:A is not initialized +const j = new A(); // Error: Error message:A is not initialized +``` + +**Solution** + +For details, see [Solution to Circular Dependencies](#solution-to-circular-dependencies). diff --git a/en/application-dev/faqs/faqs-arkts-utils.md b/en/application-dev/faqs/faqs-arkts-utils.md index 31b7d4e97ad34652957c53a7469c9ed3f5359d69..cf351a2123eeb4ba3eacc4fb4a5cdcd3952d6304 100644 --- a/en/application-dev/faqs/faqs-arkts-utils.md +++ b/en/application-dev/faqs/faqs-arkts-utils.md @@ -52,8 +52,10 @@ In addition, ArkTS provides TaskPool concurrent APIs, which are similar to the t To address the problem that a large number of threads are required, you are advised to: -- Convert multi-thread tasks into concurrent tasks and distribute them through the task pool. -- Execute I/O tasks in the calling thread (which can be the **TaskPool** thread), rather than starting new threads for them. +- Convert multithreading tasks into concurrent tasks. When it comes to I/O tasks, use TaskPool to handle them. + +- Execute I/O tasks in the calling thread (which can be the TaskPool thread), rather than starting new threads for them. + - Use worker threads (no more than 8) for resident CPU intensive tasks (which is of a small number). **References** @@ -350,6 +352,7 @@ Objects are not directly shared, and therefore all containers are thread-safe. ## What is the task scheduling mechanism in TaskPool and Worker? Do they provide the same event loop mechanism as the JS single thread? (API version 10) **TaskPool** and **Worker** use the event loop to receive messages exchanged between threads. + **Worker** does not support the setting of the message priority, but **TaskPool** does. ## What is the multithreading model of the system? (API version 10) @@ -364,7 +367,7 @@ Yes. Context can be directly transferred as a parameter. **References** -[Shared Objects](../arkts-utils/serialization-support-types.md) +1. [Sendable Object Overview](../arkts-utils/arkts-sendable.md) ## How do I implement secure access to the same shared memory in multithreaded concurrency scenarios? (API version 10) @@ -422,7 +425,7 @@ Multiple threads cannot perform operations on the same memory object simultaneou ## What is the memory sharing principle of a sendable class object of ArkTS? What are the restrictions? How do I use it? (API version 11) -The sendable class is an extension of the actor model. The memory of a sendable class object is shared among threads. However, lock-free must be used for a single thread. To prevent multiple threads from simultaneously accessing a sendable class object, use the synchronization mechanism to ensure thread safe. +The Sendable class is an extension of the actor model. The memory of a sendable class object is shared among threads. However, lock-free must be used for a single thread. To prevent multiple threads from simultaneously accessing a sendable class object, use the synchronization mechanism to ensure thread safe. A sendable object must meet the following specifications: 1. The member property is of the sendable or basic type (string, number, or boolean, but not container class, which will be supported later). @@ -503,7 +506,7 @@ Currently, the use of **synchronized** is not supported. In the future, the Asyn ## Will the main thread be blocked if await is used in the main thread of ArkTS? (API version 10) -**Description** +**Question** If the following code is executed in the main thread, will the main thread be blocked? @@ -608,79 +611,6 @@ To address the problem that a large number of threads are required, you are advi [Comparison Between TaskPool and Worker](../arkts-utils/taskpool-vs-worker.md) -## What should I do if an error message related to modular loading is displayed when running an ArkTS application? - -The following errors related to modular loading may be displayed: - -1. "Cannot find dynamic-import module 'xxxx'" - - This error indicates that the module to load is not compiled into the application package. - - Possible cause: An expression is dynamically loaded as an input parameter, but the module path is incorrect. - - ``` typescript - import(module).then(m=>{m.foo();}).catch(e=>{console.log(e)}) - ``` - - Locating method: Print the path information of the module, and check whether the path is correct. - -2. "Cannot find module 'xxxx', which is application Entry Point" - - This error indicates that the entry file is not found during application startup. - - Possible cause: The entry file is not found during application startup. - - Locating method: - - (1) Open the application project-level build file **module.json5** in the **entry/src/main** directory. - - - The following is an example of some parameters in **module.json5**. - - ``` - { - "module": { - "name": "entry", - "type": "entry", - ... - "abilities": [ - { - "name": "EntryAbility", // Module name. - "srcEntry": "./ets/entryability/EntryAbility.ts", // Relative path of the src directory to the project root directory. - "description": "$string:EntryAbility_desc", - "icon": "$media:icon", - "label": "$string:EntryAbility_label", - "startWindowIcon": "$media:icon", - "startWindowBackground": "$color:start_window_background", - "exported": true, - "skills": [ - { - "entities": [ - "entity.system.home" - ], - "actions": [ - "action.system.home" - ] - } - ] - } - ] - } - } - ``` - - (2) Check the value of **srcEntry** under **"abilities** in **module.json5**. This parameter specifies the path of the entry file. - -3. "No export named 'xxxx' which exported by 'xxxx'" - - This error indicates that no specific object is found in the module when the .so file in the HAP or HAR of the application is being loaded. - - Possible cause: The dependency between modules is pre-parsed in the static compilation phase of the module. If the imported variable name in the .ets file is incorrect, an error message is displayed in both DevEco Studio and application build phase. Note that the dependency of C++ modules is checked at runtime. - - Locating method: - - Check whether the .so file in the application contains the exported variable that causes the error, and compare the exported variable with the imported variable in the .so file. If they are inconsistent, modify the variable. - ## Can long-time listening interfaces, such as **emitter.on**, be used in a TaskPool thread? Not recommended. @@ -697,15 +627,15 @@ You are advised to use a [continuous task](../reference/apis-arkts/js-apis-taskp ## Should I call onEnqueued, onStartExecution, onExecutionFailed, and onExecutionSucceeded in a certain sequence to listen for a task in the task pool? (API version 12) - The four APIs are independent and can be called in any sequence. +The four APIs are independent and can be called in any sequence. ## How do I use a sendable class in HAR? - Use the TS HAR. +Use the TS HAR. **References** -[Compiling and Generating TS Files](../quick-start/har-package.md#compiling-and-generating-ts-files) +[Building TS Files](../quick-start/har-package.md#building-ts-files) ## When a UI component in the TS HAR is used, an error message is displayed during the build, indicating that the UI component does not meet UI component syntax. What should I do? @@ -741,4 +671,14 @@ To use a UI component in the HAR, use the source code HAR or JS HAR. - To collect data of the worker thread in any phase, run the following command: **hdc shell param set persist.ark.properties 0x4505c** - To collect data of the main thread and worker thread in any phase, run the following command: **hdc shell param set persist.ark.properties 0x6505c** - \ No newline at end of file +## Does ArkTS use an asynchronous I/O model similar to Node.js? + +Yes. Node.js uses the event loop system to process asynchronous operations, which are processed using callback functions or promises. Similarly, ArkTS uses a coroutine-based asynchronous I/O mechanism, in which I/O events are distributed to I/O threads, without blocking JS threads. Asynchronous operations can be processed using callback functions or Promise/async/await paradigm. + +## Do I/O intensive tasks like network requests need to be processed by multiple threads? + +The decision depends on the specific service scenario and implementation details. If the I/O operations are not frequent and do not affect other services of the UI main thread, multithreading is unnecessary. However, if there are many I/O requests and it takes a long time for the UI main thread to distribute these requests, employing multithreading can enhance the application's performance and response speed. The final decision depends on DevEco Studio Profiler. + +## Does the @ohos.net.http network framework need to use TaskPool for handling tasks? + +The decision depends on the specific service scenario and implementation details. If the number of network requests is small or the subsequent network data processing is not particularly time-consuming, then employing TaskPool to manage thread creation, recycling, and data transfer overhead is unnecessary. However, if there are a large number of network requests and it takes a long time to process the data obtained, leveraging TaskPool can help manage these tasks more efficiently and reduce the workload on the UI main thread. diff --git a/en/application-dev/faqs/faqs-arkui-animation-interactive-event.md b/en/application-dev/faqs/faqs-arkui-animation-interactive-event.md index d10377153ac096265a11f182821b82e1276d726a..1afca3002462e1f98feb9ef872b11d4e20526edf 100644 --- a/en/application-dev/faqs/faqs-arkui-animation-interactive-event.md +++ b/en/application-dev/faqs/faqs-arkui-animation-interactive-event.md @@ -16,7 +16,7 @@ Check the trigger device. By default, the focus event (and the **onBlur** and ** [Focus Control](../reference/apis-arkui/arkui-ts/ts-universal-attributes-focus.md) -## How do I disable the scroll event of a \ nested in the \? (API version 9) +## How do I disable the scroll event of a Grid nested in the Scroll? (API version 9) Implement nested scrolling of the containers, by using the **onScrollFrameBegin** event and the **scrollBy** method. @@ -38,7 +38,7 @@ Use either of the following: - Add **focusable(true)** to the list item to enable it to obtain focus. -- Nest a focusable component, for example, **\