diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 359bb5307e8535ab7d59faf27a7377033291821e..0000000000000000000000000000000000000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -# 默认忽略的文件 -/shelf/ -/workspace.xml diff --git a/.idea/BestPracticeSnippets.iml b/.idea/BestPracticeSnippets.iml deleted file mode 100644 index 61021940449bdc69db005bbd04a05380f5629b2c..0000000000000000000000000000000000000000 --- a/.idea/BestPracticeSnippets.iml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/git_toolbox_blame.xml b/.idea/git_toolbox_blame.xml deleted file mode 100644 index 7dc124965d28403ec2545a24d7d1cd1fec1f57d8..0000000000000000000000000000000000000000 --- a/.idea/git_toolbox_blame.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - \ No newline at end of file diff --git a/.idea/git_toolbox_prj.xml b/.idea/git_toolbox_prj.xml deleted file mode 100644 index 02b915b85f9fb22b6e51491729131d93c18d906e..0000000000000000000000000000000000000000 --- a/.idea/git_toolbox_prj.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 3ce358829caa98cea142c0d523e95c04df039a10..0000000000000000000000000000000000000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 891e6bbf8a8464839ecc108f4cb7c0a6e6ac0f5a..0000000000000000000000000000000000000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 35eb1ddfbbc029bcab630581847471d7f238ec53..0000000000000000000000000000000000000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml deleted file mode 100644 index d8d1aafa50802959a8e45febc1b1d021357a6393..0000000000000000000000000000000000000000 --- a/.idea/workspace.xml +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - { - "associatedIndex": 2 -} - - - - { - "keyToString": { - "RunOnceActivity.OpenProjectViewOnStart": "true", - "RunOnceActivity.ShowReadmeOnStart": "true" - } -} - - - - - - - - - - - - - \ No newline at end of file diff --git a/AdaptiveCapabilities/LICENSE b/AdaptiveCapabilities/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..18795a48d6b12fcdc1aa7bac9a9cb99f83815267 --- /dev/null +++ b/AdaptiveCapabilities/LICENSE @@ -0,0 +1,78 @@ + Copyright (c) 2025 Huawei Device Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + 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. + +Apache License, Version 2.0 +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. + +"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. + +2. Grant of Copyright License. + +Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. + +Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. + +You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: +1.You must give any other recipients of the Work or Derivative Works a copy of this License; and +2.You must cause any modified files to carry prominent notices stating that You changed the files; and +3.You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and +4.If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. + +You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. + +5. Submission of Contributions. + +Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. + +6. Trademarks. + +This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. + +Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. + +In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. + +While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/AdaptiveCapabilities/README.md b/AdaptiveCapabilities/README.md new file mode 100644 index 0000000000000000000000000000000000000000..875f5b6ed917faf9e7fbd2823b77466e9366f1d9 --- /dev/null +++ b/AdaptiveCapabilities/README.md @@ -0,0 +1,160 @@ +# 多设备自适应能力 + +### 介绍 + +本示例是[《一次开发,多端部署》中《自适应布局》与《多设备资源文件》](https://developer.huawei.com/consumer/cn/doc/best-practices/bpta-multi-device-adaptive-layout)的配套示例代码,展示了自适应布局、响应式布局、典型布局场景以及资源文件使用的能力。 + +| 名称 | 简介 | +| ------------ | ------------------------------------------------------------ | +| 自适应布局 | 当外部容器大小发生变化时,元素可以**根据相对关系自动变化**以适应外部容器变化的布局能力。 | +| 响应式布局 | 当外部容器大小发生变化时,元素可以**根据断点或特定的媒体特征(如屏幕方向、窗口宽高等)自动变化**以适应外部容器变化的布局能力。 | +| 典型布局场景 | 应用开发中的典型场景,包括运行横幅、网格、侧边栏等。 | +| 资源文件使用 | 根据当前的设备特征(如设备类型、屏幕密度等)或应用场景(如语言、国家、地区等),从resources目录下不同的资源限定词目录中获取相应的资源值。 | + +> 说明: +> +> * 自适应布局能力仅可以保证在外部容器大小在一定范围内变化时,容器内的元素布局合理。如果外部尺寸发生较大变化,需要借助响应式布局能力进一步适配(详见《一次开发,多端部署》中关于断点的介绍)。 +> * 为简化代码、突出重点及方便读者理解,本示例中的自适应布局部分未做多设备适配。此部分建议在DevEco自带的MatePadPro预览器中运行及查看效果,以获得最佳的体验。 +> * 响应式布局、典型布局场景、资源文件使用均做了多设备适配,推荐参考如下方式查看代码的运行效果: +> * 将应用安装到不同类型的设备,查看运行效果。 +> * 通过创建不同屏幕尺寸多个预览器,或者通过拖拽的方式改变预览器的屏幕尺寸,查看不同情况下的运行效果。 + +### 效果预览: + +| 首页 | 自适应布局 | 响应式布局 | 典型场景 | +|-----------------------------------|-----------------------------------|-----------------------------------|-----------------------------------| +| ![](screenshots/devices/img1.png) | ![](screenshots/devices/img2.png) | ![](screenshots/devices/img3.png) | ![](screenshots/devices/img4.png) | + +使用说明 + +1. 启动应用,首页展示了自适应布局、响应式布局、典型布局场景和资源文件使用四个按钮。 + +2. 点击"自适应布局"进入新页面,分别展示拉伸能力、缩放能力、隐藏能力、折行能力、均分能力、占比能力和延伸能力共7种自适应布局能力。 + +3. 点击"响应式布局"进入新页面,分别展示断点、媒体查询和栅格布局3种响应式布局能力。 + +4. 点击"典型布局场景"进入新页面,展示了如何通过自适应布局能力和响应式布局能力,实现应用开发中的典型场景。 + +5. 点击"资源文件使用"进入新页面,展示字符串和图片资源的使用。 + +### 工程目录 +``` +entry/src/main/ets +|---common +| |---BreakpointSystem.ets +| |---ColorEntity.ets +| |---DirectoryList.ets +| |---GetValueOnBreakpoint.ets +|---MainAbility +| |---MainAbility.ts +|---model +| |---Logger.ts // 日志工具 +|---pages +| |---Index.ets // 首页 +| |---atomicLayoutCapability +| | |---equipartitionCapability +| | | |---EquipartitionCapability.ets // 均分能力 +| | |---extensionCapability +| | | |---ExtensionCapability1.ets // 延伸能力1 +| | | |---ExtensionCapability2.ets // 延伸能力2 +| | |---flexibleCapability +| | | |---FlexibleCapability1.ets // 拉伸能力2 +| | | |---FlexibleCapability2.ets // 拉伸能力2 +| | |---hiddenCapability +| | | |---HiddenCapability.ets // 隐藏能力 +| | |---proportionCapability +| | | |---ProportionCapability.ets // 占比能力 +| | |---scaleCapability +| | | |---ScaleCapability.ets // 缩放能力 +| | |---wrapCapability +| | | |---WrapCapability.ets // 拆行能力 +| | |---AtomicLayoutCapabilityIndex.ets // 自适应布局 +| |---gridRow +| | |---gridRow +| | | |---GridRowSample1.ets // 栅格断点1 +| | | |---GridRowSample2.ets // 栅格断点2 +| | | |---GridRowSample3.ets // 栅格columns和gutter +| | | |---GridRowSample4.ets // 栅格margin +| | | |---GridRowSample5.ets // 栅格span +| | | |---GridRowSample6.ets // 栅格offset +| | | |---GridRowSample7.ets // 栅格order +| | | |---GridRowSample8.ets // 栅格span/offset/order继承性 +| | | |---GridRowSample9.ets // 栅格嵌套 +| | | |---GridRowSample10.ets // 栅格对齐 +| | |---GridRowLayoutIndex.ets // 栅格布局 +| |---interactionNormCapability +| | |---InteractionNormCapability.ets // 交互归一能力 +| |---resourceQualifier +| | |---ResourceQualifier.ets // 资源文件使用 +| |---responsiveLayout +| | |---ResponsiveLayoutIndex.ets +| | |---breakpoint +| | | |---Breakpoint.ets // 断点类 +| | | |---BreakpointSample.ets // 断点 +| | |---mediaQuery +| | | |---MediaQuerySample.ets // 媒体查询 +| |---typicalScene +| | |---banner +| | | |---BannerSample.ets // 广告栏 +| | |---bigImage +| | | |---BigImageSample.ets // 大图浏览 +| | |---diversion +| | | |---DiversionSample.ets // 挪移布局 +| | |---header +| | | |---HeaderSample.ets // 顶部布局 +| | |---indentation +| | | |---IndentationSample.ets // 缩进布局 +| | |---multiLaneList +| | | |---MultiLaneListSample.ets // 多列列表 +| | |---multiScene +| | | |---data +| | | | |---apliications +| | | | | |---Apliications.ets +| | | | |---home +| | | | | |---Home.ets +| | | |---pages +| | | | |---apliications +| | | | | |---Apliications.ets +| | | | |---home +| | | | | |---Home.ets +| | | | |---player +| | | | | |---Player.ets +| | | | |---MultiScene.ets // 一多典型场景 +| | |---operationEntries +| | | |---OperationEntriesSample.ets // 操作入口 +| | |---repeat +| | | |---RepeatSample.ets // 重复布局 +| | |---responsiveGrid +| | | |---ResponsiveGridSample.ets // 网格视图 +| | |---sidebar +| | | |---SidebarSample.ets // 侧边栏 +| | |---tabs +| | | |---TabsSample.ets // 页签布局 +| | |---TypicalSceneIndex.ets // 典型布局场景 +``` + +### 相关权限 + +不涉及。 + +### 依赖 + +不涉及。 + +### 约束与限制 + +1. 本示例仅支持标准系统上运行,支持设备:华为手机、平板。 +2. HarmonyOS系统:HarmonyOS 5.0.5 Release及以上。 +3. DevEco Studio版本:DevEco Studio 5.0.5 Release及以上。 +4. HarmonyOS SDK版本:HarmonyOS 5.0.5 Release SDK及以上。 + +### 下载 + +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set AdaptiveCapabilities +git checkout +``` \ No newline at end of file diff --git a/AdaptiveCapabilities/README_zh.md b/AdaptiveCapabilities/README_zh.md deleted file mode 100644 index b20c84abcf8743c0b612679e6dff9e2671688258..0000000000000000000000000000000000000000 --- a/AdaptiveCapabilities/README_zh.md +++ /dev/null @@ -1,181 +0,0 @@ -# 多设备自适应能力 - -### 介绍 - -本示例是[《一次开发,多端部署》](https://gitee.com/openharmony/docs/tree/master/zh-cn/application-dev/key-features/multi-device-app-dev)的配套示例代码,展示了[页面开发的一多能力](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/key-features/multi-device-app-dev/layout-intro.md),包括自适应布局、响应式布局、典型布局场景以及资源文件使用。 - -| 名称 | 简介 | -| ------------ | ------------------------------------------------------------ | -| 自适应布局 | 当外部容器大小发生变化时,元素可以**根据相对关系自动变化**以适应外部容器变化的布局能力。 | -| 响应式布局 | 当外部容器大小发生变化时,元素可以**根据断点或特定的媒体特征(如屏幕方向、窗口宽高等)自动变化**以适应外部容器变化的布局能力。 | -| 典型布局场景 | 应用开发中的典型场景,包括运行横幅、网格、侧边栏等。 | -| 资源文件使用 | 根据当前的设备特征(如设备类型、屏幕密度等)或应用场景(如语言、国家、地区等),从resources目录下不同的资源限定词目录中获取相应的资源值。 | - -> 说明: -> -> * 自适应布局能力仅可以保证在外部容器大小在一定范围内变化时,容器内的元素布局合理。如果外部尺寸发生较大变化,需要借助响应式布局能力进一步适配(详见《一次开发,多端部署》中关于断点的介绍)。 -> * 为简化代码、突出重点及方便读者理解,本示例中的自适应布局部分未做多设备适配。此部分建议在DevEco自带的MatePadPro预览器中运行及查看效果,以获得最佳的体验。 -> * 响应式布局、典型布局场景、资源文件使用均做了多设备适配,推荐参考如下方式查看代码的运行效果: -> * 将应用安装到不同类型的设备,查看运行效果。 -> * 将应用安装到开发板等设备中,开启设备的自由窗口能力,查看不同窗口尺寸下的运行效果。 -> * 通过创建不同屏幕尺寸多个预览器,或者通过拖拽的方式改变预览器的屏幕尺寸,查看不同情况下的运行效果。 - -### 效果预览: - -| 首页 | 自适应布局 | 响应式布局 | 典型场景 | -|------------------------------------|------------------------------------|------------------------------------|------------------------------------| -| ![](screenshots/devices/img1.jpeg) | ![](screenshots/devices/img2.jpeg) | ![](screenshots/devices/img3.jpeg) | ![](screenshots/devices/img4.jpeg) | - -使用说明 - -1. 启动应用,首页展示了自适应布局、响应式布局、典型布局场景和资源文件使用四个按钮。 - -2. 点击"自适应布局"进入新页面,分别展示拉伸能力、缩放能力、隐藏能力、折行能力、均分能力、占比能力和延伸能力共7种自适应布局能力。 - -3. 点击"响应式布局"进入新页面,分别展示断点、媒体查询和栅格布局3种响应式布局能力。 - -4. 点击"典型布局场景"进入新页面,展示了如何通过自适应布局能力和响应式布局能力,实现应用开发中的典型场景。 - -5. 点击"资源文件使用"进入新页面,展示字符串和图片资源的使用。 - -### 工程目录 -``` -entry/src/main/ets/ -|---Application -| |---AbilityStage.ts -|---common -| |---BreakpointSystem.ets -| |---DirectoryList.ets -| |---GetValueOnBreakpoint.ets -|---MainAbility -| |---MainAbility.ts -|---model -| |---Logger.ts // 日志工具 -|---pages -| |---Index.ets // 首页 -| |---atomicLayoutCapability -| | |---equipartitionCapability -| | | |---EquipartitionCapability.ets // 均分能力 -| | |---extensionCapability -| | | |---ExtensionCapability1.ets // 延伸能力1 -| | | |---ExtensionCapability2.ets // 延伸能力2 -| | |---flexibleCapability -| | | |---FlexibleCapability1.ets // 拉伸能力2 -| | | |---FlexibleCapability2.ets // 拉伸能力2 -| | |---hiddenCapability -| | | |---HiddenCapability.ets // 隐藏能力 -| | |---proportionCapability -| | | |---ProportionCapability.ets // 占比能力 -| | |---scaleCapability -| | | |---ScaleCapability.ets // 缩放能力 -| | |---wrapCapability -| | | |---WrapCapability.ets // 拆行能力 -| | |---AtomicLayoutCapabilityIndex.ets // 自适应布局 -| |---gridRow -| | |---gridRow -| | | |---GridRowSample1.ets // 栅格断点1 -| | | |---GridRowSample2.ets // 栅格断点2 -| | | |---GridRowSample3.ets // 栅格columns和gutter -| | | |---GridRowSample4.ets // 栅格margin -| | | |---GridRowSample5.ets // 栅格span -| | | |---GridRowSample6.ets // 栅格offset -| | | |---GridRowSample7.ets // 栅格order -| | | |---GridRowSample8.ets // 栅格span/offset/order继承性 -| | | |---GridRowSample9.ets // 栅格嵌套 -| | | |---GridRowSample10.ets // 栅格对齐 -| | |---GridRowLayoutIndex.ets // 栅格布局 -| |---interactionNormCapability -| | |---InteractionNormCapability.ets // 交互归一能力 -| |---resourceQualifier -| | |---ResourceQualifier.ets // 资源文件使用 -| |---responsiveLayout -| | |---ResponsiveLayoutIndex.ets -| | |---breakpoint -| | | |---BreakpointSample.ets // 断点 -| | |---mediaQuery -| | | |---MediaQuerySample.ets // 媒体查询 -| |---typicalScene -| | |---banner -| | | |---BannerSample.ets // 广告栏 -| | |---bigImage -| | | |---BigImageSample.ets // 大图浏览 -| | |---diversion -| | | |---DiversionSample.ets // 挪移布局 -| | |---header -| | | |---HeaderSample.ets // 顶部布局 -| | |---indentation -| | | |---IndentationSample.ets // 缩进布局 -| | |---multiLaneList -| | | |---MultiLaneListSample.ets // 多列列表 -| | |---multiScene -| | | |---data -| | | | |---apliications -| | | | | |---Apliications.ets -| | | | |---home -| | | | | |---Home.ets -| | | |---pages -| | | | |---apliications -| | | | | |---Apliications.ets -| | | | |---home -| | | | | |---Home.ets -| | | | |---player -| | | | | |---Player.ets -| | | | |---MultiScene.ets // 一多典型场景 -| | |---operationEntries -| | | |---OperationEntriesSample.ets // 操作入口 -| | |---repeat -| | | |---RepeatSample.ets // 重复布局 -| | |---responsiveGrid -| | | |---ResponsiveGridSample.ets // 网格视图 -| | |---sidebar -| | | |---SidebarSample.ets // 侧边栏 -| | |---tabs -| | | |---TabsSample.ets // 页签布局 -| | |---TypicalSceneIndex.ets // 典型布局场景 -``` -### 具体实现 - -* 该示例使用了路由跳转接口,实现了各个不同布局之间的页面跳转,通过MediaQueryListener方法查询媒体,matchMediaSync方法设置媒体查询的查询条件。 -* 源码链接:[BreakpointSystem.ets](entry/src/main/ets/common/BreakpointSystem.ets),[DirectoryList.ets](entry/src/main/ets/common/DirectoryList.ets) -* 接口参考:[@ohos.router](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-arkui/js-apis-system-router.md),[@ohos.mediaquery](https://docs.openharmony.cn/pages/v4.1/zh-cn/application-dev/reference/apis-arkui/js-apis-mediaquery.md) - -### 相关权限 - -不涉及。 - -### 依赖 - -不涉及。 - -### 约束与限制 - -1.本示例仅支持标准系统上运行,支持设备:RK3568。 - -2.本示例为Stage模型,支持API12版本SDK,SDK版本号(API Version 12 Release),镜像版本号(5.0.0 Release) - -3.本示例需要使用DevEco Studio NEXT Release(Build Version: 5.0.3.900, built on October 8, 2024)及以上版本才可编译运行。 - -4.本示例在开发板上运行时,可以修改开发板系统配置文件以使能应用窗口能力。 - -```` -# 将开发板文件系统的权限配置为可读写 -hdc shell mount -o rw,remount / -# 取出原始配置文件 -hdc file recv system/etc/window/resources/window_manager_config.xml C:\ -# 将文件中改为 -# 用修改后的文件替换系统中的原始文件 -hdc file send C:\window_manager_config.xml system/etc/window/resources/window_manager_config.xml -# 重启后生效 -hdc shell reboot -```` - -### 下载 - -如需单独下载本工程,执行如下命令: -``` -git init -git config core.sparsecheckout true -echo code/SuperFeature/MultiDeviceAppDev/AdaptiveCapabilities/ > .git/info/sparse-checkout -git remote add origin https://gitee.com/openharmony/applications_app_samples.git -git pull origin master -``` \ No newline at end of file diff --git a/AdaptiveCapabilities/build-profile.json5 b/AdaptiveCapabilities/build-profile.json5 index a70b8401e6ef8f7476649db4057bcdefcb3bd8a4..7421eac5cace21b28ab5e96c79ba0520f672cdd1 100644 --- a/AdaptiveCapabilities/build-profile.json5 +++ b/AdaptiveCapabilities/build-profile.json5 @@ -20,7 +20,8 @@ { "name": "default", "signingConfig": "default", - "compatibleSdkVersion": "5.0.3(15)", + "compatibleSdkVersion": "5.0.5(17)", + "targetSdkVersion": "5.0.5(17)", "runtimeOS": "HarmonyOS", "buildOption": { "strictMode": { diff --git a/AdaptiveCapabilities/entry/src/main/ets/MainAbility/MainAbility.ets b/AdaptiveCapabilities/entry/src/main/ets/MainAbility/MainAbility.ets index 9e22face6d821b460c80c8b4aa349ad5e7aedb43..3c0caaf6b201a77dae78fe25f7210199503a6b8d 100644 --- a/AdaptiveCapabilities/entry/src/main/ets/MainAbility/MainAbility.ets +++ b/AdaptiveCapabilities/entry/src/main/ets/MainAbility/MainAbility.ets @@ -13,12 +13,19 @@ * limitations under the License. */ +import { BusinessError } from '@kit.BasicServicesKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; import { UIAbility } from '@kit.AbilityKit'; import { window } from '@kit.ArkUI'; -import { hilog } from '@kit.PerformanceAnalysisKit'; import Logger from '../model/Logger'; +const DOMAIN = 0x0000; +const TAG = 'EntryAbility'; +const FORMAT = '%{public}s'; + export default class MainAbility extends UIAbility { + windowClass: window.Window | undefined = undefined; + onCreate() { Logger.info('[Sample_AdaptiveCapabilities]', 'MainAbility onCreate'); } @@ -30,15 +37,51 @@ export default class MainAbility extends UIAbility { onWindowStageCreate(windowStage: window.WindowStage) { // Main window is created, set main page for this ability Logger.info('[Sample_AdaptiveCapabilities]', 'onWindowStageCreate'); + + + windowStage.getMainWindow((err: BusinessError, data) => { + const errCode: number = err.code; + if (errCode) { + hilog.error(DOMAIN, TAG, FORMAT, + `Failed to obtain the main window. Cause code: ${err.code}, message: ${err.message}`); + return; + } + this.windowClass = data; + let isLayoutFullScreen = true; + try { + let promise = this.windowClass.setWindowLayoutFullScreen(isLayoutFullScreen).catch((err: BusinessError) => { + hilog.error(DOMAIN, TAG, FORMAT, + `Failed to set the window layout to full-screen mode. Cause code: ${err.code},message: ${err.message}`); + }); + promise.then(() => { + hilog.info(DOMAIN, TAG, FORMAT, 'Succeeded in setting the window layout to full-screen mode.'); + }).catch((err: BusinessError) => { + hilog.error(DOMAIN, TAG, FORMAT, + `Failed to set the window layout to full-screen mode. Cause code: ${err.code},message: ${err.message}`); + }); + } catch (err) { + hilog.error(DOMAIN, TAG, FORMAT, + `Failed to set the window layout to full-screen mode. Cause code: ${err.code},message: ${err.message}`); + } + this.windowClass.setSpecificSystemBarEnabled('navigationIndicator', false).catch((err: BusinessError) => { + hilog.error(DOMAIN, TAG, FORMAT, + `Failed to set the system bar to be invisible. Cause code: ${err.code},message: ${err.message}`); + }); + }); + windowStage.loadContent('pages/Index', (err) => { if (err.code) { - hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); + hilog.error(DOMAIN, TAG, FORMAT, 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); return; } - hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.'); - let windowObj = windowStage.getMainWindowSync(); - AppStorage.setOrCreate('windowObj', windowObj); - AppStorage.setOrCreate('uiContext', windowObj.getUIContext()); + hilog.info(DOMAIN, TAG, FORMAT, 'Succeeded in loading the content.'); + try { + let windowObj = windowStage.getMainWindowSync(); + AppStorage.setOrCreate('windowObj', windowObj); + AppStorage.setOrCreate('uiContext', windowObj.getUIContext()); + } catch (err) { + hilog.error(DOMAIN, TAG, FORMAT, `Failed. Cause code: ${err.code}, message: ${err.message}`); + } }); } diff --git a/AdaptiveCapabilities/entry/src/main/ets/common/DirectoryList.ets b/AdaptiveCapabilities/entry/src/main/ets/common/DirectoryList.ets index b8597f236f652fb34d73fe3a6a48b469de33f482..5a3a9c3f8dd7c5c088b2bb90e8a0f7c72d739166 100644 --- a/AdaptiveCapabilities/entry/src/main/ets/common/DirectoryList.ets +++ b/AdaptiveCapabilities/entry/src/main/ets/common/DirectoryList.ets @@ -13,6 +13,13 @@ * limitations under the License. */ +import { BusinessError } from '@kit.BasicServicesKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; + +const DOMAIN = 0x0000; +const TAG = 'DirectoryList'; +const FORMAT = '%{public}s'; + class DirectoryItem { title: Resource | string = ''; uri: string = ''; @@ -39,17 +46,23 @@ struct DirectoryList { .width('90%') .height(55) .margin(12) - .backgroundColor('#007DFF') + .backgroundColor($r('sys.color.brand')) .onClick(() => { this.getUIContext().getRouter().pushUrl({ url: item.uri + }).catch((err: BusinessError) => { + hilog.error(DOMAIN, TAG, FORMAT, `pushUrl failed, code is ${err.code}, message is ${err.message}`); }) }); }, (item: DirectoryItem) => JSON.stringify(item)); } } .width('100%') - .padding({ left: 10, right: 10, bottom: 100 }); + .padding({ + left: 10, + right: 10, + bottom: 100 + }) } } diff --git a/AdaptiveCapabilities/entry/src/main/ets/common/GetValueOnBreakpoint.ets b/AdaptiveCapabilities/entry/src/main/ets/common/GetValueOnBreakpoint.ets index a1a8b8cb9932a4744dbb01d8e22127b50d6cefb9..8b7422683ad6420897dad1dfba0015d18da54982 100644 --- a/AdaptiveCapabilities/entry/src/main/ets/common/GetValueOnBreakpoint.ets +++ b/AdaptiveCapabilities/entry/src/main/ets/common/GetValueOnBreakpoint.ets @@ -14,6 +14,11 @@ */ import { window } from '@kit.ArkUI'; +import { hilog } from '@kit.PerformanceAnalysisKit'; + +const DOMAIN = 0x0000; +const TAG = 'GetValueOnBreakpoint'; +const FORMAT = '%{public}s'; export class Breakpoints { xs: number = 0; @@ -22,7 +27,7 @@ export class Breakpoints { lg: number = 0; } -// 全局断点接口 +// Global breakpoint interface export default function getValueOnBreakpoint(breakpointsLabels: string[], breakpoints: Breakpoints): string { if (breakpointsLabels.length < 4) { return ''; @@ -31,17 +36,22 @@ export default function getValueOnBreakpoint(breakpointsLabels: string[], breakp if (windowObj == undefined) { return ''; } - let uiContext = AppStorage.get('uiContext') as UIContext; - let windowWidthVp = uiContext.px2vp(windowObj.getWindowProperties().windowRect.width); let newBreakpoint: string = ''; - if (windowWidthVp < breakpoints.sm) { - newBreakpoint = breakpointsLabels[0]; - } else if (windowWidthVp < breakpoints.md) { - newBreakpoint = breakpointsLabels[1]; - } else if (windowWidthVp < breakpoints.lg) { - newBreakpoint = breakpointsLabels[2]; - } else { - newBreakpoint = breakpointsLabels[3]; + try { + let uiContext = AppStorage.get('uiContext') as UIContext; + let windowWidthVp = uiContext.px2vp(windowObj.getWindowProperties().windowRect.width); + if (windowWidthVp < breakpoints.sm) { + newBreakpoint = breakpointsLabels[0]; + } else if (windowWidthVp < breakpoints.md) { + newBreakpoint = breakpointsLabels[1]; + } else if (windowWidthVp < breakpoints.lg) { + newBreakpoint = breakpointsLabels[2]; + } else { + newBreakpoint = breakpointsLabels[3]; + } + } catch (err) { + hilog.error(DOMAIN, TAG, FORMAT, + `Failed to obtain the window properties. Cause code: ${err.code}, message: ${err.message}`); } return newBreakpoint; } \ No newline at end of file diff --git a/AdaptiveCapabilities/entry/src/main/ets/model/Logger.ts b/AdaptiveCapabilities/entry/src/main/ets/model/Logger.ts index c9fb06f0ee72131e8c26928e2d357bc7b31da7e5..679e6ace6921f025a5e166a4c24d91b0841dab0c 100644 --- a/AdaptiveCapabilities/entry/src/main/ets/model/Logger.ts +++ b/AdaptiveCapabilities/entry/src/main/ets/model/Logger.ts @@ -13,12 +13,12 @@ * limitations under the License. */ -import hilog from '@ohos.hilog' +import { hilog } from '@kit.PerformanceAnalysisKit'; class Logger { - private domain: number - private prefix: string - private format: string = "%{public}s, %{public}s" + private domain: number; + private prefix: string; + private format: string = '%{public}s, %{public}s'; constructor(prefix: string) { this.prefix = prefix @@ -26,19 +26,19 @@ class Logger { } debug(...args: any[]) { - hilog.debug(this.domain, this.prefix, this.format, args) + hilog.debug(this.domain, this.prefix, this.format, args); } info(...args: any[]) { - hilog.info(this.domain, this.prefix, this.format, args) + hilog.info(this.domain, this.prefix, this.format, args); } warn(...args: any[]) { - hilog.warn(this.domain, this.prefix, this.format, args) + hilog.warn(this.domain, this.prefix, this.format, args); } error(...args: any[]) { - hilog.error(this.domain, this.prefix, this.format, args) + hilog.error(this.domain, this.prefix, this.format, args); } } diff --git a/AdaptiveCapabilities/entry/src/main/ets/pages/Index.ets b/AdaptiveCapabilities/entry/src/main/ets/pages/Index.ets index 88e18fc7b660835267562054b4477c8c9c840d1b..e0d1661de004873c4a92933e6396c219a248cc71 100644 --- a/AdaptiveCapabilities/entry/src/main/ets/pages/Index.ets +++ b/AdaptiveCapabilities/entry/src/main/ets/pages/Index.ets @@ -13,19 +13,35 @@ * limitations under the License. */ -import { DirectoryItem, DirectoryList } from '../common/DirectoryList' +import { DirectoryItem, DirectoryList } from '../common/DirectoryList'; @Entry @Component struct Index { private directory: DirectoryItem[] = [ - { title: $r('app.string.atomic_capability'), uri: 'pages/atomicLayoutCapability/AtomicLayoutCapabilityIndex', id:'AtomicLayoutCapabilityIndex' }, - { title: $r('app.string.responsive_layout'), uri: 'pages/responsiveLayout/ResponsiveLayoutIndex', id:'ResponsiveLayoutIndex' }, - { title: $r('app.string.typical_scenario'), uri: 'pages/typicalScene/TypicalSceneIndex', id:'TypicalSceneIndex' }, - { title: $r('app.string.resource_qualifier'), uri: 'pages/resourceQualifier/ResourceQualifier', id:'ResourceQualifier' }, - { title: $r('app.string.interaction_norm_capability'), uri: 'pages/interactionNormCapability/InteractionNormCapability', id:'InteractionNormCapability' } - ] - @State inSetValue: number = 40 + { + title: $r('app.string.atomic_capability'), + uri: 'pages/atomicLayoutCapability/AtomicLayoutCapabilityIndex', + id: 'AtomicLayoutCapabilityIndex' + }, + { + title: $r('app.string.responsive_layout'), + uri: 'pages/responsiveLayout/ResponsiveLayoutIndex', + id: 'ResponsiveLayoutIndex' + }, + { title: $r('app.string.typical_scenario'), uri: 'pages/typicalScene/TypicalSceneIndex', id: 'TypicalSceneIndex' }, + { + title: $r('app.string.resource_qualifier'), + uri: 'pages/resourceQualifier/ResourceQualifier', + id: 'ResourceQualifier' + }, + { + title: $r('app.string.interaction_norm_capability'), + uri: 'pages/interactionNormCapability/InteractionNormCapability', + id: 'InteractionNormCapability' + } + ]; + @State inSetValue: number = 40; build() { Column() { diff --git a/AdaptiveCapabilities/entry/src/main/ets/pages/atomicLayoutCapability/equipartitionCapability/EquipartitionCapability.ets b/AdaptiveCapabilities/entry/src/main/ets/pages/atomicLayoutCapability/equipartitionCapability/EquipartitionCapability.ets index 0653e5e8dd2092366811f1b1f53ca146b4f1e991..54a3b6a6010ba0ced5c964f7b89652e9ec38f5c9 100644 --- a/AdaptiveCapabilities/entry/src/main/ets/pages/atomicLayoutCapability/equipartitionCapability/EquipartitionCapability.ets +++ b/AdaptiveCapabilities/entry/src/main/ets/pages/atomicLayoutCapability/equipartitionCapability/EquipartitionCapability.ets @@ -58,29 +58,29 @@ struct EquipartitionCapability { Column() { // Distribute remaining space evenly along the main axis of the parent container. Flex({ justifyContent: FlexAlign.SpaceEvenly }) { - ForEach(this.list, (item: number) => { + ForEach(this.list, () => { this.Item(); - }, (item: number, index: number) => JSON.stringify(item) + index) + }, (item: number, index: number) => item.toString() + index) } // Distribute remaining space evenly along the main axis of the parent container. Flex({ justifyContent: FlexAlign.SpaceEvenly }) { - ForEach(this.list, (item: number) => { + ForEach(this.list, () => { this.Item(); - }, (item: number, index: number) => JSON.stringify(item) + index) + }, (item: number, index: number) => item.toString() + index) } } .width(this.rate * 100 + '%') .height(222) .padding({ top: 16 }) - .backgroundColor('#FFFFFF') + .backgroundColor($r('sys.color.font_on_primary')) .borderRadius(16) this.slider() } .width('100%') .height('100%') - .backgroundColor('#F1F3F5') + .backgroundColor($r('sys.color.background_secondary')) .alignItems(VerticalAlign.Center) .justifyContent(FlexAlign.Center) } diff --git a/AdaptiveCapabilities/entry/src/main/ets/pages/atomicLayoutCapability/extensionCapability/ExtensionCapability1.ets b/AdaptiveCapabilities/entry/src/main/ets/pages/atomicLayoutCapability/extensionCapability/ExtensionCapability1.ets index b8a4642810cbdd8f3367e58836f05c44847b6869..a4e446597da12c9c77b84658a30a26e6e1844078 100644 --- a/AdaptiveCapabilities/entry/src/main/ets/pages/atomicLayoutCapability/extensionCapability/ExtensionCapability1.ets +++ b/AdaptiveCapabilities/entry/src/main/ets/pages/atomicLayoutCapability/extensionCapability/ExtensionCapability1.ets @@ -37,7 +37,7 @@ struct ExtensionCapability1 { // Implement extension capability through Scroll and Row(or Column) components. Scroll() { Row({ space: 10 }) { - ForEach(this.appList, (item: number, index: number) => { + ForEach(this.appList, () => { Column() { Image($r('app.media.icon')) .width(48) @@ -54,7 +54,7 @@ struct ExtensionCapability1 { } .width(80) .height(102) - }, (item: number, index: number) => JSON.stringify(item) + index) + }, (item: number, index: number) => item.toString() + index) } .padding({ top: 16, left: 10 }) .height(118) diff --git a/AdaptiveCapabilities/entry/src/main/ets/pages/atomicLayoutCapability/extensionCapability/ExtensionCapability2.ets b/AdaptiveCapabilities/entry/src/main/ets/pages/atomicLayoutCapability/extensionCapability/ExtensionCapability2.ets index 3449c076596229e60badb39f509ffacdb37d21ab..a18b6ce0dd34d06e0ca3b567a7d51ab254440c26 100644 --- a/AdaptiveCapabilities/entry/src/main/ets/pages/atomicLayoutCapability/extensionCapability/ExtensionCapability2.ets +++ b/AdaptiveCapabilities/entry/src/main/ets/pages/atomicLayoutCapability/extensionCapability/ExtensionCapability2.ets @@ -37,7 +37,7 @@ struct ExtensionCapability2 { Row({ space: 10 }) { // Implement extension capability through List component. List({ space: 10 }) { - ForEach(this.appList, (item: number, index: number) => { + ForEach(this.appList, () => { ListItem() { Column() { Image($r('app.media.icon')) @@ -58,7 +58,7 @@ struct ExtensionCapability2 { } .width(80) .height(102) - }, (item: number, index: number) => JSON.stringify(item) + index) + }, (item: number, index: number) => item.toString() + index) } .padding({ top: 16, left: 10 }) .listDirection(Axis.Horizontal) @@ -77,5 +77,4 @@ struct ExtensionCapability2 { .alignItems(VerticalAlign.Center) } } - // [End ExtensionCapability2] \ No newline at end of file diff --git a/AdaptiveCapabilities/entry/src/main/ets/pages/atomicLayoutCapability/flexibleCapability/FlexibleCapability1.ets b/AdaptiveCapabilities/entry/src/main/ets/pages/atomicLayoutCapability/flexibleCapability/FlexibleCapability1.ets index 328654b8c3a6c116a0bdc67cba2ebc79efd09e8e..02a38165bb3c7d3e36ea8ad1062628b6377bf670 100644 --- a/AdaptiveCapabilities/entry/src/main/ets/pages/atomicLayoutCapability/flexibleCapability/FlexibleCapability1.ets +++ b/AdaptiveCapabilities/entry/src/main/ets/pages/atomicLayoutCapability/flexibleCapability/FlexibleCapability1.ets @@ -38,7 +38,7 @@ struct FlexibleCapability1 { Row() .width(150) .height(400) - .backgroundColor('#FFFFFF') + .backgroundColor($r('sys.color.comp_background_primary')) .flexGrow(0) .flexShrink(1) Image($r('app.media.illustrator')) @@ -51,7 +51,7 @@ struct FlexibleCapability1 { Row() .width(150) .height(400) - .backgroundColor('#FFFFFF') + .backgroundColor($r('sys.color.comp_background_primary')) .flexGrow(0) .flexShrink(1) } @@ -61,7 +61,7 @@ struct FlexibleCapability1 { } .width('100%') .height('100%') - .backgroundColor('#F1F3F5') + .backgroundColor($r('sys.color.background_secondary')) .alignItems(HorizontalAlign.Center) .justifyContent(FlexAlign.Center) } diff --git a/AdaptiveCapabilities/entry/src/main/ets/pages/atomicLayoutCapability/flexibleCapability/FlexibleCapability2.ets b/AdaptiveCapabilities/entry/src/main/ets/pages/atomicLayoutCapability/flexibleCapability/FlexibleCapability2.ets index af45d4445d8cbf65f2e99a440570dd16cf4a4bc5..a81c541c3ca6592eba0cb17b5d89d0bfcc8bc3f5 100644 --- a/AdaptiveCapabilities/entry/src/main/ets/pages/atomicLayoutCapability/flexibleCapability/FlexibleCapability2.ets +++ b/AdaptiveCapabilities/entry/src/main/ets/pages/atomicLayoutCapability/flexibleCapability/FlexibleCapability2.ets @@ -49,14 +49,14 @@ struct FlexibleCapability2 { .height(55) .borderRadius(12) .padding({ left: 13, right: 13 }) - .backgroundColor('#FFFFFF') + .backgroundColor($r('sys.color.comp_background_primary')) .width(this.rate * 100 + '%') this.slider() } .width('100%') .height('100%') - .backgroundColor('#F1F3F5') + .backgroundColor($r('sys.color.background_secondary')) .alignItems(VerticalAlign.Center) .justifyContent(FlexAlign.Center) } diff --git a/AdaptiveCapabilities/entry/src/main/ets/pages/atomicLayoutCapability/hiddenCapability/HiddenCapability.ets b/AdaptiveCapabilities/entry/src/main/ets/pages/atomicLayoutCapability/hiddenCapability/HiddenCapability.ets index 21e12b397fc3a1014948ae6ce34a94d6c4df7273..c1c5c7591e3264799fc5c6211a8c011cdd1cdb77 100644 --- a/AdaptiveCapabilities/entry/src/main/ets/pages/atomicLayoutCapability/hiddenCapability/HiddenCapability.ets +++ b/AdaptiveCapabilities/entry/src/main/ets/pages/atomicLayoutCapability/hiddenCapability/HiddenCapability.ets @@ -87,14 +87,14 @@ struct HiddenCapability { .width(this.rate * 100 + '%') .height(96) .borderRadius(16) - .backgroundColor('#FFFFFF') + .backgroundColor($r('sys.color.comp_background_primary')) .justifyContent(FlexAlign.Center) this.slider() } .width('100%') .height('100%') - .backgroundColor('#F1F3F5') + .backgroundColor($r('sys.color.background_secondary')) .alignItems(HorizontalAlign.Center) .justifyContent(FlexAlign.Center) } diff --git a/AdaptiveCapabilities/entry/src/main/ets/pages/atomicLayoutCapability/proportionCapability/ProportionCapability.ets b/AdaptiveCapabilities/entry/src/main/ets/pages/atomicLayoutCapability/proportionCapability/ProportionCapability.ets index 40cbb0e1718bbd8005bc65d0e4fbcaf8255f3f81..ae9065fbeb8e945649f0e824cc319d0cad863040 100644 --- a/AdaptiveCapabilities/entry/src/main/ets/pages/atomicLayoutCapability/proportionCapability/ProportionCapability.ets +++ b/AdaptiveCapabilities/entry/src/main/ets/pages/atomicLayoutCapability/proportionCapability/ProportionCapability.ets @@ -46,7 +46,7 @@ struct ProportionCapability { .justifyContent(FlexAlign.Center) Column() { - Image($r("app.media.pause")) + Image($r('app.media.pause')) .width(48) .height(48) } @@ -67,13 +67,13 @@ struct ProportionCapability { .width(this.rate * 100 + '%') .height(96) .borderRadius(16) - .backgroundColor('#FFFFFF') + .backgroundColor($r('sys.color.comp_background_primary')) this.slider() } .width('100%') .height('100%') - .backgroundColor('#F1F3F5') + .backgroundColor($r('sys.color.background_secondary')) .alignItems(VerticalAlign.Center) .justifyContent(FlexAlign.Center) } diff --git a/AdaptiveCapabilities/entry/src/main/ets/pages/atomicLayoutCapability/scaleCapability/ScaleCapability.ets b/AdaptiveCapabilities/entry/src/main/ets/pages/atomicLayoutCapability/scaleCapability/ScaleCapability.ets index e42983cd1c13996bcc0065697cc48cf6fd8b7754..f497d1148621f7c6783e00eb6f36b5afc54be369 100644 --- a/AdaptiveCapabilities/entry/src/main/ets/pages/atomicLayoutCapability/scaleCapability/ScaleCapability.ets +++ b/AdaptiveCapabilities/entry/src/main/ets/pages/atomicLayoutCapability/scaleCapability/ScaleCapability.ets @@ -64,7 +64,7 @@ struct ScaleCapability { // Decorative border (purely for visual demonstration purposes). .border({ width: 2, color: '#66F1CCB8' }) } - .backgroundColor('#FFFFFF') + .backgroundColor($r('sys.color.comp_background_primary')) .height(this.sliderHeight) .width(this.sliderWidth) .alignItems(HorizontalAlign.Center) @@ -74,10 +74,9 @@ struct ScaleCapability { } .height('100%') .width('100%') - .backgroundColor('#F1F3F5') + .backgroundColor($r('sys.color.background_secondary')) .alignItems(HorizontalAlign.Center) .justifyContent(FlexAlign.Center) } } - // [End ScaleCapability] \ No newline at end of file diff --git a/AdaptiveCapabilities/entry/src/main/ets/pages/atomicLayoutCapability/wrapCapability/WrapCapability.ets b/AdaptiveCapabilities/entry/src/main/ets/pages/atomicLayoutCapability/wrapCapability/WrapCapability.ets index 4ab7da14b28bf3b7cc8969ff9d9b45b09c4dabdc..d1443628822c2245a56e603fcac60404d2ac4466 100644 --- a/AdaptiveCapabilities/entry/src/main/ets/pages/atomicLayoutCapability/wrapCapability/WrapCapability.ets +++ b/AdaptiveCapabilities/entry/src/main/ets/pages/atomicLayoutCapability/wrapCapability/WrapCapability.ets @@ -46,14 +46,14 @@ struct WrapCapabilitySample { justifyContent: FlexAlign.Center, wrap: FlexWrap.Wrap }) { - ForEach(this.imageList, (item: Resource, index: number) => { + ForEach(this.imageList, (item: Resource) => { Image(item) .width(192) .height(138) .padding(10) - }, (item: Resource, index: number) => JSON.stringify(item) + index) + }, (item: Resource, index: number) => item.toString() + index) } - .backgroundColor('#FFFFFF') + .backgroundColor($r('sys.color.comp_background_primary')) .padding(20) .width(this.rate * 100 + '%') .borderRadius(16) @@ -62,10 +62,9 @@ struct WrapCapabilitySample { } .width('100%') .height('100%') - .backgroundColor('#F1F3F5') + .backgroundColor($r('sys.color.background_secondary')) .alignItems(HorizontalAlign.Center) .justifyContent(FlexAlign.Center) } } - // [End WrapCapabilitySample] \ No newline at end of file diff --git a/AdaptiveCapabilities/entry/src/main/ets/pages/gridRow/gridRow/GridRowSample1.ets b/AdaptiveCapabilities/entry/src/main/ets/pages/gridRow/gridRow/GridRowSample1.ets index 09ec20165e9b1fe49953d9c6e0e546e29ef79773..8bc12df347b151abe43aa6b9b85b6f2b210f6a9f 100644 --- a/AdaptiveCapabilities/entry/src/main/ets/pages/gridRow/gridRow/GridRowSample1.ets +++ b/AdaptiveCapabilities/entry/src/main/ets/pages/gridRow/gridRow/GridRowSample1.ets @@ -21,15 +21,14 @@ struct GridRowSample1 { @State currentBreakpoint: string = 'md'; build() { - GridRow({ breakpoints: { value: ['600vp', '700vp', '800vp', '900vp', '1000vp'] } }) { + GridRow({ breakpoints: { value: ['320vp', '600vp', '840vp', '1440vp'] } }) { GridCol({ span: { xs: 12, sm: 12, md: 12, lg: 12, - xl: 12, - xxl: 12 + xl: 12 } }) { Row() { diff --git a/AdaptiveCapabilities/entry/src/main/ets/pages/gridRow/gridRow/GridRowSample10.ets b/AdaptiveCapabilities/entry/src/main/ets/pages/gridRow/gridRow/GridRowSample10.ets index 1a9c686d87e35c8f7195a1bf542204846e10cf5f..bca08648a36d769a9be3c7186212c4fff1f86a8c 100644 --- a/AdaptiveCapabilities/entry/src/main/ets/pages/gridRow/gridRow/GridRowSample10.ets +++ b/AdaptiveCapabilities/entry/src/main/ets/pages/gridRow/gridRow/GridRowSample10.ets @@ -35,10 +35,8 @@ struct GridRowSample10 { build() { Column({ space: 5 }) { - Column() { GridRow({ columns: this.layoutColumns, direction: GridRowDirection.Row }) { - // The non-rendering component support the Height attribute of GridRow GridCol({ span: 0 }) .height('100%') @@ -48,7 +46,8 @@ struct GridRowSample10 { Text('1') .height('100%') .fontSize(24); - }.height('33.3%') + } + .height('33.3%') .backgroundColor('#ff00ff94') .alignSelf(this.col1Align); @@ -56,17 +55,19 @@ struct GridRowSample10 { Text('2') .height('100%') .fontSize(24); - }.height('33.3%') + } + .height('33.3%') .backgroundColor('#ff53e8ff') .alignSelf(this.col2Align); - }.width('100%') + } + .width('100%') .height('100%'); - }.width('100%') + } + .width('100%') .height('50%') .border({ width: 1, color: '#ff00ffe9' }); Column() { - // Radio Groups Row() { Text($r('app.string.Radio_GridRow_All_LCR')) @@ -95,7 +96,8 @@ struct GridRowSample10 { } .layoutWeight(1) .justifyContent(FlexAlign.End); - }.width('100%') + } + .width('100%') .height('25%') .justifyContent(FlexAlign.SpaceAround) .margin({ top: '1%' }); @@ -127,7 +129,8 @@ struct GridRowSample10 { } .layoutWeight(1) .justifyContent(FlexAlign.End); - }.width('100%') + } + .width('100%') .height('25%') .justifyContent(FlexAlign.SpaceAround) .margin({ top: '1%' }); @@ -159,7 +162,8 @@ struct GridRowSample10 { } .layoutWeight(1) .justifyContent(FlexAlign.End); - }.width('100%') + } + .width('100%') .height('25%') .justifyContent(FlexAlign.SpaceAround) .margin({ top: '1%' }); @@ -199,7 +203,7 @@ struct GridRowSample10 { } .width('100%') .height('30%') - .padding({left: 10, right: 10}); + .padding({ left: 10, right: 10 }); } .width('100%') .height('100%') @@ -222,7 +226,6 @@ enum VerDirection { const COL1_POSITIONS = [0, 2, 4]; // The values of the first component class GridColController { - moveAllInHor(pos: HorDirection, inst: GridRowSample10) { switch (pos) { case HorDirection.LEFT: diff --git a/AdaptiveCapabilities/entry/src/main/ets/pages/gridRow/gridRow/GridRowSample2.ets b/AdaptiveCapabilities/entry/src/main/ets/pages/gridRow/gridRow/GridRowSample2.ets index 6c97bac14c566b592f63d6ad3381355023414274..bebf930dbe9e851d85643bebdf3b93ea272f1a8d 100644 --- a/AdaptiveCapabilities/entry/src/main/ets/pages/gridRow/gridRow/GridRowSample2.ets +++ b/AdaptiveCapabilities/entry/src/main/ets/pages/gridRow/gridRow/GridRowSample2.ets @@ -26,12 +26,12 @@ struct GridRowSample2 { Column() { } .width('100%') - .backgroundColor('#19000000') + .backgroundColor($r('sys.color.comp_background_secondary')) - // Content area, resizable range: [550vp, 50vp]. + // Content area. GridRow({ breakpoints: { - value: ['100vp', '200vp', '300vp', '400vp', '500vp'], + value: ['320vp', '600vp', '840vp', '1440vp'], reference: BreakpointsReference.ComponentSize } }) { @@ -41,8 +41,7 @@ struct GridRowSample2 { sm: 12, md: 12, lg: 12, - xl: 12, - xxl: 12 + xl: 12 } }) { Row() { @@ -57,7 +56,7 @@ struct GridRowSample2 { } } .onBreakpointChange((currentBreakpoint: string) => { - this.currentBreakpoint = currentBreakpoint + this.currentBreakpoint = currentBreakpoint; }) .width('100%') } @@ -70,5 +69,4 @@ struct GridRowSample2 { .maxSideBarWidth(600) } } - // [End GridRowSample2] \ No newline at end of file diff --git a/AdaptiveCapabilities/entry/src/main/ets/pages/gridRow/gridRow/GridRowSample3.ets b/AdaptiveCapabilities/entry/src/main/ets/pages/gridRow/gridRow/GridRowSample3.ets index da436162568192530ea418b16d2fc487366c2253..e12642649ff3bb0eab3b971788516e49d7b41216 100644 --- a/AdaptiveCapabilities/entry/src/main/ets/pages/gridRow/gridRow/GridRowSample3.ets +++ b/AdaptiveCapabilities/entry/src/main/ets/pages/gridRow/gridRow/GridRowSample3.ets @@ -30,7 +30,10 @@ struct GridRowSample3 { // Config the values of columns and gutter at different breakpoints. GridRow({ columns: { sm: 4, md: 8, lg: 12 }, - gutter: { x: { sm: 8, md: 16, lg: 24 }, y: { sm: 8, md: 16, lg: 24 } } + gutter: { + x: { sm: 8, md: 16, lg: 24 }, + y: { sm: 8, md: 16, lg: 24 } + } }) { ForEach(this.bgColors, (bgColor: ResourceColor) => { GridCol({ span: { sm: 2, md: 2, lg: 2 } }) { @@ -39,7 +42,7 @@ struct GridRowSample3 { .backgroundColor(bgColor) .height(30) } - }) + }, (bgColor: ResourceColor) => bgColor.toString()) } } } diff --git a/AdaptiveCapabilities/entry/src/main/ets/pages/gridRow/gridRow/GridRowSample4.ets b/AdaptiveCapabilities/entry/src/main/ets/pages/gridRow/gridRow/GridRowSample4.ets index 345a82bf4a87f00714fd28cf10a2f8b614f06bc8..d0acd0eb09d652e0f43b06424ab3017a98cc3d4e 100644 --- a/AdaptiveCapabilities/entry/src/main/ets/pages/gridRow/gridRow/GridRowSample4.ets +++ b/AdaptiveCapabilities/entry/src/main/ets/pages/gridRow/gridRow/GridRowSample4.ets @@ -37,19 +37,22 @@ struct GridRowSample4 { .height('100%') .alignItems(VerticalAlign.Center) .justifyContent(FlexAlign.Center) - .backgroundColor('#19000000') + .backgroundColor($r('sys.color.comp_background_secondary')) } } .height(50) .borderWidth(2) .borderColor('#F1CCB8') - .padding({ left: this.gridMargin, right: this.gridMargin }) + .padding({ + left: this.gridMargin, + right: this.gridMargin + }) // Configure the left and right spacing values of grid components at different breakpoints using breakpoint change events. .onBreakpointChange((currentBreakpoint: string) => { - if (currentBreakpoint === 'lg' || currentBreakpoint === 'md') { - this.gridMargin = 24; - } else { + if (currentBreakpoint === 'xs' || currentBreakpoint === 'sm') { this.gridMargin = 12; + } else { + this.gridMargin = 24; } }) @@ -69,13 +72,16 @@ struct GridRowSample4 { .height('100%') .alignItems(VerticalAlign.Center) .justifyContent(FlexAlign.Center) - .backgroundColor('#19000000') + .backgroundColor($r('sys.color.comp_background_secondary')) } } .height(50) .borderWidth(2) .borderColor('#F1CCB8') - .margin({ left: this.gridMargin, right: this.gridMargin }) + .margin({ + left: this.gridMargin, + right: this.gridMargin + }) } } } diff --git a/AdaptiveCapabilities/entry/src/main/ets/pages/gridRow/gridRow/GridRowSample5.ets b/AdaptiveCapabilities/entry/src/main/ets/pages/gridRow/gridRow/GridRowSample5.ets index ef4ea734a8137ecee7f11791db397427e771af56..65f23c6207f55b1eb5eb80886914716da6bde030 100644 --- a/AdaptiveCapabilities/entry/src/main/ets/pages/gridRow/gridRow/GridRowSample5.ets +++ b/AdaptiveCapabilities/entry/src/main/ets/pages/gridRow/gridRow/GridRowSample5.ets @@ -29,17 +29,19 @@ struct GridRowSample5 { ]; build() { - GridRow() { + GridRow({ columns: { sm: 12, md: 12, lg: 12 } }) { ForEach(this.elements, (item: ColorArr) => { GridCol({ span: { sm: 6, md: item.index % 3 === 0 ? 0 : 4, lg: 3 } }) { Row() { - Text(`${item.index}`).fontSize(24) + Text(`${item.index}`) + .fontSize(24) } .justifyContent(FlexAlign.Center) .backgroundColor(item.color) .height(30) + .width('100%') } - }, (item: ColorArr, index: number) => JSON.stringify(item) + index) + }, (item: ColorArr, index: number) => (item.index + index).toString()) } } } diff --git a/AdaptiveCapabilities/entry/src/main/ets/pages/gridRow/gridRow/GridRowSample6.ets b/AdaptiveCapabilities/entry/src/main/ets/pages/gridRow/gridRow/GridRowSample6.ets index 71ec27bf8700625bf6be023f788a8f1570754db4..f723300a6f2776f93f1fe5be90219825d53ff656 100644 --- a/AdaptiveCapabilities/entry/src/main/ets/pages/gridRow/gridRow/GridRowSample6.ets +++ b/AdaptiveCapabilities/entry/src/main/ets/pages/gridRow/gridRow/GridRowSample6.ets @@ -29,7 +29,7 @@ struct GridRowSample6 { ]; build() { - GridRow() { + GridRow({ columns: { sm: 12, md: 12, lg: 12 } }) { ForEach(this.elements, (item: ColorArr) => { GridCol({ span: { sm: 6, md: 4, lg: 3 }, @@ -42,8 +42,9 @@ struct GridRowSample6 { .justifyContent(FlexAlign.Center) .backgroundColor(item.color) .height(30) + .width('100%') } - }, (item: ColorArr, index: number) => JSON.stringify(item) + index) + }, (item: ColorArr, index: number) => (item.index + index).toString()) } } } diff --git a/AdaptiveCapabilities/entry/src/main/ets/pages/gridRow/gridRow/GridRowSample7.ets b/AdaptiveCapabilities/entry/src/main/ets/pages/gridRow/gridRow/GridRowSample7.ets index adff56075934b97097af2e9cdc5c9a4e03af9764..a662b9ee7f32ea2109c435ae8d9201b41b1e7d25 100644 --- a/AdaptiveCapabilities/entry/src/main/ets/pages/gridRow/gridRow/GridRowSample7.ets +++ b/AdaptiveCapabilities/entry/src/main/ets/pages/gridRow/gridRow/GridRowSample7.ets @@ -29,7 +29,7 @@ struct GridRowSample7 { ]; build() { - GridRow() { + GridRow({ columns: { sm: 12, md: 12, lg: 12 } }) { ForEach(this.elements, (item: ColorArr) => { GridCol({ span: { sm: 6, md: 4, lg: 3 }, @@ -42,8 +42,9 @@ struct GridRowSample7 { .justifyContent(FlexAlign.Center) .backgroundColor(item.color) .height(30) + .width('100%') } - }, (item: ColorArr, index: number) => JSON.stringify(item) + index) + }, (item: ColorArr, index: number) => (item.index + index).toString()) } } } diff --git a/AdaptiveCapabilities/entry/src/main/ets/pages/gridRow/gridRow/GridRowSample8.ets b/AdaptiveCapabilities/entry/src/main/ets/pages/gridRow/gridRow/GridRowSample8.ets index c956269e0d80292105f25efb79f5081a2f923e02..46f53f025d18007817fa179ee6d4508676760346 100644 --- a/AdaptiveCapabilities/entry/src/main/ets/pages/gridRow/gridRow/GridRowSample8.ets +++ b/AdaptiveCapabilities/entry/src/main/ets/pages/gridRow/gridRow/GridRowSample8.ets @@ -29,7 +29,7 @@ struct GridRowSample8 { ]; build() { - GridRow() { + GridRow({ columns: { sm: 12, md: 12, lg: 12 } }) { ForEach(this.elements, (item: ColorArr) => { // If the values of the three parameters are not configured at the md breakpoint, they will inherit the values from the sm breakpoint. GridCol({ @@ -44,8 +44,9 @@ struct GridRowSample8 { .justifyContent(FlexAlign.Center) .backgroundColor(item.color) .height(30) + .width('100%') } - }, (item: ColorArr, index: number) => JSON.stringify(item) + index) + }, (item: ColorArr, index: number) => (item.index + index).toString()) } } } diff --git a/AdaptiveCapabilities/entry/src/main/ets/pages/gridRow/gridRow/GridRowSample9.ets b/AdaptiveCapabilities/entry/src/main/ets/pages/gridRow/gridRow/GridRowSample9.ets index 033277b51ee5194005e670d2f2828c69420e1978..0dea8e5a37b29377d5efbac66a947b16be7e9ff3 100644 --- a/AdaptiveCapabilities/entry/src/main/ets/pages/gridRow/gridRow/GridRowSample9.ets +++ b/AdaptiveCapabilities/entry/src/main/ets/pages/gridRow/gridRow/GridRowSample9.ets @@ -29,13 +29,13 @@ struct GridRowSample9 { ]; build() { - GridRow() { + GridRow({ columns: { sm: 12, md: 12, lg: 12 } }) { GridCol({ span: { sm: 12, md: 10, lg: 8 }, offset: { sm: 0, md: 1, lg: 2 } }) { - GridRow() { - ForEach(this.elements, (item : ColorArr) => { + GridRow({ columns: { sm: 12, md: 12, lg: 12 } }) { + ForEach(this.elements, (item: ColorArr) => { GridCol({ span: { sm: 6, md: 4, lg: 3 } }) { Row() { Text(`${item.index}`) @@ -44,10 +44,11 @@ struct GridRowSample9 { .justifyContent(FlexAlign.Center) .backgroundColor(item.color) .height(30) + .width('100%') } }, (item: ColorArr, index: number) => JSON.stringify(item) + index) } - .backgroundColor('#19000000') + .backgroundColor($r('sys.color.comp_background_secondary')) .height('100%') } } diff --git a/AdaptiveCapabilities/entry/src/main/ets/pages/interactionNormCapability/InteractionNormCapability.ets b/AdaptiveCapabilities/entry/src/main/ets/pages/interactionNormCapability/InteractionNormCapability.ets index 65a0aff726007e5507a5181e09945c4e538ead12..4e66f0305fe8f7b174bc3795512fd91e2bf7430c 100644 --- a/AdaptiveCapabilities/entry/src/main/ets/pages/interactionNormCapability/InteractionNormCapability.ets +++ b/AdaptiveCapabilities/entry/src/main/ets/pages/interactionNormCapability/InteractionNormCapability.ets @@ -12,7 +12,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { IntentionCode } from '@ohos.multimodalInput.intentionCode'; + +import { IntentionCode } from '@kit.InputKit'; import Logger from '../../model/Logger'; @Entry diff --git a/AdaptiveCapabilities/entry/src/main/ets/pages/resourceQualifier/ResourceQualifier.ets b/AdaptiveCapabilities/entry/src/main/ets/pages/resourceQualifier/ResourceQualifier.ets index e358b8449b5bab647568f35fc60fc9b133b28c10..5f47c2ad069a21c55b97d196595e3272de2a74b9 100644 --- a/AdaptiveCapabilities/entry/src/main/ets/pages/resourceQualifier/ResourceQualifier.ets +++ b/AdaptiveCapabilities/entry/src/main/ets/pages/resourceQualifier/ResourceQualifier.ets @@ -22,7 +22,7 @@ struct ResourceQualifier { Text($r('app.string.my_string')) .fontSize(60) .fontColor($r('app.color.my_color')) - Image($r("app.media.my_image")) + Image($r('app.media.my_image')) .width(100) .height(100) } diff --git a/AdaptiveCapabilities/entry/src/main/ets/pages/responsiveLayout/ResponsiveLayoutIndex.ets b/AdaptiveCapabilities/entry/src/main/ets/pages/responsiveLayout/ResponsiveLayoutIndex.ets index 04acf013a61a1ac92c6938ddbb5288e5c57aeadc..066068a91ed26e28c0337dd54fa936229dd905a5 100644 --- a/AdaptiveCapabilities/entry/src/main/ets/pages/responsiveLayout/ResponsiveLayoutIndex.ets +++ b/AdaptiveCapabilities/entry/src/main/ets/pages/responsiveLayout/ResponsiveLayoutIndex.ets @@ -13,15 +13,23 @@ * limitations under the License. */ -import { DirectoryItem, DirectoryList } from '../../common/DirectoryList' +import { DirectoryItem, DirectoryList } from '../../common/DirectoryList'; @Entry @Component struct ResponsiveLayoutIndex { private responsiveLayout: DirectoryItem[] = [ - { title: $r('app.string.breakpoint'), uri: 'pages/responsiveLayout/breakpoint/BreakpointSample', id:'BreakpointSample' }, - { title: $r('app.string.media_query'), uri: 'pages/responsiveLayout/mediaQuery/MediaQuerySample', id:'MediaQuerySample' }, - { title: $r('app.string.grid_layout'), uri: 'pages/gridRow/GridRowLayoutIndex', id:'GridRowLayoutIndex' } + { + title: $r('app.string.breakpoint'), + uri: 'pages/responsiveLayout/breakpoint/BreakpointSample', + id: 'BreakpointSample' + }, + { + title: $r('app.string.media_query'), + uri: 'pages/responsiveLayout/mediaQuery/MediaQuerySample', + id: 'MediaQuerySample' + }, + { title: $r('app.string.grid_layout'), uri: 'pages/gridRow/GridRowLayoutIndex', id: 'GridRowLayoutIndex' } ] build() { diff --git a/AdaptiveCapabilities/entry/src/main/ets/pages/responsiveLayout/breakpoint/Breakpoint.ets b/AdaptiveCapabilities/entry/src/main/ets/pages/responsiveLayout/breakpoint/Breakpoint.ets index 363d668bed8ebeae4ad6886491750b881bf040c5..e91a66e21d1cd3c933f685dc3e021da2a65b6e01 100644 --- a/AdaptiveCapabilities/entry/src/main/ets/pages/responsiveLayout/breakpoint/Breakpoint.ets +++ b/AdaptiveCapabilities/entry/src/main/ets/pages/responsiveLayout/breakpoint/Breakpoint.ets @@ -13,7 +13,7 @@ * limitations under the License. */ -import { mediaquery } from "@kit.ArkUI"; +import { mediaquery } from '@kit.ArkUI'; // [Start MediaQuery] export type BreakpointType = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl'; @@ -70,7 +70,7 @@ export class BreakpointSystem { if (mediaQueryResult.matches) { this.updateAllState(breakpoint.name); } - }) + }); }) } @@ -79,7 +79,7 @@ export class BreakpointSystem { } public stop() { - this.breakpoints.forEach((breakpoint: Breakpoint, index) => { + this.breakpoints.forEach((breakpoint: Breakpoint) => { if (breakpoint.mediaQueryListener) { breakpoint.mediaQueryListener.off('change'); } diff --git a/AdaptiveCapabilities/entry/src/main/ets/pages/responsiveLayout/breakpoint/BreakpointSample.ets b/AdaptiveCapabilities/entry/src/main/ets/pages/responsiveLayout/breakpoint/BreakpointSample.ets index 814c5121699c610c392fa0c0c67336fec3dd0292..40c0ea39981b115228f89cef03cfea58fe6053cb 100644 --- a/AdaptiveCapabilities/entry/src/main/ets/pages/responsiveLayout/breakpoint/BreakpointSample.ets +++ b/AdaptiveCapabilities/entry/src/main/ets/pages/responsiveLayout/breakpoint/BreakpointSample.ets @@ -19,7 +19,7 @@ import { BreakpointSystem, BreakpointState } from './Breakpoint'; @Entry @Component struct BreakpointSample { - @State compStr: BreakpointState = BreakpointState.of({ sm: "sm", md: "md", lg: "lg" }) + @State compStr: BreakpointState = BreakpointState.of({ sm: 'sm', md: 'md', lg: 'lg' }) @State compImg: BreakpointState = BreakpointState.of({ sm: $r('app.media.sm_new'), md: $r('app.media.md_new'), diff --git a/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/TypicalSceneIndex.ets b/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/TypicalSceneIndex.ets index dfd625a816df96862bb831a9d116de905b25b2d8..d27011cf6e7c69005045b75cce6e2ddb460c5be8 100644 --- a/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/TypicalSceneIndex.ets +++ b/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/TypicalSceneIndex.ets @@ -13,7 +13,7 @@ * limitations under the License. */ -import { DirectoryItem, DirectoryList } from '../../common/DirectoryList' +import { DirectoryItem, DirectoryList } from '../../common/DirectoryList'; @Entry @Component diff --git a/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/banner/BannerSample.ets b/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/banner/BannerSample.ets index e61b41763a181eb1c4d0a5aef7d3436f8dc1062e..0d20f3a829896b695ded830193862cf50bda01ec 100644 --- a/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/banner/BannerSample.ets +++ b/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/banner/BannerSample.ets @@ -17,7 +17,7 @@ import { BreakpointSystem, BreakPointType } from '../../../common/BreakpointSyst @Entry @Component -export default struct Banner { +struct Banner { private bannerArr: Array = [ $r('app.media.banner1'), $r('app.media.banner2'), diff --git a/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/diversion/DiversionSample.ets b/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/diversion/DiversionSample.ets index 8bb3746b6b685668d8e3c1afe4480e27028f5fe0..1c52407761ab4ae2a8b837e4129ca550d3a30d02 100644 --- a/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/diversion/DiversionSample.ets +++ b/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/diversion/DiversionSample.ets @@ -13,12 +13,18 @@ * limitations under the License. */ +import { hilog } from '@kit.PerformanceAnalysisKit'; + +const DOMAIN = 0x0000; +const TAG = 'DiversionSample'; +const FORMAT = '%{public}s'; + @Entry @Component struct DiversionSample { - @State currentBreakpoint: string = 'md' - @State imgHeight: number = 0 - @State textHeight: number = 0 + @State currentBreakpoint: string = 'md'; + @State imgHeight: number = 0; + @State textHeight: number = 0; build() { Row() { @@ -35,7 +41,8 @@ struct DiversionSample { .justifyContent(FlexAlign.Center) } .onAreaChange((oldArea: Area, newArea: Area) => { - this.imgHeight = newArea.height as number + hilog.info(DOMAIN, TAG, FORMAT, `oldArea: ${oldArea}, newArea: ${newArea}, newArea: ${this.imgHeight}`); + this.imgHeight = newArea.height as number; }) GridCol({ span: { sm: 12, md: 6, lg: 6 } }) { @@ -50,7 +57,8 @@ struct DiversionSample { .fontWeight(FontWeight.Medium) } .onAreaChange((oldArea: Area, newArea: Area) => { - this.textHeight = newArea.height as number + hilog.info(DOMAIN, TAG, FORMAT, `oldArea: ${oldArea}, newArea: ${newArea}, newArea: ${this.imgHeight}`); + this.textHeight = newArea.height as number; }) .padding({ left: 24, right: 24 }) .justifyContent(FlexAlign.Center) @@ -62,6 +70,6 @@ struct DiversionSample { }) } .height('100%') - .backgroundColor('#F1F3f5') + .backgroundColor($r('sys.color.background_secondary')) } } \ No newline at end of file diff --git a/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/header/HeaderSample.ets b/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/header/HeaderSample.ets index 1e5ec3af53a3da42d88643b95be71630d8f4993b..5e7d5fa6d84fca5b776bc014b0ff6d027adaee51 100644 --- a/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/header/HeaderSample.ets +++ b/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/header/HeaderSample.ets @@ -15,7 +15,7 @@ @Entry @Component -export default struct Header { +struct Header { @State needWrap: boolean = true build() { diff --git a/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/indentation/IndentationSample.ets b/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/indentation/IndentationSample.ets index ce0cfef1951593d9557fedd7fc55200d3437e181..f61222a6f910139ea29cd1c13b64b69926a3b3f8 100644 --- a/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/indentation/IndentationSample.ets +++ b/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/indentation/IndentationSample.ets @@ -19,7 +19,7 @@ struct IndentationSample { build() { Row() { GridRow() { - ForEach([0, 1, 2, 4], (item:number, index) => { + ForEach([0, 1, 2, 4], (item: number, index) => { GridCol({ span: { sm: 10, md: 8, lg: 8 }, offset: { @@ -38,7 +38,7 @@ struct IndentationSample { .height('100%') .alignItems((VerticalAlign.Center)) .justifyContent(FlexAlign.Center) - .backgroundColor('#F1F3f5') + .backgroundColor($r('sys.color.background_secondary')) } } @@ -73,8 +73,13 @@ struct ItemContent { } .height(128) .borderRadius(24) - .backgroundColor('#FFFFFF') - .padding({ top: 12, bottom: 12, left: 18, right: 18 }) + .backgroundColor($r('sys.color.comp_background_primary')) + .padding({ + top: 12, + bottom: 12, + left: 18, + right: 18 + }) .margin({ bottom: 12 }) } } \ No newline at end of file diff --git a/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/multiLaneList/MultiLaneListSample.ets b/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/multiLaneList/MultiLaneListSample.ets index 63a3dffe2130d97b4c43ada2391f5508448abdc6..e9f25265012d52d6f25f6ff3f791982ecffd1757 100644 --- a/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/multiLaneList/MultiLaneListSample.ets +++ b/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/multiLaneList/MultiLaneListSample.ets @@ -13,9 +13,9 @@ * limitations under the License. */ -import { BreakpointSystem, BreakPointType } from '../../../common/BreakpointSystem' +import { BreakpointSystem, BreakPointType } from '../../../common/BreakpointSystem'; -class ListItemInfo { +class ListItemInfo { name: Resource = $r('app.string.playlist_collection'); image: Resource = $r('app.media.1'); } diff --git a/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/multiScene/data/applications/Applications.ets b/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/multiScene/data/applications/Applications.ets index e2426f354d5e9e348fac8a99f58221915c2df3d0..ed9553d923024dd2b71a2d60ce060ae463cc3eda 100644 --- a/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/multiScene/data/applications/Applications.ets +++ b/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/multiScene/data/applications/Applications.ets @@ -48,4 +48,4 @@ export const ApplicationsData: Resource [] = [ $r('app.string.multiScene_application'), $r('app.string.multiScene_application'), $r('app.string.multiScene_application') -] \ No newline at end of file +]; \ No newline at end of file diff --git a/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/multiScene/data/home/Home.ets b/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/multiScene/data/home/Home.ets index 384ea15f603e6a81c49044ac7e744585c0911a25..9e593a5d7b04f1e2219d415a65f1d3b556225f4f 100644 --- a/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/multiScene/data/home/Home.ets +++ b/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/multiScene/data/home/Home.ets @@ -21,31 +21,31 @@ export interface Articles { export const ArticlesData: Articles[] = [ { - icon: $r("app.media.icon"), + icon: $r('app.media.icon'), title: $r('app.string.multiScene_title1'), disc: $r('app.string.multiScene_title1_disc') }, { - icon: $r("app.media.icon"), + icon: $r('app.media.icon'), title: $r('app.string.multiScene_title2'), disc: $r('app.string.multiScene_title2_disc') }, { - icon: $r("app.media.icon"), + icon: $r('app.media.icon'), title: $r('app.string.multiScene_title3'), disc: $r('app.string.multiScene_title3_disc') }, { - icon: $r("app.media.icon"), + icon: $r('app.media.icon'), title: $r('app.string.multiScene_title4'), disc: $r('app.string.multiScene_title4_disc') }, { - icon: $r("app.media.icon"), + icon: $r('app.media.icon'), title: $r('app.string.multiScene_title5'), disc: $r('app.string.multiScene_title5_disc') },{ - icon: $r("app.media.icon"), + icon: $r('app.media.icon'), title: $r('app.string.multiScene_title5'), disc: $r('app.string.multiScene_title5_disc') },{ @@ -54,7 +54,7 @@ export const ArticlesData: Articles[] = [ disc: $r('app.string.multiScene_title6_disc') }, { - icon: $r("app.media.icon"), + icon: $r('app.media.icon'), title: $r('app.string.multiScene_title7'), disc: $r('app.string.multiScene_title7_disc') }, @@ -73,7 +73,7 @@ export const ArticlesData: Articles[] = [ title: $r('app.string.multiScene_title10'), disc: $r('app.string.multiScene_title10_disc') } -] +]; diff --git a/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/multiScene/pages/MultiScene.ets b/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/multiScene/pages/MultiScene.ets index b48607d53018936b3cc615054db475512a1b8ebb..7c39391695ad5ac06140565fb24bdba9e9f24acc 100644 --- a/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/multiScene/pages/MultiScene.ets +++ b/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/multiScene/pages/MultiScene.ets @@ -13,7 +13,7 @@ * limitations under the License. */ -import mediaquery from '@ohos.mediaquery'; +import { mediaquery } from '@kit.ArkUI'; import { HomePage } from './home/Home'; import { Applications } from './applications/Applications'; import { Play } from './player/Player'; @@ -50,12 +50,12 @@ struct DiversionSample { NavigationTitle() { Column() { Text($r('app.string.multiScene_header_title')) - .fontColor('#182431') + .fontColor($r('sys.color.font_primary')) .fontSize(30) .lineHeight(41) .fontWeight(700) Text($r('app.string.multiScene_header_subtitle')) - .fontColor('#182431') + .fontColor($r('sys.color.font_primary')) .fontSize(14) .lineHeight(19) .opacity(0.4) @@ -126,7 +126,7 @@ struct DiversionSample { .titleMode(NavigationTitleMode.Full) } .height('100%') - .backgroundColor('#F1F3f5') + .backgroundColor($r('sys.color.background_secondary')) } } } \ No newline at end of file diff --git a/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/multiScene/pages/applications/Applications.ets b/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/multiScene/pages/applications/Applications.ets index 00dc45b2be56044a93aa312ccfa442f03b128905..60a7e1f1c4a36414d41704d4601ea48bfd6aca66 100644 --- a/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/multiScene/pages/applications/Applications.ets +++ b/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/multiScene/pages/applications/Applications.ets @@ -46,7 +46,7 @@ export struct Applications { }.width('80%') } .width('90%') - .backgroundColor('#FFFFFF') + .backgroundColor($r('sys.color.comp_background_primary')) .borderRadius(16) .padding({ top: 12 }) } diff --git a/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/multiScene/pages/home/Home.ets b/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/multiScene/pages/home/Home.ets index ca041d9163384e4fde88287788e1a1dee33fb89f..a15b626c7256dc0a6c976262ee17c3c74b11a94a 100644 --- a/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/multiScene/pages/home/Home.ets +++ b/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/multiScene/pages/home/Home.ets @@ -13,40 +13,47 @@ * limitations under the License. */ +import { hilog } from '@kit.PerformanceAnalysisKit'; import { ArticlesData, Articles } from '../../data/home/Home'; +const DOMAIN = 0x0000; +const TAG = 'DirectoryList'; +const FORMAT = '%{public}s'; + @Component export struct HomePage { private swiperController: SwiperController = new SwiperController() private bannerArr: Array = [ - $r('app.media.banner1'), - $r('app.media.banner2'), - $r('app.media.banner3'), - $r('app.media.banner4'), - $r('app.media.banner5'), - $r('app.media.banner6') - ] - @State imgHeight: number = 0 - @State textHeight: number = 0 - @State spaceBottom: number = 0 - @State currentBreakpoint: string = 'md' + $r('app.media.banner1'), + $r('app.media.banner2'), + $r('app.media.banner3'), + $r('app.media.banner4'), + $r('app.media.banner5'), + $r('app.media.banner6') + ]; + @State imgHeight: number = 0; + @State textHeight: number = 0; + @State spaceBottom: number = 0; + @State currentBreakpoint: string = 'md'; constructor() { super() } - @Builder Item(article: Articles) { + @Builder + Item(article: Articles) { Flex() { Row() { Image(article.icon) - }.width(43) + } + .width(43) .height(43) .borderRadius(12) Column() { Row() { Text(article.title) - .fontColor('#182431') + .fontColor($r('sys.color.font_primary')) .fontSize(20) } .width('100%') @@ -54,7 +61,7 @@ export struct HomePage { Row() { Text(article.disc) .fontSize(15) - .fontColor('#182431') + .fontColor($r('sys.color.font_primary')) .opacity(0.4) } .width('100%') @@ -63,8 +70,13 @@ export struct HomePage { .alignItems(HorizontalAlign.Start) .justifyContent(FlexAlign.SpaceAround) } - .padding({ top: 13, bottom: 13, left: 13, right: 13 }) - .backgroundColor('#FFFFFF') + .padding({ + top: 13, + bottom: 13, + left: 13, + right: 13 + }) + .backgroundColor($r('sys.color.comp_background_primary')) .borderRadius(25) } @@ -79,7 +91,8 @@ export struct HomePage { ForEach(this.bannerArr, (item: Resource) => { Image(item) }) - }.width('100%') + } + .width('100%') } .width('100%') .aspectRatio(1.5) @@ -89,29 +102,30 @@ export struct HomePage { .justifyContent(FlexAlign.Center) } .onAreaChange((oldArea: Area, newArea: Area) => { - this.imgHeight = newArea.height as number - console.log(String(this.imgHeight)) + this.imgHeight = newArea.height as number; + hilog.info(DOMAIN, TAG, FORMAT, `oldArea: ${oldArea}, newArea: ${newArea}, newArea: ${this.imgHeight}`); }) GridCol({ span: { sm: 12, md: 6, lg: 6 } }) { Column() { List({ space: 10, initialIndex: 0 }) { - ForEach(ArticlesData, (item : Articles) => { + ForEach(ArticlesData, (item: Articles) => { ListItem() { this.Item(item) } }) } - .listDirection(Axis.Vertical) // 排列方向 - .edgeEffect(EdgeEffect.Spring) // 滑动到边缘无效果 + .listDirection(Axis.Vertical) // orientation + .edgeEffect(EdgeEffect.Spring) // There is no effect when sliding to the edge. .onScrollIndex((firstIndex: number, lastIndex: number) => { - console.info('first' + firstIndex) - console.info('last' + lastIndex) + hilog.info(DOMAIN, TAG, FORMAT, `first: ${firstIndex}`); + hilog.info(DOMAIN, TAG, FORMAT, `last: ${lastIndex}`); }) .width('100%') } .onAreaChange((oldArea: Area, newArea: Area) => { - this.textHeight = newArea.height as number + hilog.info(DOMAIN, TAG, FORMAT, `oldArea: ${oldArea}, newArea: ${newArea}`); + this.textHeight = newArea.height as number; }) .padding({ left: 15, right: 15 }) .justifyContent(FlexAlign.Center) @@ -120,14 +134,14 @@ export struct HomePage { } .onBreakpointChange((breakPoint: string) => { - this.currentBreakpoint = breakPoint + this.currentBreakpoint = breakPoint; if (breakPoint === 'sm') { - this.spaceBottom = 20 + this.spaceBottom = 20; } else { - this.spaceBottom = 0 + this.spaceBottom = 0; } }) - - }.width('100%') + } + .width('100%') } } \ No newline at end of file diff --git a/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/multiScene/pages/player/Player.ets b/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/multiScene/pages/player/Player.ets index f2a64bb302e2008e856ab948191f56f5110e07b2..5c6f1d05e15dccfe56e28c501031dc94dea5134d 100644 --- a/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/multiScene/pages/player/Player.ets +++ b/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/multiScene/pages/player/Player.ets @@ -24,41 +24,57 @@ export struct Play { .width(200) .height(200) .objectFit(ImageFit.Contain) - }.margin({ bottom: 10 }) + } + .margin({ bottom: 10 }) } GridCol({ span: { sm: 12, md: 6, lg: 6 } }) { Row() { Button({ type: ButtonType.Circle, stateEffect: true }) { - Image($r('app.media.favorite')).width(48).height(48)} + Image($r('app.media.favorite')) + .width(48) + .height(48) + } .width(48) .height(48) .displayPriority(1) .backgroundColor('white') Button({ type: ButtonType.Circle, stateEffect: true }) { - Image($r('app.media.down')).width(48).height(48)} - .width(48) - .height(48) - .displayPriority(2) - .backgroundColor('white') + Image($r('app.media.down')) + .width(48) + .height(48) + } + .width(48) + .height(48) + .displayPriority(2) + .backgroundColor('white') Button({ type: ButtonType.Circle, stateEffect: true }) { - Image($r('app.media.pause')).width(48).height(48)} + Image($r('app.media.pause')) + .width(48) + .height(48) + } .width(48) .height(48) .displayPriority(3) .backgroundColor('white') Button({ type: ButtonType.Circle, stateEffect: true }) { - Image($r('app.media.next')).width(48).height(48)} + Image($r('app.media.next')) + .width(48) + .height(48) + } .width(48) .height(48) .displayPriority(2) .backgroundColor('white') Button({ type: ButtonType.Circle, stateEffect: true }) { - Image($r('app.media.list')).width(48).height(48)} + Image($r('app.media.list')) + .width(48) + .height(48) + } .width(48) .height(48) .displayPriority(1) @@ -68,10 +84,11 @@ export struct Play { .height('100%') .height(90) .borderRadius(16) - .backgroundColor('#FFFFFF') + .backgroundColor($r('sys.color.comp_background_primary')) .justifyContent(FlexAlign.Center) } } - }.width('80%') + } + .width('80%') } } \ No newline at end of file diff --git a/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/operationEntries/OperationEntriesSample.ets b/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/operationEntries/OperationEntriesSample.ets index 8116bbb4d01bd38efb762b8744eb83c10f5758e8..a9e814f4ca14f4836e856db41adeebb977ba187e 100644 --- a/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/operationEntries/OperationEntriesSample.ets +++ b/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/operationEntries/OperationEntriesSample.ets @@ -20,7 +20,7 @@ class OperationItem { @Entry @Component -export default struct OperationEntries { +struct OperationEntries { private listData: Array = [ { name: $r('app.string.operation1'), icon: $r('app.media.self_fm') }, { name: $r('app.string.operation2'), icon: $r('app.media.singer') }, diff --git a/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/repeat/RepeatSample.ets b/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/repeat/RepeatSample.ets index 5814dc6a58c92bcaa34d923910610db8045cc67f..1f21b9378af96b3637935cb9c07fcad0058743d0 100644 --- a/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/repeat/RepeatSample.ets +++ b/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/repeat/RepeatSample.ets @@ -58,7 +58,7 @@ struct RepeatSample { .scrollBar(BarState.Off) } .height('100%') - .backgroundColor('#F1F3F5') + .backgroundColor($r('sys.color.background_secondary')) .padding({ left: 30, right: 30 }) } } @@ -99,7 +99,7 @@ struct RepeatItemContent { right: 37 }) .height(70) - .backgroundColor('#FFFFFF') + .backgroundColor($r('sys.color.background_secondary')) .margin({ bottom: 12 }) .borderRadius(24) } diff --git a/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/responsiveGrid/ResponsiveGridSample.ets b/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/responsiveGrid/ResponsiveGridSample.ets index 24cad3738f359413f1f4ae3e000646c2d605a0b4..f573f49bc79df1dc09df3545e6bb895cc3e02325 100644 --- a/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/responsiveGrid/ResponsiveGridSample.ets +++ b/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/responsiveGrid/ResponsiveGridSample.ets @@ -22,7 +22,7 @@ class GridItemInfo { @Entry @Component -export default struct ResponsiveGrid { +struct ResponsiveGrid { private data: Array = [ { name: $r('app.string.playlist_collection'), image: $r('app.media.1') }, { name: $r('app.string.playlist_collection'), image: $r('app.media.2') }, diff --git a/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/sidebar/SidebarSample.ets b/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/sidebar/SidebarSample.ets index 450d07df7b96e5a7c6a5fbc95dc17759974bbb3a..cc694571e4c5e067a1913e4112476755c50f6b05 100644 --- a/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/sidebar/SidebarSample.ets +++ b/AdaptiveCapabilities/entry/src/main/ets/pages/typicalScene/sidebar/SidebarSample.ets @@ -17,19 +17,19 @@ import { BreakpointSystem } from '../../../common/BreakpointSystem' class ImageData { label: string = ''; - imageSrc: Resource = $r("app.media.my_image_moon"); + imageSrc: Resource = $r('app.media.my_image_moon'); } const images: ImageData[] = [ - { label: 'moon', imageSrc: $r("app.media.my_image_moon") }, - { label: 'sun', imageSrc: $r("app.media.my_image") } + { label: 'moon', imageSrc: $r('app.media.my_image_moon') }, + { label: 'sun', imageSrc: $r('app.media.my_image') } ] @Entry @Component struct SideBarSample { @StorageLink('currentBreakpoint') - private currentBreakpoint: string = "md" + private currentBreakpoint: string = 'md' private breakpointSystem: BreakpointSystem = new BreakpointSystem() @State showSideBar: boolean = false @State selectIndex: number = 0 @@ -54,7 +54,7 @@ struct SideBarSample { .fontWeight(FontWeight.Bold) .borderRadius(5) .margin(20) - .backgroundColor('#ffffff') + .backgroundColor($r('sys.color.background_secondary')) .textAlign(TextAlign.Center) .width(180) .height(36) @@ -71,7 +71,8 @@ struct SideBarSample { Column() { this.itemBuilder(0) this.itemBuilder(1) - }.backgroundColor('#F1F3F5') + } + .backgroundColor($r('sys.color.background_secondary')) .justifyContent(FlexAlign.Center) Column() { diff --git a/AdaptiveCapabilities/entry/src/main/module.json5 b/AdaptiveCapabilities/entry/src/main/module.json5 index bc90a1ccfd576e02355978e0aea277a11a316a2f..10ac59cce18741c6d637accae7fbaa0c4c210a1d 100644 --- a/AdaptiveCapabilities/entry/src/main/module.json5 +++ b/AdaptiveCapabilities/entry/src/main/module.json5 @@ -20,7 +20,7 @@ "description": "$string:entry_desc", "mainElement": "MainAbility", "deviceTypes": [ - "default", + "phone", "tablet" ], "deliveryWithInstall": true, diff --git a/AdaptiveCapabilities/entry/src/main/resources/en-tablet/element/string.json b/AdaptiveCapabilities/entry/src/main/resources/en-tablet/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..4d6296d1f109607f2c9c41eef623097183dbac51 --- /dev/null +++ b/AdaptiveCapabilities/entry/src/main/resources/en-tablet/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "my_string", + "value": "tablet" + } + ] +} \ No newline at end of file diff --git a/AdaptiveCapabilities/entry/src/main/resources/zh-tablet/element/string.json b/AdaptiveCapabilities/entry/src/main/resources/zh-tablet/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..c64ff816b94ae3ea64a55b975a1d6278d2393560 --- /dev/null +++ b/AdaptiveCapabilities/entry/src/main/resources/zh-tablet/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "my_string", + "value": "平板" + } + ] +} \ No newline at end of file diff --git a/AdaptiveCapabilities/hvigorfile.js b/AdaptiveCapabilities/hvigorfile.js deleted file mode 100644 index 5f2735e3deeaf655828407544bbed9365c258278..0000000000000000000000000000000000000000 --- a/AdaptiveCapabilities/hvigorfile.js +++ /dev/null @@ -1,2 +0,0 @@ -// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. -module.exports = require('@ohos/hvigor-ohos-plugin').appTasks \ No newline at end of file diff --git a/AdaptiveCapabilities/hvigorfile.ts b/AdaptiveCapabilities/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..20a8c119149bca149dc03919c5c1c022cd4ff077 --- /dev/null +++ b/AdaptiveCapabilities/hvigorfile.ts @@ -0,0 +1,6 @@ +import { appTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins: [] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/AdaptiveCapabilities/screenshots/devices/img1.jpeg b/AdaptiveCapabilities/screenshots/devices/img1.jpeg deleted file mode 100644 index e6d546db94e47d373678db4770ab1a50c916ce80..0000000000000000000000000000000000000000 Binary files a/AdaptiveCapabilities/screenshots/devices/img1.jpeg and /dev/null differ diff --git a/AdaptiveCapabilities/screenshots/devices/img1.png b/AdaptiveCapabilities/screenshots/devices/img1.png new file mode 100644 index 0000000000000000000000000000000000000000..1a42afd8ff6f474e08f45723666c59e783b31315 Binary files /dev/null and b/AdaptiveCapabilities/screenshots/devices/img1.png differ diff --git a/AdaptiveCapabilities/screenshots/devices/img2.jpeg b/AdaptiveCapabilities/screenshots/devices/img2.jpeg deleted file mode 100644 index 4f223e22a334e7bc0c82097b1c3848c15fe788e9..0000000000000000000000000000000000000000 Binary files a/AdaptiveCapabilities/screenshots/devices/img2.jpeg and /dev/null differ diff --git a/AdaptiveCapabilities/screenshots/devices/img2.png b/AdaptiveCapabilities/screenshots/devices/img2.png new file mode 100644 index 0000000000000000000000000000000000000000..a9fe4929aad4a50542ea97b095c55d6b6290b4cb Binary files /dev/null and b/AdaptiveCapabilities/screenshots/devices/img2.png differ diff --git a/AdaptiveCapabilities/screenshots/devices/img3.jpeg b/AdaptiveCapabilities/screenshots/devices/img3.jpeg deleted file mode 100644 index 3f3e50c290b9dea54adbb8c6e63c7666502800f0..0000000000000000000000000000000000000000 Binary files a/AdaptiveCapabilities/screenshots/devices/img3.jpeg and /dev/null differ diff --git a/AdaptiveCapabilities/screenshots/devices/img3.png b/AdaptiveCapabilities/screenshots/devices/img3.png new file mode 100644 index 0000000000000000000000000000000000000000..55e17cea6ed5e6f9008cdfd82d106e3e39adbd44 Binary files /dev/null and b/AdaptiveCapabilities/screenshots/devices/img3.png differ diff --git a/AdaptiveCapabilities/screenshots/devices/img4.jpeg b/AdaptiveCapabilities/screenshots/devices/img4.jpeg deleted file mode 100644 index d44d75046d0c5f9fcf196ecdffd731e857b55e25..0000000000000000000000000000000000000000 Binary files a/AdaptiveCapabilities/screenshots/devices/img4.jpeg and /dev/null differ diff --git a/AdaptiveCapabilities/screenshots/devices/img4.png b/AdaptiveCapabilities/screenshots/devices/img4.png new file mode 100644 index 0000000000000000000000000000000000000000..03ca6a54e5a267d907f1171efecac95bd521130d Binary files /dev/null and b/AdaptiveCapabilities/screenshots/devices/img4.png differ diff --git a/ApiUsingStandards/README.md b/ApiUsingStandards/README.md new file mode 100644 index 0000000000000000000000000000000000000000..b50c899981d12d082da345b18238bd10f949df45 --- /dev/null +++ b/ApiUsingStandards/README.md @@ -0,0 +1,66 @@ +# 易错API的使用规范 + +### 介绍 + +本示例是《易错API的使用规范》最佳实践中的代码示例片段。 + +### 使用说明 + +不涉及。 + + +### 工程目录 + +``` +├──entry/src/main/ets +│ ├──cpp +│ │ ├──CMakeList.txt // CMake文件 +│ │ ├──napi_init.cpp // napi初始化 +│ │ └──callbackTest.cpp // callback测试类 +│ ├──cpp/types/libentry +│ │ ├──oh-package.json5 // lib打包信息 +│ │ └──Index.d.ts // lib接口索引 +│ ├──entryability +│ │ └──EntryAbility.ets // 入口类 +│ ├──entrybackupability +│ │ └──EntryBackupAbility.ets // 数据备份类 +│ └──pages +│ ├──animate1.ets // 示例页面 +│ ├──animate2.ets // 示例页面 +│ ├──AVImageGenerator.ets // 示例页面 +│ ├──camera.ets // 示例页面 +│ ├──Index.ets // 示例页面 +│ ├──playStateCallback.ets // 示例页面 +│ └──StyleExample.ets // 示例页面 +└──entry/src/main/resources // 应用资源目录 +``` + + +### 具体实现 + +1. 主要配套文档介绍易错API的使用规范。 + +### 相关权限 + +不涉及。 + +### 约束与限制 + +1. 本示例仅支持标准系统上运行,支持设备:华为手机。 + +2. HarmonyOS系统:HarmonyOS 5.0.5 Release及以上。 + +3. DevEco Studio版本:DevEco Studio 5.0.5 Release及以上。 + +4. HarmonyOS SDK版本:HarmonyOS 5.0.5 Release SDK及以上。 + +### 下载 + +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set ApiUsingStandards +git checkout +``` \ No newline at end of file diff --git a/ApiUsingStandards/build-profile.json5 b/ApiUsingStandards/build-profile.json5 index 03ac3a3ae9dd397844173066e5d5ee21b49455a1..492123c253881f5bbd9bc76553bfb74e842dfb40 100644 --- a/ApiUsingStandards/build-profile.json5 +++ b/ApiUsingStandards/build-profile.json5 @@ -5,7 +5,8 @@ { "name": "default", "signingConfig": "default", - "compatibleSdkVersion": "5.0.4(16)", + "compatibleSdkVersion": "5.0.5(17)", + "targetSdkVersion": "5.0.5(17)", "runtimeOS": "HarmonyOS", "buildOption": { "strictMode": { diff --git a/ApiUsingStandards/entry/src/main/cpp/callbackTest.cpp b/ApiUsingStandards/entry/src/main/cpp/callbackTest.cpp index b032fcf4a3c369ce62a86fd54915c1a84b66d2cd..23bcd8ccd3b15052ea968f96978ad5505da0f033 100644 --- a/ApiUsingStandards/entry/src/main/cpp/callbackTest.cpp +++ b/ApiUsingStandards/entry/src/main/cpp/callbackTest.cpp @@ -1,8 +1,18 @@ -// -// Created on 2025/5/30. -// -// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found, -// please include "napi/native_api.h". +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + #include "napi/native_api.h" #include "uv.h" #define LOG_DOMAIN 0X0202 diff --git a/ApiUsingStandards/entry/src/main/cpp/napi_init.cpp b/ApiUsingStandards/entry/src/main/cpp/napi_init.cpp index 85330e3e84d1f6c8a82e544fb315483ca597d23d..d0e1aafcb6b5c3252ef439d9d9d54e8c082fda1d 100644 --- a/ApiUsingStandards/entry/src/main/cpp/napi_init.cpp +++ b/ApiUsingStandards/entry/src/main/cpp/napi_init.cpp @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + #include "napi/native_api.h" static napi_value Add(napi_env env, napi_callback_info info) diff --git a/ApiUsingStandards/entry/src/main/ets/entryability/EntryAbility.ets b/ApiUsingStandards/entry/src/main/ets/entryability/EntryAbility.ets index 508880af8c33aa838016d1cd4b2c68be2f447540..d6c8a8e454f830409bd59e18826cd56e0412125c 100644 --- a/ApiUsingStandards/entry/src/main/ets/entryability/EntryAbility.ets +++ b/ApiUsingStandards/entry/src/main/ets/entryability/EntryAbility.ets @@ -1,12 +1,33 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; import { hilog } from '@kit.PerformanceAnalysisKit'; import { window } from '@kit.ArkUI'; +import { BusinessError } from '@kit.BasicServicesKit'; const DOMAIN = 0x0000; export default class EntryAbility extends UIAbility { onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { - this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + try { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + } catch (e) { + let err = e as BusinessError; + hilog.error(DOMAIN, 'testTag', `failed code=${err.code}, message=${err.message}`); + } hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); } diff --git a/ApiUsingStandards/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets b/ApiUsingStandards/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets index 8e4de99282050bad799ac892eb85ac5449364a51..0a97e21bd7a15599af76a806695860ff1eb0ebfe 100644 --- a/ApiUsingStandards/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets +++ b/ApiUsingStandards/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + import { hilog } from '@kit.PerformanceAnalysisKit'; import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit'; diff --git a/ApiUsingStandards/entry/src/main/ets/pages/AVImageGenerator.ets b/ApiUsingStandards/entry/src/main/ets/pages/AVImageGenerator.ets index 8387d06974d2362bfba54a0d3d13ac30c88ac4c5..ce2700bea80461f986af0948f73d1a949b81e4db 100644 --- a/ApiUsingStandards/entry/src/main/ets/pages/AVImageGenerator.ets +++ b/ApiUsingStandards/entry/src/main/ets/pages/AVImageGenerator.ets @@ -1,8 +1,23 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + import { media } from '@kit.MediaKit' import { image } from '@kit.ImageKit' import { fileIo as fs, ReadOptions } from '@kit.CoreFileKit'; import { display } from '@kit.ArkUI'; -import { common } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; class AVImageGeneratorClass { pixelMap: image.PixelMap[] = []; @@ -17,53 +32,46 @@ class AVImageGeneratorClass { videoHeight: number = 0; // [Start av_image_generator_class] - async fetchFrame() { - await this.fetchMeta() + async fetchFrame(): Promise { + await this.fetchMeta(); if (canIUse("SystemCapability.Multimedia.Media.AVImageGenerator")) { - this.pixelMap = new Array - let avImageGenerator: media.AVImageGenerator = await media.createAVImageGenerator() + this.pixelMap = new Array; + let avImageGenerator: media.AVImageGenerator = await media.createAVImageGenerator(); // raw fd - avImageGenerator.fdSrc = fs.openSync(this.rootPath + this.testFilename) + avImageGenerator.fdSrc = fs.openSync(this.rootPath + this.testFilename); for (let i = 0; i < 6; i++) { - console.info(`time real ${this.diffTime[i]}`) - let pixelMap = await avImageGenerator.fetchFrameByTime(this.diffTime[i], this.seekOption, - { width: this.pixelMapWidth, height: this.pixelMapHeight }) - this.pixelMap.push(pixelMap) + let pixelMap: image.PixelMap = await avImageGenerator.fetchFrameByTime(this.diffTime[i], this.seekOption, + { width: this.pixelMapWidth, height: this.pixelMapHeight }); + this.pixelMap.push(pixelMap); if (i == 0) { - this.pixelLcd = pixelMap - let rate = pixelMap.getImageInfoSync().size.height / pixelMap.getImageInfoSync().size.width + this.pixelLcd = pixelMap; + let rate: number = pixelMap.getImageInfoSync().size.height / pixelMap.getImageInfoSync().size.width; this.lcdHeight = - display.getDefaultDisplaySync().width / 2 / display.getDefaultDisplaySync().densityPixels * rate + display.getDefaultDisplaySync().width / 2 / display.getDefaultDisplaySync().densityPixels * rate; } - let imageInfo: image.ImageInfo = pixelMap.getImageInfoSync() - console.info(`colorFormat ${imageInfo.pixelFormat} width ${imageInfo.size.width} height ${imageInfo.size.height} isHdr ${imageInfo.isHdr}`) + let imageInfo: image.ImageInfo = pixelMap.getImageInfoSync(); + hilog.info(0x0000, 'testTag', + `colorFormat ${imageInfo.pixelFormat} width ${imageInfo.size.width} height ${imageInfo.size.height} isHdr ${imageInfo.isHdr}`); } } } - async fetchMeta() { + async fetchMeta(): Promise { if (canIUse("SystemCapability.Multimedia.Media.AVMetadataExtractor")) { - console.info(`typeof ${typeof media.createAVMetadataExtractor()}`) - let avMetadataExtractor: media.AVMetadataExtractor = await media.createAVMetadataExtractor() - - + let avMetadataExtractor: media.AVMetadataExtractor = await media.createAVMetadataExtractor(); let fd: number = fs.openSync(this.rootPath + this.testFilename).fd; let fileSize: number = fs.statSync(this.rootPath + this.testFilename).size; - - let dataSrc: media.AVDataSrcDescriptor = { fileSize: fileSize, callback: (buffer, len, pos) => { if (buffer == undefined || len == undefined || pos == undefined) { - console.error(`dataSrc callback param invalid`) - return -1 + return -1; } let options: ReadOptions = { offset: pos, length: len } - let num = fs.readSync(fd, buffer, options) - console.info('readAt end, num: ' + num) + let num: number = fs.readSync(fd, buffer, options); if (num > 0 && fileSize >= pos) { return num; } @@ -71,44 +79,36 @@ class AVImageGeneratorClass { } } - - avMetadataExtractor.dataSrc = dataSrc - - - let metadata: media.AVMetadata - - + avMetadataExtractor.dataSrc = dataSrc; + let metadata: media.AVMetadata; try { - metadata = await avMetadataExtractor.fetchMetadata() + metadata = await avMetadataExtractor.fetchMetadata(); } catch (error) { - console.info('error code ' + error.code) - return + hilog.error(0x0000, 'testTag', 'error code ' + error.code); + return; } - - - console.info(`metadata ${JSON.stringify(metadata)}`) if (metadata.duration) { - console.info(`fetchMetadata success duration ${metadata.duration}`) - let duration = parseInt(metadata.duration) * 1000 - let pick = duration / 5 - this.diffTime[0] = 0 - this.diffTime[5] = duration - let time = pick + let duration: number = parseInt(metadata.duration) * 1000; + let pick: number = duration / 5; + this.diffTime[0] = 0; + this.diffTime[5] = duration; + let time: number = pick; for (let i = 1; i < 5; i++) { - this.diffTime[i] = time - time += pick + this.diffTime[i] = time; + time += pick; } } if (metadata.videoHeight && metadata.videoWidth) { - let rate = Number(metadata.videoHeight) / Number(metadata.videoWidth) + let rate: number = Number(metadata.videoHeight) / Number(metadata.videoWidth); if (metadata.videoOrientation && Number(metadata.videoOrientation) % 180) { rate = 1 / rate; } this.videoHeight = - display.getDefaultDisplaySync().width / 6 / display.getDefaultDisplaySync().densityPixels * rate + display.getDefaultDisplaySync().width / 6 / display.getDefaultDisplaySync().densityPixels * rate; } - await avMetadataExtractor.release() + await avMetadataExtractor.release(); } } + // [End av_image_generator_class] } \ No newline at end of file diff --git a/ApiUsingStandards/entry/src/main/ets/pages/Index.ets b/ApiUsingStandards/entry/src/main/ets/pages/Index.ets index 0738f87946f68a3e67f70b0397ea1c8a4ab75500..71b23174229cd3cf4b127d77e25069eb7a1f3c4a 100644 --- a/ApiUsingStandards/entry/src/main/ets/pages/Index.ets +++ b/ApiUsingStandards/entry/src/main/ets/pages/Index.ets @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + import { hilog } from '@kit.PerformanceAnalysisKit'; import testNapi from 'libentry.so'; diff --git a/ApiUsingStandards/entry/src/main/ets/pages/StyleExample.ets b/ApiUsingStandards/entry/src/main/ets/pages/StyleExample.ets index e5f00680b35ed2e1176294eb7b1fe59acc4756a4..9082508ea1fa4ef3e3ca26458ddc90aaf9be0816 100644 --- a/ApiUsingStandards/entry/src/main/ets/pages/StyleExample.ets +++ b/ApiUsingStandards/entry/src/main/ets/pages/StyleExample.ets @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + // [Start style_example] // xxx.ets @Entry diff --git a/ApiUsingStandards/entry/src/main/ets/pages/animate1.ets b/ApiUsingStandards/entry/src/main/ets/pages/animate1.ets index 7c11c06a61ce5bc9db0d707e0fb4824d073f34f6..9054e23ed408b46a94c47fe31c0227e02b1b2588 100644 --- a/ApiUsingStandards/entry/src/main/ets/pages/animate1.ets +++ b/ApiUsingStandards/entry/src/main/ets/pages/animate1.ets @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + // [Start animate_to1] class MyData { str: string; diff --git a/ApiUsingStandards/entry/src/main/ets/pages/animate2.ets b/ApiUsingStandards/entry/src/main/ets/pages/animate2.ets index 3bc6493f1b8d0d1a915492476089d79c5c431210..663bcbbd95200b1055f9dd754a48bbdbbbe306f1 100644 --- a/ApiUsingStandards/entry/src/main/ets/pages/animate2.ets +++ b/ApiUsingStandards/entry/src/main/ets/pages/animate2.ets @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + // [Start animate_to2] class MyData { diff --git a/ApiUsingStandards/entry/src/main/ets/pages/camera.ets b/ApiUsingStandards/entry/src/main/ets/pages/camera.ets index 5006ccb5997d640aa4bde9607e8f95a7ad660963..0e31101aef0778563fc1916350e2df96b7d7e3e5 100644 --- a/ApiUsingStandards/entry/src/main/ets/pages/camera.ets +++ b/ApiUsingStandards/entry/src/main/ets/pages/camera.ets @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + /** * 易错API的使用规范 */ @@ -7,11 +22,12 @@ import { camera } from '@kit.CameraKit'; class cameraClass { cameraManager: camera.CameraManager | undefined = undefined; - getCameraManager(context: Context) { + getCameraManager(context: Context): void { this.cameraManager = camera.getCameraManager(context); } - async addInput(cameraManager: camera.CameraManager, camera: camera.CameraDevice, session: camera.Session) { + async addInput(cameraManager: camera.CameraManager, camera: camera.CameraDevice, + session: camera.Session): Promise { let cameraInput: camera.CameraInput | undefined = undefined; // [Start add_input] cameraInput = cameraManager.createCameraInput(camera); @@ -22,11 +38,11 @@ class cameraClass { } async addOutput(cameraManager: camera.CameraManager, camera: camera.CameraDevice, session: camera.Session, - cameraOutputCapability: camera.CameraOutputCapability) { + cameraOutputCapability: camera.CameraOutputCapability): Promise { let previewOutput: camera.CameraOutput | undefined = undefined; let cameraInput: camera.CameraInput | undefined = undefined; let profile: camera.Profile = cameraOutputCapability.previewProfiles[0]; - let surfaceId = 'xxx'; + let surfaceId: string = 'xxx'; // [Start add_output] previewOutput = cameraManager.createPreviewOutput(profile, surfaceId); cameraInput = cameraManager.createCameraInput(camera); @@ -38,11 +54,11 @@ class cameraClass { } async addOutput1(cameraManager: camera.CameraManager, camera: camera.CameraDevice, session: camera.Session, - cameraOutputCapability: camera.CameraOutputCapability) { + cameraOutputCapability: camera.CameraOutputCapability): Promise { let previewOutput: camera.CameraOutput | undefined = undefined; let cameraInput: camera.CameraInput | undefined = undefined; let profile: camera.Profile = cameraOutputCapability.previewProfiles[0]; - let surfaceId = 'xxx'; + let surfaceId: string = 'xxx'; // [Start add_output1] previewOutput = cameraManager.createPreviewOutput(profile, surfaceId); cameraInput = cameraManager.createCameraInput(camera); @@ -53,14 +69,15 @@ class cameraClass { session.commitConfig(); // [End add_output1] } - } -let cameraInput:camera.CameraInput; -let cameraSession:camera.Session; +let cameraInput: camera.CameraInput; +let cameraSession: camera.Session; + // [Start close_release] -async function onBackground() { +async function onBackground(): Promise { await cameraInput.close(); await cameraSession.release(); } + // [End close_release] \ No newline at end of file diff --git a/ApiUsingStandards/entry/src/main/ets/pages/playStateCallback.ets b/ApiUsingStandards/entry/src/main/ets/pages/playStateCallback.ets index 7876e2a1ee16e2516f9019f465fa4964aae6510c..d9621a1659c6227cb8621016b74da65ca02fd1a3 100644 --- a/ApiUsingStandards/entry/src/main/ets/pages/playStateCallback.ets +++ b/ApiUsingStandards/entry/src/main/ets/pages/playStateCallback.ets @@ -1,10 +1,24 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + /** * 易错API的使用规范 */ import { BusinessError } from '@kit.BasicServicesKit'; import { avSession } from '@kit.AVSessionKit'; - -const TAG = 'TEST'; +import { hilog } from '@kit.PerformanceAnalysisKit'; class avSessionClass { castController!: avSession.AVCastController; @@ -14,24 +28,23 @@ class avSessionClass { playStateCallback: (state: avSession.AVPlaybackState) => void = () => { } - create(context: Context, tag: string) { + create(context: Context, tag: string): void { avSession.createAVSession(context, tag, "audio").then(async (currentAVSession: avSession.AVSession) => { this.session = currentAVSession; - let sessionController = await currentAVSession.getAVCastController(); + let sessionController: avSession.AVCastController = await currentAVSession.getAVCastController(); this.castController = sessionController; // [Start play_state_callback] - let playStateCallback = (state: avSession.AVPlaybackState) => { - + let playStateCallback: (state: avSession.AVPlaybackState) => void = (state: avSession.AVPlaybackState) => { } sessionController.on('playbackStateChange', 'all', this.playStateCallback); sessionController.off('playbackStateChange', this.playStateCallback); // [End play_state_callback] }).catch((err: BusinessError) => { - console.info(`CreateAVSession BusinessError: code: ${err.code}, message: ${err.message}`); + hilog.error(0x0000, 'testTag', `CreateAVSession BusinessError: code: ${err.code}, message: ${err.message}`); }); } - prepare() { + prepare(): void { let playItem: avSession.AVQueueItem = { itemId: 0, description: { @@ -51,19 +64,17 @@ class avSessionClass { // [Start prepare] // Preparing to play, this will not trigger actual playback, it will load and buffer this.castController?.prepare(playItem, () => { - console.info('Preparation done'); // Start playback, truly triggering the playback on the other end. Please call start after Prepare is successful. this.castController?.start(playItem, () => { - console.info('Playback started'); + hilog.info(0x0000, 'testTag', 'Playback started'); }); }); // [End prepare] } - onPrepare() { + onPrepare(): void { // [Start on_prepare] this.session?.on('pause', async () => { - console.info(TAG, `on pause , do pause task`); // Execute player pause // Set the status and progress during pause this.currentState = { diff --git a/ApiUsingStandards/entry/src/main/module.json5 b/ApiUsingStandards/entry/src/main/module.json5 index a1cea8b6a4560cee7bda7a2db52f310c035ab6c8..ad219d733f6afa5ea07f85f580208b08cc3b9041 100644 --- a/ApiUsingStandards/entry/src/main/module.json5 +++ b/ApiUsingStandards/entry/src/main/module.json5 @@ -5,9 +5,7 @@ "description": "$string:module_desc", "mainElement": "EntryAbility", "deviceTypes": [ - "phone", - "tablet", - "2in1" + "phone" ], "deliveryWithInstall": true, "installationFree": false, diff --git a/ApiUsingStandards/entry/src/main/resources/base/element/string.json b/ApiUsingStandards/entry/src/main/resources/base/element/string.json index f94595515a99e0c828807e243494f57f09251930..9ce98bfb9ff4c08bd128cf4ca71326277260f640 100644 --- a/ApiUsingStandards/entry/src/main/resources/base/element/string.json +++ b/ApiUsingStandards/entry/src/main/resources/base/element/string.json @@ -10,7 +10,7 @@ }, { "name": "EntryAbility_label", - "value": "label" + "value": "ApiUsingStandards" } ] } \ No newline at end of file diff --git a/ApiUsingStandards/oh-package.json5 b/ApiUsingStandards/oh-package.json5 index 75e4e229db0f608fc3d9471c8819d0e52fb403c5..60ef03cdf1b3f06de3df44880fb15d89e87bc1f5 100644 --- a/ApiUsingStandards/oh-package.json5 +++ b/ApiUsingStandards/oh-package.json5 @@ -4,7 +4,5 @@ "dependencies": { }, "devDependencies": { - "@ohos/hypium": "1.0.21", - "@ohos/hamock": "1.0.0" } } diff --git a/AppAspectProgrammingDesign/README.md b/AppAspectProgrammingDesign/README.md new file mode 100644 index 0000000000000000000000000000000000000000..9e5f3f2614a76367a5c468ee58d0777ecffb6e51 --- /dev/null +++ b/AppAspectProgrammingDesign/README.md @@ -0,0 +1,62 @@ +# 应用切面编程设计 + +### 介绍 + +本示例是《应用切面编程设计》最佳实践中的代码示例片段。 + +### 使用说明 + +进入首面,加载示例逻辑。 + +### 工程目录 + +``` +├──entry/src/main/ets +│ ├──entryability +│ │ └──EntryAbility.ets // 入口类 +│ ├──entrybackupability +│ │ └──EntryBackupAbility.ets // 备份恢复类 +│ └──pages +│ ├──Index.ets // 示例页面 +│ ├──Index1.ets // 示例页面 +│ ├──Index2.ets // 示例页面 +│ ├──Index3.ets // 示例页面 +│ ├──Index4.ets // 示例页面 +│ ├──Index5.ets // 示例页面 +│ ├──Index6.ets // 示例页面 +│ ├──Index7.ets // 示例页面 +│ ├──Index8.ets // 示例页面 +│ ├──Index9.ets // 示例页面 +│ └──Index10.ets // 示例页面 +└──entry/src/main/resources // 应用资源目录 +``` + + +### 具体实现 + +1. 介绍使用util.Aspect在切面编程中的方法操作,包括使用addBefore、addAfter、replace等。 + +### 相关权限 + +不涉及。 + +### 约束与限制 + +1. 本示例仅支持标准系统上运行,支持设备:华为手机。 + +2. HarmonyOS系统:HarmonyOS 5.0.5 Release及以上。 + +3. DevEco Studio版本:DevEco Studio 5.0.5 Release及以上。 + +4. HarmonyOS SDK版本:HarmonyOS 5.0.5 Release SDK及以上。 + +### 下载 + +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set AppAspectProgrammingDesign +git checkout +``` \ No newline at end of file diff --git a/AppAspectProgrammingDesign/build-profile.json5 b/AppAspectProgrammingDesign/build-profile.json5 index 03ac3a3ae9dd397844173066e5d5ee21b49455a1..492123c253881f5bbd9bc76553bfb74e842dfb40 100644 --- a/AppAspectProgrammingDesign/build-profile.json5 +++ b/AppAspectProgrammingDesign/build-profile.json5 @@ -5,7 +5,8 @@ { "name": "default", "signingConfig": "default", - "compatibleSdkVersion": "5.0.4(16)", + "compatibleSdkVersion": "5.0.5(17)", + "targetSdkVersion": "5.0.5(17)", "runtimeOS": "HarmonyOS", "buildOption": { "strictMode": { diff --git a/AppAspectProgrammingDesign/entry/src/main/module.json5 b/AppAspectProgrammingDesign/entry/src/main/module.json5 index a1cea8b6a4560cee7bda7a2db52f310c035ab6c8..ad219d733f6afa5ea07f85f580208b08cc3b9041 100644 --- a/AppAspectProgrammingDesign/entry/src/main/module.json5 +++ b/AppAspectProgrammingDesign/entry/src/main/module.json5 @@ -5,9 +5,7 @@ "description": "$string:module_desc", "mainElement": "EntryAbility", "deviceTypes": [ - "phone", - "tablet", - "2in1" + "phone" ], "deliveryWithInstall": true, "installationFree": false, diff --git a/AppAspectProgrammingDesign/entry/src/main/resources/base/element/string.json b/AppAspectProgrammingDesign/entry/src/main/resources/base/element/string.json index f94595515a99e0c828807e243494f57f09251930..162ff06f3016378f5490c97cae44fff1199ea814 100644 --- a/AppAspectProgrammingDesign/entry/src/main/resources/base/element/string.json +++ b/AppAspectProgrammingDesign/entry/src/main/resources/base/element/string.json @@ -10,7 +10,7 @@ }, { "name": "EntryAbility_label", - "value": "label" + "value": "AppAspectProgrammingDesign" } ] } \ No newline at end of file diff --git a/AppColdStart/HapAndHarDependHar/AppScope/app.json5 b/AppColdStart/HapAndHarDependHar/AppScope/app.json5 deleted file mode 100644 index 86cc9b85e3d6376e23d256dffccbcdd1d59b4e6e..0000000000000000000000000000000000000000 --- a/AppColdStart/HapAndHarDependHar/AppScope/app.json5 +++ /dev/null @@ -1,10 +0,0 @@ -{ - "app": { - "bundleName": "com.example.coldstart", - "vendor": "example", - "versionCode": 1000000, - "versionName": "1.0.0", - "icon": "$media:app_icon", - "label": "$string:app_name" - } -} diff --git a/AppColdStart/HapAndHarDependHar/AppScope/resources/base/element/string.json b/AppColdStart/HapAndHarDependHar/AppScope/resources/base/element/string.json deleted file mode 100644 index 7b173461f58b7687bc9b8423941cb83b96c12069..0000000000000000000000000000000000000000 --- a/AppColdStart/HapAndHarDependHar/AppScope/resources/base/element/string.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "string": [ - { - "name": "app_name", - "value": "ColdStart" - } - ] -} diff --git a/AppColdStart/HapAndHarDependHar/build-profile.json5 b/AppColdStart/HapAndHarDependHar/build-profile.json5 deleted file mode 100644 index 2c03ac0f094d139e2ae61c76ed8a58d81a0d8dcd..0000000000000000000000000000000000000000 --- a/AppColdStart/HapAndHarDependHar/build-profile.json5 +++ /dev/null @@ -1,43 +0,0 @@ -{ - "app": { - "signingConfigs": [], - "products": [ - { - "name": "default", - "signingConfig": "default", - "compatibleSdkVersion": "5.0.0(12)", - "runtimeOS": "HarmonyOS", - } - ], - "buildModeSet": [ - { - "name": "debug", - }, - { - "name": "release" - } - ] - }, - "modules": [ - { - "name": "entry", - "srcPath": "./entry", - "targets": [ - { - "name": "default", - "applyToProducts": [ - "default" - ] - } - ] - }, - { - "name": "har_library", - "srcPath": "./library" - }, - { - "name": "har_common", - "srcPath": "./har_common", - } - ] -} \ No newline at end of file diff --git a/AppColdStart/HapAndHarDependHar/entry/oh-package.json5 b/AppColdStart/HapAndHarDependHar/entry/oh-package.json5 deleted file mode 100644 index 0fde17fdf11b4e1e509993c6079ea76c582de11a..0000000000000000000000000000000000000000 --- a/AppColdStart/HapAndHarDependHar/entry/oh-package.json5 +++ /dev/null @@ -1,13 +0,0 @@ -{ - "name": "entry", - "version": "1.0.0", - "description": "Please describe the basic information.", - "main": "", - "author": "", - "license": "", - "dependencies": { - "har_library": "file:../library", - "har_common": "file:../har_common" - } -} - diff --git a/AppColdStart/HapAndHarDependHar/entry/src/main/ets/entryability/EntryAbility.ets b/AppColdStart/HapAndHarDependHar/entry/src/main/ets/entryability/EntryAbility.ets deleted file mode 100644 index aa7b8e4d139fe8671c5a382b0f8b80e5335c6c52..0000000000000000000000000000000000000000 --- a/AppColdStart/HapAndHarDependHar/entry/src/main/ets/entryability/EntryAbility.ets +++ /dev/null @@ -1,57 +0,0 @@ -/* -* Copyright (C) 2024 Huawei Device Co., Ltd. -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* 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. -*/ - -import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; -import { hilog } from '@kit.PerformanceAnalysisKit'; -import { window } from '@kit.ArkUI'; - - -export default class EntryAbility extends UIAbility { - onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { - hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate'); - } - - onDestroy(): void { - hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy'); - } - - onWindowStageCreate(windowStage: window.WindowStage): void { - // Main window is created, set main page for this ability - hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); - - windowStage.loadContent('pages/Index', (err) => { - if (err.code) { - hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); - return; - } - hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.'); - }); - } - - onWindowStageDestroy(): void { - // Main window is destroyed, release UI related resources - hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); - } - - onForeground(): void { - // Ability has brought to foreground - hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground'); - } - - onBackground(): void { - // Ability has back to background - hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground'); - } -} diff --git a/AppColdStart/HapAndHarDependHar/entry/src/main/ets/pages/Index.ets b/AppColdStart/HapAndHarDependHar/entry/src/main/ets/pages/Index.ets deleted file mode 100644 index 6413cae7d4867bc242c0a89f91d560ffd08780a2..0000000000000000000000000000000000000000 --- a/AppColdStart/HapAndHarDependHar/entry/src/main/ets/pages/Index.ets +++ /dev/null @@ -1,35 +0,0 @@ -/* -* Copyright (C) 2024 Huawei Device Co., Ltd. -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* 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. -*/ - -// DocsCode 1 -// entry/src/main/ets/pages/Index.ets -import { MainPage } from 'har_library'; -import { funcResult } from 'har_common'; -// DocsCode 1 - -@Entry -@Component -struct Index { - @State message: string = 'Hello World' + funcResult; - - build() { - Row() { - // 引用HAR的ArkUI组件 - MainPage() - } - .height('100%') - .width('100%') - } -} diff --git a/AppColdStart/HapAndHarDependHar/entry/src/main/module.json5 b/AppColdStart/HapAndHarDependHar/entry/src/main/module.json5 deleted file mode 100644 index 3b355d125c7bb7b28090d101652243c5facbd9ba..0000000000000000000000000000000000000000 --- a/AppColdStart/HapAndHarDependHar/entry/src/main/module.json5 +++ /dev/null @@ -1,36 +0,0 @@ -{ - "module": { - "name": "entry", - "type": "entry", - "description": "$string:module_desc", - "mainElement": "EntryAbility", - "deviceTypes": [ - "phone" - ], - "deliveryWithInstall": true, - "installationFree": false, - "pages": "$profile:main_pages", - "abilities": [ - { - "name": "EntryAbility", - "srcEntry": "./ets/entryability/EntryAbility.ets", - "description": "$string:EntryAbility_desc", - "icon": "$media:layered_image", - "label": "$string:EntryAbility_label", - "startWindowIcon": "$media:startIcon", - "startWindowBackground": "$color:start_window_background", - "exported": true, - "skills": [ - { - "entities": [ - "entity.system.home" - ], - "actions": [ - "action.system.home" - ] - } - ] - } - ] - } -} diff --git a/AppColdStart/HapAndHarDependHar/har_common/Index.ets b/AppColdStart/HapAndHarDependHar/har_common/Index.ets deleted file mode 100644 index 557674ecc19a7d3bf7692082e2713e2e6883fcf0..0000000000000000000000000000000000000000 --- a/AppColdStart/HapAndHarDependHar/har_common/Index.ets +++ /dev/null @@ -1,16 +0,0 @@ -/* -* Copyright (C) 2024 Huawei Device Co., Ltd. -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* 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. -*/ - -export { funcResult } from './src/main/ets/utils/Utils'; \ No newline at end of file diff --git a/AppColdStart/HapAndHarDependHar/har_common/obfuscation-rules.txt b/AppColdStart/HapAndHarDependHar/har_common/obfuscation-rules.txt deleted file mode 100644 index 985b2aeb7658286b17bd26eab8f217c3fe75ea8b..0000000000000000000000000000000000000000 --- a/AppColdStart/HapAndHarDependHar/har_common/obfuscation-rules.txt +++ /dev/null @@ -1,18 +0,0 @@ -# Define project specific obfuscation rules here. -# You can include the obfuscation configuration files in the current module's build-profile.json5. -# -# For more details, see -# https://gitee.com/openharmony/arkcompiler_ets_frontend/blob/master/arkguard/README.md - -# Obfuscation options: -# -disable-obfuscation: disable all obfuscations -# -enable-property-obfuscation: obfuscate the property names -# -enable-toplevel-obfuscation: obfuscate the names in the global scope -# -compact: remove unnecessary blank spaces and all line feeds -# -remove-log: remove all console.* statements -# -print-namecache: print the name cache that contains the mapping from the old names to new names -# -apply-namecache: reuse the given cache file - -# Keep options: -# -keep-property-name: specifies property names that you want to keep -# -keep-global-name: specifies names that you want to keep in the global scope \ No newline at end of file diff --git a/AppColdStart/HapAndHarDependHar/har_common/oh-package.json5 b/AppColdStart/HapAndHarDependHar/har_common/oh-package.json5 deleted file mode 100644 index c9288aefd5fa8348c6967366470b24384f1b52a0..0000000000000000000000000000000000000000 --- a/AppColdStart/HapAndHarDependHar/har_common/oh-package.json5 +++ /dev/null @@ -1,10 +0,0 @@ -{ - "name": "har_common", - "version": "1.0.0", - "description": "Please describe the basic information.", - "main": "Index.ets", - "author": "", - "license": "Apache-2.0", - "dependencies": { - } -} diff --git a/AppColdStart/HapAndHarDependHar/har_common/src/main/ets/components/mainpage/MainPage.ets b/AppColdStart/HapAndHarDependHar/har_common/src/main/ets/components/mainpage/MainPage.ets deleted file mode 100644 index 8fe31bb9fbcd035b0eddfd578f9b01099a294585..0000000000000000000000000000000000000000 --- a/AppColdStart/HapAndHarDependHar/har_common/src/main/ets/components/mainpage/MainPage.ets +++ /dev/null @@ -1,31 +0,0 @@ -/* -* Copyright (C) 2024 Huawei Device Co., Ltd. -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* 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. -*/ - -@Component -export struct MainPage { - @State message: string = 'Hello World'; - - build() { - Row() { - Column() { - Text(this.message) - .fontSize(50) - .fontWeight(FontWeight.Bold) - } - .width('100%') - } - .height('100%') - } -} diff --git a/AppColdStart/HapAndHarDependHar/har_common/src/main/ets/utils/Utils.ets b/AppColdStart/HapAndHarDependHar/har_common/src/main/ets/utils/Utils.ets deleted file mode 100644 index e22b4f60a4e92b96f9ecc8d1bb897af3994e8e8b..0000000000000000000000000000000000000000 --- a/AppColdStart/HapAndHarDependHar/har_common/src/main/ets/utils/Utils.ets +++ /dev/null @@ -1,26 +0,0 @@ -/* -* Copyright (C) 2024 Huawei Device Co., Ltd. -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* 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. -*/ - -const LARGE_NUMBER = 100000000; - -function func(): number { - let count = 0; - while (count < LARGE_NUMBER) { - count++; - } - return count; -} - -export let funcResult = func(); \ No newline at end of file diff --git a/AppColdStart/HapAndHarDependHar/har_common/src/main/module.json5 b/AppColdStart/HapAndHarDependHar/har_common/src/main/module.json5 deleted file mode 100644 index b26580cd6a0aa8c7df3ca1fc657f963a1b1b4ef4..0000000000000000000000000000000000000000 --- a/AppColdStart/HapAndHarDependHar/har_common/src/main/module.json5 +++ /dev/null @@ -1,11 +0,0 @@ -{ - "module": { - "name": "har_common", - "type": "har", - "deviceTypes": [ - "default", - "tablet", - "2in1" - ] - } -} diff --git a/AppColdStart/HapAndHarDependHar/library/Index.ets b/AppColdStart/HapAndHarDependHar/library/Index.ets deleted file mode 100644 index 6f8afc6e836c6ca8e21cba85918b0495bbc721bb..0000000000000000000000000000000000000000 --- a/AppColdStart/HapAndHarDependHar/library/Index.ets +++ /dev/null @@ -1,19 +0,0 @@ -/* -* Copyright (C) 2024 Huawei Device Co., Ltd. -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* 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. -*/ - -// [Start not_recommend_demo] -export { MainPage } from './src/main/ets/components/mainpage/MainPage'; // 冷启动强相关文件 -export { SubPage } from './src/main/ets/components/mainpage/SubPage'; // 非冷启动强相关文件 -// [End not_recommend_demo] diff --git a/AppColdStart/HapAndHarDependHar/library/build-profile.json5 b/AppColdStart/HapAndHarDependHar/library/build-profile.json5 deleted file mode 100644 index 697dff23e224373edb713dc2b8a08ed7341d5b4c..0000000000000000000000000000000000000000 --- a/AppColdStart/HapAndHarDependHar/library/build-profile.json5 +++ /dev/null @@ -1,31 +0,0 @@ -{ - "apiType": "stageMode", - "buildOption": { - }, - "buildOptionSet": [ - { - "name": "release", - "arkOptions": { - "obfuscation": { - "ruleOptions": { - "enable": true, - "files": [ - "./obfuscation-rules.txt" - ] - }, - "consumerFiles": [ - "./consumer-rules.txt" - ] - } - }, - }, - ], - "targets": [ - { - "name": "default" - }, - { - "name": "ohosTest" - } - ] -} diff --git a/AppColdStart/HapAndHarDependHar/library/consumer-rules.txt b/AppColdStart/HapAndHarDependHar/library/consumer-rules.txt deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/AppColdStart/HapAndHarDependHar/library/hvigorfile.ts b/AppColdStart/HapAndHarDependHar/library/hvigorfile.ts deleted file mode 100644 index 42187071482d292588ad40babeda74f7b8d97a23..0000000000000000000000000000000000000000 --- a/AppColdStart/HapAndHarDependHar/library/hvigorfile.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { harTasks } from '@ohos/hvigor-ohos-plugin'; - -export default { - system: harTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ - plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ -} diff --git a/AppColdStart/HapAndHarDependHar/library/obfuscation-rules.txt b/AppColdStart/HapAndHarDependHar/library/obfuscation-rules.txt deleted file mode 100644 index 985b2aeb7658286b17bd26eab8f217c3fe75ea8b..0000000000000000000000000000000000000000 --- a/AppColdStart/HapAndHarDependHar/library/obfuscation-rules.txt +++ /dev/null @@ -1,18 +0,0 @@ -# Define project specific obfuscation rules here. -# You can include the obfuscation configuration files in the current module's build-profile.json5. -# -# For more details, see -# https://gitee.com/openharmony/arkcompiler_ets_frontend/blob/master/arkguard/README.md - -# Obfuscation options: -# -disable-obfuscation: disable all obfuscations -# -enable-property-obfuscation: obfuscate the property names -# -enable-toplevel-obfuscation: obfuscate the names in the global scope -# -compact: remove unnecessary blank spaces and all line feeds -# -remove-log: remove all console.* statements -# -print-namecache: print the name cache that contains the mapping from the old names to new names -# -apply-namecache: reuse the given cache file - -# Keep options: -# -keep-property-name: specifies property names that you want to keep -# -keep-global-name: specifies names that you want to keep in the global scope \ No newline at end of file diff --git a/AppColdStart/HapAndHarDependHar/library/oh-package.json5 b/AppColdStart/HapAndHarDependHar/library/oh-package.json5 deleted file mode 100644 index 3824a8247b7ff16278737ec539e98f7b88a8de55..0000000000000000000000000000000000000000 --- a/AppColdStart/HapAndHarDependHar/library/oh-package.json5 +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "har_library", - "version": "1.0.0", - "description": "Please describe the basic information.", - "main": "Index.ets", - "author": "", - "license": "Apache-2.0", - "dependencies": { - "har_common": "file:../har_common" - } -} diff --git a/AppColdStart/HapAndHarDependHar/library/src/main/ets/components/mainpage/SubPage.ets b/AppColdStart/HapAndHarDependHar/library/src/main/ets/components/mainpage/SubPage.ets deleted file mode 100644 index 5d9893548432c492579940234cc5ab33ad7b0a64..0000000000000000000000000000000000000000 --- a/AppColdStart/HapAndHarDependHar/library/src/main/ets/components/mainpage/SubPage.ets +++ /dev/null @@ -1,14 +0,0 @@ -// [Start not_recommend_demo] -// library/src/main/ets/components/mainpage/SubPage.ets -// SubPage中的全局耗时函数 -const LARGE_NUMBER = 10000000; -function computeTask(): number { - let count = 0; - while (count < LARGE_NUMBER) { - count++; - } - return count; -} -let count = computeTask(); -// ... -// [End not_recommend_demo] \ No newline at end of file diff --git a/AppColdStart/HapAndHarDependHar/library/src/main/module.json5 b/AppColdStart/HapAndHarDependHar/library/src/main/module.json5 deleted file mode 100644 index 2892dab4fe007cb1eda74bd7189f3a55159038ff..0000000000000000000000000000000000000000 --- a/AppColdStart/HapAndHarDependHar/library/src/main/module.json5 +++ /dev/null @@ -1,11 +0,0 @@ -{ - "module": { - "name": "har_library", - "type": "har", - "deviceTypes": [ - "default", - "tablet", - "2in1" - ] - } -} diff --git a/AppColdStart/HapAndHarDependHar/library/src/main/resources/zh_CN/element/string.json b/AppColdStart/HapAndHarDependHar/library/src/main/resources/zh_CN/element/string.json deleted file mode 100644 index f51a9c8461a55f6312ef950344e3145b7f82d607..0000000000000000000000000000000000000000 --- a/AppColdStart/HapAndHarDependHar/library/src/main/resources/zh_CN/element/string.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "string": [ - { - "name": "page_show", - "value": "page from package" - } - ] -} diff --git a/AppColdStart/README.md b/AppColdStart/README.md new file mode 100644 index 0000000000000000000000000000000000000000..9ccce59eb7f80cd7e52e69c60f5c8721cf3de0b6 --- /dev/null +++ b/AppColdStart/README.md @@ -0,0 +1,66 @@ +# 应用冷启动时延优化同源示例代码 + +### 介绍 + +本示例代码为最佳实践《应用冷启动时延优化》配套示例代码。 + +### 使用说明 + +不涉及 + +### 工程目录 + +``` +├──entry/src/main/ets +│ ├──entryability +│ │ └──EntryAbility.ets // 程序入口类 +│ ├──entrybackupability +│ │ └──EntryBackupAbility.ets // 数据备份恢复类 +│ ├──pages +│ │ ├──ColdStartSlow.ets // 冷启动缓慢示例 +│ │ ├──ColdStartSpeedOptimization.ets // 冷启快速示例 +│ │ ├──ComputeTaskAsync.ets // 异步任务示例 +│ │ ├──ImportMainPage.ets // 页面导入示例 +│ │ ├──ImportMainPageDemo.ets // 减少导入文件示例 +│ │ ├──ImportSubPage.ets // 导入次级页面 +│ │ ├──Index.ets // 应用首页 +│ │ ├──NewIndex.ets // 展示网路图片首页 +│ │ ├──NotRecommendDemo.ets // 不推荐iport示例 +│ │ ├──ReduceImport.ets // 减少import导入示例 +│ │ ├──ScenariosExample.ets // 网络二次刷新示例 +│ │ └──SecondPage.ets // 跳转页面 +│ └──utils +│ ├──Calculator.ets // 耗时运算函数封装 +│ └──NetRequest.ets // 网络请求工具类 +├──entry/src/main/resources // 应用资源目录 +└──library // 静态资源共享包 + ├──src/main/ets/components/mainpage + │ ├──MainPgge.ets // 静态资源包首页 + │ └──SubPage.ets // 静态资源包次级页面 + ├──Index.ets // 入口文件,对外暴露模块方法 + ├──IndexAppStart.ets // 拆分导出文件MainPage + ├──IndexOthers.ets // 拆分导出文件SubPage + └──src/main/resources // 应用静态资源目录 +``` + +### 相关权限 + +不涉及 + +### 约束与限制 + +* 本示例仅支持标准系统上运行,支持设备:华为手机。 +* HarmonyOS系统:HarmonyOS 5.0.5 Release及以上。 +* DevEco Studio版本:DevEco Studio 5.0.5 Release及以上。 +* HarmonyOS SDK版本:HarmonyOS 5.0.5 Release SDK及以上。 + +### 下载 + +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set AppColdStart +git checkout +``` \ No newline at end of file diff --git a/AppColdStart/build-profile.json5 b/AppColdStart/build-profile.json5 index 9e87e7e6f19020fe21192844709f192cec80fd44..ae19bf006133749717f7eb1fc8ae716bca4dbd74 100644 --- a/AppColdStart/build-profile.json5 +++ b/AppColdStart/build-profile.json5 @@ -37,6 +37,10 @@ ] } ] + }, + { + "name": "library", + "srcPath": "./library", } ] } \ No newline at end of file diff --git a/AppColdStart/entry/oh-package.json5 b/AppColdStart/entry/oh-package.json5 index 248c3b7541a589682a250f86a6d3ecf7414d2d6a..caa370f06bd44102373d4d518a2c11a0a1f9d8ee 100644 --- a/AppColdStart/entry/oh-package.json5 +++ b/AppColdStart/entry/oh-package.json5 @@ -5,6 +5,8 @@ "main": "", "author": "", "license": "", - "dependencies": {} + "dependencies": { + "library": "file:../library" + } } diff --git a/AppColdStart/entry/src/main/ets/entryability/EntryAbility.ets b/AppColdStart/entry/src/main/ets/entryability/EntryAbility.ets index 90267ef7fae8fb46b5d1a0dd1c7a5a742d083909..78fd17bfd32dfbbed632567bc53a000ef3d7e686 100644 --- a/AppColdStart/entry/src/main/ets/entryability/EntryAbility.ets +++ b/AppColdStart/entry/src/main/ets/entryability/EntryAbility.ets @@ -1,16 +1,64 @@ -// [Start my_ability_stage] -// MyAbilityStage.ets -import { AbilityStage, Want } from '@kit.AbilityKit'; -import { httpRequest } from '../utils/NetRequest'; -export default class MyAbilityStage extends AbilityStage { - onCreate(): void { - // Send a network request - httpRequest(); +/* +* Copyright (C) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + +// [Start entry_ability_demo] +import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { window } from '@kit.ArkUI' + +const LARGE_NUMBER: number = 100000000; +const DELAYED_TIME: number = 1000; + + +export default class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + // Time-consuming operation + // this.computeTask(); + this.computeTaskAsync(); // Asynchronous tasks + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + windowStage.loadContent('pages/Index', (err, data) => { + if (err.code) { + console.error('Failed to load the content. Cause: ' + JSON.stringify(err) ?? ''); + return; + } + console.info('Succeeded in loading the content. Data: ' + JSON.stringify(data) ?? ''); + }); + + // Time-consuming operation + // this.computeTask(); + // this.computeTaskAsync(); // Asynchronous mission + } + + onForeground(): void { + // Time-consuming operation + // this.computeTask(); + // this.computeTaskAsync(); // Asynchronous mission + } + + private computeTask(): void { + let count: number = 0; + while (count < LARGE_NUMBER) { + count++; + } } - onAcceptWant(want: Want): string { - // Triggered in specified mode only. - return 'MyAbilityStage'; + private computeTaskAsync(): void { + setTimeout(() => { // SetTimeout is used here to achieve asynchronous delayed operation. + this.computeTask(); + }, DELAYED_TIME); } } -// [End my_ability_stage] \ No newline at end of file +// [End entry_ability_demo] \ No newline at end of file diff --git a/AppColdStart/entry/src/main/ets/entryability/EntryAbilityDemo.ets b/AppColdStart/entry/src/main/ets/entryability/EntryAbilityDemo.ets deleted file mode 100644 index f0dc3f343819e7ed2e9784f219f2c2f397ee7c4f..0000000000000000000000000000000000000000 --- a/AppColdStart/entry/src/main/ets/entryability/EntryAbilityDemo.ets +++ /dev/null @@ -1,49 +0,0 @@ -// [Start entry_ability_demo] -import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; -import { window } from '@kit.ArkUI' - -const LARGE_NUMBER = 100000000; -const DELAYED_TIME = 1000; - - -export default class EntryAbility extends UIAbility { - onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { - // Time-consuming operation - // this.computeTask(); - this.computeTaskAsync(); // Asynchronous tasks - } - - onWindowStageCreate(windowStage: window.WindowStage): void { - windowStage.loadContent('pages/Index', (err, data) => { - if (err.code) { - console.error('Failed to load the content. Cause: ' + JSON.stringify(err) ?? ''); - return; - } - console.info('Succeeded in loading the content. Data: ' + JSON.stringify(data) ?? ''); - }); - - // Time-consuming operation - // this.computeTask(); - // this.computeTaskAsync(); // Asynchronous mission - } - - onForeground(): void { - // Time-consuming operation - // this.computeTask(); - // this.computeTaskAsync(); // Asynchronous mission - } - - private computeTask(): void { - let count = 0; - while (count < LARGE_NUMBER) { - count++; - } - } - - private computeTaskAsync(): void { - setTimeout(() => { // SetTimeout is used here to achieve asynchronous delayed operation. - this.computeTask(); - }, DELAYED_TIME); - } -} -// [End entry_ability_demo] \ No newline at end of file diff --git a/AppColdStart/entry/src/main/ets/entryability/MyAbilityStage.ets b/AppColdStart/entry/src/main/ets/entryability/MyAbilityStage.ets index da3225812a26ffd802864288847604a10355df15..49c5e9274c0c4cbf8c74d83b289fdf85fad6270e 100644 --- a/AppColdStart/entry/src/main/ets/entryability/MyAbilityStage.ets +++ b/AppColdStart/entry/src/main/ets/entryability/MyAbilityStage.ets @@ -1,32 +1,31 @@ -// [Start reduce_ability_stage_time] -import { AbilityStage, Want } from '@kit.AbilityKit'; - -const LARGE_NUMBER = 100000000; -const DELAYED_TIME = 1000; +/* +* Copyright (C) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ +// [Start my_ability_stage] +// MyAbilityStage.ets +import { AbilityStage, Want } from '@kit.AbilityKit'; +import { httpRequest } from '../utils/NetRequest'; export default class MyAbilityStage extends AbilityStage { onCreate(): void { - // Time-consuming operation - // this.computeTask(); - this.computeTaskAsync(); // Asynchronous mission + // Send a network request + httpRequest(); } onAcceptWant(want: Want): string { - // Trigger in specified mode only + // Triggered in specified mode only. return 'MyAbilityStage'; } - - private computeTask(): void { - let count = 0; - while (count < LARGE_NUMBER) { - count++; - } - } - - private computeTaskAsync(): void { - setTimeout(() => { // SetTimeout is used here to achieve asynchronous delayed operation. - this.computeTask(); - }, DELAYED_TIME); - } } -// [End reduce_ability_stage_time] \ No newline at end of file +// [End my_ability_stage] \ No newline at end of file diff --git a/AppColdStart/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets b/AppColdStart/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets index 8e4de99282050bad799ac892eb85ac5449364a51..7eb1afb81759bc5d59117077cb08b938ea66d402 100644 --- a/AppColdStart/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets +++ b/AppColdStart/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets @@ -1,3 +1,18 @@ +/* +* Copyright (C) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + import { hilog } from '@kit.PerformanceAnalysisKit'; import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit'; diff --git a/AppColdStart/entry/src/main/ets/pages/ColdStartSlow.ets b/AppColdStart/entry/src/main/ets/pages/ColdStartSlow.ets index fd03ac97033a5cce90ea14d9c6daf2532259a6be..4c4bfbff3a4671e7c2e5a6cb6e91b5227f67bf54 100644 --- a/AppColdStart/entry/src/main/ets/pages/ColdStartSlow.ets +++ b/AppColdStart/entry/src/main/ets/pages/ColdStartSlow.ets @@ -1,6 +1,20 @@ +/* +* Copyright (C) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + // [Start cold_start_slow] -const LARGE_NUMBER = 200000000; -const DELAYED_TIME = 1000; +const LARGE_NUMBER: number = 200000000; @Entry @Component @@ -13,7 +27,7 @@ struct Index { } computeTask(): void { - let count = 0; + let count: number = 0; while (count < LARGE_NUMBER) { count++; } diff --git a/AppColdStart/entry/src/main/ets/pages/ColdStartSpeedOptimization.ets b/AppColdStart/entry/src/main/ets/pages/ColdStartSpeedOptimization.ets index 6efdcf6dd4233513daed9a13bf4abf53e90fe842..31fa4fefa9abb679057c8f5bb2e42464a1baf8f0 100644 --- a/AppColdStart/entry/src/main/ets/pages/ColdStartSpeedOptimization.ets +++ b/AppColdStart/entry/src/main/ets/pages/ColdStartSpeedOptimization.ets @@ -1,6 +1,21 @@ +/* +* Copyright (C) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + // [Start cold_start_speed_optimization] -const LARGE_NUMBER = 100000000; -const DELAYED_TIME = 1000; +const LARGE_NUMBER: number = 100000000; +const DELAYED_TIME: number = 1000; @Entry @Component @@ -27,7 +42,7 @@ struct Index { // [EndExclude cold_start_speed_optimization] computeTask(): void { - let count = 0; + let count: number = 0; while (count < LARGE_NUMBER) { count++; } diff --git a/AppColdStart/entry/src/main/ets/pages/ComputeTaskAsync.ets b/AppColdStart/entry/src/main/ets/pages/ComputeTaskAsync.ets index 53d1a1a4f24078e2406316888d23104d0edaaafe..e8e5d6ff44973b249a2cc9f64e1dc408165d4c6d 100644 --- a/AppColdStart/entry/src/main/ets/pages/ComputeTaskAsync.ets +++ b/AppColdStart/entry/src/main/ets/pages/ComputeTaskAsync.ets @@ -1,6 +1,21 @@ +/* +* Copyright (C) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + // [Start compute_task_async] -const LARGE_NUMBER = 100000000; -const DELAYED_TIME = 1000; +const LARGE_NUMBER: number = 100000000; +const DELAYED_TIME: number = 1000; @Entry @Component @@ -26,7 +41,7 @@ struct Index { } private computeTask(): void { - let count = 0; + let count: number = 0; while (count < LARGE_NUMBER) { count++; } diff --git a/AppColdStart/entry/src/main/ets/pages/ImportMainPage.ets b/AppColdStart/entry/src/main/ets/pages/ImportMainPage.ets index 581fc19ec1e16d748f5a674c9164b669664856f2..07ce5a68692bd50ef90f1e4aa1c8a8b11740f38e 100644 --- a/AppColdStart/entry/src/main/ets/pages/ImportMainPage.ets +++ b/AppColdStart/entry/src/main/ets/pages/ImportMainPage.ets @@ -1,3 +1,18 @@ +/* +* Copyright (C) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + // [Start import_main_page] // Index.ets import { MainPage } from 'library/IndexAppStart'; diff --git a/AppColdStart/entry/src/main/ets/pages/ImportMainPageDemo.ets b/AppColdStart/entry/src/main/ets/pages/ImportMainPageDemo.ets index b348b090bde12e91d74342d1f8430bcff0465ebf..eb5f107823f86cf37f176f626346b4069c9c26c9 100644 --- a/AppColdStart/entry/src/main/ets/pages/ImportMainPageDemo.ets +++ b/AppColdStart/entry/src/main/ets/pages/ImportMainPageDemo.ets @@ -1,3 +1,18 @@ +/* +* Copyright (C) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + // [Start import_main_page_demo] // Index.ets import { MainPage } from 'library/src/main/ets/components/mainpage/MainPage'; diff --git a/AppColdStart/entry/src/main/ets/pages/ImportOthers.ets b/AppColdStart/entry/src/main/ets/pages/ImportOthers.ets deleted file mode 100644 index c867ddd5d95672a010cbb35a16080c761cb13457..0000000000000000000000000000000000000000 --- a/AppColdStart/entry/src/main/ets/pages/ImportOthers.ets +++ /dev/null @@ -1,22 +0,0 @@ -// [Start import_others] -import { add } from 'hsp1'; -import { add2 } from 'hsp2'; -import { add3 } from 'hsp3'; -import { add4 } from 'hsp4'; -import { add5 } from 'hsp5'; -import { add6 } from 'hsp6'; -import { add7 } from 'hsp7'; -import { add8 } from 'hsp8'; -import { add9 } from 'hsp9'; -import { add10 } from 'hsp10'; -import { add11 } from 'hsp11'; -import { add12 } from 'hsp12'; -import { add13 } from 'hsp13'; -import { add14 } from 'hsp14'; -import { add15 } from 'hsp15'; -import { add16 } from 'hsp16'; -import { add17 } from 'hsp17'; -import { add18 } from 'hsp18'; -import { add19 } from 'hsp19'; -import { add20 } from 'hsp20' -// [End import_others] \ No newline at end of file diff --git a/AppColdStart/entry/src/main/ets/pages/ImportSubPage.ets b/AppColdStart/entry/src/main/ets/pages/ImportSubPage.ets index 61c1be1d1ecb55d7dc957d1bc6254cbbd4ae3996..13806a93588479c80de14babfd365df82bac6dcf 100644 --- a/AppColdStart/entry/src/main/ets/pages/ImportSubPage.ets +++ b/AppColdStart/entry/src/main/ets/pages/ImportSubPage.ets @@ -1,3 +1,18 @@ +/* +* Copyright (C) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + // [Start import_sub_page] // SecondPage.ets import { SubPage } from 'library/IndexOthers'; diff --git a/AppColdStart/entry/src/main/ets/pages/Index.ets b/AppColdStart/entry/src/main/ets/pages/Index.ets index 13b64258e8c48209fdb0ced0bc1f6bf10f9acf7d..aea2e929eba5f67b343912779488de16f3607896 100644 --- a/AppColdStart/entry/src/main/ets/pages/Index.ets +++ b/AppColdStart/entry/src/main/ets/pages/Index.ets @@ -1,3 +1,18 @@ +/* +* Copyright (C) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + // [Start request_in_home] // entry/src/main/ets/pages/Index.ets import { httpRequest } from '../utils/NetRequest'; @@ -10,15 +25,22 @@ PersistentStorage.persistProp('netData', undefined); @Entry @Component struct Index { - @State message: string = 'Hello World' + number; // In order to reflect the performance benefits, refer to the execution result number of the time-consuming function. + // In order to reflect the performance benefits, refer to the execution result number of the time-consuming function. + @State message: string = 'Hello World' + number; @StorageLink('netData') netData: PixelMap | undefined = undefined; - build(){ - Row(){ + + build() { + Column() { + Text(this.message) + .fontSize(32) Image(this.netData) .objectFit(ImageFit.Contain) .width('50%') .height('50%') } + .width('100%') + .height('100%') + .justifyContent(FlexAlign.Center) .onAppear(() => { // Send a network request httpRequest(); diff --git a/AppColdStart/entry/src/main/ets/pages/NewIndex.ets b/AppColdStart/entry/src/main/ets/pages/NewIndex.ets index cd0605ce633c12bf9e38c17ac51ab5f146c7adb6..dc90821aa2a48f02ad8bc30cb82eb4a7a00c021c 100644 --- a/AppColdStart/entry/src/main/ets/pages/NewIndex.ets +++ b/AppColdStart/entry/src/main/ets/pages/NewIndex.ets @@ -1,3 +1,18 @@ +/* +* Copyright (C) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + // [Start new_index] // Index.ets import { number } from '../utils/Calculator'; diff --git a/AppColdStart/entry/src/main/ets/pages/NotRecommendDemo.ets b/AppColdStart/entry/src/main/ets/pages/NotRecommendDemo.ets index 87ea199a85fc04ffa253b8543e63c0dad76dbdf2..c1ad2bab5315bfa4236e97a0957a65de5909ca49 100644 --- a/AppColdStart/entry/src/main/ets/pages/NotRecommendDemo.ets +++ b/AppColdStart/entry/src/main/ets/pages/NotRecommendDemo.ets @@ -1,3 +1,18 @@ +/* +* Copyright (C) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + // [Start not_recommend_demo] // entry/src/main/ets/pages/Index.ets import { MainPage } from 'library/Index'; // Unrecommended usage: Direct import of subPage.ets files related to cold start non-strong diff --git a/AppColdStart/entry/src/main/ets/pages/ReduceImport.ets b/AppColdStart/entry/src/main/ets/pages/ReduceImport.ets index 3bad56357edfdd48692665631668cba2c91942cd..b241a34b36b59977bd76b9d7ad2ac0174ef06973 100644 --- a/AppColdStart/entry/src/main/ets/pages/ReduceImport.ets +++ b/AppColdStart/entry/src/main/ets/pages/ReduceImport.ets @@ -1,3 +1,18 @@ +/* +* Copyright (C) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + // [Start reduce_import] // Optimize modules that reduce import /*import { ConfigurationConstant, contextConstant, wantConstant } from '@kit.AbilityKit'; @@ -8,9 +23,7 @@ import { atomicService } from '@kit.ScenarioFusionKit'; import { sim } from '@kit.TelephonyKit';*/ -import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; -import { hilog } from '@kit.PerformanceAnalysisKit'; -import { window } from '@kit.ArkUI'; +import { UIAbility } from '@kit.AbilityKit'; export default class EntryAbility extends UIAbility { diff --git a/AppColdStart/entry/src/main/ets/pages/ScenariosExample.ets b/AppColdStart/entry/src/main/ets/pages/ScenariosExample.ets index 7eb5bc424885de0edb7d8e3010e55f306ca2acb6..b086f51ab5353a9d49ddf31400f637b0aa284afc 100644 --- a/AppColdStart/entry/src/main/ets/pages/ScenariosExample.ets +++ b/AppColdStart/entry/src/main/ets/pages/ScenariosExample.ets @@ -1,10 +1,25 @@ +/* +* Copyright (C) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + // [Start scenarios_example] // Index.ets import { http } from '@kit.NetworkKit'; import { image } from '@kit.ImageKit'; import { BusinessError } from '@kit.BasicServicesKit'; import { abilityAccessCtrl, common, Permissions } from '@kit.AbilityKit'; -import { fileIo as fs } from '@kit.CoreFileKit'; +import { fileIo, fileIo as fs } from '@kit.CoreFileKit'; const PERMISSIONS: Array = [ 'ohos.permission.READ_MEDIA', @@ -22,7 +37,7 @@ struct Index { /** * Download picture resources from the Internet through the http request method */ - async getPicture() { + async getPicture(): Promise { http.createHttp() .request('https://www.example1.com/POST?e=f&g=h', (error: BusinessError, data: http.HttpResponse) => { @@ -42,7 +57,7 @@ struct Index { * Use createPixelMap to replace pictures of ArrayBuffer type with PixelMap type * @param data:Resources obtained from the network */ - transcodePixelMap(data: http.HttpResponse) { + transcodePixelMap(data: http.HttpResponse): void { if (http.ResponseCode.OK === data.responseCode) { const imageData: ArrayBuffer = data.result as ArrayBuffer; // Create a picture source instance through ArrayBuffer @@ -67,19 +82,18 @@ struct Index { } } - - /** - * 保存ArrayBuffer到沙箱路径 - * @param buffer:图片ArrayBuffer - * @returns - */ async saveImage(buffer: ArrayBuffer | string): Promise { - const context = this.getUIContext().getHostContext() as common.UIAbilityContext; - const filePath: string = context.cacheDir + '/test.jpg'; - AppStorage.set('net_picture', filePath); - const file = await fs.open(filePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); - await fs.write(file.fd, buffer); - await fs.close(file.fd); + try { + const context:common.UIAbilityContext = this.getUIContext().getHostContext() as common.UIAbilityContext; + const filePath: string = context.cacheDir + '/test.jpg'; + AppStorage.set('net_picture', filePath); + const file: fileIo.File = await fs.open(filePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); + await fs.write(file.fd, buffer); + await fs.close(file.fd); + } catch (err) { + let error = err as BusinessError; + console.error(`onAddForm err, code: ${error.code}, mesage: ${error.message}`); + } } @@ -100,10 +114,9 @@ struct Index { } } - async aboutToAppear(): Promise { - const context = this.getUIContext().getHostContext() as common.UIAbilityContext; - const atManager = abilityAccessCtrl.createAtManager(); + const context: common.UIAbilityContext = this.getUIContext().getHostContext() as common.UIAbilityContext; + const atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager(); await atManager.requestPermissionsFromUser(context, PERMISSIONS); this.useCachePic(); // Get data from local storage this.getPicture(); // Obtain data from the network side diff --git a/AppColdStart/entry/src/main/ets/pages/SecondPage.ets b/AppColdStart/entry/src/main/ets/pages/SecondPage.ets index 34891c80268b250c5cc7396ddce787b4859c427d..889d45ffec4014698ba9f6472b4bf414139350b5 100644 --- a/AppColdStart/entry/src/main/ets/pages/SecondPage.ets +++ b/AppColdStart/entry/src/main/ets/pages/SecondPage.ets @@ -1,3 +1,18 @@ +/* +* Copyright (C) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + // [Start not_recommend_demo] // entry/src/main/ets/pages/SecondPage.ets import { SubPage } from 'library/Index'; diff --git a/AppColdStart/entry/src/main/ets/utils/Calculator.ets b/AppColdStart/entry/src/main/ets/utils/Calculator.ets index d41b4edcf2722dbfbc5647edfbc2da8d54447c74..4a6a84ff999d2fea2450142bef336aa3790fd4c8 100644 --- a/AppColdStart/entry/src/main/ets/utils/Calculator.ets +++ b/AppColdStart/entry/src/main/ets/utils/Calculator.ets @@ -1,8 +1,9 @@ // [Start request_in_home] // Calculator.ets -const LARGE_NUMBER = 100000000; +const LARGE_NUMBER: number = 100000000; + function computeTask(): number { - let count = 0; + let count: number = 0; while (count < LARGE_NUMBER) { count++; } diff --git a/AppColdStart/entry/src/main/ets/utils/NetRequest.ets b/AppColdStart/entry/src/main/ets/utils/NetRequest.ets index 75a6da13490c36bce8dda37bb2b91a1d72eaa9d1..e5cabcf5e3b3d881f1a23bc95c7a4306b7b58deb 100644 --- a/AppColdStart/entry/src/main/ets/utils/NetRequest.ets +++ b/AppColdStart/entry/src/main/ets/utils/NetRequest.ets @@ -6,10 +6,10 @@ import { http } from '@kit.NetworkKit'; import { BusinessError } from '@kit.BasicServicesKit'; import { image } from '@kit.ImageKit'; // Download picture resources from the Internet through the http request method -export function httpRequest() { +export function httpRequest(): void { hiTraceMeter.startTrace('Http Request', 1); http.createHttp() - // The actual development needs to "https://www.example1.com/POST?e=f&g=h"replaced with the real website address to visit + // The actual development needs to "https://www.example1.com/POST?e=f&g=h"replaced with the real website address to visit .request('https://www.example1.com/POST?e=f&g=h', (error: BusinessError, data: http.HttpResponse) => { if (error) { @@ -23,7 +23,7 @@ export function httpRequest() { } // Use createPixelMap to replace pictures of ArrayBuffer types with PixelMap types. -function transcodePixelMap(data: http.HttpResponse) { +function transcodePixelMap(data: http.HttpResponse): void { if (http.ResponseCode.OK === data.responseCode) { const imageData: ArrayBuffer = data.result as ArrayBuffer; // Create a picture source instance through ArrayBuffer diff --git a/AppColdStart/entry/src/main/resources/base/element/float.json b/AppColdStart/entry/src/main/resources/base/element/float.json index 33ea22304f9b1485b5f22d811023701b5d4e35b6..a0a93dd91fd48f08f3a9532c76e9b26e68d4c034 100644 --- a/AppColdStart/entry/src/main/resources/base/element/float.json +++ b/AppColdStart/entry/src/main/resources/base/element/float.json @@ -5,4 +5,4 @@ "value": "50fp" } ] -} +} \ No newline at end of file diff --git a/AppColdStart/entry/src/main/resources/base/element/string.json b/AppColdStart/entry/src/main/resources/base/element/string.json index f94595515a99e0c828807e243494f57f09251930..0549cb3e0bf016383038ffc1c975f9fcb117269b 100644 --- a/AppColdStart/entry/src/main/resources/base/element/string.json +++ b/AppColdStart/entry/src/main/resources/base/element/string.json @@ -10,7 +10,7 @@ }, { "name": "EntryAbility_label", - "value": "label" + "value": "AppColdStart" } ] } \ No newline at end of file diff --git a/AppColdStart/entry/src/main/resources/base/profile/main_pages.json b/AppColdStart/entry/src/main/resources/base/profile/main_pages.json index 1898d94f58d6128ab712be2c68acc7c98e9ab9ce..55c3f007f87b7ce5206d325f968cc56f2f79441f 100644 --- a/AppColdStart/entry/src/main/resources/base/profile/main_pages.json +++ b/AppColdStart/entry/src/main/resources/base/profile/main_pages.json @@ -2,4 +2,4 @@ "src": [ "pages/Index" ] -} +} \ No newline at end of file diff --git a/AppColdStart/entry/src/ohosTest/module.json5 b/AppColdStart/entry/src/ohosTest/module.json5 deleted file mode 100644 index 509a3a28a3e6be8d7f98cc563fa8195657d77d1d..0000000000000000000000000000000000000000 --- a/AppColdStart/entry/src/ohosTest/module.json5 +++ /dev/null @@ -1,11 +0,0 @@ -{ - "module": { - "name": "entry_test", - "type": "feature", - "deviceTypes": [ - "phone" - ], - "deliveryWithInstall": true, - "installationFree": false - } -} diff --git a/AppColdStart/library/Index.ets b/AppColdStart/library/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..b9d2467c5092233d4a4b74072162cf6169cff33a --- /dev/null +++ b/AppColdStart/library/Index.ets @@ -0,0 +1,19 @@ +/* +* Copyright (C) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + +// [Start not_recommend_demo] +export { MainPage } from './src/main/ets/components/mainpage/MainPage'; // Cold start strong related files +export { SubPage } from './src/main/ets/components/mainpage/SubPage'; // Non-cold start strong related files +// [End not_recommend_demo] diff --git a/AppColdStart/HapAndHarDependHar/library/IndexAppStart.ets b/AppColdStart/library/IndexAppStart.ets similarity index 100% rename from AppColdStart/HapAndHarDependHar/library/IndexAppStart.ets rename to AppColdStart/library/IndexAppStart.ets diff --git a/AppColdStart/HapAndHarDependHar/library/IndexOthers.ets b/AppColdStart/library/IndexOthers.ets similarity index 100% rename from AppColdStart/HapAndHarDependHar/library/IndexOthers.ets rename to AppColdStart/library/IndexOthers.ets diff --git a/AppColdStart/HapAndHarDependHar/har_common/build-profile.json5 b/AppColdStart/library/build-profile.json5 similarity index 100% rename from AppColdStart/HapAndHarDependHar/har_common/build-profile.json5 rename to AppColdStart/library/build-profile.json5 diff --git a/AppColdStart/HapAndHarDependHar/har_common/consumer-rules.txt b/AppColdStart/library/consumer-rules.txt similarity index 100% rename from AppColdStart/HapAndHarDependHar/har_common/consumer-rules.txt rename to AppColdStart/library/consumer-rules.txt diff --git a/AppColdStart/HapAndHarDependHar/har_common/hvigorfile.ts b/AppColdStart/library/hvigorfile.ts similarity index 100% rename from AppColdStart/HapAndHarDependHar/har_common/hvigorfile.ts rename to AppColdStart/library/hvigorfile.ts diff --git a/AppColdStart/HapAndHarDependHar/entry/obfuscation-rules.txt b/AppColdStart/library/obfuscation-rules.txt similarity index 100% rename from AppColdStart/HapAndHarDependHar/entry/obfuscation-rules.txt rename to AppColdStart/library/obfuscation-rules.txt diff --git a/AppColdStart/library/oh-package.json5 b/AppColdStart/library/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..0651f82cdedfec5fbf293e03a9158fb88cfc40a6 --- /dev/null +++ b/AppColdStart/library/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "name": "library", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "Index.ets", + "author": "", + "license": "Apache-2.0", + "dependencies": { + } +} diff --git a/AppColdStart/HapAndHarDependHar/library/src/main/ets/components/mainpage/MainPage.ets b/AppColdStart/library/src/main/ets/components/mainpage/MainPage.ets similarity index 100% rename from AppColdStart/HapAndHarDependHar/library/src/main/ets/components/mainpage/MainPage.ets rename to AppColdStart/library/src/main/ets/components/mainpage/MainPage.ets diff --git a/AppColdStart/library/src/main/ets/components/mainpage/SubPage.ets b/AppColdStart/library/src/main/ets/components/mainpage/SubPage.ets new file mode 100644 index 0000000000000000000000000000000000000000..437d9c689926a8268a21907ed2284aac0d4281b7 --- /dev/null +++ b/AppColdStart/library/src/main/ets/components/mainpage/SubPage.ets @@ -0,0 +1,31 @@ +// [Start not_recommend_demo] +// library/src/main/ets/components/mainpage/SubPage.ets +// Global time-consuming functions in SubPage +const LARGE_NUMBER: number = 10000000; + +function computeTask(): number { + let count: number = 0; + while (count < LARGE_NUMBER) { + count++; + } + return count; +} + +computeTask(); +// ... +// [End not_recommend_demo] +@Component +export struct SubPage { + @Consume pathStack: NavPathStack; + @State message: string = 'HAR SubPage'; + + build() { + Row() { + Text(this.message) + .fontSize(32) + .fontWeight(FontWeight.Bold) + }.onClick(() => { + this.pathStack.pushPath({ name: 'SecondPage' }); + }) + } +} \ No newline at end of file diff --git a/AppColdStart/library/src/main/module.json5 b/AppColdStart/library/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..dd30f8e0de7154e00da5009b23df656940652a64 --- /dev/null +++ b/AppColdStart/library/src/main/module.json5 @@ -0,0 +1,11 @@ +{ + "module": { + "name": "library", + "type": "har", + "deviceTypes": [ + "default", + "tablet", + "2in1" + ] + } +} diff --git a/AppColdStart/HapAndHarDependHar/har_common/src/main/resources/base/element/string.json b/AppColdStart/library/src/main/resources/base/element/string.json similarity index 100% rename from AppColdStart/HapAndHarDependHar/har_common/src/main/resources/base/element/string.json rename to AppColdStart/library/src/main/resources/base/element/string.json diff --git a/AppColdStart/HapAndHarDependHar/library/src/main/resources/base/element/string.json b/AppColdStart/library/src/main/resources/en_US/element/string.json similarity index 100% rename from AppColdStart/HapAndHarDependHar/library/src/main/resources/base/element/string.json rename to AppColdStart/library/src/main/resources/en_US/element/string.json diff --git a/AppColdStart/HapAndHarDependHar/library/src/main/resources/en_US/element/string.json b/AppColdStart/library/src/main/resources/zh_CN/element/string.json similarity index 100% rename from AppColdStart/HapAndHarDependHar/library/src/main/resources/en_US/element/string.json rename to AppColdStart/library/src/main/resources/zh_CN/element/string.json diff --git a/AppColdStart/oh-package-lock.json5 b/AppColdStart/oh-package-lock.json5 deleted file mode 100644 index 7fcf818273347b97063c0c0a151bb14770ca1c79..0000000000000000000000000000000000000000 --- a/AppColdStart/oh-package-lock.json5 +++ /dev/null @@ -1,27 +0,0 @@ -{ - "meta": { - "stableOrder": true - }, - "lockfileVersion": 3, - "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", - "specifiers": { - "@ohos/hamock@1.0.0": "@ohos/hamock@1.0.0", - "@ohos/hypium@1.0.21": "@ohos/hypium@1.0.21" - }, - "packages": { - "@ohos/hamock@1.0.0": { - "name": "@ohos/hamock", - "version": "1.0.0", - "integrity": "sha512-K6lDPYc6VkKe6ZBNQa9aoG+ZZMiwqfcR/7yAVFSUGIuOAhPvCJAo9+t1fZnpe0dBRBPxj2bxPPbKh69VuyAtDg==", - "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hamock/-/hamock-1.0.0.har", - "registryType": "ohpm" - }, - "@ohos/hypium@1.0.21": { - "name": "@ohos/hypium", - "version": "1.0.21", - "integrity": "sha512-iyKGMXxE+9PpCkqEwu0VykN/7hNpb+QOeIuHwkmZnxOpI+dFZt6yhPB7k89EgV1MiSK/ieV/hMjr5Z2mWwRfMQ==", - "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hypium/-/hypium-1.0.21.har", - "registryType": "ohpm" - } - } -} \ No newline at end of file diff --git a/AppColdStart/oh-package.json5 b/AppColdStart/oh-package.json5 index a8aff0c5aff22d78aa26fd19c3861f4320e951ff..2d9c74ff34f1383ec920815a40399dd0fe46a6c5 100644 --- a/AppColdStart/oh-package.json5 +++ b/AppColdStart/oh-package.json5 @@ -4,7 +4,5 @@ "dependencies": { }, "devDependencies": { - "@ohos/hypium": "1.0.21", - "@ohos/hamock": "1.0.0" } } diff --git a/AppDataSecurity/README.md b/AppDataSecurity/README.md index 08b246b6a4c69cd627abdcec9ee9092e8735af2b..7cb0831413ddac5cfa4fd99b1b4e1641632fd496 100644 --- a/AppDataSecurity/README.md +++ b/AppDataSecurity/README.md @@ -3,6 +3,17 @@ ### 简介 本示例实现了获取文件路径以及通用密钥库加解密算法。 +### 效果图 +| 首页 | +|----------------------------------------------------| +| | + +### 使用说明 +1. 点击获取通用文件路径获取el2文件路径。 +2. 点击获取EL1文件路径获取el1文件路径。 +3. 点击加密会执行加密算法,可通过日志查看加密结果。 +4. 点击解密对加密的数据进行解密,可通过日志查看解密结果。 + ### 工程目录 ``` ├──entry/src/main/ets/ @@ -27,8 +38,19 @@ 1. 本示例仅支持标准系统上运行,支持设备:华为手机。 -2. HarmonyOS系统:HarmonyOS NEXT Release及以上。 +2. HarmonyOS系统:HarmonyOS 5.0.5 Release及以上。 + +3. DevEco Studio版本:DevEco Studio 5.0.5 Release及以上。 -3. DevEco Studio版本:DevEco Studio NEXT Release及以上。 +4. HarmonyOS SDK版本:HarmonyOS 5.0.5 Release SDK及以上。 -4. HarmonyOS SDK版本:HarmonyOS NEXT Release SDK及以上。 \ No newline at end of file +### 下载 + +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set AppDataSecurity +git checkout +``` \ No newline at end of file diff --git a/AppDataSecurity/README_EN.md b/AppDataSecurity/README_EN.md index 65d2d7ccdd092b4f11acbc14d12c510339068001..d4e1e5d587088ed9e2093093b9c9f5eb6553e3d6 100644 --- a/AppDataSecurity/README_EN.md +++ b/AppDataSecurity/README_EN.md @@ -3,6 +3,11 @@ ### Overview This sample implements file paths and HUKS encryption/decryption algorithm. +### Effect +| Home Page | +|-------------------------------------------------------| +| | + ### Project Directory ``` ├──entry/src/main/ets/ @@ -32,3 +37,14 @@ N/A 3. The DevEco Studio version must be DevEco Studio NEXT Release or later. 4. The HarmonyOS SDK version must be HarmonyOS NEXT Release SDK or later. + +### Download + +To download this project separately, execute the following command: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set AppDataSecurity +git checkout +``` diff --git a/AppDataSecurity/build-profile.json5 b/AppDataSecurity/build-profile.json5 index 1e69556b3411622cb2e87a87389653bb34f1b148..9e87e7e6f19020fe21192844709f192cec80fd44 100644 --- a/AppDataSecurity/build-profile.json5 +++ b/AppDataSecurity/build-profile.json5 @@ -5,7 +5,8 @@ { "name": "default", "signingConfig": "default", - "compatibleSdkVersion": "5.0.0(12)", + "targetSdkVersion": "5.0.5(17)", + "compatibleSdkVersion": "5.0.5(17)", "runtimeOS": "HarmonyOS", "buildOption": { "strictMode": { diff --git a/AppDataSecurity/entry/src/main/ets/pages/Index.ets b/AppDataSecurity/entry/src/main/ets/pages/Index.ets index 3574ed8a8f6ac64de5ecd52c7ccca64bc73814fa..2baf55383cc4e367ea0f6de1dd430508bdbce339 100644 --- a/AppDataSecurity/entry/src/main/ets/pages/Index.ets +++ b/AppDataSecurity/entry/src/main/ets/pages/Index.ets @@ -65,7 +65,7 @@ struct Index { } // [Start get_el2_path] - getEl2Path() { + getEl2Path(): void { let context = this.getUIContext().getHostContext() as common.UIAbilityContext; context.area = contextConstant.AreaMode.EL2; let filePath = context.filesDir + '/health_data.txt'; @@ -74,7 +74,7 @@ struct Index { // [End get_el2_path] // [Start get_el1_path] - getEl1Path() { + getEl1Path(): void { let context = this.getUIContext().getHostContext() as common.UIAbilityContext; context.area = contextConstant.AreaMode.EL1; let filePath = context.filesDir + '/health_data.txt'; @@ -83,51 +83,60 @@ struct Index { // [End get_el1_path] } -let aesKeyAlias = 'test_aesKeyAlias'; +let aesKeyAlias: string = 'test_aesKeyAlias'; let handle: number; -let plainText = '123456'; -let IV = '001122334455'; +let plainText: string = '123456'; +let IV: string = '001122334455'; let cipherData: Uint8Array; // [Start write_file] -function writeFile(filePath: string, data: string) { - let file = fileIo.openSync(filePath, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE); - let writeLen = fileIo.writeSync(file.fd, data); - hilog.info(0x0000, 'AppDataSecurity', 'The length of str is: ' + writeLen); - fileIo.closeSync(file); +function writeFile(filePath: string, data: string): void { + try { + let file = fileIo.openSync(filePath, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE); + let writeLen = fileIo.writeSync(file.fd, data); + hilog.info(0x0000, 'AppDataSecurity', 'The length of str is: ' + writeLen); + fileIo.closeSync(file); + } catch (error) { + hilog.error(0x0000, 'AppDataSecurity', `writeFile error ${JSON.stringify(error)}`); + } } function readFile(filePath: string): string { - let file = fileIo.openSync(filePath, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE); - let arrayBuffer = new ArrayBuffer(1024); + try { + let file = fileIo.openSync(filePath, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE); + let arrayBuffer = new ArrayBuffer(1024); - class Option { - public offset: number = 0; - public length: number = 0; - } + class Option { + public offset: number = 0; + public length: number = 0; + } - let option = new Option(); - option.length = arrayBuffer.byteLength; - let readLen = fileIo.readSync(file.fd, arrayBuffer, option); - let buf = buffer.from(arrayBuffer, 0, readLen); - hilog.info(0x0000, 'AppDataSecurity', `The length of of file: ${readLen}`); - fileIo.closeSync(file); - return buf.toString(); + let option = new Option(); + option.length = arrayBuffer.byteLength; + let readLen = fileIo.readSync(file.fd, arrayBuffer, option); + let buf = buffer.from(arrayBuffer, 0, readLen); + hilog.info(0x0000, 'AppDataSecurity', `The length of of file: ${readLen}`); + fileIo.closeSync(file); + return buf.toString(); + } catch (error) { + hilog.error(0x0000, 'AppDataSecurity', `readFile error ${JSON.stringify(error)}`); + } + return ''; } // [End write_file] -function StringToUint8Array(str: string) { +function StringToUint8Array(str: string): Uint8Array { let textEncoder = util.TextEncoder.create('utf-8'); return textEncoder.encodeInto(str); } -function Uint8ArrayToString(fileData: Uint8Array) { +function Uint8ArrayToString(fileData: Uint8Array): string { let textDecoder = util.TextDecoder.create('utf-8'); return textDecoder.decodeToString(fileData); } // [Start get_aes_generate_properties] -function GetAesGenerateProperties() { +function GetAesGenerateProperties(): Array { let properties: Array = [{ tag: huks.HuksTag.HUKS_TAG_ALGORITHM, value: huks.HuksKeyAlg.HUKS_ALG_AES @@ -144,7 +153,7 @@ function GetAesGenerateProperties() { // [End get_aes_generate_properties] // [Start get_aes_encrypt_properties] -function GetAesEncryptProperties() { +function GetAesEncryptProperties(): Array { let properties: Array = [{ tag: huks.HuksTag.HUKS_TAG_ALGORITHM, value: huks.HuksKeyAlg.HUKS_ALG_AES @@ -169,7 +178,7 @@ function GetAesEncryptProperties() { // [End get_aes_encrypt_properties] // [Start get_aes_decrypt_properties] -function GetAesDecryptProperties() { +function GetAesDecryptProperties(): Array { let properties: Array = [{ tag: huks.HuksTag.HUKS_TAG_ALGORITHM, value: huks.HuksKeyAlg.HUKS_ALG_AES @@ -194,7 +203,7 @@ function GetAesDecryptProperties() { // [End get_aes_decrypt_properties] // [Start generate_aes_key] -async function GenerateAesKey() { +async function GenerateAesKey(): Promise { let genProperties = GetAesGenerateProperties(); let options: huks.HuksOptions = { properties: genProperties @@ -210,7 +219,7 @@ async function GenerateAesKey() { // [End generate_aes_key] // [Start encrypt_data] -async function EncryptData() { +async function EncryptData(): Promise { let encryptProperties = GetAesEncryptProperties(); let options: huks.HuksOptions = { properties: encryptProperties, @@ -234,7 +243,7 @@ async function EncryptData() { }) } -async function DecryptData() { +async function DecryptData(): Promise { let decryptOptions = GetAesDecryptProperties() let options: huks.HuksOptions = { properties: decryptOptions, @@ -258,7 +267,7 @@ async function DecryptData() { } // [End encrypt_data] -async function DeleteKey() { +async function DeleteKey(): Promise { let emptyOptions: huks.HuksOptions = { properties: [] }; diff --git a/AppDataSecurity/screenshots/device/phone.png b/AppDataSecurity/screenshots/device/phone.png new file mode 100644 index 0000000000000000000000000000000000000000..15a61b5893983d1104c8cc40ed8ad12bf2da9d67 Binary files /dev/null and b/AppDataSecurity/screenshots/device/phone.png differ diff --git a/AppDataSecurity/screenshots/device/phone_en.png b/AppDataSecurity/screenshots/device/phone_en.png new file mode 100644 index 0000000000000000000000000000000000000000..c12d6edaa7358a46bbf4baca21f0cc8266dd2d8f Binary files /dev/null and b/AppDataSecurity/screenshots/device/phone_en.png differ diff --git a/AppFreeze/AppScope/app.json5 b/AppFreeze/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..e2a0e082396a57f4f87681236b885cf552741164 --- /dev/null +++ b/AppFreeze/AppScope/app.json5 @@ -0,0 +1,10 @@ +{ + "app": { + "bundleName": "com.example.appfreeze", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:layered_image", + "label": "$string:app_name" + } +} diff --git a/AppFreeze/AppScope/resources/base/element/string.json b/AppFreeze/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..3bd6025d487422080411763227a3a4ae82611c4e --- /dev/null +++ b/AppFreeze/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "AppFreeze" + } + ] +} diff --git a/MultiCommunityApplication/AppScope/resources/base/media/background.png b/AppFreeze/AppScope/resources/base/media/background.png similarity index 100% rename from MultiCommunityApplication/AppScope/resources/base/media/background.png rename to AppFreeze/AppScope/resources/base/media/background.png diff --git a/MultiCommunityApplication/products/phone/src/main/resources/base/media/foreground.png b/AppFreeze/AppScope/resources/base/media/foreground.png similarity index 100% rename from MultiCommunityApplication/products/phone/src/main/resources/base/media/foreground.png rename to AppFreeze/AppScope/resources/base/media/foreground.png diff --git a/AppColdStart/HapAndHarDependHar/entry/src/main/resources/base/media/layered_image.json b/AppFreeze/AppScope/resources/base/media/layered_image.json similarity index 100% rename from AppColdStart/HapAndHarDependHar/entry/src/main/resources/base/media/layered_image.json rename to AppFreeze/AppScope/resources/base/media/layered_image.json diff --git a/AppFreeze/README.md b/AppFreeze/README.md new file mode 100644 index 0000000000000000000000000000000000000000..8cb68c28187503ad3e13fe6f54c32343f33c7596 --- /dev/null +++ b/AppFreeze/README.md @@ -0,0 +1,62 @@ +# 应用冻屏(AppFreeze)样例代码工程 + +### 介绍 + +本示例为应用冻屏(AppFreeze)样例代码工程,包含最佳实践文档中涉及的分析方法、优化建议、问题案例等内容的局部样例代码。工程本身不具备实际功能,开发者请直接阅读具体源码结合文档来理解应用冻屏(AppFreeze)类问题的产生原因,规避方法等。 + + +### 效果预览 + +不涉及 + +### 工程目录 +``` +├──entry/src/main +│ ├──cpp +│ │ └──pages +│ │ ├──CMakeLists.txt +│ │ ├──napi_init.txt // C++ init示例代码 +│ │ └──AppFreezeCase.cpp // C++ 样例代码 +│ └──ets +│ ├──pages +│ │ ├──appfreezecase.ets // ArkTS样例代码 +│ │ └──Index.ets // 首页 +│ ├──entryability +│ │ └──EntryAbility.ets // Ability的生命周期回调内容 +│ └──entrybackupability +│ └──EntryBackupAbility.ets // 应用数据备份恢复类 +└──entry/src/main/resources // 应用资源目录 +``` + +### 具体实现 + +不涉及。 + +### 相关权限 + +不涉及。 + +### 依赖 + +不涉及。 + +### 约束与限制 + +1. 本示例仅支持标准系统上运行,支持设备:华为手机、华为PC/2in1设备、华为平板。 + +2. HarmonyOS系统:HarmonyOS NEXT 5.0.5 Release及以上。 + +3. DevEco Studio版本:DevEco Studio NEXT 5.0.5 Release及以上。 + +4. HarmonyOS SDK版本:HarmonyOS NEXT 5.0.5 Release SDK及以上。 + +### 下载 + +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set AppFreeze +git checkout +``` \ No newline at end of file diff --git a/AppFreeze/build-profile.json5 b/AppFreeze/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..9e87e7e6f19020fe21192844709f192cec80fd44 --- /dev/null +++ b/AppFreeze/build-profile.json5 @@ -0,0 +1,42 @@ +{ + "app": { + "signingConfigs": [], + "products": [ + { + "name": "default", + "signingConfig": "default", + "targetSdkVersion": "5.0.5(17)", + "compatibleSdkVersion": "5.0.5(17)", + "runtimeOS": "HarmonyOS", + "buildOption": { + "strictMode": { + "caseSensitiveCheck": true, + "useNormalizedOHMUrl": true + } + } + } + ], + "buildModeSet": [ + { + "name": "debug", + }, + { + "name": "release" + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/ArkUI/UI_Component_Performance_Optimization/code-linter.json5 b/AppFreeze/code-linter.json5 similarity index 100% rename from ArkUI/UI_Component_Performance_Optimization/code-linter.json5 rename to AppFreeze/code-linter.json5 diff --git a/AppColdStart/entry/.gitignore b/AppFreeze/entry/.gitignore similarity index 100% rename from AppColdStart/entry/.gitignore rename to AppFreeze/entry/.gitignore diff --git a/NativeSoIntegration/Ndk/build-profile.json5 b/AppFreeze/entry/build-profile.json5 similarity index 100% rename from NativeSoIntegration/Ndk/build-profile.json5 rename to AppFreeze/entry/build-profile.json5 diff --git a/AppColdStart/HapAndHarDependHar/entry/hvigorfile.ts b/AppFreeze/entry/hvigorfile.ts similarity index 100% rename from AppColdStart/HapAndHarDependHar/entry/hvigorfile.ts rename to AppFreeze/entry/hvigorfile.ts diff --git a/NativeSoIntegration/Ndk/obfuscation-rules.txt b/AppFreeze/entry/obfuscation-rules.txt similarity index 100% rename from NativeSoIntegration/Ndk/obfuscation-rules.txt rename to AppFreeze/entry/obfuscation-rules.txt diff --git a/UseSendable/entry/oh-package-lock.json5 b/AppFreeze/entry/oh-package-lock.json5 similarity index 100% rename from UseSendable/entry/oh-package-lock.json5 rename to AppFreeze/entry/oh-package-lock.json5 diff --git a/AppFreeze/entry/oh-package.json5 b/AppFreeze/entry/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..54cb066266f9993f5a023f2ac5a8dfc5d2574643 --- /dev/null +++ b/AppFreeze/entry/oh-package.json5 @@ -0,0 +1,11 @@ +{ + "name": "entry", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "", + "author": "", + "license": "", + "dependencies": { + "libentry.so": "file:./src/main/cpp/types/libentry" + } +} \ No newline at end of file diff --git a/AppFreeze/entry/src/main/cpp/AppFreezeCase.cpp b/AppFreeze/entry/src/main/cpp/AppFreezeCase.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2edf7ba5785dba8d46a2c438c5dc4466daf52d15 --- /dev/null +++ b/AppFreeze/entry/src/main/cpp/AppFreezeCase.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ +/** + * 最佳实践:AppFreeze 类问题优化建议 + */ + +#include +#include +#include + +std::mutex mtx; +std::vector sharedVec; + +// [Start appfreeze_advise1] +bool ContainTarget(int target) { + auto ret = std::find(sharedVec.begin(), sharedVec.end(), target); + if (ret == sharedVec.end()) { + return false; + } + return true; +} + +int AppFreezeAdvise1() { + // ... + mtx.lock(); + if (ContainTarget(1)) { + return -1; + // 没有释放锁 + } + // 没有释放锁 + return 0; +} +// [End appfreeze_advise1] + + +/** + * 最佳实践:AppFreeze 类问题案例 + */ + +// [Start appfreeze_case_1_negative] +int AppFreezeAdviseNegative() { + // ... + mtx.lock(); + if (ContainTarget(1)) { + return -1; + } + // ... + return 0; +} +// [End appfreeze_case_1_negative] + +// [Start appfreeze_case_1_positive] +int AppFreezeAdvisePositive() { + // ... + mtx.lock(); + if (ContainTarget(1)) { + mtx.unlock(); + return -1; + } + mtx.unlock(); + // ... + return 0; +} +// [End appfreeze_case_1_positive] \ No newline at end of file diff --git a/AppFreeze/entry/src/main/cpp/CMakeLists.txt b/AppFreeze/entry/src/main/cpp/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..3f9027b26132982df2949b3071b856ace4fa75cb --- /dev/null +++ b/AppFreeze/entry/src/main/cpp/CMakeLists.txt @@ -0,0 +1,15 @@ +# the minimum version of CMake. +cmake_minimum_required(VERSION 3.5.0) +project(CppCrash) + +set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}) + +if(DEFINED PACKAGE_FIND_FILE) + include(${PACKAGE_FIND_FILE}) +endif() + +include_directories(${NATIVERENDER_ROOT_PATH} + ${NATIVERENDER_ROOT_PATH}/include) + +add_library(entry SHARED napi_init.cpp AppFreezeCase.cpp) +target_link_libraries(entry PUBLIC libace_napi.z.so) \ No newline at end of file diff --git a/AppFreeze/entry/src/main/cpp/napi_init.cpp b/AppFreeze/entry/src/main/cpp/napi_init.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d0e1aafcb6b5c3252ef439d9d9d54e8c082fda1d --- /dev/null +++ b/AppFreeze/entry/src/main/cpp/napi_init.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + +#include "napi/native_api.h" + +static napi_value Add(napi_env env, napi_callback_info info) +{ + size_t argc = 2; + napi_value args[2] = {nullptr}; + + napi_get_cb_info(env, info, &argc, args , nullptr, nullptr); + + napi_valuetype valuetype0; + napi_typeof(env, args[0], &valuetype0); + + napi_valuetype valuetype1; + napi_typeof(env, args[1], &valuetype1); + + double value0; + napi_get_value_double(env, args[0], &value0); + + double value1; + napi_get_value_double(env, args[1], &value1); + + napi_value sum; + napi_create_double(env, value0 + value1, &sum); + + return sum; + +} + +EXTERN_C_START +static napi_value Init(napi_env env, napi_value exports) +{ + napi_property_descriptor desc[] = { + { "add", nullptr, Add, nullptr, nullptr, nullptr, napi_default, nullptr } + }; + napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); + return exports; +} +EXTERN_C_END + +static napi_module demoModule = { + .nm_version = 1, + .nm_flags = 0, + .nm_filename = nullptr, + .nm_register_func = Init, + .nm_modname = "entry", + .nm_priv = ((void*)0), + .reserved = { 0 }, +}; + +extern "C" __attribute__((constructor)) void RegisterEntryModule(void) +{ + napi_module_register(&demoModule); +} diff --git a/NativeSoIntegration/Ndk/src/main/cpp/types/libentry/Index.d.ts b/AppFreeze/entry/src/main/cpp/types/libentry/index.d.ts similarity index 100% rename from NativeSoIntegration/Ndk/src/main/cpp/types/libentry/Index.d.ts rename to AppFreeze/entry/src/main/cpp/types/libentry/index.d.ts diff --git a/AppFreeze/entry/src/main/cpp/types/libentry/oh-package.json5 b/AppFreeze/entry/src/main/cpp/types/libentry/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..17f2fec28b34ad5d42507c4fa15c7e4d0d16eb70 --- /dev/null +++ b/AppFreeze/entry/src/main/cpp/types/libentry/oh-package.json5 @@ -0,0 +1,6 @@ +{ + "name": "libentry.so", + "types": "./index.d.ts", + "version": "1.0.0", + "description": "Please describe the basic information." +} \ No newline at end of file diff --git a/AppFreeze/entry/src/main/ets/entryability/EntryAbility.ets b/AppFreeze/entry/src/main/ets/entryability/EntryAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..a7e8ad07979614ccfe122b70e0ccd7306acaef68 --- /dev/null +++ b/AppFreeze/entry/src/main/ets/entryability/EntryAbility.ets @@ -0,0 +1,48 @@ +import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; + +const DOMAIN = 0x0000; + +export default class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + try { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + } catch (err) { + hilog.info(DOMAIN, 'testTag', '%{public}s', 'setColorMode fail'); + } + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onDestroy(): void { + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + // Main window is created, set main page for this ability + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + windowStage.loadContent('pages/Index', (err) => { + if (err.code) { + hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err)); + return; + } + hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.'); + }); + } + + onWindowStageDestroy(): void { + // Main window is destroyed, release UI related resources + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground(): void { + // Ability has brought to foreground + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground(): void { + // Ability has back to background + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground'); + } +} \ No newline at end of file diff --git a/AppFreeze/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets b/AppFreeze/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e4de99282050bad799ac892eb85ac5449364a51 --- /dev/null +++ b/AppFreeze/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets @@ -0,0 +1,16 @@ +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit'; + +const DOMAIN = 0x0000; + +export default class EntryBackupAbility extends BackupExtensionAbility { + async onBackup() { + hilog.info(DOMAIN, 'testTag', 'onBackup ok'); + await Promise.resolve(); + } + + async onRestore(bundleVersion: BundleVersion) { + hilog.info(DOMAIN, 'testTag', 'onRestore ok %{public}s', JSON.stringify(bundleVersion)); + await Promise.resolve(); + } +} \ No newline at end of file diff --git a/AppFreeze/entry/src/main/ets/pages/Index.ets b/AppFreeze/entry/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..0f481f696485b8c840d49ad9e7d7dff7f6b71241 --- /dev/null +++ b/AppFreeze/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + +@Entry +@Component +struct Index { + @State message: string = 'Hello World'; + + build() { + RelativeContainer() { + Text(this.message) + .id('HelloWorld') + .fontSize($r('app.float.page_text_font_size')) + .fontWeight(FontWeight.Bold) + .alignRules({ + center: { anchor: '__container__', align: VerticalAlign.Center }, + middle: { anchor: '__container__', align: HorizontalAlign.Center } + }) + .onClick(() => { + this.message = 'Welcome'; + }) + } + .height('100%') + .width('100%') + } +} \ No newline at end of file diff --git a/AppFreeze/entry/src/main/ets/pages/appfreezecase.ets b/AppFreeze/entry/src/main/ets/pages/appfreezecase.ets new file mode 100644 index 0000000000000000000000000000000000000000..3dca8efbfe7ec84ca112e48cf56decc5945cc800 --- /dev/null +++ b/AppFreeze/entry/src/main/ets/pages/appfreezecase.ets @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ +/** + * 最佳实践:应用冻屏优化建议 + */ + +import fs from '@ohos.file.fs'; + +@Component +struct ItemType { + @State xxx1 : number = 1; + @State xxx2 : number = 2; + @State themeStyle : string = "xxx"; + + build() {} +} + +// [Start appfreeze_advise2] +function getForeachKey(item : ItemType) : string { + // ... + return `${item.xxx2}${item.xxx2}...${item.themeStyle}`; +} // 这部分逻辑如果较为耗时,执行次数多,总时长就是发生冻屏的耗时操作 +// [End appfreeze_advise2] + +/** + * 最佳实践:应用冻屏优化建议 + */ + +// [Start appfreeze_advise3] +function xxxFunction1(fileUris : string[]): void { + // ... + for (const fileuri of fileUris) { + let file = fs.openSync(fileuri, fs.OpenMode.READ_ONLY); + // ... + } + // ... +} // 如果使用同步操作,需要考虑到容器弱网或无网等极端情况发生 +// [End appfreeze_advise3] + +// [Start appfreeze_case_3_positive] +async function xxxFunction2(fileUris : string[]) : Promise { + // ... + AppStorage.setOrCreate('isLoadingPic', true); // 用于页面load效果展示 + for (const fileuri of fileUris) { + let file = await fs.openSync(fileuri, fs.OpenMode.READ_ONLY); // 改为异步加载 + // ... + } + // ... +} +// [End appfreeze_case_3_positive] \ No newline at end of file diff --git a/AppFreeze/entry/src/main/module.json5 b/AppFreeze/entry/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a1cea8b6a4560cee7bda7a2db52f310c035ab6c8 --- /dev/null +++ b/AppFreeze/entry/src/main/module.json5 @@ -0,0 +1,52 @@ +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ets", + "description": "$string:EntryAbility_desc", + "icon": "$media:layered_image", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:startIcon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ], + "extensionAbilities": [ + { + "name": "EntryBackupAbility", + "srcEntry": "./ets/entrybackupability/EntryBackupAbility.ets", + "type": "backup", + "exported": false, + "metadata": [ + { + "name": "ohos.extension.backup", + "resource": "$profile:backup_config" + } + ], + } + ] + } +} \ No newline at end of file diff --git a/AppColdStart/HapAndHarDependHar/entry/src/main/resources/base/element/color.json b/AppFreeze/entry/src/main/resources/base/element/color.json similarity index 100% rename from AppColdStart/HapAndHarDependHar/entry/src/main/resources/base/element/color.json rename to AppFreeze/entry/src/main/resources/base/element/color.json diff --git a/NativeSoIntegration/Ndk/src/main/resources/base/element/float.json b/AppFreeze/entry/src/main/resources/base/element/float.json similarity index 100% rename from NativeSoIntegration/Ndk/src/main/resources/base/element/float.json rename to AppFreeze/entry/src/main/resources/base/element/float.json diff --git a/AppColdStart/HapAndHarDependHar/entry/src/main/resources/base/element/string.json b/AppFreeze/entry/src/main/resources/base/element/string.json similarity index 100% rename from AppColdStart/HapAndHarDependHar/entry/src/main/resources/base/element/string.json rename to AppFreeze/entry/src/main/resources/base/element/string.json diff --git a/MultiCommunityApplication/products/phone/src/main/resources/base/media/background.png b/AppFreeze/entry/src/main/resources/base/media/background.png similarity index 100% rename from MultiCommunityApplication/products/phone/src/main/resources/base/media/background.png rename to AppFreeze/entry/src/main/resources/base/media/background.png diff --git a/MultiVideoApplication/AppScope/resources/base/media/foreground.png b/AppFreeze/entry/src/main/resources/base/media/foreground.png similarity index 100% rename from MultiVideoApplication/AppScope/resources/base/media/foreground.png rename to AppFreeze/entry/src/main/resources/base/media/foreground.png diff --git a/CrossPlatformCompatibility/entry/src/main/resources/base/media/layered_image.json b/AppFreeze/entry/src/main/resources/base/media/layered_image.json similarity index 100% rename from CrossPlatformCompatibility/entry/src/main/resources/base/media/layered_image.json rename to AppFreeze/entry/src/main/resources/base/media/layered_image.json diff --git a/AppColdStart/HapAndHarDependHar/entry/src/main/resources/base/media/startIcon.png b/AppFreeze/entry/src/main/resources/base/media/startIcon.png similarity index 100% rename from AppColdStart/HapAndHarDependHar/entry/src/main/resources/base/media/startIcon.png rename to AppFreeze/entry/src/main/resources/base/media/startIcon.png diff --git a/MultMusicHome/products/phone/src/main/resources/base/profile/backup_config.json b/AppFreeze/entry/src/main/resources/base/profile/backup_config.json similarity index 100% rename from MultMusicHome/products/phone/src/main/resources/base/profile/backup_config.json rename to AppFreeze/entry/src/main/resources/base/profile/backup_config.json diff --git a/AppColdStart/HapAndHarDependHar/entry/src/main/resources/base/profile/main_pages.json b/AppFreeze/entry/src/main/resources/base/profile/main_pages.json similarity index 100% rename from AppColdStart/HapAndHarDependHar/entry/src/main/resources/base/profile/main_pages.json rename to AppFreeze/entry/src/main/resources/base/profile/main_pages.json diff --git a/AppFreeze/entry/src/main/resources/dark/element/color.json b/AppFreeze/entry/src/main/resources/dark/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..79b11c2747aec33e710fd3a7b2b3c94dd9965499 --- /dev/null +++ b/AppFreeze/entry/src/main/resources/dark/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#000000" + } + ] +} \ No newline at end of file diff --git a/AppColdStart/entry/src/mock/mock-config.json5 b/AppFreeze/entry/src/mock/mock-config.json5 similarity index 100% rename from AppColdStart/entry/src/mock/mock-config.json5 rename to AppFreeze/entry/src/mock/mock-config.json5 diff --git a/ApiUsingStandards/entry/src/ohosTest/ets/test/Ability.test.ets b/AppFreeze/entry/src/ohosTest/ets/test/Ability.test.ets similarity index 100% rename from ApiUsingStandards/entry/src/ohosTest/ets/test/Ability.test.ets rename to AppFreeze/entry/src/ohosTest/ets/test/Ability.test.ets diff --git a/ApiUsingStandards/entry/src/ohosTest/ets/test/List.test.ets b/AppFreeze/entry/src/ohosTest/ets/test/List.test.ets similarity index 100% rename from ApiUsingStandards/entry/src/ohosTest/ets/test/List.test.ets rename to AppFreeze/entry/src/ohosTest/ets/test/List.test.ets diff --git a/ApiUsingStandards/entry/src/ohosTest/module.json5 b/AppFreeze/entry/src/ohosTest/module.json5 similarity index 100% rename from ApiUsingStandards/entry/src/ohosTest/module.json5 rename to AppFreeze/entry/src/ohosTest/module.json5 diff --git a/ApiUsingStandards/entry/src/test/List.test.ets b/AppFreeze/entry/src/test/List.test.ets similarity index 100% rename from ApiUsingStandards/entry/src/test/List.test.ets rename to AppFreeze/entry/src/test/List.test.ets diff --git a/ApiUsingStandards/entry/src/test/LocalUnit.test.ets b/AppFreeze/entry/src/test/LocalUnit.test.ets similarity index 100% rename from ApiUsingStandards/entry/src/test/LocalUnit.test.ets rename to AppFreeze/entry/src/test/LocalUnit.test.ets diff --git a/AppFreeze/hvigor/hvigor-config.json5 b/AppFreeze/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..5bebc9755447385d82ce4138f54d991b1f85f348 --- /dev/null +++ b/AppFreeze/hvigor/hvigor-config.json5 @@ -0,0 +1,22 @@ +{ + "modelVersion": "5.0.5", + "dependencies": { + }, + "execution": { + // "analyze": "normal", /* Define the build analyze mode. Value: [ "normal" | "advanced" | false ]. Default: "normal" */ + // "daemon": true, /* Enable daemon compilation. Value: [ true | false ]. Default: true */ + // "incremental": true, /* Enable incremental compilation. Value: [ true | false ]. Default: true */ + // "parallel": true, /* Enable parallel compilation. Value: [ true | false ]. Default: true */ + // "typeCheck": false, /* Enable typeCheck. Value: [ true | false ]. Default: false */ + }, + "logging": { + // "level": "info" /* Define the log level. Value: [ "debug" | "info" | "warn" | "error" ]. Default: "info" */ + }, + "debugging": { + // "stacktrace": false /* Disable stacktrace compilation. Value: [ true | false ]. Default: false */ + }, + "nodeOptions": { + // "maxOldSpaceSize": 8192 /* Enable nodeOptions maxOldSpaceSize compilation. Unit M. Used for the daemon process. Default: 8192*/ + // "exposeGC": true /* Enable to trigger garbage collection explicitly. Default: true*/ + } +} diff --git a/AppColdStart/HapAndHarDependHar/hvigorfile.ts b/AppFreeze/hvigorfile.ts similarity index 100% rename from AppColdStart/HapAndHarDependHar/hvigorfile.ts rename to AppFreeze/hvigorfile.ts diff --git a/ArkUI/Lazy_Loading_Optimizes_Performance/oh-package-lock.json5 b/AppFreeze/oh-package-lock.json5 similarity index 100% rename from ArkUI/Lazy_Loading_Optimizes_Performance/oh-package-lock.json5 rename to AppFreeze/oh-package-lock.json5 diff --git a/AppFreeze/oh-package.json5 b/AppFreeze/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a8aff0c5aff22d78aa26fd19c3861f4320e951ff --- /dev/null +++ b/AppFreeze/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "modelVersion": "5.0.5", + "description": "Please describe the basic information.", + "dependencies": { + }, + "devDependencies": { + "@ohos/hypium": "1.0.21", + "@ohos/hamock": "1.0.0" + } +} diff --git a/AppPrivacyProtection/README.en.md b/AppPrivacyProtection/README.en.md index 3d2bb52a740a2d251f547328805999ff56d82efb..ac7ec58b9d3bfa82d49b2ebc3e657a8cf7e27a3d 100644 --- a/AppPrivacyProtection/README.en.md +++ b/AppPrivacyProtection/README.en.md @@ -47,8 +47,19 @@ N/A 1. This sample is supported only on Huawei phones running the standard system. -2. The HarmonyOS version must be HarmonyOS NEXT Beta 1 or later. +2. The HarmonyOS version must be HarmonyOS 5.0.5 Release or later. -3. The DevEco Studio version must be DevEco Studio NEXT Beta1 or later. +3. The DevEco Studio version must be DevEco Studio 5.0.5 Release or later. -4. The HarmonyOS SDK version must be HarmonyOS NEXT Beta1 SDK or later. +4. The HarmonyOS SDK version must be HarmonyOS 5.0.5 Release SDK or later. + +### Download + +To download this project separately, execute the following command: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set AppPrivacyProtection +git checkout +``` diff --git a/AppPrivacyProtection/README.md b/AppPrivacyProtection/README.md index 4c2270dbaf26e1f41f97d3290a7079e685699f97..489516615c9f929247ed6e9f37fb17a04fd13f31 100644 --- a/AppPrivacyProtection/README.md +++ b/AppPrivacyProtection/README.md @@ -45,11 +45,22 @@ 1. 本示例仅支持标准系统上运行,支持设备:华为手机。 -2. HarmonyOS系统:HarmonyOS 5.0.0 Release及以上。 +2. HarmonyOS系统:HarmonyOS 5.0.5 Release及以上。 -3. DevEco Studio版本:DevEco Studio 5.0.0 Release及以上。 +3. DevEco Studio版本:DevEco Studio 5.0.5 Release及以上。 -4. HarmonyOS SDK版本:HarmonyOS 5.0.0 Release SDK及以上。 +4. HarmonyOS SDK版本:HarmonyOS 5.0.5 Release SDK及以上。 + +### 下载 + +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set AppPrivacyProtection +git checkout +``` diff --git a/AppPrivacyProtection/build-profile.json5 b/AppPrivacyProtection/build-profile.json5 index 1e69556b3411622cb2e87a87389653bb34f1b148..492123c253881f5bbd9bc76553bfb74e842dfb40 100644 --- a/AppPrivacyProtection/build-profile.json5 +++ b/AppPrivacyProtection/build-profile.json5 @@ -5,7 +5,8 @@ { "name": "default", "signingConfig": "default", - "compatibleSdkVersion": "5.0.0(12)", + "compatibleSdkVersion": "5.0.5(17)", + "targetSdkVersion": "5.0.5(17)", "runtimeOS": "HarmonyOS", "buildOption": { "strictMode": { diff --git a/AppPrivacyProtection/entry/src/main/ets/pages/ApproximatelyLocationDemo.ets b/AppPrivacyProtection/entry/src/main/ets/pages/ApproximatelyLocationDemo.ets index d24fcb14e743a9723dceb0125ca771ae600759f3..4d1d7adf2ccfdcb5957f15fd044a612494ec4fa8 100644 --- a/AppPrivacyProtection/entry/src/main/ets/pages/ApproximatelyLocationDemo.ets +++ b/AppPrivacyProtection/entry/src/main/ets/pages/ApproximatelyLocationDemo.ets @@ -30,12 +30,18 @@ struct ApproximatelyLocationDemo { // [End request_permission] const bundleFlags = bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION; const bundleInfo = bundleManager.getBundleInfoForSelfSync(bundleFlags); - const grantStatus = accessManager.checkAccessTokenSync(bundleInfo.appInfo.accessTokenId, permissions[0]); - + let grantStatus: abilityAccessCtrl.GrantStatus | null = null; + try { + grantStatus = accessManager.checkAccessTokenSync(bundleInfo.appInfo.accessTokenId, permissions[0]); + } catch (error) { + let err = error as BusinessError; + Logger.error(`showToast failed, code=${err.code}, message=${err.message}`); + } return new Promise((resolve, reject) => { if (grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_DENIED) { // [Start request_permission] - accessManager.requestPermissionsFromUser(this.getUIContext().getHostContext(), ['ohos.permission.APPROXIMATELY_LOCATION']) + accessManager.requestPermissionsFromUser(this.getUIContext().getHostContext(), + ['ohos.permission.APPROXIMATELY_LOCATION']) .then((data) => { let grantStatus: Array = data.authResults; if (grantStatus.length > 0 && grantStatus[0] === 0) { @@ -48,15 +54,20 @@ struct ApproximatelyLocationDemo { // The user rejects the authorization Logger.info('request permissions denied'); // [StartExclude request_permission] - this.getUIContext().getPromptAction().showToast({ - message: 'This function requires the location permission. Go to the settings page to authorize the permission' - }); + try { + this.getUIContext().getPromptAction().showToast({ + message: 'This function requires the location permission. Go to the settings page to authorize the permission' + }); + } catch (error) { + let err = error as BusinessError; + Logger.error(`showToast failed, code=${err.code}, message=${err.message}`); + } resolve(-1); // [EndExclude request_permission] } Logger.info(`request permissions result: ${JSON.stringify(data)}`); }) - // [End request_permission] + // [End request_permission] .catch((error: BusinessError) => { Logger.error(`request permissions exception, Catch error:${JSON.stringify(error)}`); reject(error); @@ -67,7 +78,6 @@ struct ApproximatelyLocationDemo { }); } - getLocation() { this.requestPermissions().then(data => { diff --git a/AppPrivacyProtection/entry/src/main/ets/pages/Index.ets b/AppPrivacyProtection/entry/src/main/ets/pages/Index.ets index f190b3ea84857682f733a7f4a3636082a07dca37..78cc67a40ac38c67f4d8fa85651be9e60ab158a3 100644 --- a/AppPrivacyProtection/entry/src/main/ets/pages/Index.ets +++ b/AppPrivacyProtection/entry/src/main/ets/pages/Index.ets @@ -25,7 +25,13 @@ struct Index { const accessManager = abilityAccessCtrl.createAtManager(); const bundleFlags = bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION; const bundleInfo = bundleManager.getBundleInfoForSelfSync(bundleFlags); - const grantStatus = accessManager.checkAccessTokenSync(bundleInfo.appInfo.accessTokenId, permissions[0]); + let grantStatus: abilityAccessCtrl.GrantStatus | null = null; + try { + grantStatus = accessManager.checkAccessTokenSync(bundleInfo.appInfo.accessTokenId, permissions[0]); + } catch (error) { + let err = error as BusinessError; + Logger.error(`checkAccessTokenSync failed, code=${err.code}, message=${err.message}`); + } if (grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_DENIED) { // [Start permission_camera] accessManager.requestPermissionsFromUser(this.getUIContext().getHostContext(), ['ohos.permission.CAMERA']) @@ -36,18 +42,31 @@ struct Index { } else { Logger.info('request permissions denied'); // [StartExclude permission_camera] - this.getUIContext().getPromptAction().showToast({ - message: 'This function requires the camera permission. Go to the settings page to authorize the permission' - }); + try { + this.getUIContext().getPromptAction().showToast({ + message: 'This function requires the camera permission. Go to the settings page to authorize the permission' + }); + } catch (error) { + let err = error as BusinessError; + Logger.error(`showToast failed, code=${err.code}, message=${err.message}`); + } // [EndExclude permission_camera] } }) - // [End permission_camera] + // [End permission_camera] .catch((error: BusinessError) => { Logger.error(`request permissions exception, Catch error:${JSON.stringify(error)}`); }) } else { Logger.info('request permissions granted'); + try { + this.getUIContext().getPromptAction().showToast({ + message: 'request permissions has granted' + }); + } catch (error) { + let err = error as BusinessError; + Logger.error(`showToast failed, code=${err.code}, message=${err.message}`); + } } } @@ -57,13 +76,29 @@ struct Index { .height(40) .width('100%') .onClick(() => { - this.getUIContext().getRouter().pushUrl({ url: 'pages/ApproximatelyLocationDemo' }); + this.getUIContext() + .getRouter() + .pushUrl({ url: 'pages/ApproximatelyLocationDemo' }) + .then(() => { + Logger.info(`showToast success`); + }) + .catch((err: BusinessError) => { + Logger.error(`showToast failed, code=${err.code}, message=${err.message}`); + }) }) Button($r('app.string.use_picker')) .height(40) .width('100%') .onClick(() => { - this.getUIContext().getRouter().pushUrl({ url: 'pages/PickerDemo' }); + this.getUIContext() + .getRouter() + .pushUrl({ url: 'pages/PickerDemo' }) + .then(() => { + Logger.info(`showToast success`); + }) + .catch((err: BusinessError) => { + Logger.error(`showToast failed, code=${err.code}, message=${err.message}`); + }) }) Button($r('app.string.apply_camera_permissions')) .height(40) diff --git a/AppPrivacyProtection/entry/src/main/ets/pages/PickerDemo.ets b/AppPrivacyProtection/entry/src/main/ets/pages/PickerDemo.ets index 672e4fc2f9175a07f8fc33b914beefc5e3fb0383..2af5826d33d175f2c72ecdcde7ca86498e8adff1 100644 --- a/AppPrivacyProtection/entry/src/main/ets/pages/PickerDemo.ets +++ b/AppPrivacyProtection/entry/src/main/ets/pages/PickerDemo.ets @@ -16,7 +16,6 @@ // [Start picker_demo] import { photoAccessHelper } from '@kit.MediaLibraryKit'; import { BusinessError } from '@kit.BasicServicesKit'; -// [End picker_demo] import Logger from '../utils/Logger'; @Entry @@ -27,23 +26,25 @@ struct PickerDemo { build() { RelativeContainer() { Image(this.imageUri) - .width('100%') + // [StartExclude picker_demo] + .width('60%') .margin({ bottom: 12 }) .alignRules({ center: { anchor: '__container__', align: VerticalAlign.Center }, middle: { anchor: '__container__', align: HorizontalAlign.Center } }) - + // [EndExclude picker_demo] Button($r('app.string.select_picture')) + // [StartExclude picker_demo] .height(40) .width('100%') .margin({ bottom: 44 }) .alignRules({ - center: { anchor: '__container__', align: VerticalAlign.Center }, + center: { anchor: '__container__', align: VerticalAlign.Bottom }, middle: { anchor: '__container__', align: HorizontalAlign.Center } }) + // [EndExclude picker_demo] .onClick(() => { - // [Start picker_demo] const photoSelectOptions = new photoAccessHelper.PhotoSelectOptions(); photoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE; photoSelectOptions.maxSelectNumber = 5; @@ -54,11 +55,13 @@ struct PickerDemo { }).catch((err: BusinessError) => { Logger.error(`PhotoViewPicker.select failed with err: ${JSON.stringify(err)}`) }) - // [End picker_demo] }) } + // [StartExclude picker_demo] .height('100%') .width('100%') .padding(16) + // [EndExclude picker_demo] } -} \ No newline at end of file +} +// [End picker_demo] \ No newline at end of file diff --git a/ArkTS_high_performance_segment/README.md b/ArkTS_high_performance_segment/README.md index e112b3470786aac68ca9c192131ef9edf90ccbba..7bffe6a58bf8030b50237d6d9ede610f7ae875a4 100644 --- a/ArkTS_high_performance_segment/README.md +++ b/ArkTS_high_performance_segment/README.md @@ -1,3 +1,26 @@ # ArkTS高性能编程代码片段 +## 介绍 +最佳实践->应用框架->ArkTS语言->ArkTS高性能编程。 -最佳实践->应用框架->ArkTS语言->ArkTS高性能编程 \ No newline at end of file +## 相关权限 +无 + +## 约束与限制 +* 本示例仅支持标准系统上运行,支持设备:华为手机。 + +* HarmonyOS系统:HarmonyOS 5.0.5 Release及以上。 + +* DevEco Studio版本:DevEco Studio 5.0.5 Release及以上。 + +* HarmonyOS SDK版本:HarmonyOS 5.0.5 Release SDK及以上。 + +## 下载 + +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set ArkTS_high_performance_segment +git checkout +``` \ No newline at end of file diff --git a/ArkTS_high_performance_segment/entry/src/main/ets/segment/segment6.ets b/ArkTS_high_performance_segment/entry/src/main/ets/segment/segment6.ets new file mode 100644 index 0000000000000000000000000000000000000000..a04b9687cc09be36c347177fccbcd1bb1bfbf253 --- /dev/null +++ b/ArkTS_high_performance_segment/entry/src/main/ets/segment/segment6.ets @@ -0,0 +1,74 @@ +// Attention: This is the counterexample file + +// [Start export_multi_levels] +// main: Hap import har file +import { one } from '@har/Index' + +// har/Index.ets (one level) +export * from './InnerIndex' +export * from './Utils' +export * from './Logs' +export * from './Service' +export * from './Common' +export * from './Feature' + +// InnerIndex.ets (two level) +export * from './ThirdIndex' +export { two } from 'Temp' +export * from './Utils' +export * from './Logs' +export * from './Service' + +// ...more level + +// LastIndex.ets (N level) +export * from './Utils'; +export { three } from 'Temp' +export * from './Numbers' + +// Numbers.ets +export const One: number = 1; +// [End export_multi_levels] + +// [Start export_one_level] +// main: Hap import har file +import { one } from '@har/Index' + +// har/Index.ets +export * from './Numbers' // only one level + +// Numbers.ets +export const one: number = 1; +// [End export_one_level] + +// [Start multi_star_export] +// main.ets +import { one } from '@har/Index'; + +// @har/Index.ets +export * from './Numbers' +export * from './Utils' +export * from './Logs' +export * from './Service' +export * from './Common' +export * from './Feature' + +// Numbers.ets +export const one : number = 1; +// [End multi_star_export] + +// [Start name_export] +// main.ets +import { one } from '@har/Index'; + +// @har/Index.ets +export { one } from '../Numbers' // use named export +export * from './Utils' +export * from './Logs' +export * from './Service' +export * from './Common' +export * from './Feature' + +// Numbers.ets +export const one: number = 1; +// [End name_export] \ No newline at end of file diff --git a/ArkUI/Component_Nesting_Optimization/README_zh.md b/ArkUI/Component_Nesting_Optimization/README_zh.md new file mode 100644 index 0000000000000000000000000000000000000000..ae48f3220d53b9cf54d92065afdc0f0092045269 --- /dev/null +++ b/ArkUI/Component_Nesting_Optimization/README_zh.md @@ -0,0 +1,51 @@ +# 不同场景下组件嵌套的性能优化策略 + +### 介绍 + +本示例是[《组件嵌套优化》](https://developer.huawei.com/consumer/cn/doc/best-practices/bpta-component-nesting-optimization)的配套示例代码,通过正反例代码展示页面布局时,如何减少性能开销。 + + +### 工程目录 +``` +├──entry/src/main/ets // 代码区 +│ ├──entryability +│ │ └──EntryAbility.ets // 程序入口类 +│ ├──entrybackupability +│ │ └──EntryBackupAbility.ets +│ ├──pages +│ │ └──Index.ets +│ └──segment +│ ├──segment1.ets // 场景1 +│ ├──segment2.ets // 场景2 +│ ├──segment3.ets // 场景3 +│ ├──segment4.ets // 场景4 +│ ├──segment5.ets // 场景5 +│ └──segment6.ets // 场景6 +└──entry/src/main/resources // 应用资源目录 +``` + +### 相关权限 + +不涉及。 + +### 依赖 + +不涉及。 + +### 约束与限制 + +1. 本示例仅支持标准系统上运行,支持设备:华为手机。 +2. HarmonyOS系统:HarmonyOS 5.0.5 Release及以上。 +3. DevEco Studio版本:DevEco Studio 5.0.5 Release及以上。 +4. HarmonyOS SDK版本:HarmonyOS 5.0.5 Release SDK及以上。 + +### 下载 + +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set ArkUI/Component_Nesting_Optimization +git checkout +``` \ No newline at end of file diff --git a/ArkUI/Component_Nesting_Optimization/entry/src/main/ets/entryability/EntryAbility.ets b/ArkUI/Component_Nesting_Optimization/entry/src/main/ets/entryability/EntryAbility.ets index 508880af8c33aa838016d1cd4b2c68be2f447540..faef53f986d5fbedc6ba520c813ee0d0dbd18f9a 100644 --- a/ArkUI/Component_Nesting_Optimization/entry/src/main/ets/entryability/EntryAbility.ets +++ b/ArkUI/Component_Nesting_Optimization/entry/src/main/ets/entryability/EntryAbility.ets @@ -1,4 +1,5 @@ import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { BusinessError } from '@kit.BasicServicesKit' import { hilog } from '@kit.PerformanceAnalysisKit'; import { window } from '@kit.ArkUI'; @@ -6,7 +7,12 @@ const DOMAIN = 0x0000; export default class EntryAbility extends UIAbility { onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { - this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + try { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + } catch (error) { + let err = error as BusinessError; + hilog.warn(0x000, 'testTag', `setColorMode failed, code=${err.code}, message=${err.message}`); + } hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); } diff --git a/ArkUI/Component_Nesting_Optimization/entry/src/main/ets/segment/segment2.ets b/ArkUI/Component_Nesting_Optimization/entry/src/main/ets/segment/segment2.ets index c606b3482bd58e8a18b45ec9a4180705322798db..e4e30ddff6e535cc6207e10e50791ed8823d4ade 100644 --- a/ArkUI/Component_Nesting_Optimization/entry/src/main/ets/segment/segment2.ets +++ b/ArkUI/Component_Nesting_Optimization/entry/src/main/ets/segment/segment2.ets @@ -61,7 +61,7 @@ struct ModifierCustom { build() { Column() { - Text('Hello Word') + Text('Hello World') }.attributeModifier(this.modifier) } } diff --git a/ArkUI/Component_Nesting_Optimization/entry/src/main/ets/segment/segment6.ets b/ArkUI/Component_Nesting_Optimization/entry/src/main/ets/segment/segment6.ets index 6f51145bc8bf0138c343b01b0bb7be7e2dc64a7b..86f22e9f56dd9dea8c110e05825e856a4c6ff5fc 100644 --- a/ArkUI/Component_Nesting_Optimization/entry/src/main/ets/segment/segment6.ets +++ b/ArkUI/Component_Nesting_Optimization/entry/src/main/ets/segment/segment6.ets @@ -1,6 +1,7 @@ // [Start Case5] import { ColorMetrics } from '@kit.ArkUI'; import { BusinessError } from '@kit.BasicServicesKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; @Component struct ColorMeasure { @@ -18,7 +19,12 @@ struct ColorMeasure { getBlendColor(baseColor: ResourceColor, addColor: ResourceColor): ColorMetrics { if (!baseColor || !addColor) { - return ColorMetrics.resourceColor(Color.Black); + try { + return ColorMetrics.resourceColor(Color.Black); + } catch (error) { + let err = error as BusinessError; + hilog.warn(0x000, 'testTag', `showToast failed, code=${err.code}, message=${err.message}`); + } } let sourceColor: ColorMetrics; try { @@ -48,4 +54,5 @@ struct ColorMetricsExample { } } } + // [End Case5] \ No newline at end of file diff --git a/ArkUI/Component_Nesting_Optimization/entry/src/main/module.json5 b/ArkUI/Component_Nesting_Optimization/entry/src/main/module.json5 index a1cea8b6a4560cee7bda7a2db52f310c035ab6c8..ad219d733f6afa5ea07f85f580208b08cc3b9041 100644 --- a/ArkUI/Component_Nesting_Optimization/entry/src/main/module.json5 +++ b/ArkUI/Component_Nesting_Optimization/entry/src/main/module.json5 @@ -5,9 +5,7 @@ "description": "$string:module_desc", "mainElement": "EntryAbility", "deviceTypes": [ - "phone", - "tablet", - "2in1" + "phone" ], "deliveryWithInstall": true, "installationFree": false, diff --git a/ArkUI/Component_Nesting_Optimization/entry/src/main/resources/base/element/string.json b/ArkUI/Component_Nesting_Optimization/entry/src/main/resources/base/element/string.json index f94595515a99e0c828807e243494f57f09251930..ac8f28701c8c94819a1b34d5c402c751cdfa61d3 100644 --- a/ArkUI/Component_Nesting_Optimization/entry/src/main/resources/base/element/string.json +++ b/ArkUI/Component_Nesting_Optimization/entry/src/main/resources/base/element/string.json @@ -10,7 +10,7 @@ }, { "name": "EntryAbility_label", - "value": "label" + "value": "component-nesting-optimization" } ] } \ No newline at end of file diff --git a/ArkUI/Component_Redundancy_Refresh_Optimization/README.md b/ArkUI/Component_Redundancy_Refresh_Optimization/README.md new file mode 100644 index 0000000000000000000000000000000000000000..594a40f5c0a8c7c5adc3da40351e996df77543d7 --- /dev/null +++ b/ArkUI/Component_Redundancy_Refresh_Optimization/README.md @@ -0,0 +1,58 @@ +# 组件冗余刷新解决方案样例代码工程 + +### 介绍 + +本示例为组件冗余刷新解决方案样例代码工程,包含组件冗余刷新解决方案正例和反例内容的局部样例代码。工程本身不具备实际功能,开发者请直接阅读具体源码结合文档来理解。 + + +### 效果预览 + +不涉及 + +### 工程目录 +``` +├──entry/src/main/ets +│ ├──entryability +│ │ └──EntryAbility.ets // 程序入口类 +│ ├──entrybackupability +│ │ └──EntryBackupAbility.ets // 应用数据备份恢复类 +│ ├──pages +│ │ └──Index.ets // 首页 +│ └──segment +│ ├──segment1 // 反例 +│ └──segment2 // 正例 +└──entry/src/main/resources // 应用静态资源目录 +``` + +### 具体实现 + +不涉及。 + +### 相关权限 + +不涉及。 + +### 依赖 + +不涉及。 + +### 约束与限制 + +1. 本示例仅支持标准系统上运行,支持设备:华为手机、华为PC/2in1设备、华为平板。 + +2. HarmonyOS系统:HarmonyOS NEXT 5.0.5 Release及以上。 + +3. DevEco Studio版本:DevEco Studio NEXT 5.0.5 Release及以上。 + +4. HarmonyOS SDK版本:HarmonyOS NEXT 5.0.5 Release SDK及以上。 + +### 下载 + +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set ArkUI/Component_Redundancy_Refresh_Optimization +git checkout +``` \ No newline at end of file diff --git a/ArkUI/Component_Redundancy_Refresh_Optimization/entry/src/main/ets/entryability/EntryAbility.ets b/ArkUI/Component_Redundancy_Refresh_Optimization/entry/src/main/ets/entryability/EntryAbility.ets index 508880af8c33aa838016d1cd4b2c68be2f447540..2880ca09588393e53ffafcdb1a11f66cdde90b4f 100644 --- a/ArkUI/Component_Redundancy_Refresh_Optimization/entry/src/main/ets/entryability/EntryAbility.ets +++ b/ArkUI/Component_Redundancy_Refresh_Optimization/entry/src/main/ets/entryability/EntryAbility.ets @@ -1,4 +1,5 @@ import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { BusinessError } from '@kit.BasicServicesKit'; import { hilog } from '@kit.PerformanceAnalysisKit'; import { window } from '@kit.ArkUI'; @@ -6,7 +7,12 @@ const DOMAIN = 0x0000; export default class EntryAbility extends UIAbility { onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { - this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + try { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + } catch (error) { + let err = error as BusinessError; + hilog.warn(0x000, 'testTag', `setColorMode failed, code=${err.code}, message=${err.message}`); + } hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); } diff --git a/ArkUI/Component_Redundancy_Refresh_Optimization/entry/src/main/ets/segment/segment1.ets b/ArkUI/Component_Redundancy_Refresh_Optimization/entry/src/main/ets/segment/segment1.ets index 9b3c26bca072a24651ba4dea953e552d6e67360c..386160749164fc280e3d43499b18082b0d1cd426 100644 --- a/ArkUI/Component_Redundancy_Refresh_Optimization/entry/src/main/ets/segment/segment1.ets +++ b/ArkUI/Component_Redundancy_Refresh_Optimization/entry/src/main/ets/segment/segment1.ets @@ -24,39 +24,54 @@ struct ComponentA { Column() { // Components that use state variables SpecialImage({ specialImageUiStyle: this.uiStyle }) - Stack() { - Column() { - Image($r('app.media.startIcon')) - .height(78) - .width(78) - .scale({ - x: this.uiStyle.scaleX, - y: this.uiStyle.scaleY - }) - } - - Stack() { - Text('Hello World') - } + Column() { + // 需要替换为开发者所需的图像资源文件 + Image($r('app.media.startIcon')) + .height('150vp') + .width('150vp') + .scale({ + x: this.uiStyle.scaleX, + y: this.uiStyle.scaleY + }) + Text('Hello World') + .fontWeight(FontWeight.Bold) } .translate({ x: this.uiStyle.translateX, y: this.uiStyle.translateY }) - + .width('95%') + .height('200vp') + .margin({ + top: '10vp', + left: '15vp', + right: '15vp' + }) + .borderRadius('16vp') + .backgroundColor(Color.White) // Modify the value of a state variable via a button click callback, causing the corresponding component to refresh. Column() { Button('Move') + .width('80%') .onClick(() => { this.getUIContext().animateTo({ duration: animationDuration }, () => { this.uiStyle.translateY = (this.uiStyle.translateY + translateYChangeValue) % translateYChangeRange; }) }) Button('Scale') + .width('80%') .onClick(() => { this.uiStyle.scaleX = (this.uiStyle.scaleX + scaleXChangeValue) % scaleXChangeRange; }) + .margin({ + top: '10vp', + left: '15vp', + right: '15vp' + }) } + .height('35%') + .justifyContent(FlexAlign.End) + .width('100%') } } } @@ -74,15 +89,26 @@ struct SpecialImage { build() { Column() { + // 需要替换为开发者所需的图像资源文件 Image($r('app.media.startIcon')) - .size({ width: 200, height: 200 }) + .size({ width: 78, height: 78 }) .scale({ x: this.specialImageUiStyle.scaleX, y: this.specialImageUiStyle.scaleY }) .opacity(this.isRenderSpecialImage()) Text("SpecialImage") + .fontWeight(FontWeight.Bold) } + .width('95%') + .margin({ + top: '10vp', + left: '15vp', + right: '15vp' + }) + .borderRadius('16vp') + .height('200vp') + .backgroundColor(Color.White) } } @@ -100,6 +126,7 @@ struct DFXStateBeforeOptimization { } .width('100%') .height('100%') + .backgroundColor(0xDCDCDC) } } diff --git a/ArkUI/Component_Redundancy_Refresh_Optimization/entry/src/main/ets/segment/segment2.ets b/ArkUI/Component_Redundancy_Refresh_Optimization/entry/src/main/ets/segment/segment2.ets index c44e19606b9c18e7d6026f8a0f61d97a77e52290..1583092b1b7b8809a68ce07f5f4823c1ff29e04a 100644 --- a/ArkUI/Component_Redundancy_Refresh_Optimization/entry/src/main/ets/segment/segment2.ets +++ b/ArkUI/Component_Redundancy_Refresh_Optimization/entry/src/main/ets/segment/segment2.ets @@ -40,27 +40,36 @@ struct ComponentA { specialImageScaleStyle: this.scaleStyle }) // Other UI components - Stack() { Column() { + // 需要替换为开发者所需的图像资源文件 Image($r('app.media.startIcon')) + .height('150vp') + .width('150vp') .scale({ x: this.scaleStyle.scaleX, y: this.scaleStyle.scaleY }) - } - - Stack() { Text('Hello World') + .fontWeight(FontWeight.Bold) } - } + .translate({ x: this.translateStyle.translateX, y: this.translateStyle.translateY }) - + .width('95%') + .height('200vp') + .margin({ + top: '10vp', + left: '15vp', + right: '15vp' + }) + .borderRadius('16vp') + .backgroundColor(Color.White) // Modify the value of a state variable via a button click callback, causing the corresponding component to refresh. Column() { Button('Move') + .width('80%') .onClick(() => { this.getUIContext().animateTo({ duration: animationDuration }, () => { this.translateStyle.translateY = @@ -68,10 +77,19 @@ struct ComponentA { }) }) Button('Scale') + .width('80%') .onClick(() => { this.scaleStyle.scaleX = (this.scaleStyle.scaleX + scaleXChangeValue) % scaleXChangeRange; }) + .margin({ + top: '10vp', + left: '15vp', + right: '15vp' + }) } + .height('35%') + .justifyContent(FlexAlign.End) + .width('100%') } } } @@ -90,14 +108,26 @@ struct SpecialImage { build() { Column() { + // 需要替换为开发者所需的图像资源文件 Image($r('app.media.startIcon')) + .size({ width: 78, height: 78 }) .scale({ x: this.specialImageScaleStyle.scaleX, y: this.specialImageScaleStyle.scaleY }) .opacity(this.isRenderSpecialImage()) Text("SpecialImage") + .fontWeight(FontWeight.Bold) } + .width('95%') + .margin({ + top: '10vp', + left: '15vp', + right: '15vp' + }) + .borderRadius('16vp') + .height('200vp') + .backgroundColor(Color.White) } } @@ -113,6 +143,9 @@ struct DFXStateAfterOptimization { translateStyle: this.uiStyle.translateStyle, }) } + .width('100%') + .height('100%') + .backgroundColor(0xDCDCDC) } } diff --git a/ArkUI/Lazy_Loading_Optimizes_Performance/README.md b/ArkUI/Lazy_Loading_Optimizes_Performance/README.md new file mode 100644 index 0000000000000000000000000000000000000000..819198a50f3463d6d2c9cfd46b5cd7722bc0ceb4 --- /dev/null +++ b/ArkUI/Lazy_Loading_Optimizes_Performance/README.md @@ -0,0 +1,53 @@ +# 布局优化指导 +## 介绍 +本例介绍了5种优化手段,分别为使用系统提供的动画接口、使用图形变换属性变化组件布局、参数相同时使用同一个animateTo、多次animateTo时统一更新状态变量、使用renderGroup。通过这些优化手段的单个使用或组合使用,可以对动画帧率、应用卡顿等方面带来优化,提升性能和用户体验。 + +## 效果预览 +不涉及 + +## 使用说明 +不涉及 + +## 工程目录 +``` +├──entry/src/main/ets // 代码区 +│ ├──entryability +│ │ └──EntryAbility.ets // 程序入口类 +│ ├──entrybackupability +│ │ └──EntryBackupAbility.ets // 应用数据备份和恢复 +│ ├──pages +│ │ └──Index.ets // 首页 +│ └──segment +│ ├──segment1.ets // ForEach页面 +│ └──segment2.ets // LazyForEach页面 +└──entry/src/main/resources // 应用资源目录 +``` + +## 具体实现 + +不涉及。 + +## 相关权限 + +不涉及。 + +## 约束与限制 + +1. 本示例仅支持标准系统上运行,支持设备:华为手机。 + +2. HarmonyOS系统:HarmonyOS 5.0.5 Release及以上。 + +3. DevEco Studio版本:DevEco Studio 5.0.5 Release及以上。 + +4. HarmonyOS SDK版本:HarmonyOS 5.0.5 Release SDK及以上。 + +## 下载 + +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set ArkUI/Lazy_Loading_Optimizes_Performance +git checkout +``` \ No newline at end of file diff --git a/ArkUI/Lazy_Loading_Optimizes_Performance/entry/src/main/ets/entryability/EntryAbility.ets b/ArkUI/Lazy_Loading_Optimizes_Performance/entry/src/main/ets/entryability/EntryAbility.ets index 508880af8c33aa838016d1cd4b2c68be2f447540..a7e8ad07979614ccfe122b70e0ccd7306acaef68 100644 --- a/ArkUI/Lazy_Loading_Optimizes_Performance/entry/src/main/ets/entryability/EntryAbility.ets +++ b/ArkUI/Lazy_Loading_Optimizes_Performance/entry/src/main/ets/entryability/EntryAbility.ets @@ -6,7 +6,11 @@ const DOMAIN = 0x0000; export default class EntryAbility extends UIAbility { onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { - this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + try { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + } catch (err) { + hilog.info(DOMAIN, 'testTag', '%{public}s', 'setColorMode fail'); + } hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); } diff --git a/ArkUI/Lazy_Loading_Optimizes_Performance/entry/src/main/ets/pages/Index.ets b/ArkUI/Lazy_Loading_Optimizes_Performance/entry/src/main/ets/pages/Index.ets index bfb9190d4b26c6248dea78b6da3eddc37dde5389..2da5d3f7349279647d7511efed13f8c75b176e2d 100644 --- a/ArkUI/Lazy_Loading_Optimizes_Performance/entry/src/main/ets/pages/Index.ets +++ b/ArkUI/Lazy_Loading_Optimizes_Performance/entry/src/main/ets/pages/Index.ets @@ -22,11 +22,11 @@ struct Index { }.margin({ left: 10, right: 10 }) }.onAppear(() => { // Record the number of times the component is created through onAppear - console.info("appear:" + lazyForEachItem) + console.info('appear:' + lazyForEachItem); }) }, (item: string) => { // Print the key value in the keyGenerator function - console.info("key:" + item) + console.info('key:' + item); return item; }) // [End Lazy_for_each] diff --git a/ArkUI/Lazy_Loading_Optimizes_Performance/entry/src/main/resources/base/element/string.json b/ArkUI/Lazy_Loading_Optimizes_Performance/entry/src/main/resources/base/element/string.json index f94595515a99e0c828807e243494f57f09251930..79995ff14b6a7263a947a5f63ff4cd1820a7a436 100644 --- a/ArkUI/Lazy_Loading_Optimizes_Performance/entry/src/main/resources/base/element/string.json +++ b/ArkUI/Lazy_Loading_Optimizes_Performance/entry/src/main/resources/base/element/string.json @@ -10,7 +10,7 @@ }, { "name": "EntryAbility_label", - "value": "label" + "value": "LazyLoad" } ] } \ No newline at end of file diff --git a/ArkUI/Proper_Use_Layout/README.md b/ArkUI/Proper_Use_Layout/README.md index f51b77558444e5ba33447d1070bc788576c83f46..061425f4779180d24cfb6a2b3d9d11453a6bfd82 100644 --- a/ArkUI/Proper_Use_Layout/README.md +++ b/ArkUI/Proper_Use_Layout/README.md @@ -2,10 +2,6 @@ ## 介绍 本例通过Scroll嵌套List,对比List设置宽度和不设置的情况。 -## 预览效果 - -img.png - ## 工程目录 ``` ├──entry/src/main/ets // 代码区 @@ -16,20 +12,35 @@ │ ├──pages │ │ └──Index.ets // 首页 │ └──segment -│ ├──segment1.ets -│ ├──segment2.ets -│ └──segment3.ets +│ ├──segment1.ets // List列表数据 +│ ├──segment2.ets // List不设置宽高 +│ └──segment3.ets // List设置固定高度 └──entry/src/main/resources // 应用资源目录 ``` +## 使用说明 +示例代码包含两个场景: +* Scroll嵌套List,List不设置宽高。 +* Scroll嵌套List,List设置固定宽高。 ## 相关权限 无 ## 约束与限制 -* 本示例仅支持标准系统上运行,支持设备:华为手机。 +1. 本示例仅支持标准系统上运行,支持设备:华为手机。 + +2. HarmonyOS系统:HarmonyOS 5.0.5 Release及以上。 -* HarmonyOS系统:HarmonyOS NEXT Release及以上。 +3. DevEco Studio版本:DevEco Studio 5.0.5 Release及以上。 -* DevEco Studio版本:DevEco Studio NEXT Release及以上。 +4. HarmonyOS SDK版本:HarmonyOS 5.0.5 Release SDK及以上。 -* HarmonyOS SDK版本:HarmonyOS NEXT Release SDK及以上。 \ No newline at end of file +## 下载 + +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set ArkUI/Proper_Use_Layout +git checkout +``` \ No newline at end of file diff --git a/ArkUI/Proper_Use_Layout/README_EN.md b/ArkUI/Proper_Use_Layout/README_EN.md index 58b21c1bb15c9b10e45c2555e9c5fb0b30ecd026..99f230393d37c542f62bdee2f9a5924b5284b3c3 100644 --- a/ArkUI/Proper_Use_Layout/README_EN.md +++ b/ArkUI/Proper_Use_Layout/README_EN.md @@ -25,10 +25,21 @@ This example uses Scroll to nest a List and compares the situations where the Li N/A ## Constraints -* This sample is supported only on Huawei phones running the standard system. +1. This sample is supported only on Huawei phones running the standard system. -* The HarmonyOS version must be HarmonyOS NEXT Release or later. +2. The HarmonyOS version must be HarmonyOS 5.0.5 Release or later. -* The DevEco Studio version must be DevEco Studio NEXT Release or later. +3. The DevEco Studio version must be DevEco Studio 5.0.5 Release or later. -* The HarmonyOS SDK version must be HarmonyOS NEXT Release SDK or later. +4. The HarmonyOS SDK version must be HarmonyOS 5.0.5 Release SDK or later. + +## Download + +To download this project separately, execute the following command: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set ArkUI/Proper_Use_Layout +git checkout +``` diff --git a/ArkUI/Proper_Use_Layout/entry/src/main/ets/entryability/EntryAbility.ets b/ArkUI/Proper_Use_Layout/entry/src/main/ets/entryability/EntryAbility.ets index 508880af8c33aa838016d1cd4b2c68be2f447540..5282cb6dd13ef29510ba872b3e237c9fab7732fb 100644 --- a/ArkUI/Proper_Use_Layout/entry/src/main/ets/entryability/EntryAbility.ets +++ b/ArkUI/Proper_Use_Layout/entry/src/main/ets/entryability/EntryAbility.ets @@ -1,4 +1,20 @@ +/* +* Copyright (C) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { BusinessError } from '@kit.BasicServicesKit'; import { hilog } from '@kit.PerformanceAnalysisKit'; import { window } from '@kit.ArkUI'; @@ -6,7 +22,12 @@ const DOMAIN = 0x0000; export default class EntryAbility extends UIAbility { onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { - this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + try { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + } catch (error) { + let err = error as BusinessError; + hilog.warn(0x000, 'testTag', `setColorMode failed, code=${err.code}, message=${err.message}`); + } hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); } diff --git a/ArkUI/Proper_Use_Layout/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets b/ArkUI/Proper_Use_Layout/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets index 8e4de99282050bad799ac892eb85ac5449364a51..7eb1afb81759bc5d59117077cb08b938ea66d402 100644 --- a/ArkUI/Proper_Use_Layout/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets +++ b/ArkUI/Proper_Use_Layout/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets @@ -1,3 +1,18 @@ +/* +* Copyright (C) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + import { hilog } from '@kit.PerformanceAnalysisKit'; import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit'; diff --git a/ArkUI/Proper_Use_Layout/entry/src/main/ets/pages/Index.ets b/ArkUI/Proper_Use_Layout/entry/src/main/ets/pages/Index.ets index 8e2d24ad42693fc877d51bb7820f0a9da68fa135..c149968e780eb9bac1ecb78fb539dff080631356 100644 --- a/ArkUI/Proper_Use_Layout/entry/src/main/ets/pages/Index.ets +++ b/ArkUI/Proper_Use_Layout/entry/src/main/ets/pages/Index.ets @@ -1,23 +1,59 @@ +/* +* Copyright (C) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ +import { BusinessError } from '@kit.BasicServicesKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; + @Entry @Component struct Index { - @State message: string = 'Hello World'; - build() { - RelativeContainer() { - Text(this.message) - .id('HelloWorld') - .fontSize($r('app.float.page_text_font_size')) - .fontWeight(FontWeight.Bold) - .alignRules({ - center: { anchor: '__container__', align: VerticalAlign.Center }, - middle: { anchor: '__container__', align: HorizontalAlign.Center } + Column({ space: 15 }) { + Button('to segment2') + .width('100%') + .onClick(() => { + this.getUIContext() + .getRouter() + .pushUrl({ + url: 'segment/segment2' + }) + .then(() => { + hilog.info(0x000, 'testTag', `pushUrl succeed.`); + }) + .catch((err: BusinessError) => { + hilog.warn(0x000, 'testTag', `pushUrl failed. code=${err.code}, message=${err.message}`); + }) }) + Button('to segment3') + .width('100%') .onClick(() => { - this.message = 'Welcome'; + this.getUIContext() + .getRouter() + .pushUrl({ + url: 'segment/segment3' + }) + .then(() => { + hilog.info(0x000, 'testTag', `pushUrl succeed.`); + }) + .catch((err: BusinessError) => { + hilog.warn(0x000, 'testTag', `pushUrl failed. code=${err.code}, message=${err.message}`); + }) }) } .height('100%') .width('100%') + .justifyContent(FlexAlign.End) + .padding({ left: 12, right: 12, bottom: 15 }) } } \ No newline at end of file diff --git a/ArkUI/Proper_Use_Layout/entry/src/main/ets/segment/segment1.ets b/ArkUI/Proper_Use_Layout/entry/src/main/ets/segment/segment1.ets index e638042083e9b1c6fd0590e406ea45cb80740030..78e7470d1cd9603a56bae794a705f9aaf2b0da8e 100644 --- a/ArkUI/Proper_Use_Layout/entry/src/main/ets/segment/segment1.ets +++ b/ArkUI/Proper_Use_Layout/entry/src/main/ets/segment/segment1.ets @@ -1,3 +1,18 @@ +/* +* Copyright (C) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + // [Start Case1] class BasicDataSource implements IDataSource { private listeners: DataChangeListener[] = []; @@ -29,31 +44,31 @@ class BasicDataSource implements IDataSource { notifyDataReload(): void { this.listeners.forEach(listener => { listener.onDataReloaded(); - }) + }); } notifyDataAdd(index: number): void { this.listeners.forEach(listener => { listener.onDataAdd(index); - }) + }); } notifyDataChange(index: number): void { this.listeners.forEach(listener => { listener.onDataChange(index); - }) + }); } notifyDataDelete(index: number): void { this.listeners.forEach(listener => { listener.onDataDelete(index); - }) + }); } notifyDataMove(from: number, to: number): void { this.listeners.forEach(listener => { listener.onDataMove(from, to); - }) + }); } } @@ -65,22 +80,18 @@ export class MyDataSource extends BasicDataSource { return this.dataArray.length; } - public getData(index: number): string { return this.dataArray[index]; } - public addData(index: number, data: string): void { this.dataArray.splice(index, 0, data); this.notifyDataAdd(index); } - public pushData(data: string): void { this.dataArray.push(data); this.notifyDataAdd(this.dataArray.length - 1); } } - // [End Case1] \ No newline at end of file diff --git a/ArkUI/Proper_Use_Layout/entry/src/main/ets/segment/segment2.ets b/ArkUI/Proper_Use_Layout/entry/src/main/ets/segment/segment2.ets index 8a35f830bdb7994fb799fa75247bd13ecac808da..ceba20c641185308c1a3da842bbf0dbfcb72936e 100644 --- a/ArkUI/Proper_Use_Layout/entry/src/main/ets/segment/segment2.ets +++ b/ArkUI/Proper_Use_Layout/entry/src/main/ets/segment/segment2.ets @@ -1,3 +1,18 @@ +/* +* Copyright (C) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + // [Start Case2] import { MyDataSource } from './segment1'; @@ -12,7 +27,9 @@ struct NotSetHeightTestPage { LazyForEach(this.data, (item: string, index: number) => { ListItem() { Row() { - Text('item value: ' + item + (index + 1)).fontSize(20).margin(10) + Text('item value: ' + item + (index + 1)) + .fontSize(20) + .margin(10) } } }) @@ -20,5 +37,4 @@ struct NotSetHeightTestPage { } } } - // [End Case2] \ No newline at end of file diff --git a/ArkUI/Proper_Use_Layout/entry/src/main/ets/segment/segment3.ets b/ArkUI/Proper_Use_Layout/entry/src/main/ets/segment/segment3.ets index 8e402c582648152c4fbc2ee9ba9fd998df0e788d..d6af7e0482e95f6af54386d19e9e2c4596b0bbed 100644 --- a/ArkUI/Proper_Use_Layout/entry/src/main/ets/segment/segment3.ets +++ b/ArkUI/Proper_Use_Layout/entry/src/main/ets/segment/segment3.ets @@ -1,7 +1,21 @@ +/* +* Copyright (C) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + // [Start Case3] import { MyDataSource } from './segment1'; - @Entry @Component struct SetHeightTestPage { @@ -13,13 +27,16 @@ struct SetHeightTestPage { LazyForEach(this.data, (item: string, index: number) => { ListItem() { Row() { - Text('item value: ' + item + (index + 1)).fontSize(20).margin(10) + Text('item value: ' + item + (index + 1)) + .fontSize(20) + .margin(10) } } }) - }.width('100%').height(500) + } + .width('100%') + .height(500) } } } - // [End Case3] \ No newline at end of file diff --git a/ArkUI/Proper_Use_Layout/entry/src/main/module.json5 b/ArkUI/Proper_Use_Layout/entry/src/main/module.json5 index a1cea8b6a4560cee7bda7a2db52f310c035ab6c8..44c5e49d8129f5d5bcc87ee6768d4a007d4877ca 100644 --- a/ArkUI/Proper_Use_Layout/entry/src/main/module.json5 +++ b/ArkUI/Proper_Use_Layout/entry/src/main/module.json5 @@ -6,8 +6,6 @@ "mainElement": "EntryAbility", "deviceTypes": [ "phone", - "tablet", - "2in1" ], "deliveryWithInstall": true, "installationFree": false, diff --git a/ArkUI/Proper_Use_Layout/entry/src/main/resources/base/profile/main_pages.json b/ArkUI/Proper_Use_Layout/entry/src/main/resources/base/profile/main_pages.json index 1898d94f58d6128ab712be2c68acc7c98e9ab9ce..7230a3f2b31a1de8b2b3a36a3e4448bb571b3434 100644 --- a/ArkUI/Proper_Use_Layout/entry/src/main/resources/base/profile/main_pages.json +++ b/ArkUI/Proper_Use_Layout/entry/src/main/resources/base/profile/main_pages.json @@ -1,5 +1,7 @@ { "src": [ - "pages/Index" + "pages/Index", + "segment/segment2", + "segment/segment3" ] } diff --git a/ArkUI/Proper_Use_Layout/entry/src/mock/mock-config.json5 b/ArkUI/Proper_Use_Layout/entry/src/mock/mock-config.json5 deleted file mode 100644 index 7a73a41bfdf76d6f793007240d80983a52f15f97..0000000000000000000000000000000000000000 --- a/ArkUI/Proper_Use_Layout/entry/src/mock/mock-config.json5 +++ /dev/null @@ -1,2 +0,0 @@ -{ -} \ No newline at end of file diff --git a/ArkUI/Proper_Use_Layout/entry/src/ohosTest/ets/test/Ability.test.ets b/ArkUI/Proper_Use_Layout/entry/src/ohosTest/ets/test/Ability.test.ets deleted file mode 100644 index 85c78f67579d6e31b5f5aeea463e216b9b141048..0000000000000000000000000000000000000000 --- a/ArkUI/Proper_Use_Layout/entry/src/ohosTest/ets/test/Ability.test.ets +++ /dev/null @@ -1,35 +0,0 @@ -import { hilog } from '@kit.PerformanceAnalysisKit'; -import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; - -export default function abilityTest() { - describe('ActsAbilityTest', () => { - // Defines a test suite. Two parameters are supported: test suite name and test suite function. - beforeAll(() => { - // Presets an action, which is performed only once before all test cases of the test suite start. - // This API supports only one parameter: preset action function. - }) - beforeEach(() => { - // Presets an action, which is performed before each unit test case starts. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: preset action function. - }) - afterEach(() => { - // Presets a clear action, which is performed after each unit test case ends. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: clear action function. - }) - afterAll(() => { - // Presets a clear action, which is performed after all test cases of the test suite end. - // This API supports only one parameter: clear action function. - }) - it('assertContain', 0, () => { - // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. - hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); - let a = 'abc'; - let b = 'b'; - // Defines a variety of assertion methods, which are used to declare expected boolean conditions. - expect(a).assertContain(b); - expect(a).assertEqual(a); - }) - }) -} \ No newline at end of file diff --git a/ArkUI/Proper_Use_Layout/entry/src/ohosTest/ets/test/List.test.ets b/ArkUI/Proper_Use_Layout/entry/src/ohosTest/ets/test/List.test.ets deleted file mode 100644 index 794c7dc4ed66bd98fa3865e07922906e2fcef545..0000000000000000000000000000000000000000 --- a/ArkUI/Proper_Use_Layout/entry/src/ohosTest/ets/test/List.test.ets +++ /dev/null @@ -1,5 +0,0 @@ -import abilityTest from './Ability.test'; - -export default function testsuite() { - abilityTest(); -} \ No newline at end of file diff --git a/ArkUI/Proper_Use_Layout/entry/src/test/List.test.ets b/ArkUI/Proper_Use_Layout/entry/src/test/List.test.ets deleted file mode 100644 index bb5b5c3731e283dd507c847560ee59bde477bbc7..0000000000000000000000000000000000000000 --- a/ArkUI/Proper_Use_Layout/entry/src/test/List.test.ets +++ /dev/null @@ -1,5 +0,0 @@ -import localUnitTest from './LocalUnit.test'; - -export default function testsuite() { - localUnitTest(); -} \ No newline at end of file diff --git a/ArkUI/Proper_Use_Layout/entry/src/test/LocalUnit.test.ets b/ArkUI/Proper_Use_Layout/entry/src/test/LocalUnit.test.ets deleted file mode 100644 index 165fc1615ee8618b4cb6a622f144a9a707eee99f..0000000000000000000000000000000000000000 --- a/ArkUI/Proper_Use_Layout/entry/src/test/LocalUnit.test.ets +++ /dev/null @@ -1,33 +0,0 @@ -import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; - -export default function localUnitTest() { - describe('localUnitTest', () => { - // Defines a test suite. Two parameters are supported: test suite name and test suite function. - beforeAll(() => { - // Presets an action, which is performed only once before all test cases of the test suite start. - // This API supports only one parameter: preset action function. - }); - beforeEach(() => { - // Presets an action, which is performed before each unit test case starts. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: preset action function. - }); - afterEach(() => { - // Presets a clear action, which is performed after each unit test case ends. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: clear action function. - }); - afterAll(() => { - // Presets a clear action, which is performed after all test cases of the test suite end. - // This API supports only one parameter: clear action function. - }); - it('assertContain', 0, () => { - // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. - let a = 'abc'; - let b = 'b'; - // Defines a variety of assertion methods, which are used to declare expected boolean conditions. - expect(a).assertContain(b); - expect(a).assertEqual(a); - }); - }); -} \ No newline at end of file diff --git a/ArkUI/Proper_Use_Layout/oh-package.json5 b/ArkUI/Proper_Use_Layout/oh-package.json5 index a8aff0c5aff22d78aa26fd19c3861f4320e951ff..f440d114b8a9d9aeadd0e891bba0d0d076e70936 100644 --- a/ArkUI/Proper_Use_Layout/oh-package.json5 +++ b/ArkUI/Proper_Use_Layout/oh-package.json5 @@ -3,8 +3,5 @@ "description": "Please describe the basic information.", "dependencies": { }, - "devDependencies": { - "@ohos/hypium": "1.0.21", - "@ohos/hamock": "1.0.0" - } + "devDependencies": {} } diff --git a/ArkUI/Proper_Use_Layout/screenshots/Screenshot.jpeg b/ArkUI/Proper_Use_Layout/screenshots/Screenshot.jpeg deleted file mode 100644 index 5c4d3548c337cfa452db36ff85aa23a952e0afd7..0000000000000000000000000000000000000000 Binary files a/ArkUI/Proper_Use_Layout/screenshots/Screenshot.jpeg and /dev/null differ diff --git a/ArkUI/PureTabsExt/README.md b/ArkUI/PureTabsExt/README.md new file mode 100644 index 0000000000000000000000000000000000000000..fdd98fc080aae135424c3b0faef31e68194d3c2a --- /dev/null +++ b/ArkUI/PureTabsExt/README.md @@ -0,0 +1,61 @@ +# Tabs开发实践案例-补充案例 +### 简介 + 本示例主要Tabs组件常用的场景实践示例的补充内容,补充了TabsBar显示效果相关的子场景,包含TabBar背景模糊效果、页签超出TabBar区域显示、TabBar边缘渐隐、TabBar偏移、切换指定页签等场景。 + +### 效果预览 +| TabBar背景模糊效果 | 页签超出TabBar区域显示,TabBar边缘渐隐 | TabBar偏移 | 切换指定页签 | +|--------------------------------------------|--------------------------------------------|--------------------------------------|-------------------------------------| +| ![image](screenshots/device/tab_ext_1.png) | ![image](screenshots/device/tab_ext_2.png) | ![image](screenshots/device/tab_ext_3.png) | ![image](screenshots/device/tab_ext_4.png) | +### 工程目录 +``` +├──entry/src/main/ets // 代码区 +│ ├──common +│ │ └──constant +│ │ └──Constants.ets // 常量类 +│ ├──entryability +│ │ └──EntryAbility.ets // 程序入口类 +│ ├──entrybackupability +│ │ └──EntryBackupAbility.ets +│ ├──pages +│ │ └──Index.ets // 入口页 +│ └──view +│ ├──InTabComponent.ets // 设置TabBar偏移量及透明度 +│ ├──OutTabComponent.ets // 页签超出TabBar区域显示 +│ ├──SearchBarComponent.ets // 搜索框 +│ └──SwitchTabComponent.ets // 切换至指定页签 +└──entry/src/main/resources // 应用资源目录 +``` +### 具体实现 +- TabBar背景模糊效果 + 通过设置Tabs组件的barOverlap属性,可以实现TabBar变模糊并叠加在TabContent之上,并且配合barBackgroundBlurStyle属性实现毛玻璃效果。 +- 页签超出TabBar区域显示 + 通过barModifier设置tabBar的clip属性,实现页签超出tabBar区域显示效果。 +- TabBar边缘渐隐 + 通过配置fadingEdge(true)实现TabBar边缘渐隐。 +- TabBar偏移 + 通过TabsController的setTabBarTranslate()、setTabBarOpacity()方法可以设置TabBar偏移量及透明度。 +- 切换指定页签 + Tabs组件除了自带的滑动切换和点击切换功能外,还提供了两种可编程方式来切换页签。第一种是通过调用TabsController的changeIndex()方法,切换到指定的index;第二种是定义一个由@State修饰的变量currentIndex,并将其绑定到Tabs,通过修改currentIndex的值来触发页签切换。 + +### 相关权限 +无 + +### 约束与限制 +1. 本示例仅支持标准系统上运行,支持设备:华为手机。 + +2. HarmonyOS系统:HarmonyOS 5.0.5 Release及以上。 + +3. DevEco Studio版本:DevEco Studio 5.0.5 Release及以上。 + +4. HarmonyOS SDK版本:HarmonyOS 5.0.5 Release SDK及以上。 + +### 下载 + +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set ArkUI/PureTabsExt +git checkout +``` diff --git a/ArkUI/PureTabsExt/entry/src/main/ets/entryability/EntryAbility.ets b/ArkUI/PureTabsExt/entry/src/main/ets/entryability/EntryAbility.ets index d3ee54d2beea61d38866762868bd056d3e39e3c9..6e8ddad71a3f9ef705cc39a675342118ec298ffd 100644 --- a/ArkUI/PureTabsExt/entry/src/main/ets/entryability/EntryAbility.ets +++ b/ArkUI/PureTabsExt/entry/src/main/ets/entryability/EntryAbility.ets @@ -14,6 +14,7 @@ */ import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { BusinessError } from '@kit.BasicServicesKit'; import { hilog } from '@kit.PerformanceAnalysisKit'; import { window } from '@kit.ArkUI'; @@ -21,7 +22,12 @@ const DOMAIN = 0x0000; export default class EntryAbility extends UIAbility { onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { - this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + try { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + } catch (error) { + let err = error as BusinessError; + hilog.warn(0x000, 'testTag', `setColorMode failed, code=${err.code}, message=${err.message}`); + } hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); } diff --git a/ArkUI/PureTabsExt/entry/src/main/ets/view/InTabComponent.ets b/ArkUI/PureTabsExt/entry/src/main/ets/view/InTabComponent.ets index 95476169b1cf53aa29d639b0bb914a0e9189d0f4..81999269719c8423601719861109f4c5a6cc2673 100644 --- a/ArkUI/PureTabsExt/entry/src/main/ets/view/InTabComponent.ets +++ b/ArkUI/PureTabsExt/entry/src/main/ets/view/InTabComponent.ets @@ -12,7 +12,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { AbilityConstant,Configuration } from "@kit.AbilityKit"; +import { AbilityConstant, common,Configuration } from "@kit.AbilityKit"; +import { BusinessError } from '@kit.BasicServicesKit'; +import { hilog } from "@kit.PerformanceAnalysisKit"; // [Start tabs_bar_translate] @Component @@ -38,10 +40,13 @@ export default struct InTabComponent { } private async updateTabItems(){ - await this.getUIContext().getHostContext()?.resourceManager.getStringArrayValue($r('app.strarray.in_tabs_items')) + await this.getUIContext().getHostContext()?.resourceManager.getStringArrayValue($r('app.strarray.in_tabs_items').id) .then((strarray: string[]) => { this.tabItems = strarray; - }); + }) + .catch((err: BusinessError) => { + hilog.error(0x000, 'testTag', `getStringArrayValue failed, code=${err.code}, message=${err.message}`) + }) } subscribeSystemLanguageUpdate() { diff --git a/ArkUI/PureTabsExt/entry/src/main/ets/view/SwitchTabComponent.ets b/ArkUI/PureTabsExt/entry/src/main/ets/view/SwitchTabComponent.ets index 03adf3c67f746e3df24c07e84a6b43595957b9f3..e2528a293becb424feb6926c7ecbd0dfba35af70 100644 --- a/ArkUI/PureTabsExt/entry/src/main/ets/view/SwitchTabComponent.ets +++ b/ArkUI/PureTabsExt/entry/src/main/ets/view/SwitchTabComponent.ets @@ -13,7 +13,8 @@ * limitations under the License. */ import { AbilityConstant, Configuration } from "@kit.AbilityKit"; -import { Constants } from "../common/constant/Constants"; +import { BusinessError } from '@kit.BasicServicesKit'; +import { hilog } from "@kit.PerformanceAnalysisKit"; // [Start custom_switch_tab] @Component @@ -32,10 +33,13 @@ export default struct SwitchTabComponent { private async updateTabItems() { await this.getUIContext() - .getHostContext()?.resourceManager.getStringArrayValue($r('app.strarray.switch_tabs_items')) + .getHostContext()?.resourceManager.getStringArrayValue($r('app.strarray.switch_tabs_items').id) .then((strarray: string[]) => { this.tabItems = strarray; - }); + }) + .catch((err: BusinessError) => { + hilog.error(0x000, 'testTag', `getStringArrayValue failed, code=${err.code}, message=${err.message}`) + }) } subscribeSystemLanguageUpdate() { diff --git a/ArkUI/PureTabsExt/entry/src/main/module.json5 b/ArkUI/PureTabsExt/entry/src/main/module.json5 index a1cea8b6a4560cee7bda7a2db52f310c035ab6c8..44c5e49d8129f5d5bcc87ee6768d4a007d4877ca 100644 --- a/ArkUI/PureTabsExt/entry/src/main/module.json5 +++ b/ArkUI/PureTabsExt/entry/src/main/module.json5 @@ -6,8 +6,6 @@ "mainElement": "EntryAbility", "deviceTypes": [ "phone", - "tablet", - "2in1" ], "deliveryWithInstall": true, "installationFree": false, diff --git a/ArkTS_high_performance_segment/.gitignore b/ArkUI/StateManagement/.gitignore similarity index 100% rename from ArkTS_high_performance_segment/.gitignore rename to ArkUI/StateManagement/.gitignore diff --git a/ArkUI/StateManagement/AppScope/app.json5 b/ArkUI/StateManagement/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..555e16abacdd36eb1771ceff940174bfe7e8faf2 --- /dev/null +++ b/ArkUI/StateManagement/AppScope/app.json5 @@ -0,0 +1,10 @@ +{ + "app": { + "bundleName": "com.example.statemanagement", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:layered_image", + "label": "$string:app_name" + } +} diff --git a/ArkUI/StateManagement/AppScope/resources/base/element/string.json b/ArkUI/StateManagement/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f2aaa15ddeb29f99e8453bc919d10efcf44d0361 --- /dev/null +++ b/ArkUI/StateManagement/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "StateManagement" + } + ] +} diff --git a/MultiVideoApplication/AppScope/resources/base/media/background.png b/ArkUI/StateManagement/AppScope/resources/base/media/background.png similarity index 100% rename from MultiVideoApplication/AppScope/resources/base/media/background.png rename to ArkUI/StateManagement/AppScope/resources/base/media/background.png diff --git a/MultiVideoApplication/products/phone/src/main/resources/base/media/foreground.png b/ArkUI/StateManagement/AppScope/resources/base/media/foreground.png similarity index 100% rename from MultiVideoApplication/products/phone/src/main/resources/base/media/foreground.png rename to ArkUI/StateManagement/AppScope/resources/base/media/foreground.png diff --git a/MultiCommunityApplication/AppScope/resources/base/media/layered_image.json b/ArkUI/StateManagement/AppScope/resources/base/media/layered_image.json similarity index 100% rename from MultiCommunityApplication/AppScope/resources/base/media/layered_image.json rename to ArkUI/StateManagement/AppScope/resources/base/media/layered_image.json diff --git a/ArkUI/StateManagement/LICENSE b/ArkUI/StateManagement/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..18795a48d6b12fcdc1aa7bac9a9cb99f83815267 --- /dev/null +++ b/ArkUI/StateManagement/LICENSE @@ -0,0 +1,78 @@ + Copyright (c) 2025 Huawei Device Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + 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. + +Apache License, Version 2.0 +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. + +"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. + +2. Grant of Copyright License. + +Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. + +Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. + +You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: +1.You must give any other recipients of the Work or Derivative Works a copy of this License; and +2.You must cause any modified files to carry prominent notices stating that You changed the files; and +3.You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and +4.If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. + +You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. + +5. Submission of Contributions. + +Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. + +6. Trademarks. + +This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. + +Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. + +In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. + +While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/ArkUI/StateManagement/README.md b/ArkUI/StateManagement/README.md new file mode 100644 index 0000000000000000000000000000000000000000..58903262d186e9383751d7479108a5a2a42c258f --- /dev/null +++ b/ArkUI/StateManagement/README.md @@ -0,0 +1,34 @@ +# 状态管理最佳实践 + +### 介绍 + +本示例通过ArkUI状态管理@State、@Prop、@Link、@Observed等装饰器,实现不同页面之间状态同步情景和应用的数据状态管理情景。帮助开发者掌握应用的数据状态同步处理。 + +### 相关权限 + +不涉及。 + +### 依赖 + +不涉及。 + +### 约束与限制 + +1.本示例仅支持标准系统上运行,支持设备:华为手机。 + +2.HarmonyOS系统:HarmonyOS 5.0.5 Release及以上。 + +3.DevEco Studio版本:DevEco Studio 5.0.5 Release及以上。 + +4.HarmonyOS SDK版本:HarmonyOS 5.0.5 Release SDK及以上。 + +### 下载 + +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set ArkUI/StateManagement +git checkout +``` diff --git a/ArkUI/StateManagement/build-profile.json5 b/ArkUI/StateManagement/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..9e87e7e6f19020fe21192844709f192cec80fd44 --- /dev/null +++ b/ArkUI/StateManagement/build-profile.json5 @@ -0,0 +1,42 @@ +{ + "app": { + "signingConfigs": [], + "products": [ + { + "name": "default", + "signingConfig": "default", + "targetSdkVersion": "5.0.5(17)", + "compatibleSdkVersion": "5.0.5(17)", + "runtimeOS": "HarmonyOS", + "buildOption": { + "strictMode": { + "caseSensitiveCheck": true, + "useNormalizedOHMUrl": true + } + } + } + ], + "buildModeSet": [ + { + "name": "debug", + }, + { + "name": "release" + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/ArkUI/orientationDevelopment/code-linter.json5 b/ArkUI/StateManagement/code-linter.json5 similarity index 100% rename from ArkUI/orientationDevelopment/code-linter.json5 rename to ArkUI/StateManagement/code-linter.json5 diff --git a/ArkUI/Component_Nesting_Optimization/entry/.gitignore b/ArkUI/StateManagement/entry/.gitignore similarity index 100% rename from ArkUI/Component_Nesting_Optimization/entry/.gitignore rename to ArkUI/StateManagement/entry/.gitignore diff --git a/Privacy/ContactData/build-profile.json5 b/ArkUI/StateManagement/entry/build-profile.json5 similarity index 100% rename from Privacy/ContactData/build-profile.json5 rename to ArkUI/StateManagement/entry/build-profile.json5 diff --git a/ArkUI/StateManagement/entry/hvigorfile.ts b/ArkUI/StateManagement/entry/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..b0e3a1ab98a91bc918d6404b2413111a5011f14a --- /dev/null +++ b/ArkUI/StateManagement/entry/hvigorfile.ts @@ -0,0 +1,6 @@ +import { hapTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins: [] /* Custom plugin to extend the functionality of Hvigor. */ +} \ No newline at end of file diff --git a/Privacy/ContactData/obfuscation-rules.txt b/ArkUI/StateManagement/entry/obfuscation-rules.txt similarity index 100% rename from Privacy/ContactData/obfuscation-rules.txt rename to ArkUI/StateManagement/entry/obfuscation-rules.txt diff --git a/CrossPlatformCompatibility/entry/oh-package.json5 b/ArkUI/StateManagement/entry/oh-package.json5 similarity index 100% rename from CrossPlatformCompatibility/entry/oh-package.json5 rename to ArkUI/StateManagement/entry/oh-package.json5 diff --git a/ArkUI/StateManagement/entry/src/main/ets/entryability/EntryAbility.ets b/ArkUI/StateManagement/entry/src/main/ets/entryability/EntryAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..508880af8c33aa838016d1cd4b2c68be2f447540 --- /dev/null +++ b/ArkUI/StateManagement/entry/src/main/ets/entryability/EntryAbility.ets @@ -0,0 +1,44 @@ +import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; + +const DOMAIN = 0x0000; + +export default class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onDestroy(): void { + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + // Main window is created, set main page for this ability + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + windowStage.loadContent('pages/Index', (err) => { + if (err.code) { + hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err)); + return; + } + hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.'); + }); + } + + onWindowStageDestroy(): void { + // Main window is destroyed, release UI related resources + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground(): void { + // Ability has brought to foreground + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground(): void { + // Ability has back to background + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground'); + } +} \ No newline at end of file diff --git a/ArkUI/StateManagement/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets b/ArkUI/StateManagement/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e4de99282050bad799ac892eb85ac5449364a51 --- /dev/null +++ b/ArkUI/StateManagement/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets @@ -0,0 +1,16 @@ +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit'; + +const DOMAIN = 0x0000; + +export default class EntryBackupAbility extends BackupExtensionAbility { + async onBackup() { + hilog.info(DOMAIN, 'testTag', 'onBackup ok'); + await Promise.resolve(); + } + + async onRestore(bundleVersion: BundleVersion) { + hilog.info(DOMAIN, 'testTag', 'onRestore ok %{public}s', JSON.stringify(bundleVersion)); + await Promise.resolve(); + } +} \ No newline at end of file diff --git a/ArkUI/StateManagement/entry/src/main/ets/pages/Index.ets b/ArkUI/StateManagement/entry/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..633adadd00282a226ff7901c1d9e32a19e85d144 --- /dev/null +++ b/ArkUI/StateManagement/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + +@Entry +@Component +struct Index { + private buttonList: string[] = + Array.from({ length: 12 }, (_: number, i: number) => `Segment${i + 1}`); + @Provide("appPathStack") appPathStack: NavPathStack = new NavPathStack(); + @Provide("discoverPathStack") discoverPathStack: NavPathStack = new NavPathStack(); + + build() { + Navigation(this.appPathStack) { + List({ space: 12 }) { + ForEach(this.buttonList, (item: string) => { + ListItem() { + Button(item).onClick(() => this.appPathStack.pushPathByName(item, null)); + } + }, (item: string) => item) + } + .width('100%') + .height('100%') + .alignListItem(ListItemAlign.Center) + } + .mode(NavigationMode.Stack) + .height('100%') + .width('100%') + } +} \ No newline at end of file diff --git a/ArkUI/StateManagement/entry/src/main/ets/segment/segment.ets b/ArkUI/StateManagement/entry/src/main/ets/segment/segment.ets new file mode 100644 index 0000000000000000000000000000000000000000..90d01106be3521aba361fb5f63de6decafa920f4 --- /dev/null +++ b/ArkUI/StateManagement/entry/src/main/ets/segment/segment.ets @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ +@Builder +export function Segment01Builder() { + NavDestination(){ + MyComponent() + } +} + +// [Start Counter_example1_start] +@Observed +class Translate { + translateX: number = 20; +} + +@Component +struct MyComponent { + @State translateObj: Translate = new Translate(); // The variable translateObj is not associated with any UI component and should not be defined as a state variable + @State buttonMsg: string = 'I am button'; // The variable buttonMsg is not associated with any UI component and should not be defined as a state variable + build() { + } +} +// [End Counter_example1_start] \ No newline at end of file diff --git a/ArkUI/StateManagement/entry/src/main/ets/segment/segment10.ets b/ArkUI/StateManagement/entry/src/main/ets/segment/segment10.ets new file mode 100644 index 0000000000000000000000000000000000000000..a0763e90c13a47f0817efe4ec9d4934eef9ccf9e --- /dev/null +++ b/ArkUI/StateManagement/entry/src/main/ets/segment/segment10.ets @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + +@Builder +export function Segment10Builder() { + NavDestination(){ + Index() + } +} +// [Start Counter_example5] +@Component +struct Index { + @State currentIndex: number = 0; // The subscript of the currently selected list item + private listData: string[] = []; + + + aboutToAppear(): void { + for (let i = 0; i < 10; i++) { + this.listData.push(`${i}`); + } + } + + + build() { + Row() { + Column() { + List() { + ForEach(this.listData, (item: string, index: number) => { + ListItem() { + ListItemComponent({ item: item, index: index, currentIndex: this.currentIndex }) + } + }) + } + .alignListItem(ListItemAlign.Center) + } + .width('100%') + } + .height('100%') + } +} + + +@Component +struct ListItemComponent { + @Prop item: string; + @Prop index: number; // The subscript of the list item + @Link currentIndex: number; + private sizeFont: number = 50; + + + isRender(): number { + console.info(`ListItemComponent ${this.index} Text is rendered`); + return this.sizeFont; + } + + + build() { + Column() { + Text(this.item) + .fontSize(this.isRender())// Dynamically set the color of the text according to the difference between the index and currentIndex of the current list item. + .fontColor(Math.abs(this.index - this.currentIndex) <= 1 ? Color.Red : Color.Blue) + .onClick(() => { + this.currentIndex = this.index; + }) + } + } +} +// [End Counter_example5] \ No newline at end of file diff --git a/ArkUI/StateManagement/entry/src/main/ets/segment/segment11.ets b/ArkUI/StateManagement/entry/src/main/ets/segment/segment11.ets new file mode 100644 index 0000000000000000000000000000000000000000..e611c0d9f6abcb1b87b978219a50cdd98e9935b5 --- /dev/null +++ b/ArkUI/StateManagement/entry/src/main/ets/segment/segment11.ets @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + +@Builder +export function Segment11Builder() { + NavDestination(){ + UseWatchListener() + } +} +// [Start Case7] +@Entry +@Component +struct UseWatchListener { + @State currentIndex: number = 0; // The subscript of the currently selected list item + private listData: string[] = []; + aboutToAppear(): void { + for (let i = 0; i < 10; i++) { + this.listData.push(`${i}`); + } + } + build() { + Row() { + Column() { + List() { + ForEach(this.listData, (item: string, index: number) => { + ListItem() { + ListItemComponent({ item: item, index: index, currentIndex: this.currentIndex }) + } + }) + } + .height('100%') + .width('100%') + .alignListItem(ListItemAlign.Center) + } + .width('100%') + } + .height('100%') + } +} +@Component +struct ListItemComponent { + @Prop item: string; + @Prop index: number; // The subscript of the list item + @Link @Watch('onCurrentIndexUpdate') currentIndex: number; + @State color: Color = Math.abs(this.index - this.currentIndex) <= 1 ? Color.Red : Color.Blue; + isRender(): number { + console.info(`ListItemComponent ${this.index} Text is rendered`); + return 50; + } + onCurrentIndexUpdate() { + // Dynamically modifies the value of color based on the difference between the index and currentIndex of the current list item. + this.color = Math.abs(this.index - this.currentIndex) <= 1 ? Color.Red : Color.Blue; + } + build() { + Column() { + Text(this.item) + .fontSize(this.isRender()) + .fontColor(this.color) + .onClick(() => { + this.currentIndex = this.index; + }) + } + } +} +// [End Case7] \ No newline at end of file diff --git a/ArkUI/StateManagement/entry/src/main/ets/segment/segment12.ets b/ArkUI/StateManagement/entry/src/main/ets/segment/segment12.ets new file mode 100644 index 0000000000000000000000000000000000000000..07d106c3f27da228fb75c780475ba5e06e78a4ac --- /dev/null +++ b/ArkUI/StateManagement/entry/src/main/ets/segment/segment12.ets @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + +// [Start Case8] +import { ButtonComponent } from '../segment/segment13'; +import { ListItemComponent } from '../segment/segment14'; +@Entry +@Component +struct UseEmitterPublish { + listData: string[] = ['A', 'B', 'C', 'D', 'E', 'F']; + build() { + Column() { + Row() { + Column() { + ButtonComponent() + } + } + Column() { + Column() { + List() { + ForEach(this.listData, (item: string, index: number) => { + ListItemComponent({ myItem: item, index: index }) + }) + } + .height('100%') + .width('100%') + .alignListItem(ListItemAlign.Center) + } + } + } + } +} +// [End Case8] +@Builder +export function Segment12Builder() { + NavDestination(){ + UseEmitterPublish() + } +} \ No newline at end of file diff --git a/ArkUI/StateManagement/entry/src/main/ets/segment/segment13.ets b/ArkUI/StateManagement/entry/src/main/ets/segment/segment13.ets new file mode 100644 index 0000000000000000000000000000000000000000..5acd363a25e1fbe438dd152b11d2d3d55bb78434 --- /dev/null +++ b/ArkUI/StateManagement/entry/src/main/ets/segment/segment13.ets @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + +// [Start Case9] +import { emitter } from '@kit.BasicServicesKit'; +const CHANGE_COLOR_EVENT_ID = 1; +@Component +export struct ButtonComponent { + value: number = 2; + build() { + Button(`下标是${this.value}的倍数的组件文字变为红色`) + .onClick(() => { + let event: emitter.InnerEvent = { + eventId: CHANGE_COLOR_EVENT_ID, + priority: emitter.EventPriority.LOW + }; + let eventData: emitter.EventData = { + data: { + value: this.value + } + }; + // Sends an event with eventId of CHANGE_COLOR_EVENT_ID and event content of eventData + emitter.emit(event, eventData); + this.value++; + }) + } +} +// [End Case9] \ No newline at end of file diff --git a/ArkUI/StateManagement/entry/src/main/ets/segment/segment14.ets b/ArkUI/StateManagement/entry/src/main/ets/segment/segment14.ets new file mode 100644 index 0000000000000000000000000000000000000000..f82a457d79d29d2665e9baac6473a0d6de45371d --- /dev/null +++ b/ArkUI/StateManagement/entry/src/main/ets/segment/segment14.ets @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + +// [Start Case10] +import { emitter } from '@kit.BasicServicesKit'; +const CHANGE_COLOR_EVENT_ID = 1; +@Component +export struct ListItemComponent { + @State color: Color = Color.Black; + @Prop index: number; + @Prop myItem: string; + aboutToAppear(): void { + let event: emitter.InnerEvent = { + eventId: CHANGE_COLOR_EVENT_ID + }; + // Execute this callback after receiving an event with eventId of CHANGE_COLOR_EVENT_ID + let callback = (eventData: emitter.EventData): void => { + if (eventData.data?.value !== 0 && this.index % eventData.data?.value === 0) { + this.color = Color.Red; + } + }; + // Subscribe to events with eventId of CHANGE_COLOR_EVENT_ID + emitter.on(event, callback); + } + build() { + Column() { + Text(this.myItem) + .fontSize(50) + .fontColor(this.color) + } + } +} +// [End Case10] \ No newline at end of file diff --git a/ArkUI/StateManagement/entry/src/main/ets/segment/segment2.ets b/ArkUI/StateManagement/entry/src/main/ets/segment/segment2.ets new file mode 100644 index 0000000000000000000000000000000000000000..d7d88d7929bb146ed9d5bde52fa93a6d7a800992 --- /dev/null +++ b/ArkUI/StateManagement/entry/src/main/ets/segment/segment2.ets @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ +@Builder +export function Segment02Builder() { + NavDestination(){ + MyComponent() + } +} +// [Start Counter_example2_start] +@Observed +class Translate { + translateX: number = 20; +} + +@Component +struct MyComponent { + @State translateObj: Translate = new Translate(); + @State buttonMsg: string = 'I am button'; + build() { + Column() { + Button(this.buttonMsg) // Here we just read the value of the variable buttonMsg, without any write operation. + } + } +} +// [End Counter_example2_start] \ No newline at end of file diff --git a/ArkUI/StateManagement/entry/src/main/ets/segment/segment3.ets b/ArkUI/StateManagement/entry/src/main/ets/segment/segment3.ets new file mode 100644 index 0000000000000000000000000000000000000000..833ab40910d6fb4154911c9c20c40591c9b9b503 --- /dev/null +++ b/ArkUI/StateManagement/entry/src/main/ets/segment/segment3.ets @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + +@Builder +export function Segment03Builder() { + NavDestination(){ + UnnecessaryState1() + } +} +// [Start Case1_start] +@Observed +class Translate { + translateX: number = 20; +} + +@Component +struct UnnecessaryState1 { + @State translateObj: Translate = new Translate(); // If there are both read and write operations and a Button component is associated with it, it is recommended to use state variables. + buttonMsg = 'I am button'; // Only read the value of the variable buttonMsg, without any write operations, just use the general variables directly + build() { + Column() { + Button(this.buttonMsg) + .onClick(() => { + this.getUIContext().animateTo({ + duration: 50 + }, () => { + this.translateObj.translateX = (this.translateObj.translateX + 50) % 150; // Reassign value to variable translateObj when clicked. + }) + }) + } + .translate({ + x: this.translateObj.translateX // Retrieve the value in translateObj. + }) + } +} +// [End Case1_start] \ No newline at end of file diff --git a/ArkUI/StateManagement/entry/src/main/ets/segment/segment4.ets b/ArkUI/StateManagement/entry/src/main/ets/segment/segment4.ets new file mode 100644 index 0000000000000000000000000000000000000000..21f5a4df2ffd5e877f367455afc9c85307a896f9 --- /dev/null +++ b/ArkUI/StateManagement/entry/src/main/ets/segment/segment4.ets @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ +@Builder +export function Segment04Builder() { + NavDestination(){ + Index() + } +} +// [Start counter_example] + +@Component +struct Index { + @State message: string = ''; + // Define methods for changing state variables (multiple modifications of state variables) + appendMsg(newMsg: string) { + this.message += newMsg; + this.message += ';'; + this.message += '
'; + } + build() { + Column() { + Button('Click Print Log') + .onClick(() => { + this.appendMsg('Operational state variables'); // Calling encapsulated methods for changing state variables + }) + .width('90%') + .backgroundColor(Color.Blue) + .fontColor(Color.White) + .margin({ top: 10}) + } + .justifyContent(FlexAlign.Start) + .alignItems(HorizontalAlign.Center) + .margin({ top: 15 }) + } +} +// [End counter_example] \ No newline at end of file diff --git a/ArkUI/StateManagement/entry/src/main/ets/segment/segment5.ets b/ArkUI/StateManagement/entry/src/main/ets/segment/segment5.ets new file mode 100644 index 0000000000000000000000000000000000000000..c05f303c48e006387e25e7fd6ec90aa48174cfc2 --- /dev/null +++ b/ArkUI/StateManagement/entry/src/main/ets/segment/segment5.ets @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ +@Builder +export function Segment05Builder() { + NavDestination(){ + UnnecessaryState2() + } +} +// [Start Case2_start] +@Entry +@Component +struct UnnecessaryState2 { + @State message: string = ''; + // Define methods for changing state variables (intermediate variables are manipulated during method execution, state variables are modified only once) + appendMsg(newMsg: string) { + let message = this.message; + message += newMsg; + message += ';'; + message += '
'; + this.message = message; + } + build() { + Column() { + Button('Click Print Log') + .onClick(() => { + this.appendMsg('Manipulating Temporary Variables'); // Calling encapsulated methods for changing state variables + }) + .width('90%') + .backgroundColor(Color.Blue) + .fontColor(Color.White) + .margin({ top: 10 }) + } + .justifyContent(FlexAlign.Start) + .alignItems(HorizontalAlign.Center) + .margin({ top: 15 }) + } +} +// [End Case2_start] \ No newline at end of file diff --git a/ArkUI/StateManagement/entry/src/main/ets/segment/segment6.ets b/ArkUI/StateManagement/entry/src/main/ets/segment/segment6.ets new file mode 100644 index 0000000000000000000000000000000000000000..42beb0647c32f1c87f156443ab02d8c01cb687d7 --- /dev/null +++ b/ArkUI/StateManagement/entry/src/main/ets/segment/segment6.ets @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ +@Builder +export function Segment06Builder() { + NavDestination(){ + UserInfoView() + } +} + +interface IUserAccountRepository { + getUserData(): Promise; +} +// [Start Case3_start] +// Data structure of user information UserData +export interface UserData { + id: string; + username: string; + description: string; + // ... +} +// [StartExclude Case3_start] +class bb { + private userAccountRepository: IUserAccountRepository; + + constructor(repository: IUserAccountRepository) { + this.userAccountRepository = repository; + } + // [EndExclude Case3_start] + // Getting server-side user information in a business class + getUserData(): void { + this.userAccountRepository.getUserData().then((data: UserData) => { + // 1.Storing user information data into AppStorage + AppStorage.setOrCreate('userData', data); + }); + } + // [StartExclude Case3_start] +} +// [EndExclude Case3_start] +// View component for displaying user information at the top of the “My” module +@Component +struct UserInfoView { + // 2.Receive user information stored in AppStorage using @StorageLink decorator in UI + @StorageLink('userData') userData: UserData | null = null; + build() { + Column() { + Row() { + // ... + Column() { + // 3.Display the user name in the userData. + Text(this.userData ? this.userData.username : 'default_login') + // ... + } + } + // ... + } + // ... + } +} +// [End Case3_start] \ No newline at end of file diff --git a/ArkUI/StateManagement/entry/src/main/ets/segment/segment7.ets b/ArkUI/StateManagement/entry/src/main/ets/segment/segment7.ets new file mode 100644 index 0000000000000000000000000000000000000000..4e6961c9a3ec328f373b0c61f1913aae8a27340c --- /dev/null +++ b/ArkUI/StateManagement/entry/src/main/ets/segment/segment7.ets @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ +@Builder +export function Segment07Builder() { + NavDestination(){ + ArticleCardView() + } +} +interface IUserAccountRepository { + getUserData(): Promise; +} + +export class LearningResource { + id: string = ""; + collectionCount: number = 0; +} + +@Component +struct ActionButtonView { + imgResource: Resource = $r("app.media.icon"); + count: number = 0; + textWidth: number = 0; + + build() { + Column() { + Image(this.imgResource) + .width(this.textWidth) + Text(this.count.toString()) + } + .alignItems(HorizontalAlign.Center) + } +} + +// [Start Case4] +export interface UserData { + id: string; + username: string; + description: string; + + // 1. Add a list of resources in the user's collection on the user information UserData id Information Type Definition + collectedIds: string[]; + // ... +} +// [StartExclude Case4] +class cc { + private userAccountRepository: IUserAccountRepository; + + constructor(repository: IUserAccountRepository) { + this.userAccountRepository = repository; + } + // [EndExclude Case4] + // Getting server-side user information in a business class + getUserData(): void { + this.userAccountRepository.getUserData().then((data: UserData) => { + // 2.Storing user information data into AppStorage + AppStorage.setOrCreate('userData', data); + }) + } + // [StartExclude Case4] +} +// [EndExclude Case4] + +// Article card component of the Explore module +@Component +export struct ArticleCardView { + // 3.Get the user information object userData on the ExploreArticleList card with the @StorageLink decorator + @StorageLink('userData') userData: UserData | null = null; + @Prop articleItem: LearningResource = new LearningResource(); + + // 4.Calculate whether the current article is favorite or not according to the favorite information array + isCollected(): boolean { + return !!this.userData && this.userData.collectedIds.some((id: string) => id === this.articleItem.id); + } + + // 7.Handling interface like interaction logic: when the userData state sub-property collectedIds received using the @StorageLink decorator is modified, the new value is synchronized to AppStorage + handleCollected(): void { + // [StartExclude Case4] + const resourceId = this.articleItem.id; + // [EndExclude Case4] + const index = this.userData?.collectedIds.findIndex((id: string) => id === this.articleItem.id) as number; + if (index === -1) { + this.userData?.collectedIds.push(resourceId); + } else { + this.userData?.collectedIds.splice(index, 1); + } + // ... + } + + build() { + ActionButtonView({ + // 5.Determine whether the favorite icon is highlighted according to whether the current article has been favorited by the user or not + imgResource: this.isCollected() ? $r('app.media.icon') : $r('app.media.icon'), + count: this.articleItem.collectionCount, + textWidth: 77 + }) + .onClick(() => { + // 6.When the user clicks on the favorites icon, the function that handles changes to the status of the favorites is called + this.handleCollected(); + }) + } +} +// [End Case4] \ No newline at end of file diff --git a/ArkUI/StateManagement/entry/src/main/ets/segment/segment8.ets b/ArkUI/StateManagement/entry/src/main/ets/segment/segment8.ets new file mode 100644 index 0000000000000000000000000000000000000000..f00b3af02224556ee3cf6123002aecb91fe3f5ee --- /dev/null +++ b/ArkUI/StateManagement/entry/src/main/ets/segment/segment8.ets @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ +@Builder +export function Segment08Builder() { + NavDestination(){ + ArticleCardView() + } +} +@Component +struct ActionButtonView { + imgResource: Resource = $r("app.media.icon"); + count: number = 0; + textWidth: number = 0; + + build() { + Column() { + Image(this.imgResource) + .width(this.textWidth) + Text(this.count.toString()) + } + .alignItems(HorizontalAlign.Center) + } +} + +export class LearningResource { + id: string = ""; + collectionCount: number = 0; +} + +interface IUserAccountRepository { + getUserData(): Promise; +} + +export interface UserData { + id: string; + username: string; + description: string; + collectedIds: string[]; +} + +class dd { + private userAccountRepository: IUserAccountRepository; + + constructor(repository: IUserAccountRepository) { + this.userAccountRepository = repository; + } + // [Start Case5] + // Getting user information in a business class + getUserData(): void { + this.userAccountRepository.getUserData().then((data: UserData) => { + //1.Separate storage of user collection information data in AppStorage + AppStorage.setOrCreate('collectedIds', data.collectedIds); + AppStorage.setOrCreate('userData', data); + }) + } + // [End Case5] +} + +// [Start Case5] +// Article card component of the Explore module +@Component +export struct ArticleCardView { + // 2.Getting collection information stored in AppStorage via @StorageLink decorator + @StorageLink('collectedIds') collectedIds: string[] = []; + @Prop articleItem: LearningResource = new LearningResource(); + // 3.Calculate whether the current article is favorite or not according to the favorite information array + isCollected(): boolean { + return this.collectedIds.some((id: string) => id === this.articleItem.id); + } + // 6.Handling interface like interaction logic: when the state collectedIds received using the @StorageLink decorator are modified, the new values are synchronized to AppStorage + handleCollected(): void { + // [StartExclude Case5] + const resourceId = this.articleItem.id; + // [EndExclude Case5] + const index = this.collectedIds.findIndex((id: string) => id === this.articleItem.id); + if (index === -1) { + this.collectedIds.push(resourceId); + } else { + this.collectedIds.splice(index, 1); + } + // ... + } + build(){ + ActionButtonView({ + // 4.Determine whether the favorite icon is highlighted according to whether the current article has been favorited by the user or not + imgResource: this.isCollected() ? $r('app.media.icon') : $r('app.media.icon'), + count: this.articleItem.collectionCount, + textWidth: 77 + }) + .onClick(() => { + // 5.When the user clicks on the favorites icon, the function that handles changes to the status of the favorites is called + this.handleCollected(); + }) + } +} +// [End Case5] \ No newline at end of file diff --git a/ArkUI/StateManagement/entry/src/main/ets/segment/segment9.ets b/ArkUI/StateManagement/entry/src/main/ets/segment/segment9.ets new file mode 100644 index 0000000000000000000000000000000000000000..f436e5dcbb18765cb254671541778d2463123fa5 --- /dev/null +++ b/ArkUI/StateManagement/entry/src/main/ets/segment/segment9.ets @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ +@Builder +export function Segment09Builder() { + NavDestination() { + DiscoverView() + } +} + +export class LearningResource { + id: string = ""; + collectionCount: number = 0; +} + +export class CommonConstants { + static readonly SPACE_12: number = 12; +} + +interface GeneratedTypeLiteralInterface_1 { + swiperData: LearningResource[]; +} + +@Component +struct HotFeedsView { + @Prop hotFeedList: never[] = []; + showMore: () => void = () => { + }; + handleClick: (item: LearningResource) => void = () => { + }; + + build() { + Column() + } +} + +@Component +struct TechArticlesView { + @Prop articlesDataSource: never[] = []; + handleClick: (item: LearningResource) => void = () => { + }; + + build() { + Column() + } +} + +// [Start discover_view] +@Component +export struct DiscoverView { + // [StartExclude Case6] + private jumpList = () => { + } + @State hotFeedList: never[] = []; + @State articlesDataSource: never[] = []; + @State discoverModel: GeneratedTypeLiteralInterface_1 = { swiperData: [] }; + // [EndExclude Case6] + // 1.Getting shared state related to jump logic + @Consume('appPathStack') appPathStack: NavPathStack; + @Consume('discoverPathStack') discoverPathStack: NavPathStack; + @StorageProp('currentBreakpoint') currentBreakpoint: string = 'BreakpointTypeEnum.MD'; + + // 5.Centralize the jump processing logic of the 3 components in the parent component + jumpDetail(item: LearningResource): void { + if (this.currentBreakpoint === 'BreakpointTypeEnum.LG') { + this.discoverPathStack.pushPathByName('articleDetail', item); + } else { + this.appPathStack.pushPathByName('articleDetail', item); + } + } + + build() { + // [StartExclude Case6] + Column() { + List() { + ListItem() { + BannerView({ + swiperData: this.discoverModel.swiperData, + // 2.The top rotator component passes in the parent component's logic handler function + handleClick: (item: LearningResource) => this.jumpDetail(item) + }) + } + // [EndExclude Case6] + ListItem() { + Column({ space: CommonConstants.SPACE_12 }) { + HotFeedsView({ + hotFeedList: this.hotFeedList, + showMore: this.jumpList, + // 3.Information list component passes in the logic handler function of the parent component + handleClick: (item: LearningResource) => this.jumpDetail(item) + }) + TechArticlesView({ + articlesDataSource: this.articlesDataSource, + // 4.Logic handler function passed to parent component by technical article component + handleClick: (item: LearningResource) => this.jumpDetail(item) + }) + } + } + } + } + // [End Case6] + } +} + +// [Start Case6] +@Component +struct BannerView { + @Prop swiperData: LearningResource[] = []; + private swiperController: SwiperController = new SwiperController(); + // 6.The rotatoire component receives the logic handler passed to it by the parent component. + handleClick: (item: LearningResource) => void = () => { + }; + + build() { + Swiper(this.swiperController) { + ForEach(this.swiperData, (item: LearningResource) => { + Row() { + // $r('app.media.icon') needs to be replaced with the resource file required by the developer + Image($r('app.media.icon')) + .width(55) + .height(55) + // Set the border radius to 5vp + .borderRadius($r('app.float.component_radius')) + // 7.When clicking on an image, call the received function to process the logic + .onClick(() => this.handleClick(item)) + } + // ... + }, (item: LearningResource) => item.id) + } + // ... + } +} +// [End discover_view] \ No newline at end of file diff --git a/ArkUI/StateManagement/entry/src/main/module.json5 b/ArkUI/StateManagement/entry/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..e3043e123012d257b0cbe3486df843e11a205aa9 --- /dev/null +++ b/ArkUI/StateManagement/entry/src/main/module.json5 @@ -0,0 +1,51 @@ +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "phone" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "routerMap": "$profile:route_map", + "abilities": [ + { + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ets", + "description": "$string:EntryAbility_desc", + "icon": "$media:layered_image", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:startIcon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ], + "extensionAbilities": [ + { + "name": "EntryBackupAbility", + "srcEntry": "./ets/entrybackupability/EntryBackupAbility.ets", + "type": "backup", + "exported": false, + "metadata": [ + { + "name": "ohos.extension.backup", + "resource": "$profile:backup_config" + } + ], + } + ] + } +} \ No newline at end of file diff --git a/MultiDeviceCommunication/products/phone/src/main/resources/base/element/color.json b/ArkUI/StateManagement/entry/src/main/resources/base/element/color.json similarity index 100% rename from MultiDeviceCommunication/products/phone/src/main/resources/base/element/color.json rename to ArkUI/StateManagement/entry/src/main/resources/base/element/color.json diff --git a/ArkUI/StateManagement/entry/src/main/resources/base/element/float.json b/ArkUI/StateManagement/entry/src/main/resources/base/element/float.json new file mode 100644 index 0000000000000000000000000000000000000000..4597c2b7452d28dae9f7582611272807909fb97a --- /dev/null +++ b/ArkUI/StateManagement/entry/src/main/resources/base/element/float.json @@ -0,0 +1,68 @@ +{ + "float": [ + { + "name": "tips_font_size", + "value": "16" + }, + { + "name": "source_code_font_size", + "value": "12" + }, + { + "name": "circle_size", + "value": "40" + }, + { + "name": "component_radius", + "value": "5" + }, + { + "name": "button_text_size", + "value": "16" + }, + { + "name": "button_height", + "value": "40" + }, + { + "name": "border_width", + "value": "1" + }, + { + "name": "title_bar_height", + "value": "60" + }, + { + "name": "icon_back_size", + "value": "20" + }, + { + "name": "page_padding", + "value": "12" + }, + { + "name": "title_font_size", + "value": "18" + }, + { + "name": "title_margin", + "value": "16" + }, + { + "name": "divider_height", + "value": "1" + }, + { + "name": "code_view_bottom", + "value": "20" + }, + { + "name": "select_font_size", + "value": "16" + }, + { + "name": "margin_bottom", + "value": "50vp" + } + ] +} \ No newline at end of file diff --git a/ArkUI/StateManagement/entry/src/main/resources/base/element/string.json b/ArkUI/StateManagement/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/ArkUI/StateManagement/entry/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/MultiVideoApplication/products/phone/src/main/resources/base/media/background.png b/ArkUI/StateManagement/entry/src/main/resources/base/media/background.png similarity index 100% rename from MultiVideoApplication/products/phone/src/main/resources/base/media/background.png rename to ArkUI/StateManagement/entry/src/main/resources/base/media/background.png diff --git a/NativeSoIntegration/Ndk/src/main/resources/base/media/foreground.png b/ArkUI/StateManagement/entry/src/main/resources/base/media/foreground.png similarity index 100% rename from NativeSoIntegration/Ndk/src/main/resources/base/media/foreground.png rename to ArkUI/StateManagement/entry/src/main/resources/base/media/foreground.png diff --git a/MultMusicHome/features/live/src/main/resources/base/media/icon.png b/ArkUI/StateManagement/entry/src/main/resources/base/media/icon.png similarity index 100% rename from MultMusicHome/features/live/src/main/resources/base/media/icon.png rename to ArkUI/StateManagement/entry/src/main/resources/base/media/icon.png diff --git a/MultiCommunityApplication/products/phone/src/main/resources/base/media/layered_image.json b/ArkUI/StateManagement/entry/src/main/resources/base/media/layered_image.json similarity index 100% rename from MultiCommunityApplication/products/phone/src/main/resources/base/media/layered_image.json rename to ArkUI/StateManagement/entry/src/main/resources/base/media/layered_image.json diff --git a/CrossPlatformCompatibility/entry/src/main/resources/base/media/startIcon.png b/ArkUI/StateManagement/entry/src/main/resources/base/media/startIcon.png similarity index 100% rename from CrossPlatformCompatibility/entry/src/main/resources/base/media/startIcon.png rename to ArkUI/StateManagement/entry/src/main/resources/base/media/startIcon.png diff --git a/NativeSoIntegration/entry/src/main/resources/base/profile/backup_config.json b/ArkUI/StateManagement/entry/src/main/resources/base/profile/backup_config.json similarity index 100% rename from NativeSoIntegration/entry/src/main/resources/base/profile/backup_config.json rename to ArkUI/StateManagement/entry/src/main/resources/base/profile/backup_config.json diff --git a/MultMusicHome/products/phone/src/main/resources/base/profile/main_pages.json b/ArkUI/StateManagement/entry/src/main/resources/base/profile/main_pages.json similarity index 100% rename from MultMusicHome/products/phone/src/main/resources/base/profile/main_pages.json rename to ArkUI/StateManagement/entry/src/main/resources/base/profile/main_pages.json diff --git a/ArkUI/StateManagement/entry/src/main/resources/base/profile/route_map.json b/ArkUI/StateManagement/entry/src/main/resources/base/profile/route_map.json new file mode 100644 index 0000000000000000000000000000000000000000..2332bd59ec9d30a1b2273dfc85b221c0100fdd61 --- /dev/null +++ b/ArkUI/StateManagement/entry/src/main/resources/base/profile/route_map.json @@ -0,0 +1,64 @@ +{ + "routerMap": [ + { + "name": "Segment1", + "pageSourceFile": "src/main/ets/segment/segment.ets", + "buildFunction": "Segment01Builder" + }, + { + "name": "Segment2", + "pageSourceFile": "src/main/ets/segment/segment2.ets", + "buildFunction": "Segment02Builder" + }, + { + "name": "Segment3", + "pageSourceFile": "src/main/ets/segment/segment3.ets", + "buildFunction": "Segment03Builder" + }, + { + "name": "Segment4", + "pageSourceFile": "src/main/ets/segment/segment4.ets", + "buildFunction": "Segment04Builder" + }, + { + "name": "Segment5", + "pageSourceFile": "src/main/ets/segment/segment5.ets", + "buildFunction": "Segment05Builder" + }, + { + "name": "Segment6", + "pageSourceFile": "src/main/ets/segment/segment6.ets", + "buildFunction": "Segment06Builder" + }, + { + "name": "Segment7", + "pageSourceFile": "src/main/ets/segment/segment7.ets", + "buildFunction": "Segment07Builder" + }, + { + "name": "Segment8", + "pageSourceFile": "src/main/ets/segment/segment8.ets", + "buildFunction": "Segment08Builder" + }, + { + "name": "Segment9", + "pageSourceFile": "src/main/ets/segment/segment9.ets", + "buildFunction": "Segment09Builder" + }, + { + "name": "Segment10", + "pageSourceFile": "src/main/ets/segment/segment10.ets", + "buildFunction": "Segment10Builder" + }, + { + "name": "Segment11", + "pageSourceFile": "src/main/ets/segment/segment11.ets", + "buildFunction": "Segment11Builder" + }, + { + "name": "Segment12", + "pageSourceFile": "src/main/ets/segment/segment12.ets", + "buildFunction": "Segment12Builder" + } + ] +} \ No newline at end of file diff --git a/ArkUI/StateManagement/entry/src/main/resources/dark/element/color.json b/ArkUI/StateManagement/entry/src/main/resources/dark/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..79b11c2747aec33e710fd3a7b2b3c94dd9965499 --- /dev/null +++ b/ArkUI/StateManagement/entry/src/main/resources/dark/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#000000" + } + ] +} \ No newline at end of file diff --git a/ArkUI/StateManagement/hvigor/hvigor-config.json5 b/ArkUI/StateManagement/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..5bebc9755447385d82ce4138f54d991b1f85f348 --- /dev/null +++ b/ArkUI/StateManagement/hvigor/hvigor-config.json5 @@ -0,0 +1,22 @@ +{ + "modelVersion": "5.0.5", + "dependencies": { + }, + "execution": { + // "analyze": "normal", /* Define the build analyze mode. Value: [ "normal" | "advanced" | false ]. Default: "normal" */ + // "daemon": true, /* Enable daemon compilation. Value: [ true | false ]. Default: true */ + // "incremental": true, /* Enable incremental compilation. Value: [ true | false ]. Default: true */ + // "parallel": true, /* Enable parallel compilation. Value: [ true | false ]. Default: true */ + // "typeCheck": false, /* Enable typeCheck. Value: [ true | false ]. Default: false */ + }, + "logging": { + // "level": "info" /* Define the log level. Value: [ "debug" | "info" | "warn" | "error" ]. Default: "info" */ + }, + "debugging": { + // "stacktrace": false /* Disable stacktrace compilation. Value: [ true | false ]. Default: false */ + }, + "nodeOptions": { + // "maxOldSpaceSize": 8192 /* Enable nodeOptions maxOldSpaceSize compilation. Unit M. Used for the daemon process. Default: 8192*/ + // "exposeGC": true /* Enable to trigger garbage collection explicitly. Default: true*/ + } +} diff --git a/ArkUI/StateManagement/hvigorfile.ts b/ArkUI/StateManagement/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..47113e2e36ecefde41c136272a0bd6ff745cffe4 --- /dev/null +++ b/ArkUI/StateManagement/hvigorfile.ts @@ -0,0 +1,6 @@ +import { appTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins: [] /* Custom plugin to extend the functionality of Hvigor. */ +} \ No newline at end of file diff --git a/ArkUI/StateManagement/oh-package.json5 b/ArkUI/StateManagement/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..f440d114b8a9d9aeadd0e891bba0d0d076e70936 --- /dev/null +++ b/ArkUI/StateManagement/oh-package.json5 @@ -0,0 +1,7 @@ +{ + "modelVersion": "5.0.5", + "description": "Please describe the basic information.", + "dependencies": { + }, + "devDependencies": {} +} diff --git a/ArkUI/UI_Component_Performance_Optimization/README.md b/ArkUI/UI_Component_Performance_Optimization/README.md new file mode 100644 index 0000000000000000000000000000000000000000..c34a00fd467753eec993d7d34f89d821f94aeca3 --- /dev/null +++ b/ArkUI/UI_Component_Performance_Optimization/README.md @@ -0,0 +1,54 @@ +# UI组件性能优化同源示例代码 + +### 介绍 + +本示例代码为最佳实践《UI组件性能优化》配套示例代码。 + +### 使用说明 + +不涉及 + +### 工程目录 + +``` +├──entry/src/main/ets +│ ├──components +│ │ └──DiscoverView.ets // 程序入口类 +│ ├──entryability +│ │ └──EntryAbility.ets // 程序入口类 +│ ├──entrybackupability +│ │ └──EntryBackupAbility.ets // 数据备份恢复类 +│ └──pages +│ ├──segment.ets // 避免在自定义组件的生命周期内执行高耗时操作:反例1 +│ ├──segment2.ets // 避免在自定义组件的生命周期内执行高耗时操作:正例1 +│ ├──segment3.ets // 避免在自定义组件的生命周期内执行高耗时操作:反例2 +│ ├──segment4.ets // 避免在自定义组件的生命周期内执行高耗时操作:正例2 +│ ├──segment5.ets // 按需注册组件属性同源代码:反例 +│ ├──segment6.ets // 按需注册组件属性同源代码:正例 +│ ├──segment7.ets // 优先使用@Builder方法代替自定义组件:反例 +│ ├──segment8.ets // 优先使用@Builder方法代替自定义组件:正例 +│ └──segment9.ets // 按需注册组件属性同源代码 +└──entry/src/main/resources // 应用资源目录 +``` + +### 相关权限 + +不涉及 + +### 约束与限制 + +* 本示例仅支持标准系统上运行,支持设备:华为手机。 +* HarmonyOS系统:HarmonyOS 5.0.5 Release及以上。 +* DevEco Studio版本:DevEco Studio 5.0.5 Release及以上。 +* HarmonyOS SDK版本:HarmonyOS 5.0.5 Release SDK及以上。 + +### 下载 + +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set ArkUI/UI_Component_Performance_Optimization +git checkout +``` \ No newline at end of file diff --git a/ArkUI/UI_Component_Performance_Optimization/entry/src/main/ets/entryability/EntryAbility.ets b/ArkUI/UI_Component_Performance_Optimization/entry/src/main/ets/entryability/EntryAbility.ets index 508880af8c33aa838016d1cd4b2c68be2f447540..2880ca09588393e53ffafcdb1a11f66cdde90b4f 100644 --- a/ArkUI/UI_Component_Performance_Optimization/entry/src/main/ets/entryability/EntryAbility.ets +++ b/ArkUI/UI_Component_Performance_Optimization/entry/src/main/ets/entryability/EntryAbility.ets @@ -1,4 +1,5 @@ import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { BusinessError } from '@kit.BasicServicesKit'; import { hilog } from '@kit.PerformanceAnalysisKit'; import { window } from '@kit.ArkUI'; @@ -6,7 +7,12 @@ const DOMAIN = 0x0000; export default class EntryAbility extends UIAbility { onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { - this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + try { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + } catch (error) { + let err = error as BusinessError; + hilog.warn(0x000, 'testTag', `setColorMode failed, code=${err.code}, message=${err.message}`); + } hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); } diff --git a/ArkUI/UI_Component_Performance_Optimization/entry/src/main/ets/pages/Index.ets b/ArkUI/UI_Component_Performance_Optimization/entry/src/main/ets/pages/Index.ets index 8e2d24ad42693fc877d51bb7820f0a9da68fa135..6db84a6aab5bf5551c2d3347b36e88984529a63d 100644 --- a/ArkUI/UI_Component_Performance_Optimization/entry/src/main/ets/pages/Index.ets +++ b/ArkUI/UI_Component_Performance_Optimization/entry/src/main/ets/pages/Index.ets @@ -1,3 +1,18 @@ +/* +* Copyright (C) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + @Entry @Component struct Index { diff --git a/ArkUI/UI_Component_Performance_Optimization/entry/src/main/ets/segment/segment.ets b/ArkUI/UI_Component_Performance_Optimization/entry/src/main/ets/segment/segment.ets index 039bda5ceed91007f03d34807fecdee17c185526..4704c9fb45be172a75926e80c87d7d1e637fd81f 100644 --- a/ArkUI/UI_Component_Performance_Optimization/entry/src/main/ets/segment/segment.ets +++ b/ArkUI/UI_Component_Performance_Optimization/entry/src/main/ets/segment/segment.ets @@ -1,3 +1,18 @@ +/* +* Copyright (C) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + interface VideoItem { id: string; } diff --git a/ArkUI/UI_Component_Performance_Optimization/entry/src/main/ets/segment/segment2.ets b/ArkUI/UI_Component_Performance_Optimization/entry/src/main/ets/segment/segment2.ets index 7a121f36751fee30196f6d12c7cf13716a515886..0387711e0c56d43453896d18515089d5df534da8 100644 --- a/ArkUI/UI_Component_Performance_Optimization/entry/src/main/ets/segment/segment2.ets +++ b/ArkUI/UI_Component_Performance_Optimization/entry/src/main/ets/segment/segment2.ets @@ -1,3 +1,18 @@ +/* +* Copyright (C) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + interface VideoItem { id: string; } diff --git a/ArkUI/UI_Component_Performance_Optimization/entry/src/main/ets/segment/segment3.ets b/ArkUI/UI_Component_Performance_Optimization/entry/src/main/ets/segment/segment3.ets index bd174e171860db3886f3fe52c6f39c0887feea8d..21ead008686725b558138723d28e0ac41c5062c9 100644 --- a/ArkUI/UI_Component_Performance_Optimization/entry/src/main/ets/segment/segment3.ets +++ b/ArkUI/UI_Component_Performance_Optimization/entry/src/main/ets/segment/segment3.ets @@ -1,6 +1,22 @@ +/* +* Copyright (C) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + // [Start Counter_example2] -import { hiTraceMeter } from '@kit.PerformanceAnalysisKit'; +import { hilog, hiTraceMeter } from '@kit.PerformanceAnalysisKit'; import { common } from '@kit.AbilityKit'; +import { BusinessError } from '@kit.BasicServicesKit'; @Entry @Component @@ -11,7 +27,12 @@ struct Index { aboutToAppear(): void { hiTraceMeter.startTrace('getStringSync', 1); // The input parameter of the getStringSync interface uses the resource directly, without using the resource ID. - this.context.resourceManager.getStringSync($r('app.string.app_name')); + try { + this.context.resourceManager.getStringSync($r('app.string.app_name')); + } catch (error) { + let err = error as BusinessError; + hilog.warn(0x000, 'testTag', `getStringSync failed, code=${err.code}, message=${err.message}`); + } hiTraceMeter.finishTrace('getStringSync', 1); } diff --git a/ArkUI/UI_Component_Performance_Optimization/entry/src/main/ets/segment/segment4.ets b/ArkUI/UI_Component_Performance_Optimization/entry/src/main/ets/segment/segment4.ets index 0d67985f237d6452273361a7bbc6f4f649065200..39cba0d0ec295d212836984ee20c02a00ffd4ce8 100644 --- a/ArkUI/UI_Component_Performance_Optimization/entry/src/main/ets/segment/segment4.ets +++ b/ArkUI/UI_Component_Performance_Optimization/entry/src/main/ets/segment/segment4.ets @@ -1,6 +1,22 @@ +/* +* Copyright (C) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + // [Start Case2] -import { hiTraceMeter } from '@kit.PerformanceAnalysisKit'; +import { hilog, hiTraceMeter } from '@kit.PerformanceAnalysisKit'; import { common } from '@kit.AbilityKit'; +import { BusinessError } from '@kit.BasicServicesKit'; @Entry @Component @@ -11,8 +27,12 @@ struct Index { aboutToAppear(): void { hiTraceMeter.startTrace('getStringSyncAfter', 2); // The input parameter of the getStringSync interface uses the resource ID. - - this.context.resourceManager.getStringSync($r('app.string.app_name').id); + try { + this.context.resourceManager.getStringSync($r('app.string.app_name').id); + } catch (error) { + let err = error as BusinessError; + hilog.warn(0x000, 'testTag', `getStringSync failed, code=${err.code}, message=${err.message}`); + } hiTraceMeter.finishTrace('getStringSyncAfter', 2); } diff --git a/ArkUI/UI_Component_Performance_Optimization/entry/src/main/ets/segment/segment5.ets b/ArkUI/UI_Component_Performance_Optimization/entry/src/main/ets/segment/segment5.ets index 3f43982e3ca8b1d6a2e2b62b9d9539828119a720..f5ca8fdc9e23275cb89cdf188cf2bdc1fa8d21cc 100644 --- a/ArkUI/UI_Component_Performance_Optimization/entry/src/main/ets/segment/segment5.ets +++ b/ArkUI/UI_Component_Performance_Optimization/entry/src/main/ets/segment/segment5.ets @@ -1,3 +1,18 @@ +/* +* Copyright (C) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + // [Start Case3] import { util } from '@kit.ArkTS'; @@ -26,8 +41,6 @@ const getUsers = () => { }); } - -@Entry @Component export struct AvatarGrid { @State users: User[] = getUsers(); diff --git a/ArkUI/UI_Component_Performance_Optimization/entry/src/main/ets/segment/segment6.ets b/ArkUI/UI_Component_Performance_Optimization/entry/src/main/ets/segment/segment6.ets index b29dfa1b1e6ee326c642420700a3e8aaef63edb7..1d22d89f4c8db8c6f8705a2795c8a24382c6f034 100644 --- a/ArkUI/UI_Component_Performance_Optimization/entry/src/main/ets/segment/segment6.ets +++ b/ArkUI/UI_Component_Performance_Optimization/entry/src/main/ets/segment/segment6.ets @@ -1,3 +1,18 @@ +/* +* Copyright (C) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + @Observed class User { avatarImage: ResourceStr; diff --git a/ArkUI/UI_Component_Performance_Optimization/entry/src/main/ets/segment/segment7.ets b/ArkUI/UI_Component_Performance_Optimization/entry/src/main/ets/segment/segment7.ets index 188c5301f45f60f4ff4ac316cc821383e3038cc1..5389a92dd5e0e00b7239f71007b2d935e6b0f070 100644 --- a/ArkUI/UI_Component_Performance_Optimization/entry/src/main/ets/segment/segment7.ets +++ b/ArkUI/UI_Component_Performance_Optimization/entry/src/main/ets/segment/segment7.ets @@ -1,3 +1,18 @@ +/* +* Copyright (C) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + // [Start Case5] import { util } from '@kit.ArkTS'; diff --git a/ArkUI/UI_Component_Performance_Optimization/entry/src/main/ets/segment/segment8.ets b/ArkUI/UI_Component_Performance_Optimization/entry/src/main/ets/segment/segment8.ets index 1cf9b3d0248a19d4e864686f2037c80c395b3654..8054117cb3db3de27b433b8ee10b4c0088b7b974 100644 --- a/ArkUI/UI_Component_Performance_Optimization/entry/src/main/ets/segment/segment8.ets +++ b/ArkUI/UI_Component_Performance_Optimization/entry/src/main/ets/segment/segment8.ets @@ -1,3 +1,18 @@ +/* +* Copyright (C) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + interface User { id: string; name: string; diff --git a/ArkUI/UI_Component_Performance_Optimization/entry/src/main/ets/segment/segment9.ets b/ArkUI/UI_Component_Performance_Optimization/entry/src/main/ets/segment/segment9.ets index 28a75b39e42d9b54800d3c0254433a9783c0cc93..055b3e0f8ff2999176255511323a041f469c0b04 100644 --- a/ArkUI/UI_Component_Performance_Optimization/entry/src/main/ets/segment/segment9.ets +++ b/ArkUI/UI_Component_Performance_Optimization/entry/src/main/ets/segment/segment9.ets @@ -1,3 +1,18 @@ +/* +* Copyright (C) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + function convertColorSegmentsToString(name:string){ return name } diff --git a/ArkUI/UI_Component_Performance_Optimization/entry/src/main/module.json5 b/ArkUI/UI_Component_Performance_Optimization/entry/src/main/module.json5 index a1cea8b6a4560cee7bda7a2db52f310c035ab6c8..ad219d733f6afa5ea07f85f580208b08cc3b9041 100644 --- a/ArkUI/UI_Component_Performance_Optimization/entry/src/main/module.json5 +++ b/ArkUI/UI_Component_Performance_Optimization/entry/src/main/module.json5 @@ -5,9 +5,7 @@ "description": "$string:module_desc", "mainElement": "EntryAbility", "deviceTypes": [ - "phone", - "tablet", - "2in1" + "phone" ], "deliveryWithInstall": true, "installationFree": false, diff --git a/ArkUI/UI_Component_Performance_Optimization/entry/src/main/resources/base/element/string.json b/ArkUI/UI_Component_Performance_Optimization/entry/src/main/resources/base/element/string.json index f94595515a99e0c828807e243494f57f09251930..aff8f905a24cc896edb83c849b54a67bf34923a1 100644 --- a/ArkUI/UI_Component_Performance_Optimization/entry/src/main/resources/base/element/string.json +++ b/ArkUI/UI_Component_Performance_Optimization/entry/src/main/resources/base/element/string.json @@ -10,7 +10,7 @@ }, { "name": "EntryAbility_label", - "value": "label" + "value": "UIComponentPerformance" } ] } \ No newline at end of file diff --git a/ArkUI/UI_Component_Performance_Optimization/entry/src/mock/mock-config.json5 b/ArkUI/UI_Component_Performance_Optimization/entry/src/mock/mock-config.json5 deleted file mode 100644 index 7a73a41bfdf76d6f793007240d80983a52f15f97..0000000000000000000000000000000000000000 --- a/ArkUI/UI_Component_Performance_Optimization/entry/src/mock/mock-config.json5 +++ /dev/null @@ -1,2 +0,0 @@ -{ -} \ No newline at end of file diff --git a/ArkUI/UI_Component_Performance_Optimization/entry/src/ohosTest/ets/test/Ability.test.ets b/ArkUI/UI_Component_Performance_Optimization/entry/src/ohosTest/ets/test/Ability.test.ets deleted file mode 100644 index 85c78f67579d6e31b5f5aeea463e216b9b141048..0000000000000000000000000000000000000000 --- a/ArkUI/UI_Component_Performance_Optimization/entry/src/ohosTest/ets/test/Ability.test.ets +++ /dev/null @@ -1,35 +0,0 @@ -import { hilog } from '@kit.PerformanceAnalysisKit'; -import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; - -export default function abilityTest() { - describe('ActsAbilityTest', () => { - // Defines a test suite. Two parameters are supported: test suite name and test suite function. - beforeAll(() => { - // Presets an action, which is performed only once before all test cases of the test suite start. - // This API supports only one parameter: preset action function. - }) - beforeEach(() => { - // Presets an action, which is performed before each unit test case starts. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: preset action function. - }) - afterEach(() => { - // Presets a clear action, which is performed after each unit test case ends. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: clear action function. - }) - afterAll(() => { - // Presets a clear action, which is performed after all test cases of the test suite end. - // This API supports only one parameter: clear action function. - }) - it('assertContain', 0, () => { - // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. - hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); - let a = 'abc'; - let b = 'b'; - // Defines a variety of assertion methods, which are used to declare expected boolean conditions. - expect(a).assertContain(b); - expect(a).assertEqual(a); - }) - }) -} \ No newline at end of file diff --git a/ArkUI/UI_Component_Performance_Optimization/entry/src/ohosTest/ets/test/List.test.ets b/ArkUI/UI_Component_Performance_Optimization/entry/src/ohosTest/ets/test/List.test.ets deleted file mode 100644 index 794c7dc4ed66bd98fa3865e07922906e2fcef545..0000000000000000000000000000000000000000 --- a/ArkUI/UI_Component_Performance_Optimization/entry/src/ohosTest/ets/test/List.test.ets +++ /dev/null @@ -1,5 +0,0 @@ -import abilityTest from './Ability.test'; - -export default function testsuite() { - abilityTest(); -} \ No newline at end of file diff --git a/ArkUI/UI_Component_Performance_Optimization/entry/src/ohosTest/module.json5 b/ArkUI/UI_Component_Performance_Optimization/entry/src/ohosTest/module.json5 deleted file mode 100644 index 55725a929993a8a18b3808d41ef037759440488b..0000000000000000000000000000000000000000 --- a/ArkUI/UI_Component_Performance_Optimization/entry/src/ohosTest/module.json5 +++ /dev/null @@ -1,13 +0,0 @@ -{ - "module": { - "name": "entry_test", - "type": "feature", - "deviceTypes": [ - "phone", - "tablet", - "2in1" - ], - "deliveryWithInstall": true, - "installationFree": false - } -} diff --git a/ArkUI/UI_Component_Performance_Optimization/entry/src/test/List.test.ets b/ArkUI/UI_Component_Performance_Optimization/entry/src/test/List.test.ets deleted file mode 100644 index bb5b5c3731e283dd507c847560ee59bde477bbc7..0000000000000000000000000000000000000000 --- a/ArkUI/UI_Component_Performance_Optimization/entry/src/test/List.test.ets +++ /dev/null @@ -1,5 +0,0 @@ -import localUnitTest from './LocalUnit.test'; - -export default function testsuite() { - localUnitTest(); -} \ No newline at end of file diff --git a/ArkUI/UI_Component_Performance_Optimization/entry/src/test/LocalUnit.test.ets b/ArkUI/UI_Component_Performance_Optimization/entry/src/test/LocalUnit.test.ets deleted file mode 100644 index 165fc1615ee8618b4cb6a622f144a9a707eee99f..0000000000000000000000000000000000000000 --- a/ArkUI/UI_Component_Performance_Optimization/entry/src/test/LocalUnit.test.ets +++ /dev/null @@ -1,33 +0,0 @@ -import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; - -export default function localUnitTest() { - describe('localUnitTest', () => { - // Defines a test suite. Two parameters are supported: test suite name and test suite function. - beforeAll(() => { - // Presets an action, which is performed only once before all test cases of the test suite start. - // This API supports only one parameter: preset action function. - }); - beforeEach(() => { - // Presets an action, which is performed before each unit test case starts. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: preset action function. - }); - afterEach(() => { - // Presets a clear action, which is performed after each unit test case ends. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: clear action function. - }); - afterAll(() => { - // Presets a clear action, which is performed after all test cases of the test suite end. - // This API supports only one parameter: clear action function. - }); - it('assertContain', 0, () => { - // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. - let a = 'abc'; - let b = 'b'; - // Defines a variety of assertion methods, which are used to declare expected boolean conditions. - expect(a).assertContain(b); - expect(a).assertEqual(a); - }); - }); -} \ No newline at end of file diff --git a/ArkUI/UI_Component_Performance_Optimization/oh-package-lock.json5 b/ArkUI/UI_Component_Performance_Optimization/oh-package-lock.json5 deleted file mode 100644 index c6f99f5c73b06c5fdef7ec6f491b74b7befebe2e..0000000000000000000000000000000000000000 --- a/ArkUI/UI_Component_Performance_Optimization/oh-package-lock.json5 +++ /dev/null @@ -1,27 +0,0 @@ -{ - "meta": { - "stableOrder": true - }, - "lockfileVersion": 3, - "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", - "specifiers": { - "@ohos/hamock@1.0.0": "@ohos/hamock@1.0.0", - "@ohos/hypium@1.0.21": "@ohos/hypium@1.0.21" - }, - "packages": { - "@ohos/hamock@1.0.0": { - "name": "@ohos/hamock", - "version": "1.0.0", - "integrity": "sha512-K6lDPYc6VkKe6ZBNQa9aoG+ZZMiwqfcR/7yAVFSUGIuOAhPvCJAo9+t1fZnpe0dBRBPxj2bxPPbKh69VuyAtDg==", - "resolved": "https://repo.harmonyos.com/ohpm/@ohos/hamock/-/hamock-1.0.0.har", - "registryType": "ohpm" - }, - "@ohos/hypium@1.0.21": { - "name": "@ohos/hypium", - "version": "1.0.21", - "integrity": "sha512-iyKGMXxE+9PpCkqEwu0VykN/7hNpb+QOeIuHwkmZnxOpI+dFZt6yhPB7k89EgV1MiSK/ieV/hMjr5Z2mWwRfMQ==", - "resolved": "https://repo.harmonyos.com/ohpm/@ohos/hypium/-/hypium-1.0.21.har", - "registryType": "ohpm" - } - } -} \ No newline at end of file diff --git a/ArkUI/orientationDevelopment/.gitignore b/ArkUI/orientationDevelopment/.gitignore deleted file mode 100644 index d2ff20141ceed86d87c0ea5d99481973005bab2b..0000000000000000000000000000000000000000 --- a/ArkUI/orientationDevelopment/.gitignore +++ /dev/null @@ -1,12 +0,0 @@ -/node_modules -/oh_modules -/local.properties -/.idea -**/build -/.hvigor -.cxx -/.clangd -/.clang-format -/.clang-tidy -**/.test -/.appanalyzer \ No newline at end of file diff --git a/ArkUI/orientationDevelopment/README.md b/ArkUI/orientationDevelopment/README.md new file mode 100644 index 0000000000000000000000000000000000000000..493e9a6baaed2155ab4c401db2cf7afa6a515a4d --- /dev/null +++ b/ArkUI/orientationDevelopment/README.md @@ -0,0 +1,53 @@ +# 多设备同源代码工程 + +## 介绍 + +本示例为窗口方向与多设备功能开发同源代码工程,包含最佳实践文档中包含的推荐使用方法的样例代码。工程本身不具备实际功能,开发者请直接阅读文档结合源码来理解多设备功能开发。 + +## 效果预览 + +不涉及。 + +## 工程目录 + +``` +entry/src/main/ +├──configautorotation // 窗口自动旋转 +├──configlandscapeauto // 窗口横屏 +├──configportrait // 窗口竖屏 +├──ets // 主目录 +└──resources // 资源目录 +``` + +## 具体实现 + +不涉及。 + +## 相关权限 + +不涉及。 + +## 依赖 + +不涉及。 + +## 约束与限制 + +1.本示例仅支持标准系统上运行,支持设备:华为手机。 + +2.HarmonyOS系统:HarmonyOS 5.0.5 Release及以上。 + +3.DevEco Studio版本:DevEco Studio 5.0.5 Release及以上。 + +4.HarmonyOS SDK版本:HarmonyOS 5.0.5 Release SDK及以上。 + +## 下载 + +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set ArkUI/orientationDevelopment +git checkout +``` \ No newline at end of file diff --git a/ArkUI/orientationDevelopment/build-profile.json5 b/ArkUI/orientationDevelopment/build-profile.json5 index 30857c313183c9cea23ffc9137be34d42de2f8c2..9e87e7e6f19020fe21192844709f192cec80fd44 100644 --- a/ArkUI/orientationDevelopment/build-profile.json5 +++ b/ArkUI/orientationDevelopment/build-profile.json5 @@ -5,8 +5,8 @@ { "name": "default", "signingConfig": "default", - "targetSdkVersion": "5.1.0(18)", - "compatibleSdkVersion": "5.0.3(15)", + "targetSdkVersion": "5.0.5(17)", + "compatibleSdkVersion": "5.0.5(17)", "runtimeOS": "HarmonyOS", "buildOption": { "strictMode": { diff --git a/ArkUI/orientationDevelopment/entry/build-profile.json5 b/ArkUI/orientationDevelopment/entry/build-profile.json5 index 4d611879c7913fb0610c686e2399258ab3a6dad1..0311b505dbf43f0d22662c8d783c5f4464d15b15 100644 --- a/ArkUI/orientationDevelopment/entry/build-profile.json5 +++ b/ArkUI/orientationDevelopment/entry/build-profile.json5 @@ -20,9 +20,6 @@ "targets": [ { "name": "default" - }, - { - "name": "ohosTest", } ] } \ No newline at end of file diff --git a/ArkUI/orientationDevelopment/entry/src/main/ets/entryability/EntryAbility.ets b/ArkUI/orientationDevelopment/entry/src/main/ets/entryability/EntryAbility.ets index e8c03cc6c6e444af4f89db8e2e19222d6c589536..a9c879303eaf4476d0d4e70d152facf8775b76a1 100644 --- a/ArkUI/orientationDevelopment/entry/src/main/ets/entryability/EntryAbility.ets +++ b/ArkUI/orientationDevelopment/entry/src/main/ets/entryability/EntryAbility.ets @@ -1,12 +1,33 @@ -import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + +import { ConfigurationConstant, UIAbility } from '@kit.AbilityKit'; +import { BusinessError } from '@kit.BasicServicesKit'; import { hilog } from '@kit.PerformanceAnalysisKit'; import { window } from '@kit.ArkUI'; const DOMAIN = 0x0000; export default class EntryAbility extends UIAbility { - onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { - this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + onCreate(): void { + try { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + } catch (error) { + hilog.error(DOMAIN, 'testTag', '%{public}s', + `Failed to setColorMode. Cause code: ${error.code}, message: ${error.message}`); + } hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); } @@ -17,7 +38,10 @@ export default class EntryAbility extends UIAbility { onWindowStageCreate(windowStage: window.WindowStage): void { // Main window is created, set main page for this ability hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); - AppStorage.setOrCreate('mainWindow', windowStage.getMainWindow()); + AppStorage.setOrCreate('mainWindow', windowStage.getMainWindow().catch((error: BusinessError) => { + hilog.error(DOMAIN, 'testTag', '%{public}s', + `Failed to getMainWindow. Cause code: ${error.code}, message: ${error.message}`); + })); windowStage.loadContent('pages/Index', (err) => { if (err.code) { hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err)); diff --git a/ArkUI/orientationDevelopment/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets b/ArkUI/orientationDevelopment/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets index 8e4de99282050bad799ac892eb85ac5449364a51..293e76aed652b84544ff154932a0ce9b60bfe9de 100644 --- a/ArkUI/orientationDevelopment/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets +++ b/ArkUI/orientationDevelopment/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets @@ -1,5 +1,20 @@ -import { hilog } from '@kit.PerformanceAnalysisKit'; +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; const DOMAIN = 0x0000; diff --git a/ArkUI/orientationDevelopment/entry/src/main/ets/pages/Index.ets b/ArkUI/orientationDevelopment/entry/src/main/ets/pages/Index.ets index 1c7a6e8aafb095c7e79d163cd5bf9ff1af6efdde..148c0a8e2bfdce69389db03a76be4aaec59137ab 100644 --- a/ArkUI/orientationDevelopment/entry/src/main/ets/pages/Index.ets +++ b/ArkUI/orientationDevelopment/entry/src/main/ets/pages/Index.ets @@ -1,11 +1,31 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + // [Start enable_nfc] import { nfcController } from '@kit.ConnectivityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; @Entry @Component struct Index { // [StartExclude enable_nfc] @State message: string = 'Hello World'; + + aboutToAppear(): void { + this.canIUseNfc(); + } // [EndExclude enable_nfc] canIUseNfc(): void { @@ -17,11 +37,14 @@ struct Index { } // [End caniuse_nfc_core] // [EndExclude enable_nfc] + if (canIUse('SystemCapability.Communication.NFC.Core')){ try { nfcController.enableNfc(); hilog.info(0x0000, 'Index', `nfcController enableNfc success`); } catch (businessError) { hilog.error(0x0000, 'Index', `nfcController enableNfc businessError: ${businessError}`); + }}else { + hilog.info(0x0000, 'Index', 'NFC not by this device.'); } // [StartExclude enable_nfc] } diff --git a/ArkUI/orientationDevelopment/entry/src/main/ets/pages/OrientationPage.ets b/ArkUI/orientationDevelopment/entry/src/main/ets/pages/OrientationPage.ets index 8b4022b387159e2ed1b76ecbe552cc9988db34bc..72e0ed10f9749da076c654256e9fcd7aa442986e 100644 --- a/ArkUI/orientationDevelopment/entry/src/main/ets/pages/OrientationPage.ets +++ b/ArkUI/orientationDevelopment/entry/src/main/ets/pages/OrientationPage.ets @@ -14,7 +14,7 @@ struct OrientationPage { aboutToAppear() { this.setOrientation(1); let callback = async () => { - let getDefaultDisplay = await display.getDefaultDisplaySync(); + let getDefaultDisplay = display.getDefaultDisplaySync(); this.rotation = getDefaultDisplay.rotation; this.message = ORIENTATION[this.rotation]; }; diff --git a/ArkUI/orientationDevelopment/entry/src/main/module.json5 b/ArkUI/orientationDevelopment/entry/src/main/module.json5 index f3a040d043f1fa5927db2c414ca731b7428f6231..1b7aac5b37b3cc701b01c64c5b44ae542c653811 100644 --- a/ArkUI/orientationDevelopment/entry/src/main/module.json5 +++ b/ArkUI/orientationDevelopment/entry/src/main/module.json5 @@ -60,6 +60,18 @@ } ] } + ], + "requestPermissions": [ + { + "name": "ohos.permission.MANAGE_SECURE_SETTINGS", + "reason": "$string:manage_secure_settings_reason", + "usedScene": { + "abilities": [ + "FormAbility" + ], + "when": "inuse" + } + } ] // [EndExclude module] } diff --git a/ArkUI/orientationDevelopment/entry/src/main/resources/base/element/string.json b/ArkUI/orientationDevelopment/entry/src/main/resources/base/element/string.json index f94595515a99e0c828807e243494f57f09251930..9075650e024664fe588c4b836609f4d048de9d54 100644 --- a/ArkUI/orientationDevelopment/entry/src/main/resources/base/element/string.json +++ b/ArkUI/orientationDevelopment/entry/src/main/resources/base/element/string.json @@ -11,6 +11,10 @@ { "name": "EntryAbility_label", "value": "label" + }, + { + "name": "manage_secure_settings_reason", + "value": "To enable NFC, you need to apply for this permission." } ] } \ No newline at end of file diff --git a/ArkUI/orientationDevelopment/entry/src/ohosTest/ets/test/Ability.test.ets b/ArkUI/orientationDevelopment/entry/src/ohosTest/ets/test/Ability.test.ets deleted file mode 100644 index 85c78f67579d6e31b5f5aeea463e216b9b141048..0000000000000000000000000000000000000000 --- a/ArkUI/orientationDevelopment/entry/src/ohosTest/ets/test/Ability.test.ets +++ /dev/null @@ -1,35 +0,0 @@ -import { hilog } from '@kit.PerformanceAnalysisKit'; -import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; - -export default function abilityTest() { - describe('ActsAbilityTest', () => { - // Defines a test suite. Two parameters are supported: test suite name and test suite function. - beforeAll(() => { - // Presets an action, which is performed only once before all test cases of the test suite start. - // This API supports only one parameter: preset action function. - }) - beforeEach(() => { - // Presets an action, which is performed before each unit test case starts. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: preset action function. - }) - afterEach(() => { - // Presets a clear action, which is performed after each unit test case ends. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: clear action function. - }) - afterAll(() => { - // Presets a clear action, which is performed after all test cases of the test suite end. - // This API supports only one parameter: clear action function. - }) - it('assertContain', 0, () => { - // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. - hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); - let a = 'abc'; - let b = 'b'; - // Defines a variety of assertion methods, which are used to declare expected boolean conditions. - expect(a).assertContain(b); - expect(a).assertEqual(a); - }) - }) -} \ No newline at end of file diff --git a/ArkUI/orientationDevelopment/entry/src/ohosTest/ets/test/List.test.ets b/ArkUI/orientationDevelopment/entry/src/ohosTest/ets/test/List.test.ets deleted file mode 100644 index 794c7dc4ed66bd98fa3865e07922906e2fcef545..0000000000000000000000000000000000000000 --- a/ArkUI/orientationDevelopment/entry/src/ohosTest/ets/test/List.test.ets +++ /dev/null @@ -1,5 +0,0 @@ -import abilityTest from './Ability.test'; - -export default function testsuite() { - abilityTest(); -} \ No newline at end of file diff --git a/ArkUI/orientationDevelopment/entry/src/ohosTest/module.json5 b/ArkUI/orientationDevelopment/entry/src/ohosTest/module.json5 deleted file mode 100644 index cae0a4a066790141a32a4546bdc6976fa0a4225c..0000000000000000000000000000000000000000 --- a/ArkUI/orientationDevelopment/entry/src/ohosTest/module.json5 +++ /dev/null @@ -1,14 +0,0 @@ -{ - "module": { - "name": "entry_test", - "type": "feature", - "deviceTypes": [ - "phone", - "tablet", - "2in1", - "wearable" - ], - "deliveryWithInstall": true, - "installationFree": false - } -} diff --git a/AvoidTimeComsume/README.md b/AvoidTimeComsume/README.md index 454a1672429571f10324a4df9a851b7ee1a8f5de..4805fe672f81dc8efe1aa8ff0a47080ad8f288dc 100644 --- a/AvoidTimeComsume/README.md +++ b/AvoidTimeComsume/README.md @@ -1,10 +1,11 @@ # **主线程耗时操作优化指导** ## 介绍 在应用开发实践中,有效避免主线程执行冗余与易耗时操作是至关重要的策略。此举能有效降低主线程负载,提升UI的响应速度。面对高频回调接口在短时间内密集触发的场景,需要避免接口内的耗时操作,尽量保证主线程不被长时间占用,从而防止阻塞UI渲染,引发界面卡顿或掉帧现象。 -本实例结束开发过程中常见的冗余操作,常见的高频回调场景以及其他主线程优化思路。 +本实例介绍开发过程中常见的冗余操作,常见的高频回调场景以及其他主线程优化思路。 ## 预览效果 -![](screenshots/output-15_53_54.gif) + + ## 工程目录 ``` ├──entry/src/main/ets // 代码区 @@ -16,7 +17,7 @@ │ │ └──EntryBackupAbility.ets │ ├──pages │ │ └──Index.ets // 首页 -│ └──views.ets +│ └──views │ ├──ConditionalRendering.ets // 条件渲染页 │ ├──GetStrOfId.ets // ID资源获取页 │ ├──GetStrOfResource.ets // 资源获取页 @@ -36,28 +37,40 @@ └──entry/src/main/resources // 应用资源目录 ``` ## 使用说明 -“避免冗余操作”的正例和反例,反例中包含release版本中冗余日志打印、Trace打点以及无业务代码的空回调,降低了性能。 - -“高频回调场景中避免执行耗时操作”的正例和反例,以下常见高频回调场景中需要避免执行耗时操作: -* 高频事件回调 -* 组件复用回调 -* 组件生命周期回调 -* 循环渲染 -* 组件属性 - -反例中在高频事件中执行了上述耗时操作,降低了性能。 - -“避免使用耗时接口”的正例和反例,反例中使用了没有指定资源id的接口,导致耗时增加,从而影响了性能。 - -“使用多线程”是正例,开启多线程后,渲染页面速度加快,提升了性能。 +* 点击含有冗余操作按钮,进入二级页面。 +* 点击不含有冗余操作按钮,进入二级页面。 +* 点击组件复用反例按钮,进入二级页面,上下滑动,观察页面存在掉帧的现象。 +* 点击组件复用正例按钮,进入二级页面,上下滑动,页面滑动流畅。 +* 点击循环渲染反例按钮,进入二级页面,上下滑动,观察页面存在掉帧的现象。 +* 点击循环渲染正例按钮,进入二级页面,上下滑动,页面滑动流畅。 +* 点击组件属性反例按钮,进入二级页面,点击按钮,观察页面变化。 +* 点击组件属性正例按钮,进入二级页面,点击按钮,观察页面变化。 +* 点击通过资源对象按钮,进入二级页面。 +* 点击通过资源ID按钮,进入二级页面。 +* 点击使用异步按钮,进入二级页面,上下滑动,页面滑动流畅。 +* 点击使用多线程按钮,进入二级页面,上下滑动,页面滑动流畅。 +* 点击高频事件回调执行耗时操作按钮,进入二级页面。 +* 点击高频事件回调不执行耗时操作按钮,进入二级页面。 +* 点击条件渲染按钮,进入二级页面,点击按钮,观察页面变化。 ## 相关权限 -无 +不涉及 ## 约束与限制 * 本示例仅支持标准系统上运行,支持设备:华为手机。 -* HarmonyOS系统:HarmonyOS NEXT Release及以上。 +* HarmonyOS系统:HarmonyOS 5.0.5 Release及以上。 + +* DevEco Studio版本:DevEco Studio 5.0.5 Release及以上。 + +* HarmonyOS SDK版本:HarmonyOS 5.0.5 Release SDK及以上。 -* DevEco Studio版本:DevEco Studio NEXT Release及以上。 +## 下载 -* HarmonyOS SDK版本:HarmonyOS NEXT Release SDK及以上。 \ No newline at end of file +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set AvoidTimeComsume +git checkout +``` \ No newline at end of file diff --git a/AvoidTimeComsume/README_EN.md b/AvoidTimeComsume/README_EN.md index 3042a16cb75fb18ec1817feec95e570aac3784fa..bae0f4ece15dbce9cc3897993711b794967341a0 100644 --- a/AvoidTimeComsume/README_EN.md +++ b/AvoidTimeComsume/README_EN.md @@ -3,8 +3,6 @@ In application development practices, it is important to effectively prevent the main thread from performing redundant and time-consuming operations. This can effectively reduce the load of the main thread and speed up the UI response. In scenarios where high-frequency callbacks are frequently triggered in a short period of time, time-consuming operations in the APIs need to be avoided to ensure that the main thread is not occupied for a long time. This prevents UI rendering from being blocked to avoid frame freezing or frame loss. This sample describes common redundant operations, common high-frequency callback scenarios, and other main thread optimization methods during development. -## Preview -![](screenshots/output-15_16_3.gif) ## Project Directory ``` ├──entry/src/main/ets // Code @@ -56,8 +54,19 @@ N/A ## Constraints * This sample is supported only on Huawei phones running the standard system. -* The HarmonyOS version must be HarmonyOS NEXT Release or later. +* The HarmonyOS version must be HarmonyOS 5.0.5 Release or later. -* The DevEco Studio version must be DevEco Studio NEXT Release or later. +* The DevEco Studio version must be DevEco Studio 5.0.5 Release or later. -* The HarmonyOS SDK version must be HarmonyOS NEXT Release SDK or later. +* The HarmonyOS SDK version must be HarmonyOS 5.0.5 Release SDK or later. + +## Download + +To download this project separately, execute the following command: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set AvoidTimeComsume +git checkout +``` diff --git a/AvoidTimeComsume/build-profile.json5 b/AvoidTimeComsume/build-profile.json5 index b2cc02977d74631a63703f33a1ae6c1f94d81219..6addf0233cf8ed875ba6574c0c91538334c17921 100644 --- a/AvoidTimeComsume/build-profile.json5 +++ b/AvoidTimeComsume/build-profile.json5 @@ -6,7 +6,8 @@ { "name": "default", "signingConfig": "default", - "compatibleSdkVersion": "5.0.0(12)", + "compatibleSdkVersion": "5.0.5(17)", + "targetSdkVersion": "5.0.5(17)", "runtimeOS": "HarmonyOS", } ], diff --git a/AvoidTimeComsume/entry/src/main/ets/entryability/EntryAbility.ets b/AvoidTimeComsume/entry/src/main/ets/entryability/EntryAbility.ets index 80c495ede2460b86c56489c6c654126b77f31de6..471cad2a7dac7c186ecf07b2b15d41c2274b5370 100644 --- a/AvoidTimeComsume/entry/src/main/ets/entryability/EntryAbility.ets +++ b/AvoidTimeComsume/entry/src/main/ets/entryability/EntryAbility.ets @@ -39,7 +39,11 @@ export default class EntryAbility extends UIAbility { return; } hilog.info(0x0000, 'Sample', 'Succeeded in loading the content.'); - AppStorage.setOrCreate('uiContext', windowStage.getMainWindowSync().getUIContext()); + try { + AppStorage.setOrCreate('uiContext', windowStage.getMainWindowSync().getUIContext()); + } catch (error) { + hilog.error(0x0000, 'Sample', 'Failed to getMainWindowSync. Cause: %{public}s', JSON.stringify(error) ?? ''); + } }); windowStage.getMainWindow().then((windowObj) => { diff --git a/AvoidTimeComsume/entry/src/main/ets/pages/Index.ets b/AvoidTimeComsume/entry/src/main/ets/pages/Index.ets index e0258427c40dc9eb4b6459254820f2d07353f24e..8e2e7bf6cccd25a580d581b77918e6e3db87eb83 100644 --- a/AvoidTimeComsume/entry/src/main/ets/pages/Index.ets +++ b/AvoidTimeComsume/entry/src/main/ets/pages/Index.ets @@ -12,6 +12,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import { BusinessError } from '@kit.BasicServicesKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; class DirectoryItem { title: ResourceStr = ''; @@ -107,6 +109,8 @@ struct Index { .onClick(() => { this.getUIContext().getRouter().pushUrl({ url: item.uri + }).catch((error: BusinessError)=>{ + hilog.error(0x0000,'',`pushUrl failed. code=${error.code}, message=${error.message}`); }); }) } @@ -128,6 +132,8 @@ struct Index { .onClick(() => { this.getUIContext().getRouter().pushUrl({ url: 'views/NegativeOfOnScroll' + }).catch((error: BusinessError)=>{ + hilog.error(0x0000,'',`pushUrl failed. code=${error.code}, message=${error.message}`); }); }) Button($r('app.string.positive_of_onScroll')) @@ -139,6 +145,8 @@ struct Index { .onClick(() => { this.getUIContext().getRouter().pushUrl({ url: 'views/PositiveOfOnScroll' + }).catch((error: BusinessError)=>{ + hilog.error(0x0000,'',`pushUrl failed. code=${error.code}, message=${error.message}`); }); }) Button($r('app.string.conditional_rendering')) @@ -150,7 +158,9 @@ struct Index { .onClick(() => { this.getUIContext().getRouter().pushUrl({ url: 'views/ConditionalRendering' - }); + }).catch((error: BusinessError)=>{ + hilog.error(0x0000,'',`pushUrl failed. code=${error.code}, message=${error.message}`); + });; }) } .padding({ left: 16, right: 16, bottom: 44 }) diff --git a/AvoidTimeComsume/entry/src/main/ets/views/ConditionalRendering.ets b/AvoidTimeComsume/entry/src/main/ets/views/ConditionalRendering.ets index 382f6fa052d3e715ce5b0df966e644ac85809278..ca0d90579746c63a4079ed6b7cc7d7d6d5e2d7a5 100644 --- a/AvoidTimeComsume/entry/src/main/ets/views/ConditionalRendering.ets +++ b/AvoidTimeComsume/entry/src/main/ets/views/ConditionalRendering.ets @@ -13,9 +13,9 @@ * limitations under the License. */ +// [Start conditional_rendering] import { hilog } from '@kit.PerformanceAnalysisKit'; -// [Start conditional_rendering] @Entry @Component struct MyComponent { @@ -26,6 +26,7 @@ struct MyComponent { Column({ space: 10 }) { Row({ space: 5 }) { Column() { + // $r('app.media.chevron_left') It needs to be replaced with the resources required by the developers Image($r('app.media.chevron_left')) .width(16) .height(16) @@ -77,7 +78,7 @@ struct MyComponent { @Component struct CustomComponentA { aboutToAppear(): void { - let temp = 0; + let temp: number = 0; for (let i = 0; i < 1000000; i++) { temp += 1; } @@ -85,7 +86,7 @@ struct CustomComponentA { } aboutToDisappear(): void { - let temp = 0; + let temp: number = 0; for (let i = 0; i < 1000000; i++) { temp += 1; } @@ -103,7 +104,7 @@ struct CustomComponentA { @Component struct CustomComponentB { aboutToAppear(): void { - let temp = 0; + let temp: number = 0; for (let i = 0; i < 1000000; i++) { temp += 1; } @@ -111,7 +112,7 @@ struct CustomComponentB { } aboutToDisappear(): void { - let temp = 0; + let temp: number = 0; for (let i = 0; i < 1000000; i++) { temp += 1; } diff --git a/AvoidTimeComsume/entry/src/main/ets/views/GetStrOfId.ets b/AvoidTimeComsume/entry/src/main/ets/views/GetStrOfId.ets index c0c91c35cc43a9500b38113de23643617d0db950..2dad628dc99368e72d05e8d046541d504c924ef8 100644 --- a/AvoidTimeComsume/entry/src/main/ets/views/GetStrOfId.ets +++ b/AvoidTimeComsume/entry/src/main/ets/views/GetStrOfId.ets @@ -14,7 +14,7 @@ */ // [Start get_str_of_id] -import { hiTraceMeter } from '@kit.PerformanceAnalysisKit'; +import { hilog, hiTraceMeter } from '@kit.PerformanceAnalysisKit'; @Entry @Component @@ -23,8 +23,12 @@ struct GetStrOfId { aboutToAppear(): void { hiTraceMeter.startTrace('getStringSyncAfter', 1); - // The input parameter of the getStringSync operation directly uses the resource and does use the resource ID - this.getUIContext().getHostContext()!.resourceManager.getStringSync($r('app.string.test').id) + // The input parameter of the getStringSync operation directly uses the resource and resource ID + try { + this.getUIContext().getHostContext()!.resourceManager.getStringSync($r('app.string.test').id) + } catch (error) { + hilog.error(0x0000,'',`getStringSync failed. code=${error.code}, message=${error.message}`); + } hiTraceMeter.finishTrace('getStringSyncAfter', 1) } diff --git a/AvoidTimeComsume/entry/src/main/ets/views/GetStrOfResource.ets b/AvoidTimeComsume/entry/src/main/ets/views/GetStrOfResource.ets index db9f6697178b564713a2cf8db7b2fb03660e2099..edf6f5ec9cbc18b62ec02a500a368cc1c71bb75a 100644 --- a/AvoidTimeComsume/entry/src/main/ets/views/GetStrOfResource.ets +++ b/AvoidTimeComsume/entry/src/main/ets/views/GetStrOfResource.ets @@ -14,7 +14,7 @@ */ // [Start get_str_of_resource] -import { hiTraceMeter } from '@kit.PerformanceAnalysisKit'; +import { hilog, hiTraceMeter } from '@kit.PerformanceAnalysisKit'; @Entry @@ -25,7 +25,11 @@ struct GetStrOfResource { aboutToAppear(): void { hiTraceMeter.startTrace('getStringSync', 1); // The input parameter of the getStringSync operation directly uses the resource and does not use the resource ID - this.getUIContext().getHostContext()!.resourceManager.getStringSync($r('app.string.test')) + try { + this.getUIContext().getHostContext()!.resourceManager.getStringSync($r('app.string.test').id) + } catch (error) { + hilog.error(0x0000,'',`getStringSync failed. code=${error.code}, message=${error.message}`); + } hiTraceMeter.finishTrace('getStringSync', 1) } diff --git a/AvoidTimeComsume/entry/src/main/ets/views/NegativeOfGrid.ets b/AvoidTimeComsume/entry/src/main/ets/views/NegativeOfGrid.ets index 10dc77d32809a74dfe91536457bde5cdad3ce7a0..0390ed3f5e24336b6c158b06dbf25a10d747db25 100644 --- a/AvoidTimeComsume/entry/src/main/ets/views/NegativeOfGrid.ets +++ b/AvoidTimeComsume/entry/src/main/ets/views/NegativeOfGrid.ets @@ -14,7 +14,6 @@ */ import { hiTraceMeter } from '@kit.PerformanceAnalysisKit'; -import { router } from '@kit.ArkUI'; class MyDataSource implements IDataSource { private dataArray: number[] = []; diff --git a/AvoidTimeComsume/entry/src/main/ets/views/NoRedundantOperation.ets b/AvoidTimeComsume/entry/src/main/ets/views/NoRedundantOperation.ets index 383ec3876813141be4d827ffa6ed4c47875e511e..c50fc4448d6899d581b16f746bd1ffa679a48923 100644 --- a/AvoidTimeComsume/entry/src/main/ets/views/NoRedundantOperation.ets +++ b/AvoidTimeComsume/entry/src/main/ets/views/NoRedundantOperation.ets @@ -14,7 +14,6 @@ */ import { hilog } from '@kit.PerformanceAnalysisKit'; -import { router } from '@kit.ArkUI'; // [Start no_redundant_operation] // Redundancy operation example diff --git a/AvoidTimeComsume/entry/src/main/ets/views/PositiveOfProperty.ets b/AvoidTimeComsume/entry/src/main/ets/views/PositiveOfProperty.ets index 1ce7eab8ea5024ae3037b809b959c54cda4b7fb3..431f46ecfb11ee22975ae5b7ae825d5155d0f1ce 100644 --- a/AvoidTimeComsume/entry/src/main/ets/views/PositiveOfProperty.ets +++ b/AvoidTimeComsume/entry/src/main/ets/views/PositiveOfProperty.ets @@ -16,6 +16,7 @@ // [Start positive_of_property] import { taskpool } from '@kit.ArkTS'; // Task pools import { hilog } from '@kit.PerformanceAnalysisKit'; +import { BusinessError } from '@kit.BasicServicesKit'; @Concurrent function getHeight(): number { @@ -31,7 +32,9 @@ function getHeight(): number { // Execute getHeight taskpool.execute(getHeight).then((value: Object) => { AppStorage.setOrCreate('height', value); -}) +}).catch((error: BusinessError)=>{ + hilog.error(0x0000,'',`execute failed. code=${error.code}, message=${error.message}`); +}); @Entry @Component diff --git a/AvoidTimeComsume/entry/src/main/ets/views/UseAsync.ets b/AvoidTimeComsume/entry/src/main/ets/views/UseAsync.ets index cb40596a524299b49ecba14efab78bc5b5b5cbe6..76f17e27f2d49f16cc4685704ae015a49f0d7cf8 100644 --- a/AvoidTimeComsume/entry/src/main/ets/views/UseAsync.ets +++ b/AvoidTimeComsume/entry/src/main/ets/views/UseAsync.ets @@ -16,7 +16,8 @@ import { Item, ResponseData, dataToItem } from '../common/Item'; import { WaterFlowDataSource } from './WaterFlowDataSource'; import { buffer } from '@kit.ArkTS'; - +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { BusinessError } from '@kit.BasicServicesKit'; @Entry @Component @@ -122,9 +123,15 @@ struct WaterFlowExample2 { // data.json is the local json data, which is about 20 MB in size, and simulates getting data from the network await this.getUIContext().getHostContext()!.resourceManager.getRawFileContent('data.json').then((data: Uint8Array) => { // parse json - let str = buffer.from(data).toString(); - res = JSON.parse(str); - }) + try { + let str: string = buffer.from(data).toString(); + res = JSON.parse(str); + } catch (error) { + hilog.error(0x0000,'',`buffer.from failed. code=${error.code}, message=${error.message}`); + } + }).catch((error: BusinessError)=>{ + hilog.error(0x0000,'',`getRawFileContent failed. code=${error.code}, message=${error.message}`); + }); return dataToItem(res.data) } diff --git a/AvoidTimeComsume/entry/src/main/ets/views/UseTaskPool.ets b/AvoidTimeComsume/entry/src/main/ets/views/UseTaskPool.ets index cd2ecf9fa7bb45f021a9c2d7816070b1b016dd13..650c4ddec72f633a818605da180ea106ef13ef78 100644 --- a/AvoidTimeComsume/entry/src/main/ets/views/UseTaskPool.ets +++ b/AvoidTimeComsume/entry/src/main/ets/views/UseTaskPool.ets @@ -16,6 +16,8 @@ import { buffer, taskpool } from '@kit.ArkTS'; import { Item, ResponseData, dataToItem } from '../common/Item'; import { WaterFlowDataSource } from './WaterFlowDataSource'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { BusinessError } from '@kit.BasicServicesKit'; @Entry @Component @@ -23,7 +25,7 @@ struct WaterFlowExample { @State fontSize: number = 24; scroller: Scroller = new Scroller(); dataSource: WaterFlowDataSource = new WaterFlowDataSource(); - UIContext = this.getUIContext() + UIContext: UIContext = this.getUIContext() @Builder itemFoot() { @@ -123,18 +125,31 @@ struct WaterFlowExample { // The following methods are defined outside of the component async function taskPoolExecute(UIContext: UIContext): Promise { let task: taskpool.Task = new taskpool.Task(mockRequestData, UIContext); - return await taskpool.execute(task) as Item[]; + let result: Item[] = []; + try { + result = await taskpool.execute(task) as Item[] + } catch (error) { + hilog.error(0x0000,'',`execute failed. code=${error.code}, message=${error.message}`); + } + return result; } +@Concurrent async function mockRequestData(context: Context): Promise { let res: ResponseData = new ResponseData(); // data.json is the local json data, which is about 20 MB in size, and simulates getting data from the network await context.resourceManager.getRawFileContent('data.json').then((data: Uint8Array) => { // parse json - let str = buffer.from(data).toString(); - res = JSON.parse(str); - }) - let arr = dataToItem(res.data); + try { + let str: string = buffer.from(data).toString(); + res = JSON.parse(str); + } catch (error) { + hilog.error(0x0000,'',`buffer.from failed. code=${error.code}, message=${error.message}`); + } + }).catch((error: BusinessError)=>{ + hilog.error(0x0000,'',`getRawFileContent failed. code=${error.code}, message=${error.message}`); + }); + let arr: Item[] = dataToItem(res.data); return arr; } diff --git a/AvoidTimeComsume/screenshots/homePage.png b/AvoidTimeComsume/screenshots/homePage.png new file mode 100644 index 0000000000000000000000000000000000000000..c1f73094e0cc410ab9742b6a9d7849a4c87a40a0 Binary files /dev/null and b/AvoidTimeComsume/screenshots/homePage.png differ diff --git a/AvoidTimeComsume/screenshots/output-15_16_3.gif b/AvoidTimeComsume/screenshots/output-15_16_3.gif deleted file mode 100644 index 8edf68e5b8a0b97a89b25f71dd0a5d641399d7b4..0000000000000000000000000000000000000000 Binary files a/AvoidTimeComsume/screenshots/output-15_16_3.gif and /dev/null differ diff --git a/AvoidTimeComsume/screenshots/output-15_53_54.gif b/AvoidTimeComsume/screenshots/output-15_53_54.gif deleted file mode 100644 index 42fc9bd5c53efbab0f801c76f336e4b440e5ecdb..0000000000000000000000000000000000000000 Binary files a/AvoidTimeComsume/screenshots/output-15_53_54.gif and /dev/null differ diff --git a/BackgroundBlur/README.en.md b/BackgroundBlur/README.en.md index 92581dcc4462cec3b1b9e066bbe7b6fbfa75d32f..49126a76823303502b64ed2d7fda2c8455bafc21 100644 --- a/BackgroundBlur/README.en.md +++ b/BackgroundBlur/README.en.md @@ -69,8 +69,19 @@ N/A 1. This sample is supported only on Huawei phones running the standard system. -2. The HarmonyOS version must be HarmonyOS NEXT Release or later. +2. The HarmonyOS version must be HarmonyOS 5.0.5 Release or later. -3. The DevEco Studio version must be DevEco Studio NEXT Release or later. +3. The DevEco Studio version must be DevEco Studio 5.0.5 Release or later. -4. The HarmonyOS SDK version must be HarmonyOS NEXT Release SDK or later. +4. The HarmonyOS SDK version must be HarmonyOS5.0.5 Release SDK or later. + +### Download + +To download this project separately, execute the following command: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set BackgroundBlur +git checkout +``` \ No newline at end of file diff --git a/BackgroundBlur/README.md b/BackgroundBlur/README.md index 63ce6893af1f7cebc46281cc14bd6821d09766b2..c51ddcdc97119d50ce83f58ef11e4e856121b931 100644 --- a/BackgroundBlur/README.md +++ b/BackgroundBlur/README.md @@ -30,7 +30,7 @@ │ ├──entryability │ │ └──EntryAbility.ets // Ability的生命周期回调内容 │ ├──entrybackupability -│ │ └──EntryBackupAbility.ets +│ │ └──EntryBackupAbility.ets // 应用数据备份和恢复 │ └──pages │ ├──AdaptiveColorMode.ets // 视图层-使用AdaptiveColor取色效果页面 │ ├──ColorPickerMode.ets // 视图层-使用ColorPicker取色效果页面 @@ -59,8 +59,19 @@ 1.本示例仅支持标准系统上运行,支持设备:华为手机。 -2.HarmonyOS系统:HarmonyOS NEXT Release及以上。 +2.HarmonyOS系统:HarmonyOS 5.0.5 Release及以上。 -3.DevEco Studio版本:DevEco Studio NEXT Release及以上。 +3.DevEco Studio版本:DevEco Studio 5.0.5 Release及以上。 -4.HarmonyOS SDK版本:HarmonyOS NEXT Release SDK及以上。 +4.HarmonyOS SDK版本:HarmonyOS 5.0.5 Release SDK及以上。 + +### 下载 + +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set BackgroundBlur +git checkout +``` diff --git a/BackgroundBlur/build-profile.json5 b/BackgroundBlur/build-profile.json5 index adce96361e2c935e9a1f0c303bea4da26485e58b..79d90a8b6d11889d5f388820c296223aaa8e51b5 100644 --- a/BackgroundBlur/build-profile.json5 +++ b/BackgroundBlur/build-profile.json5 @@ -4,7 +4,8 @@ { "name": "default", "signingConfig": "default", - "compatibleSdkVersion": "5.0.0(12)", + "compatibleSdkVersion": "5.0.5(17)", + "targetSdkVersion": "5.0.5(17)", "runtimeOS": "HarmonyOS" } ], diff --git a/BackgroundBlur/entry/src/main/ets/pages/ColorPickerMode.ets b/BackgroundBlur/entry/src/main/ets/pages/ColorPickerMode.ets index 5109b43bce5c0e8d291013250cf1e15305a271fe..fc6cdbbb49858ca29281bc3dbd96a0eeb00fb203 100644 --- a/BackgroundBlur/entry/src/main/ets/pages/ColorPickerMode.ets +++ b/BackgroundBlur/entry/src/main/ets/pages/ColorPickerMode.ets @@ -30,16 +30,18 @@ export struct ColorPickerMode { @State blurColor: string = 'rgba(255,255,255,255)'; async blurPix(resource: Resource) { - const context = this.getUIContext().getHostContext()!; - const resourceMgr = context.resourceManager - const fileData = await resourceMgr.getMediaContent(resource) - const buffer = fileData.buffer - let imageSource = image.createImageSource(buffer as ArrayBuffer) - this.pixMap = await imageSource.createPixelMap(); - // create a color picker for color extraction - this.kitColor = (await effectKit.createColorPicker(this.pixMap, [0, 0, 1, 1])).getAverageColor(); - // convert to the format of the blur interface color parameter - this.blurColor = 'rgba(' + this.kitColor.red + ',' + this.kitColor.green + ',' + this.kitColor.blue + ',0)'; + try { + const context: Context = this.getUIContext().getHostContext()!; + const fileData: Uint8Array = await context.resourceManager.getMediaContent(resource.id); + const buffer: ArrayBufferLike = fileData.buffer + let imageSource: image.ImageSource = image.createImageSource(buffer as ArrayBuffer) + this.pixMap = await imageSource.createPixelMap(); + // create a color picker for color extraction + this.kitColor = (await effectKit.createColorPicker(this.pixMap, [0, 0, 1, 1])).getAverageColor(); + // convert to the format of the blur interface color parameter + this.blurColor = 'rgba(' + this.kitColor.red + ',' + this.kitColor.green + ',' + this.kitColor.blue + ',0)'; + } catch (err) { + } } build() { @@ -72,4 +74,5 @@ export struct ColorPickerMode { .hideTitleBar(true) } } + // [End color_picker] diff --git a/BackgroundBlur/hvigor/hvigor-config.json5 b/BackgroundBlur/hvigor/hvigor-config.json5 index 06b2783670a348f95533b352c1ceda909a842bbc..5bebc9755447385d82ce4138f54d991b1f85f348 100644 --- a/BackgroundBlur/hvigor/hvigor-config.json5 +++ b/BackgroundBlur/hvigor/hvigor-config.json5 @@ -1,5 +1,5 @@ { - "modelVersion": "5.0.0", + "modelVersion": "5.0.5", "dependencies": { }, "execution": { diff --git a/BackgroundBlur/oh-package.json5 b/BackgroundBlur/oh-package.json5 index 0cec98259052cc175d04dbcf61780de4bc9785f4..f440d114b8a9d9aeadd0e891bba0d0d076e70936 100644 --- a/BackgroundBlur/oh-package.json5 +++ b/BackgroundBlur/oh-package.json5 @@ -1,5 +1,5 @@ { - "modelVersion": "5.0.0", + "modelVersion": "5.0.5", "description": "Please describe the basic information.", "dependencies": { }, diff --git a/BptaUseResources/.gitignore b/BptaUseResources/.gitignore deleted file mode 100644 index d2ff20141ceed86d87c0ea5d99481973005bab2b..0000000000000000000000000000000000000000 --- a/BptaUseResources/.gitignore +++ /dev/null @@ -1,12 +0,0 @@ -/node_modules -/oh_modules -/local.properties -/.idea -**/build -/.hvigor -.cxx -/.clangd -/.clang-format -/.clang-tidy -**/.test -/.appanalyzer \ No newline at end of file diff --git a/BptaUseResources/README.md b/BptaUseResources/README.md index d71e93dee2e251b09a1a8168e45491cfaab59d5c..475e9c17d4a36d2a7d48850042883cb3eb31623d 100644 --- a/BptaUseResources/README.md +++ b/BptaUseResources/README.md @@ -4,17 +4,33 @@ 无长时任务的应用退到后台时,不允许进行蓝牙扫描。 +### 使用说明 +不涉及 + ### 工程结构&模块类型 ``` -├──entry/src/main/ets/ -│ ├──entryability -│ │ └──EntryAbility.ets // 配置类 -│ └──pages -│ └──Index.ets // 程序入口 -│ └──Https.ets // HTTP数据请求 -│ └──Bluetooth.ets // 合理使用蓝牙资源 -└──entry/src/main/resource // 应用静态资源目录 +├──entry/src/main +│ ├──ets +│ │ ├──entryability +│ │ │ └──EntryAbility.ets // 配置类 +│ │ ├──entrybackupability +│ │ │ └──EntryBackupAbility.ets // 应用数据备份恢复类 +│ │ └──pages +│ │ ├──Index.ets // 程序入口 +│ │ ├──Gps.ets // gps示例 +│ │ ├──Sensor.ets // 传感器示例 +│ │ ├──Socket.ets // socket示例 +│ │ ├──WebSocket.ets // WebSocket示例 +│ │ ├──Https.ets // HTTP数据请求 +│ │ └──Bluetooth.ets // 合理使用蓝牙资源 +│ └──cpp +│ ├──types +│ │ └──index.d.ts // c++导出方法 +│ ├──CMakeLists.txt +│ ├──napi_init.cpp // 合理使用蓝牙资源 +│ └──OpenSL.cpp // 初始化代码 +└──entry/src/main/resource // 应用静态资源目录 ``` @@ -26,8 +42,19 @@ 1. 本示例仅支持标准系统上运行,支持设备:华为手机。 -2. HarmonyOS 系统:HarmonyOS NEXT Developer Beta1 及以上。 +2. HarmonyOS 系统:HarmonyOS 5.0.5 Release及以上。 + +3. DevEco Studio 版本:DevEco Studio 5.0.5 Release及以上。 + +4. HarmonyOS SDK 版本:HarmonyOS 5.0.5 Release SDK及以上。 -3. DevEco Studio 版本:DevEco Studio NEXT Developer Beta1 及以上。 +### 下载 -4. HarmonyOS SDK 版本:HarmonyOS NEXT Developer Beta1 SDK 及以上。 +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set BptaUseResources +git checkout +``` diff --git a/BptaUseResources/build-profile.json5 b/BptaUseResources/build-profile.json5 index 9e87e7e6f19020fe21192844709f192cec80fd44..f120cc13b0fec135d32bc1b97b13b9f71542a237 100644 --- a/BptaUseResources/build-profile.json5 +++ b/BptaUseResources/build-profile.json5 @@ -12,6 +12,9 @@ "strictMode": { "caseSensitiveCheck": true, "useNormalizedOHMUrl": true + }, + "packOptions": { + "enableSourceCodeCheck": false } } } diff --git a/BptaUseResources/entry/.gitignore b/BptaUseResources/entry/.gitignore deleted file mode 100644 index e2713a2779c5a3e0eb879efe6115455592caeea5..0000000000000000000000000000000000000000 --- a/BptaUseResources/entry/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -/node_modules -/oh_modules -/.preview -/build -/.cxx -/.test \ No newline at end of file diff --git a/BptaUseResources/entry/src/main/cpp/CMakeLists.txt b/BptaUseResources/entry/src/main/cpp/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..1acd3ec1c568e86cb70911ecc57edfbb21bcd1ea --- /dev/null +++ b/BptaUseResources/entry/src/main/cpp/CMakeLists.txt @@ -0,0 +1,15 @@ +# the minimum version of CMake. +cmake_minimum_required(VERSION 3.5.0) +project(CppCrash) + +set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}) + +if(DEFINED PACKAGE_FIND_FILE) + include(${PACKAGE_FIND_FILE}) +endif() + +include_directories(${NATIVERENDER_ROOT_PATH} + ${NATIVERENDER_ROOT_PATH}/include) + +add_library(entry SHARED napi_init.cpp) +target_link_libraries(entry PUBLIC libace_napi.z.so) \ No newline at end of file diff --git a/BptaUseResources/entry/src/main/cpp/OpenSL.cpp b/BptaUseResources/entry/src/main/cpp/OpenSL.cpp new file mode 100644 index 0000000000000000000000000000000000000000..000428eb92e8303673c2eeef0bcf86ecfcb894b7 --- /dev/null +++ b/BptaUseResources/entry/src/main/cpp/OpenSL.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ +/** + * 最佳实践:合理使用音频资源 + * 场景三:播音场景(OpenSL ES) + */ + +// [Start open_sl_es] +//The foreground scene starts to play +SLPlayItfplayItf=nullptr; +(*pcmPlayerObject)->GetInterface(pcmPlayerObject,SL_IID_PLAY,&playItf); +(*playItf)->SetPlayState(playItf,SL_PLAYSTATE_PLAYING); +// Stop playing the background scene +(*playItf)->SetPlayState(playItf,SL_PLAYSTATE_STOPPED); +(*pcmPlayerObject)->Destroy(pcmPlayerObject); +(*engineObject)->Destroy(engineObject); +// [End open_sl_es] + +/** + * 最佳实践:合理使用音频资源 + * 场景四:播音场景(OHAudio) + */ + +// [Start oh_audio] +//Construct the audio stream to play +OH_AudioRenderer*audioRenderer; +ret=OH_AudioStreamBuilder_GenerateRenderer(builder,&audioRenderer); + +//The foreground scene starts to play +ret=OH_AudioRenderer_Start(audioRenderer); +// Stop playing the background scene +ret=OH_AudioRenderer_Stop(audioRenderer); +// [End oh_audio] \ No newline at end of file diff --git a/BptaUseResources/entry/src/main/cpp/napi_init.cpp b/BptaUseResources/entry/src/main/cpp/napi_init.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d0e1aafcb6b5c3252ef439d9d9d54e8c082fda1d --- /dev/null +++ b/BptaUseResources/entry/src/main/cpp/napi_init.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + +#include "napi/native_api.h" + +static napi_value Add(napi_env env, napi_callback_info info) +{ + size_t argc = 2; + napi_value args[2] = {nullptr}; + + napi_get_cb_info(env, info, &argc, args , nullptr, nullptr); + + napi_valuetype valuetype0; + napi_typeof(env, args[0], &valuetype0); + + napi_valuetype valuetype1; + napi_typeof(env, args[1], &valuetype1); + + double value0; + napi_get_value_double(env, args[0], &value0); + + double value1; + napi_get_value_double(env, args[1], &value1); + + napi_value sum; + napi_create_double(env, value0 + value1, &sum); + + return sum; + +} + +EXTERN_C_START +static napi_value Init(napi_env env, napi_value exports) +{ + napi_property_descriptor desc[] = { + { "add", nullptr, Add, nullptr, nullptr, nullptr, napi_default, nullptr } + }; + napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); + return exports; +} +EXTERN_C_END + +static napi_module demoModule = { + .nm_version = 1, + .nm_flags = 0, + .nm_filename = nullptr, + .nm_register_func = Init, + .nm_modname = "entry", + .nm_priv = ((void*)0), + .reserved = { 0 }, +}; + +extern "C" __attribute__((constructor)) void RegisterEntryModule(void) +{ + napi_module_register(&demoModule); +} diff --git a/BptaUseResources/entry/src/main/cpp/types/libentry/index.d.ts b/BptaUseResources/entry/src/main/cpp/types/libentry/index.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..e44f3615a4767c36b4fdc841b781af96bf1971a8 --- /dev/null +++ b/BptaUseResources/entry/src/main/cpp/types/libentry/index.d.ts @@ -0,0 +1 @@ +export const add: (a: number, b: number) => number; \ No newline at end of file diff --git a/BptaUseResources/entry/src/main/cpp/types/libentry/oh-package.json5 b/BptaUseResources/entry/src/main/cpp/types/libentry/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..17f2fec28b34ad5d42507c4fa15c7e4d0d16eb70 --- /dev/null +++ b/BptaUseResources/entry/src/main/cpp/types/libentry/oh-package.json5 @@ -0,0 +1,6 @@ +{ + "name": "libentry.so", + "types": "./index.d.ts", + "version": "1.0.0", + "description": "Please describe the basic information." +} \ No newline at end of file diff --git a/BptaUseResources/entry/src/main/ets/entryability/EntryAbility.ets b/BptaUseResources/entry/src/main/ets/entryability/EntryAbility.ets index 508880af8c33aa838016d1cd4b2c68be2f447540..69f8a2d6d7d3ebb7dbb2a410be697942b91153bd 100644 --- a/BptaUseResources/entry/src/main/ets/entryability/EntryAbility.ets +++ b/BptaUseResources/entry/src/main/ets/entryability/EntryAbility.ets @@ -1,12 +1,18 @@ import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; import { hilog } from '@kit.PerformanceAnalysisKit'; import { window } from '@kit.ArkUI'; +import { BusinessError } from '@kit.BasicServicesKit'; const DOMAIN = 0x0000; export default class EntryAbility extends UIAbility { onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { - this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + try { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + } catch (error) { + let err = error as BusinessError; + hilog.warn(0x000, 'testTag', `setColorMode failed, code=${err.code}, message=${err.message}`); + } hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); } diff --git a/BptaUseResources/entry/src/main/ets/pages/Bluetooth.ets b/BptaUseResources/entry/src/main/ets/pages/Bluetooth.ets index 4ec6438cf8ebaf8f61d0b3276bae9f9d5d6f6223..06b4493552e0b08b7366c942c8a1589caf0c5cd3 100644 --- a/BptaUseResources/entry/src/main/ets/pages/Bluetooth.ets +++ b/BptaUseResources/entry/src/main/ets/pages/Bluetooth.ets @@ -5,6 +5,8 @@ // [Start blue_tooth] import { UIAbility } from '@kit.AbilityKit'; import { ble } from '@kit.ConnectivityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { BusinessError } from '@kit.BasicServicesKit'; // [StartExclude blue_tooth] const scanFilter: ble.ScanFilter = {} @@ -20,15 +22,25 @@ const advResponse = undefined export default class EntryAbility extends UIAbility { // ... onForeground(): void { - //Initiate Ble scan and broadcast as required by the service at the foreground - ble.startBLEScan([scanFilter], scanOptions); - ble.startAdvertising(setting, advData, advResponse); + try { + //Initiate Ble scan and broadcast as required by the service at the foreground + ble.startBLEScan([scanFilter], scanOptions); + ble.startAdvertising(setting, advData, advResponse); + } catch (error) { + let err = error as BusinessError; + hilog.warn(0x000, 'testTag', `startBLEScan or startAdvertising failed, code=${err.code}, message=${err.message}`); + } } onBackground(): void { - // Return to the background to stop the Ble scanning and broadcast, which is the same as the application - ble.stopBLEScan(); - ble.stopAdvertising(); + try { + // Return to the background to stop the Ble scanning and broadcast, which is the same as the application + ble.stopBLEScan(); + ble.stopAdvertising(); + } catch (error) { + let err = error as BusinessError; + hilog.warn(0x000, 'testTag', `stopBLEScan or stopAdvertising failed, code=${err.code}, message=${err.message}`); + } } } // [End blue_tooth] \ No newline at end of file diff --git a/BptaUseResources/entry/src/main/ets/pages/Gps.ets b/BptaUseResources/entry/src/main/ets/pages/Gps.ets index b43d05d2255d1b3044689f33ac35ab3094565ce1..5d427bf5c5ee49c11815944ce2f48f81905d0cd9 100644 --- a/BptaUseResources/entry/src/main/ets/pages/Gps.ets +++ b/BptaUseResources/entry/src/main/ets/pages/Gps.ets @@ -5,11 +5,14 @@ // [Start gps_resources] import { UIAbility } from '@kit.AbilityKit'; import { geoLocationManager } from '@kit.LocationKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { BusinessError } from '@kit.BasicServicesKit'; // [StartExclude gps_resources] let locationChange = (location: geoLocationManager.Location): void => { console.log('locationChanger:data:' + JSON.stringify(location)); }; + // [EndExclude gps_resources] export default class EntryAbility extends UIAbility { @@ -25,13 +28,24 @@ export default class EntryAbility extends UIAbility { let locationChange = (location: geoLocationManager.Location): void => { console.log('locationChanger:data:' + JSON.stringify(location)); }; - //The change of the listening position - geoLocationManager.on('locationChange', requestInfo, locationChange); + try { + //The change of the listening position + geoLocationManager.on('locationChange', requestInfo, locationChange); + } catch (error) { + let err = error as BusinessError; + hilog.warn(0x000, 'testTag', `geoLocationManager on failed, code=${err.code}, message=${err.message}`); + } } onBackground(): void { - //The backstage cancels the listening - geoLocationManager.off('locationChange', locationChange); + try { + //The backstage cancels the listening + geoLocationManager.off('locationChange', locationChange); + } catch (error) { + let err = error as BusinessError; + hilog.warn(0x000, 'testTag', `geoLocationManager off failed, code=${err.code}, message=${err.message}`); + } } } + // [End gps_resources] \ No newline at end of file diff --git a/BptaUseResources/entry/src/main/ets/pages/Https.ets b/BptaUseResources/entry/src/main/ets/pages/Https.ets index 8b62be4c91f66a1b93d085bc97d464ec57c243e5..cc982b87e49afe01ef81442ef965b1ce6c839ef3 100644 --- a/BptaUseResources/entry/src/main/ets/pages/Https.ets +++ b/BptaUseResources/entry/src/main/ets/pages/Https.ets @@ -11,7 +11,7 @@ export default class EntryAbility extends UIAbility { // ... onForeground(): void { // Create an HTTP request based on the service requirements at the foreground - let httpRequest = http.createHttp(); + let httpRequest: http.HttpRequest = http.createHttp(); // ... } diff --git a/BptaUseResources/entry/src/main/ets/pages/Sensor.ets b/BptaUseResources/entry/src/main/ets/pages/Sensor.ets index 5c2a2b938ec5e38075841f923b0ba55f2be899f8..d0c2ce295fffe7f7735f4b05c65532bd734e43d4 100644 --- a/BptaUseResources/entry/src/main/ets/pages/Sensor.ets +++ b/BptaUseResources/entry/src/main/ets/pages/Sensor.ets @@ -5,21 +5,34 @@ // [Start sensor_resources] import { UIAbility } from '@kit.AbilityKit'; import { sensor } from '@kit.SensorServiceKit'; +import { BusinessError } from '@kit.BasicServicesKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; export default class EntryAbility extends UIAbility { // ... onForeground(): void { - //In the foreground, listen to the required type of sensor based on the service requirements - sensor.on(sensor.SensorId.ACCELEROMETER, (data: sensor.AccelerometerResponse) => { - console.info("Succeededinobtainingdata.x:" + data.x + "y:" + data.y + "z:" + data.z); - }, { - interval: 100000000 - }); + try { + //In the foreground, listen to the required type of sensor based on the service requirements + sensor.on(sensor.SensorId.ACCELEROMETER, (data: sensor.AccelerometerResponse) => { + console.info("Succeeded in obtaining data.x:" + data.x + "y:" + data.y + "z:" + data.z); + }, { + interval: 100000000 + }); + } catch (error) { + let err = error as BusinessError; + hilog.warn(0x000, 'testTag', `sensor on failed, code=${err.code}, message=${err.message}`); + } } onBackground(): void { - //The backstage cancels the listening - sensor.off(sensor.SensorId.ACCELEROMETER); + try { + //The backstage cancels the listening + sensor.off(sensor.SensorId.ACCELEROMETER); + } catch (error) { + let err = error as BusinessError; + hilog.warn(0x000, 'testTag', `sensor off failed, code=${err.code}, message=${err.message}`); + } } } + // [End sensor_resources] \ No newline at end of file diff --git a/BptaUseResources/entry/src/main/ets/pages/Socket.ets b/BptaUseResources/entry/src/main/ets/pages/Socket.ets index 36756870d54fa3eb44a52ed222809204b1820b0f..15e743afb268fbe91724b9a7cfd235e15d0a444f 100644 --- a/BptaUseResources/entry/src/main/ets/pages/Socket.ets +++ b/BptaUseResources/entry/src/main/ets/pages/Socket.ets @@ -13,10 +13,12 @@ export default class EntryAbility extends UIAbility { tcp: socket.TCPSocket = socket.constructTCPSocketInstance(); onForeground(): void { - //In the foreground, create a socket connection and send service data as required - this.tcp.bind(ipAddress, (err: BusinessError) => {}) - this.tcp.connect(tcpConnect, (err: BusinessError) => {}) - this.tcp.send(tcpSendOptions, (err: BusinessError) => {}) + /** + * In the foreground, create a socket connection and send service data as required, for example: + * this.tcp.bind(ipAddress, (err: BusinessError) => {}) + * this.tcp.connect(tcpConnect, (err: BusinessError) => {}) + * this.tcp.send(tcpSendOptions, (err: BusinessError) => {}) + */ } onBackground(): void { diff --git a/BptaUseResources/entry/src/main/ets/pages/WebSocket.ets b/BptaUseResources/entry/src/main/ets/pages/WebSocket.ets index 0afda565d00790761b0d2a911df53af0e1ff74e0..89ff8307be64a9c51e459441ab2f4e32dcfe0fec 100644 --- a/BptaUseResources/entry/src/main/ets/pages/WebSocket.ets +++ b/BptaUseResources/entry/src/main/ets/pages/WebSocket.ets @@ -11,7 +11,7 @@ import { BusinessError } from '@kit.BasicServicesKit'; export default class EntryAbility extends UIAbility { // Create a websocket based on service requirements - ws = webSocket.createWebSocket(); + ws: webSocket.WebSocket = webSocket.createWebSocket(); onForeground(): void { diff --git a/BptaUseResources/entry/src/main/ets/pages/music/AvPlayer.ets b/BptaUseResources/entry/src/main/ets/pages/music/AvPlayer.ets index 3664d1f95aa8060810a29d04c57767e3d6c3e228..a7a93ff8a95b028bac61748b588634b201fb8021 100644 --- a/BptaUseResources/entry/src/main/ets/pages/music/AvPlayer.ets +++ b/BptaUseResources/entry/src/main/ets/pages/music/AvPlayer.ets @@ -2,28 +2,41 @@ * 最佳实践:合理使用音频资源 * 场景二:播音场景(AVPlayer) */ - +// [Start sound_pool] import { fileIo as fs } from '@kit.CoreFileKit'; import { media } from '@kit.MediaKit'; +import { BusinessError } from '@kit.BasicServicesKit'; + +// [End sound_pool] + // [Start av_player] import { UIAbility } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; // [StartExclude av_player] let avPlayer: media.AVPlayer + // [EndExclude av_player] export default class EntryAbility extends UIAbility { // ... onForeground(): void { //Playing according to service requirements in the foreground - avPlayer.play(); + avPlayer.play() + .catch((err: BusinessError) => { + hilog.error(0x000, 'testTag', `avPlayer play failed, code=${err.code}, message=${err.message}`) + }) } onBackground(): void { // Return to the background to stop playing or pause - avPlayer.stop(); // Or pause(); + avPlayer.stop() // Or pause(); + .catch((err: BusinessError) => { + hilog.error(0x000, 'testTag', `avPlayer stop failed, code=${err.code}, message=${err.message}`) + }) } } + // [End av_player] /** @@ -35,16 +48,32 @@ let soundId: number; let streamId: number; let uri: string; let soundPool: media.SoundPool; +// [Start sound_pool] const SoundPool = async () => { - // [Start sound_pool] + //Construct the audio stream to play await fs.open('/test_01.mp3', fs.OpenMode.READ_ONLY).then((file: fs.File) => { console.info("filefd:" + file.fd); uri = 'fd://' + (file.fd).toString() - }); // '/test_01.mp3' is used as an example. The path of the file needs to be transferred - soundId = await soundPool.load(uri); - //The foreground scene starts to play - streamId = await soundPool.play(soundId); - //Stop playing in the background scenario: soundPool.stop (streamId); - // [End sound_pool] -} \ No newline at end of file + }) // '/test_01.mp3' is used as an example. The path of the file needs to be transferred + .catch((err: BusinessError) => { + hilog.error(0x000, 'testTag', `avPlayer stop failed, code=${err.code}, message=${err.message}`); + }) + await soundPool.load(uri) + .then((soundId: number) => { + //The foreground scene starts to play + soundPool.play(soundId) + .then((data: number) => { + streamId = data; + hilog.info(0x000, 'testTag', 'setPreferredOrientation success'); + }) + .catch((err: BusinessError) => { + hilog.error(0x000, 'testTag', `soundPool play failed, code=${err.code}, message=${err.message}`); + }) + //Stop playing in the background scenario: soundPool.stop (streamId); + }) + .catch((err: BusinessError) => { + hilog.error(0x000, 'testTag', `soundPool load failed, code=${err.code}, message=${err.message}`); + }) +} +// [End sound_pool] diff --git a/BptaUseResources/entry/src/main/ets/pages/music/OpenSL.cpp b/BptaUseResources/entry/src/main/ets/pages/music/OpenSL.cpp deleted file mode 100644 index 23a867c9363ded2a61b64c68845df72723b832d1..0000000000000000000000000000000000000000 --- a/BptaUseResources/entry/src/main/ets/pages/music/OpenSL.cpp +++ /dev/null @@ -1,31 +0,0 @@ -/** - * 最佳实践:合理使用音频资源 - * 场景三:播音场景(OpenSL ES) - */ - -// [Start open_sl_es] -//The foreground scene starts to play -SLPlayItfplayItf=nullptr; -(*pcmPlayerObject)->GetInterface(pcmPlayerObject,SL_IID_PLAY,&playItf); -(*playItf)->SetPlayState(playItf,SL_PLAYSTATE_PLAYING); -// Stop playing the background scene -(*playItf)->SetPlayState(playItf,SL_PLAYSTATE_STOPPED); -(*pcmPlayerObject)->Destroy(pcmPlayerObject); -(*engineObject)->Destroy(engineObject); -// [End open_sl_es] - -/** - * 最佳实践:合理使用音频资源 - * 场景四:播音场景(OHAudio) - */ - -// [Start oh_audio] -//Construct the audio stream to play -OH_AudioRenderer*audioRenderer; -ret=OH_AudioStreamBuilder_GenerateRenderer(builder,&audioRenderer); - -//The foreground scene starts to play -ret=OH_AudioRenderer_Start(audioRenderer); -// Stop playing the background scene -ret=OH_AudioRenderer_Stop(audioRenderer); -// [End oh_audio] \ No newline at end of file diff --git a/BptaUseResources/entry/src/main/module.json5 b/BptaUseResources/entry/src/main/module.json5 index a1cea8b6a4560cee7bda7a2db52f310c035ab6c8..2695312b12d7bbaf393763583192e727d45ce5ac 100644 --- a/BptaUseResources/entry/src/main/module.json5 +++ b/BptaUseResources/entry/src/main/module.json5 @@ -5,9 +5,7 @@ "description": "$string:module_desc", "mainElement": "EntryAbility", "deviceTypes": [ - "phone", - "tablet", - "2in1" + "phone" ], "deliveryWithInstall": true, "installationFree": false, @@ -45,7 +43,49 @@ "name": "ohos.extension.backup", "resource": "$profile:backup_config" } - ], + ] + } + ], + "requestPermissions": [ + { + "name": "ohos.permission.ACCESS_BLUETOOTH", + "reason": "$string:app_name", + "usedScene": { + "abilities": [ + "EntryAbility" + ], + "when": "always" + } + }, + { + "name": "ohos.permission.APPROXIMATELY_LOCATION", + "reason": "$string:app_name", + "usedScene": { + "abilities": [ + "EntryAbility" + ], + "when": "always" + } + }, + { + "name": "ohos.permission.ACCELEROMETER", + "reason": "$string:app_name", + "usedScene": { + "abilities": [ + "EntryAbility" + ], + "when": "always" + } + }, + { + "name": "ohos.permission.INTERNET", + "reason": "$string:app_name", + "usedScene": { + "abilities": [ + "EntryAbility" + ], + "when": "always" + } } ] } diff --git a/BptaUseResources/entry/src/main/resources/base/element/string.json b/BptaUseResources/entry/src/main/resources/base/element/string.json index f94595515a99e0c828807e243494f57f09251930..6c3318398d1ad6008ddce90cb9435814a1ee3d41 100644 --- a/BptaUseResources/entry/src/main/resources/base/element/string.json +++ b/BptaUseResources/entry/src/main/resources/base/element/string.json @@ -10,7 +10,7 @@ }, { "name": "EntryAbility_label", - "value": "label" + "value": "BptaUseResources" } ] } \ No newline at end of file diff --git a/BptaUseResources/entry/src/mock/mock-config.json5 b/BptaUseResources/entry/src/mock/mock-config.json5 deleted file mode 100644 index 7a73a41bfdf76d6f793007240d80983a52f15f97..0000000000000000000000000000000000000000 --- a/BptaUseResources/entry/src/mock/mock-config.json5 +++ /dev/null @@ -1,2 +0,0 @@ -{ -} \ No newline at end of file diff --git a/BptaUseResources/entry/src/ohosTest/ets/test/Ability.test.ets b/BptaUseResources/entry/src/ohosTest/ets/test/Ability.test.ets deleted file mode 100644 index 85c78f67579d6e31b5f5aeea463e216b9b141048..0000000000000000000000000000000000000000 --- a/BptaUseResources/entry/src/ohosTest/ets/test/Ability.test.ets +++ /dev/null @@ -1,35 +0,0 @@ -import { hilog } from '@kit.PerformanceAnalysisKit'; -import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; - -export default function abilityTest() { - describe('ActsAbilityTest', () => { - // Defines a test suite. Two parameters are supported: test suite name and test suite function. - beforeAll(() => { - // Presets an action, which is performed only once before all test cases of the test suite start. - // This API supports only one parameter: preset action function. - }) - beforeEach(() => { - // Presets an action, which is performed before each unit test case starts. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: preset action function. - }) - afterEach(() => { - // Presets a clear action, which is performed after each unit test case ends. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: clear action function. - }) - afterAll(() => { - // Presets a clear action, which is performed after all test cases of the test suite end. - // This API supports only one parameter: clear action function. - }) - it('assertContain', 0, () => { - // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. - hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); - let a = 'abc'; - let b = 'b'; - // Defines a variety of assertion methods, which are used to declare expected boolean conditions. - expect(a).assertContain(b); - expect(a).assertEqual(a); - }) - }) -} \ No newline at end of file diff --git a/BptaUseResources/entry/src/ohosTest/ets/test/List.test.ets b/BptaUseResources/entry/src/ohosTest/ets/test/List.test.ets deleted file mode 100644 index 794c7dc4ed66bd98fa3865e07922906e2fcef545..0000000000000000000000000000000000000000 --- a/BptaUseResources/entry/src/ohosTest/ets/test/List.test.ets +++ /dev/null @@ -1,5 +0,0 @@ -import abilityTest from './Ability.test'; - -export default function testsuite() { - abilityTest(); -} \ No newline at end of file diff --git a/BptaUseResources/entry/src/ohosTest/module.json5 b/BptaUseResources/entry/src/ohosTest/module.json5 deleted file mode 100644 index 55725a929993a8a18b3808d41ef037759440488b..0000000000000000000000000000000000000000 --- a/BptaUseResources/entry/src/ohosTest/module.json5 +++ /dev/null @@ -1,13 +0,0 @@ -{ - "module": { - "name": "entry_test", - "type": "feature", - "deviceTypes": [ - "phone", - "tablet", - "2in1" - ], - "deliveryWithInstall": true, - "installationFree": false - } -} diff --git a/BptaUseResources/entry/src/test/List.test.ets b/BptaUseResources/entry/src/test/List.test.ets deleted file mode 100644 index bb5b5c3731e283dd507c847560ee59bde477bbc7..0000000000000000000000000000000000000000 --- a/BptaUseResources/entry/src/test/List.test.ets +++ /dev/null @@ -1,5 +0,0 @@ -import localUnitTest from './LocalUnit.test'; - -export default function testsuite() { - localUnitTest(); -} \ No newline at end of file diff --git a/BptaUseResources/entry/src/test/LocalUnit.test.ets b/BptaUseResources/entry/src/test/LocalUnit.test.ets deleted file mode 100644 index 165fc1615ee8618b4cb6a622f144a9a707eee99f..0000000000000000000000000000000000000000 --- a/BptaUseResources/entry/src/test/LocalUnit.test.ets +++ /dev/null @@ -1,33 +0,0 @@ -import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; - -export default function localUnitTest() { - describe('localUnitTest', () => { - // Defines a test suite. Two parameters are supported: test suite name and test suite function. - beforeAll(() => { - // Presets an action, which is performed only once before all test cases of the test suite start. - // This API supports only one parameter: preset action function. - }); - beforeEach(() => { - // Presets an action, which is performed before each unit test case starts. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: preset action function. - }); - afterEach(() => { - // Presets a clear action, which is performed after each unit test case ends. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: clear action function. - }); - afterAll(() => { - // Presets a clear action, which is performed after all test cases of the test suite end. - // This API supports only one parameter: clear action function. - }); - it('assertContain', 0, () => { - // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. - let a = 'abc'; - let b = 'b'; - // Defines a variety of assertion methods, which are used to declare expected boolean conditions. - expect(a).assertContain(b); - expect(a).assertEqual(a); - }); - }); -} \ No newline at end of file diff --git a/BptaUseResources/oh-package-lock.json5 b/BptaUseResources/oh-package-lock.json5 deleted file mode 100644 index 7fcf818273347b97063c0c0a151bb14770ca1c79..0000000000000000000000000000000000000000 --- a/BptaUseResources/oh-package-lock.json5 +++ /dev/null @@ -1,27 +0,0 @@ -{ - "meta": { - "stableOrder": true - }, - "lockfileVersion": 3, - "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", - "specifiers": { - "@ohos/hamock@1.0.0": "@ohos/hamock@1.0.0", - "@ohos/hypium@1.0.21": "@ohos/hypium@1.0.21" - }, - "packages": { - "@ohos/hamock@1.0.0": { - "name": "@ohos/hamock", - "version": "1.0.0", - "integrity": "sha512-K6lDPYc6VkKe6ZBNQa9aoG+ZZMiwqfcR/7yAVFSUGIuOAhPvCJAo9+t1fZnpe0dBRBPxj2bxPPbKh69VuyAtDg==", - "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hamock/-/hamock-1.0.0.har", - "registryType": "ohpm" - }, - "@ohos/hypium@1.0.21": { - "name": "@ohos/hypium", - "version": "1.0.21", - "integrity": "sha512-iyKGMXxE+9PpCkqEwu0VykN/7hNpb+QOeIuHwkmZnxOpI+dFZt6yhPB7k89EgV1MiSK/ieV/hMjr5Z2mWwRfMQ==", - "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hypium/-/hypium-1.0.21.har", - "registryType": "ohpm" - } - } -} \ No newline at end of file diff --git a/BptaUseSoftware/.gitignore b/BptaUseSoftware/.gitignore deleted file mode 100644 index d2ff20141ceed86d87c0ea5d99481973005bab2b..0000000000000000000000000000000000000000 --- a/BptaUseSoftware/.gitignore +++ /dev/null @@ -1,12 +0,0 @@ -/node_modules -/oh_modules -/local.properties -/.idea -**/build -/.hvigor -.cxx -/.clangd -/.clang-format -/.clang-tidy -**/.test -/.appanalyzer \ No newline at end of file diff --git a/BptaUseSoftware/README.md b/BptaUseSoftware/README.md new file mode 100644 index 0000000000000000000000000000000000000000..1a2f33a56bbc27d5108accdc784831d5ec2bc99b --- /dev/null +++ b/BptaUseSoftware/README.md @@ -0,0 +1,62 @@ +# 后台软件资源合理使用样例代码工程 + +### 介绍 + +本示例为后台软件资源合理使用样例代码工程,包含最佳实践文档中的后台上传下载合理使用、后台音频播放合理使用、后台定位导航服务合理使用、后台系统资源合理使用等内容的局部样例代码。工程本身不具备实际功能,开发者请直接阅读具体源码结合文档来理解。 + + +### 效果预览 + +不涉及 + +### 工程目录 +``` +├──entry/src/main/ets +│ ├──entryability +│ │ └──EntryAbility.ets // 程序入口类 +│ ├──entrybackupability +│ │ └──EntryBackupAbility.ets // 应用数据备份恢复类 +│ └──pages +│ ├─Audio.ets // 音频类示例代码 +│ ├─Download.ets // 上传下载示例代码 +│ ├─GpsOne.ets // 定位导航服务示例代码1 +│ ├─GpsTwo.ets // 定位导航服务示例代码2 +│ ├─Index.ets // 首页 +│ ├─LockByApplication.ets // 系统资源示例代码1 +│ ├─LockBySystem.ets // 系统资源示例代码2 +│ └─Upload.ets // 上传下载类示例代码 +└──entry/src/main/resources // 应用静态资源目录 +``` + +### 具体实现 + +不涉及。 + +### 相关权限 + +不涉及。 + +### 依赖 + +不涉及。 + +### 约束与限制 + +1. 本示例仅支持标准系统上运行,支持设备:华为手机、华为PC/2in1设备、华为平板。 + +2. HarmonyOS系统:HarmonyOS NEXT 5.0.5 Release及以上。 + +3. DevEco Studio版本:DevEco Studio NEXT 5.0.5 Release及以上。 + +4. HarmonyOS SDK版本:HarmonyOS NEXT 5.0.5 Release SDK及以上。 + +### 下载 + +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set BptaUseSoftware +git checkout +``` \ No newline at end of file diff --git a/BptaUseSoftware/entry/.gitignore b/BptaUseSoftware/entry/.gitignore deleted file mode 100644 index e2713a2779c5a3e0eb879efe6115455592caeea5..0000000000000000000000000000000000000000 --- a/BptaUseSoftware/entry/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -/node_modules -/oh_modules -/.preview -/build -/.cxx -/.test \ No newline at end of file diff --git a/BptaUseSoftware/entry/src/main/ets/entryability/EntryAbility.ets b/BptaUseSoftware/entry/src/main/ets/entryability/EntryAbility.ets index ea1bd6886f92a2fa8bc8e31b646d47ebf620f2a9..2d0f5e06e283a254cbc63c81e2cf6b69754cb4b7 100644 --- a/BptaUseSoftware/entry/src/main/ets/entryability/EntryAbility.ets +++ b/BptaUseSoftware/entry/src/main/ets/entryability/EntryAbility.ets @@ -1,4 +1,5 @@ import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { BusinessError } from '@kit.BasicServicesKit'; import { hilog } from '@kit.PerformanceAnalysisKit'; import { window } from '@kit.ArkUI'; @@ -6,7 +7,12 @@ const DOMAIN = 0x0000; export default class EntryAbility extends UIAbility { onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { - this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + try { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + } catch (error) { + let err = error as BusinessError; + hilog.warn(0x000, 'testTag', `setColorMode failed, code=${err.code}, message=${err.message}`); + } hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); } @@ -24,8 +30,13 @@ export default class EntryAbility extends UIAbility { return; } hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.'); - let uiContext: UIContext | undefined = windowStage.getMainWindowSync().getUIContext() - AppStorage.setOrCreate('uiContext', uiContext); + try { + let uiContext: UIContext | undefined = windowStage.getMainWindowSync().getUIContext() + AppStorage.setOrCreate('uiContext', uiContext); + } catch (error) { + let err = error as BusinessError; + hilog.warn(0x000, 'testTag', `getUIContext failed, code=${err.code}, message=${err.message}`); + } }); } diff --git a/BptaUseSoftware/entry/src/main/ets/pages/Audio.ets b/BptaUseSoftware/entry/src/main/ets/pages/Audio.ets index b1d823641545e3a90209c4a25fd63cd3b8ec300f..415bb3e629fc7a2d775f185815bceddde34844b2 100644 --- a/BptaUseSoftware/entry/src/main/ets/pages/Audio.ets +++ b/BptaUseSoftware/entry/src/main/ets/pages/Audio.ets @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + /** * 最佳实践:合理使用音频播放 */ @@ -6,6 +21,8 @@ import { fileIo as fs } from '@kit.CoreFileKit'; // [StartExclude audio_bpta] import { audio } from '@kit.AudioKit'; +import { BusinessError } from '@kit.BasicServicesKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; let audioStreamInfo: audio.AudioStreamInfo = { samplingRate: audio.AudioSamplingRate.SAMPLE_RATE_48000, @@ -43,9 +60,13 @@ async function read() { let path = context.filesDir; // Path of the file const filePath = path + '/voice_call_data.wav'; // Prohibit the file from being played silently - let file: fs.File = fs.openSync(filePath, fs.OpenMode.READ_ONLY); // Open the file - let buf = new ArrayBuffer(bufferSize); - let readSize: number = await fs.read(file.fd, buf); // Read the file content - let writeSize: number = await audioRenderer.write(buf); // Play the file content + try { + let file: fs.File = fs.openSync(filePath, fs.OpenMode.READ_ONLY); // Open the file + let buf = new ArrayBuffer(bufferSize); + let readSize: number = await fs.read(file.fd, buf); // Read the file content + } catch (error) { + let err = error as BusinessError; + hilog.warn(0x000, 'testTag', `openSync or read failed, code=${err.code}, message=${err.message}`); + } } // [End audio_bpta] \ No newline at end of file diff --git a/BptaUseSoftware/entry/src/main/ets/pages/Download.ets b/BptaUseSoftware/entry/src/main/ets/pages/Download.ets index f48d442ea24adb5f153788568e5b319ecdf86f2b..8691ab2add75ce930f1a047ad6f7679626c6a651 100644 --- a/BptaUseSoftware/entry/src/main/ets/pages/Download.ets +++ b/BptaUseSoftware/entry/src/main/ets/pages/Download.ets @@ -1,23 +1,54 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + /** * 最佳实践:后台合理使用上传下载 * 场景二:下载 */ - // [Start software_download] import { BusinessError, request } from '@kit.BasicServicesKit'; +import { common } from '@kit.AbilityKit'; + +// [End software_download] -try { - request.downloadFile(this.getUIContext().getHostContext(), { - url: 'https://xxxx/xxxxx.hap', // IP address of the server to download the file - filePath: 'xxx/xxxxx.hap' - }, (err: BusinessError, data: request.DownloadTask) => { - if (err) { - console.error(`Failedtorequestthedownload.Code:${err.code},message:${err.message}`); - return; +@Entry +@Component +struct Download { + build() { + } + + + funcA() { + // [Start software_download] + try { + let context = this.getUIContext().getHostContext() as common.UIAbilityContext; + request.downloadFile(context, { + url: 'https://xxxx/xxxxx.hap', // IP address of the server to download the file + filePath: 'xxx/xxxxx.hap' + }, (err: BusinessError, data: request.DownloadTask) => { + if (err) { + console.error(`Failedtorequestthedownload.Code:${err.code},message:${err.message}`); + return; + } + let downloadTask: request.DownloadTask = data; + }); + } catch (err) { + console.error(`Failedtorequestthedownload.err:${JSON.stringify(err)}`); } - let downloadTask: request.DownloadTask = data; - }); -} catch (err) { - console.error(`Failedtorequestthedownload.err:${JSON.stringify(err)}`); + // [End software_download] + } } -// [End software_download] \ No newline at end of file + + diff --git a/BptaUseSoftware/entry/src/main/ets/pages/GpsOne.ets b/BptaUseSoftware/entry/src/main/ets/pages/GpsOne.ets index 46c3c4f46d75eda0667aa9dde5bd694ec8db7fb4..3ddcde7939f8ac5f6dedae934b45e1a026497e2e 100644 --- a/BptaUseSoftware/entry/src/main/ets/pages/GpsOne.ets +++ b/BptaUseSoftware/entry/src/main/ets/pages/GpsOne.ets @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + /** * 最佳实践:后台合理使用定位导航服务 * 场景一:方式1 diff --git a/BptaUseSoftware/entry/src/main/ets/pages/GpsTwo.ets b/BptaUseSoftware/entry/src/main/ets/pages/GpsTwo.ets index a3661fd5e8014e3c80410b817e5a8a0c75662ad5..fa9124056a4fe7bde06ea83aa6d42fe4aa0636d7 100644 --- a/BptaUseSoftware/entry/src/main/ets/pages/GpsTwo.ets +++ b/BptaUseSoftware/entry/src/main/ets/pages/GpsTwo.ets @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + /** * 最佳实践:后台合理使用定位导航服务 * 场景二:方式2 diff --git a/BptaUseSoftware/entry/src/main/ets/pages/Index.ets b/BptaUseSoftware/entry/src/main/ets/pages/Index.ets index 8e2d24ad42693fc877d51bb7820f0a9da68fa135..0f481f696485b8c840d49ad9e7d7dff7f6b71241 100644 --- a/BptaUseSoftware/entry/src/main/ets/pages/Index.ets +++ b/BptaUseSoftware/entry/src/main/ets/pages/Index.ets @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + @Entry @Component struct Index { diff --git a/BptaUseSoftware/entry/src/main/ets/pages/LockByApplication.ets b/BptaUseSoftware/entry/src/main/ets/pages/LockByApplication.ets index 236f0d5bc4d351d30cd3ff27711b1cc39c1afa27..fe063ec6ba797c814bfc54fea61815019bba22fe 100644 --- a/BptaUseSoftware/entry/src/main/ets/pages/LockByApplication.ets +++ b/BptaUseSoftware/entry/src/main/ets/pages/LockByApplication.ets @@ -1,15 +1,36 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + /** * 最佳实践:后台合理使用系统资源 * 场景一:应用直接持锁 */ // [Start bpta_lock_by_application] import { runningLock } from '@kit.BasicServicesKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { BusinessError } from '@kit.BasicServicesKit'; // Return to the background to release the lock runningLock.create('running_lock_test', runningLock.RunningLockType.BACKGROUND) .then((lock: runningLock.RunningLock) => { - lock.unhold(); - console.info('create running lock and unlock success'); + try { + lock.unhold(); + } catch (error) { + let err = error as BusinessError; + hilog.warn(0x000, 'testTag', `setColorMode failed, code=${err.code}, message=${err.message}`); + } }) .catch((err: Error) => { console.error('create running lock failed, err: ' + err); diff --git a/BptaUseSoftware/entry/src/main/ets/pages/LockBySystem.ets b/BptaUseSoftware/entry/src/main/ets/pages/LockBySystem.ets index ba481213a06987c151297f6967ee7eda5af5a0cd..37dd742f201cd991973db9bba9636a555d6db862 100644 --- a/BptaUseSoftware/entry/src/main/ets/pages/LockBySystem.ets +++ b/BptaUseSoftware/entry/src/main/ets/pages/LockBySystem.ets @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + /** * 最佳实践:后台合理使用系统资源 * 场景一:系统帮助应用持锁 diff --git a/BptaUseSoftware/entry/src/main/ets/pages/Upload.ets b/BptaUseSoftware/entry/src/main/ets/pages/Upload.ets index 56f5cb42e1dc13eef4931028aec8a6f32dc47156..902ecae1a1fd59d7025813be306a6355f82316cc 100644 --- a/BptaUseSoftware/entry/src/main/ets/pages/Upload.ets +++ b/BptaUseSoftware/entry/src/main/ets/pages/Upload.ets @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + /** * 最佳实践:后台合理使用上传下载 * 场景一:上传 diff --git a/BptaUseSoftware/entry/src/main/module.json5 b/BptaUseSoftware/entry/src/main/module.json5 index a1cea8b6a4560cee7bda7a2db52f310c035ab6c8..1da6fb5663deb76fabe8914ebe7bb408f54e52c9 100644 --- a/BptaUseSoftware/entry/src/main/module.json5 +++ b/BptaUseSoftware/entry/src/main/module.json5 @@ -45,7 +45,15 @@ "name": "ohos.extension.backup", "resource": "$profile:backup_config" } - ], + ] + } + ], + "requestPermissions": [ + { + "name": "ohos.permission.RUNNING_LOCK" + }, + { + "name": "ohos.permission.INTERNET" } ] } diff --git a/BptaUseSoftware/entry/src/mock/mock-config.json5 b/BptaUseSoftware/entry/src/mock/mock-config.json5 deleted file mode 100644 index 7a73a41bfdf76d6f793007240d80983a52f15f97..0000000000000000000000000000000000000000 --- a/BptaUseSoftware/entry/src/mock/mock-config.json5 +++ /dev/null @@ -1,2 +0,0 @@ -{ -} \ No newline at end of file diff --git a/BptaUseSoftware/entry/src/ohosTest/ets/test/Ability.test.ets b/BptaUseSoftware/entry/src/ohosTest/ets/test/Ability.test.ets deleted file mode 100644 index 85c78f67579d6e31b5f5aeea463e216b9b141048..0000000000000000000000000000000000000000 --- a/BptaUseSoftware/entry/src/ohosTest/ets/test/Ability.test.ets +++ /dev/null @@ -1,35 +0,0 @@ -import { hilog } from '@kit.PerformanceAnalysisKit'; -import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; - -export default function abilityTest() { - describe('ActsAbilityTest', () => { - // Defines a test suite. Two parameters are supported: test suite name and test suite function. - beforeAll(() => { - // Presets an action, which is performed only once before all test cases of the test suite start. - // This API supports only one parameter: preset action function. - }) - beforeEach(() => { - // Presets an action, which is performed before each unit test case starts. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: preset action function. - }) - afterEach(() => { - // Presets a clear action, which is performed after each unit test case ends. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: clear action function. - }) - afterAll(() => { - // Presets a clear action, which is performed after all test cases of the test suite end. - // This API supports only one parameter: clear action function. - }) - it('assertContain', 0, () => { - // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. - hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); - let a = 'abc'; - let b = 'b'; - // Defines a variety of assertion methods, which are used to declare expected boolean conditions. - expect(a).assertContain(b); - expect(a).assertEqual(a); - }) - }) -} \ No newline at end of file diff --git a/BptaUseSoftware/entry/src/ohosTest/ets/test/List.test.ets b/BptaUseSoftware/entry/src/ohosTest/ets/test/List.test.ets deleted file mode 100644 index 794c7dc4ed66bd98fa3865e07922906e2fcef545..0000000000000000000000000000000000000000 --- a/BptaUseSoftware/entry/src/ohosTest/ets/test/List.test.ets +++ /dev/null @@ -1,5 +0,0 @@ -import abilityTest from './Ability.test'; - -export default function testsuite() { - abilityTest(); -} \ No newline at end of file diff --git a/BptaUseSoftware/entry/src/ohosTest/module.json5 b/BptaUseSoftware/entry/src/ohosTest/module.json5 deleted file mode 100644 index 55725a929993a8a18b3808d41ef037759440488b..0000000000000000000000000000000000000000 --- a/BptaUseSoftware/entry/src/ohosTest/module.json5 +++ /dev/null @@ -1,13 +0,0 @@ -{ - "module": { - "name": "entry_test", - "type": "feature", - "deviceTypes": [ - "phone", - "tablet", - "2in1" - ], - "deliveryWithInstall": true, - "installationFree": false - } -} diff --git a/BptaUseSoftware/entry/src/test/List.test.ets b/BptaUseSoftware/entry/src/test/List.test.ets deleted file mode 100644 index bb5b5c3731e283dd507c847560ee59bde477bbc7..0000000000000000000000000000000000000000 --- a/BptaUseSoftware/entry/src/test/List.test.ets +++ /dev/null @@ -1,5 +0,0 @@ -import localUnitTest from './LocalUnit.test'; - -export default function testsuite() { - localUnitTest(); -} \ No newline at end of file diff --git a/BptaUseSoftware/entry/src/test/LocalUnit.test.ets b/BptaUseSoftware/entry/src/test/LocalUnit.test.ets deleted file mode 100644 index 165fc1615ee8618b4cb6a622f144a9a707eee99f..0000000000000000000000000000000000000000 --- a/BptaUseSoftware/entry/src/test/LocalUnit.test.ets +++ /dev/null @@ -1,33 +0,0 @@ -import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; - -export default function localUnitTest() { - describe('localUnitTest', () => { - // Defines a test suite. Two parameters are supported: test suite name and test suite function. - beforeAll(() => { - // Presets an action, which is performed only once before all test cases of the test suite start. - // This API supports only one parameter: preset action function. - }); - beforeEach(() => { - // Presets an action, which is performed before each unit test case starts. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: preset action function. - }); - afterEach(() => { - // Presets a clear action, which is performed after each unit test case ends. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: clear action function. - }); - afterAll(() => { - // Presets a clear action, which is performed after all test cases of the test suite end. - // This API supports only one parameter: clear action function. - }); - it('assertContain', 0, () => { - // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. - let a = 'abc'; - let b = 'b'; - // Defines a variety of assertion methods, which are used to declare expected boolean conditions. - expect(a).assertContain(b); - expect(a).assertEqual(a); - }); - }); -} \ No newline at end of file diff --git a/BptaUseSoftware/oh-package.json5 b/BptaUseSoftware/oh-package.json5 index a8aff0c5aff22d78aa26fd19c3861f4320e951ff..f440d114b8a9d9aeadd0e891bba0d0d076e70936 100644 --- a/BptaUseSoftware/oh-package.json5 +++ b/BptaUseSoftware/oh-package.json5 @@ -3,8 +3,5 @@ "description": "Please describe the basic information.", "dependencies": { }, - "devDependencies": { - "@ohos/hypium": "1.0.21", - "@ohos/hamock": "1.0.0" - } + "devDependencies": {} } diff --git a/CanvasDraw/build-profile.json5 b/CanvasDraw/build-profile.json5 index 19b2d1d0b868064df8c461ecdbbdbb5f6755b07f..e5f3b3c8a7cc93d377d31d5616c9c5603a009d63 100644 --- a/CanvasDraw/build-profile.json5 +++ b/CanvasDraw/build-profile.json5 @@ -20,7 +20,8 @@ { "name": "default", "signingConfig": "default", - "compatibleSdkVersion": "5.0.0(12)", + "targetSdkVersion": "5.0.5(17)", + "compatibleSdkVersion": "5.0.5(17)", "runtimeOS": "HarmonyOS", } ], diff --git a/ClickResponseOptimization/.gitignore b/ClickResponseOptimization/.gitignore deleted file mode 100644 index d2ff20141ceed86d87c0ea5d99481973005bab2b..0000000000000000000000000000000000000000 --- a/ClickResponseOptimization/.gitignore +++ /dev/null @@ -1,12 +0,0 @@ -/node_modules -/oh_modules -/local.properties -/.idea -**/build -/.hvigor -.cxx -/.clangd -/.clang-format -/.clang-tidy -**/.test -/.appanalyzer \ No newline at end of file diff --git a/ClickResponseOptimization/README.en.md b/ClickResponseOptimization/README.en.md deleted file mode 100644 index 9d38a44356b0addb0ce8c11f883c622ae9a9dc9e..0000000000000000000000000000000000000000 --- a/ClickResponseOptimization/README.en.md +++ /dev/null @@ -1,4 +0,0 @@ - -### Introduction - -Sample codes accompanying the best practice articles "Click Response Delay Analysis" and "Click Response Optimization" diff --git a/ClickResponseOptimization/README.md b/ClickResponseOptimization/README.md index ce522f87e3870661daa9d23eaab66a6e76d39606..71d7913acc6fbbe222edba05690edf4df6cd1bf0 100644 --- a/ClickResponseOptimization/README.md +++ b/ClickResponseOptimization/README.md @@ -1,4 +1,74 @@ +# 点击响应时延分析 -### 简介 +### 介绍 -与最佳实践文章《点击响应时延分析》和《点击响应优化》配套的示例代码 +本示例是《点击响应时延分析》最佳实践中的代码示例片段。 + +### 使用说明 + +进入首面,加载示例逻辑。 + + +### 工程目录 + +``` +├──entry/src/main/ets +│ ├──common/constants +│ │ ├──AppConstant.ets // app常量 +│ │ ├──ChatConstants.ets // chat常量 +│ │ ├──WorldCommonConstants.ets // 公共常量 +│ │ └──WorldConstants.ets // 公共常量 +│ ├──common/db +│ │ ├──AccountData.ets // account数据 +│ │ ├──AccountTable.ets // account表 +│ │ └──Rdb.ets // rdb工具类 +│ ├──entryability +│ │ └──EntryAbility.ets // 入口类 +│ ├──model +│ │ └──ChatModel.ets // chat数据模型 +│ ├──pages +│ │ ├──CameraOptPage.ets // 示例页面 +│ │ ├──CameraPage.ets // 示例页面 +│ │ ├──CityListPage.ets // 示例页面 +│ │ ├──ConcurrentOptPage.ets // 示例页面 +│ │ ├──Index.ets // 首页 +│ │ ├──PanGestureDistanceOptPage.ets // 示例页面 +│ │ ├──PanGestureDistancePage.ets // 示例页面 +│ │ ├──ProfilePage.ets // 示例页面 +│ │ └──VisionOptPage.ets // 示例页面 +│ └──view +│ ├──ArticleSkeletonView.ets // 骨架屏view +│ ├──LoadingView.ets // 加载view +│ └──OptChatItemView.ets // 优化后的chat view +└──entry/src/main/resources // 应用资源目录 +``` + + +### 具体实现 + +1. 针对点击响应时延分析经,介绍这方面的常见性能优化方法。 + +### 相关权限 + +不涉及。 + +### 约束与限制 + +1. 本示例仅支持标准系统上运行,支持设备:华为手机。 + +2. HarmonyOS系统:HarmonyOS 5.0.5 Release及以上。 + +3. DevEco Studio版本:DevEco Studio 5.0.5 Release及以上。 + +4. HarmonyOS SDK版本:HarmonyOS 5.0.5 Release SDK及以上。 + +### 下载 + +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set ClickResponseOptimization +git checkout +``` \ No newline at end of file diff --git a/ClickResponseOptimization/build-profile.json5 b/ClickResponseOptimization/build-profile.json5 index c033ce4278fb0641d84107c3c134047ac487368e..a33e1f2b1fb22dcb09d8042de60fd767ec874a2a 100644 --- a/ClickResponseOptimization/build-profile.json5 +++ b/ClickResponseOptimization/build-profile.json5 @@ -5,7 +5,8 @@ { "name": "default", "signingConfig": "default", - "compatibleSdkVersion": "5.0.0(12)", + "targetSdkVersion": "5.0.5(17)", + "compatibleSdkVersion": "5.0.5(17)", "runtimeOS": "HarmonyOS", } ], diff --git a/ClickResponseOptimization/entry/.gitignore b/ClickResponseOptimization/entry/.gitignore deleted file mode 100644 index e2713a2779c5a3e0eb879efe6115455592caeea5..0000000000000000000000000000000000000000 --- a/ClickResponseOptimization/entry/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -/node_modules -/oh_modules -/.preview -/build -/.cxx -/.test \ No newline at end of file diff --git a/ClickResponseOptimization/entry/obfuscation-rules.txt b/ClickResponseOptimization/entry/obfuscation-rules.txt index 985b2aeb7658286b17bd26eab8f217c3fe75ea8b..a1dfa0bd175984dc49e641436aa67b1de1b8abeb 100644 --- a/ClickResponseOptimization/entry/obfuscation-rules.txt +++ b/ClickResponseOptimization/entry/obfuscation-rules.txt @@ -15,4 +15,8 @@ # Keep options: # -keep-property-name: specifies property names that you want to keep -# -keep-global-name: specifies names that you want to keep in the global scope \ No newline at end of file +# -keep-global-name: specifies names that you want to keep in the global scope +-enable-property-obfuscation +-enable-toplevel-obfuscation +-enable-filename-obfuscation +-enable-export-obfuscation \ No newline at end of file diff --git a/ClickResponseOptimization/entry/src/main/ets/pages/CityListPage.ets b/ClickResponseOptimization/entry/src/main/ets/pages/CityListPage.ets index a681610fb040e908915e2358c1f279f390c53b0d..c4e7e8dd96a8ec7849e8efa6ef6118e25250eaa1 100644 --- a/ClickResponseOptimization/entry/src/main/ets/pages/CityListPage.ets +++ b/ClickResponseOptimization/entry/src/main/ets/pages/CityListPage.ets @@ -20,7 +20,10 @@ import taskpool from '@ohos.taskpool'; import hiTraceMeter from '@ohos.hiTraceMeter'; import { AppConstant } from '../common/constants/AppConstant'; import router from '@ohos.router'; +import { BusinessError } from '@kit.BasicServicesKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +const DOMAIN = 0x0000; const alphabets = ['#', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']; @@ -52,9 +55,15 @@ struct CityList { // asynchronous thread computeTaskAsync() { let task: taskpool.Task = new taskpool.Task(computeTask); - taskpool.execute(task).then((res) => { - this.citys = res as string[] - }) + try { + taskpool.execute(task).then((res) => { + this.citys = res as string[] + }); + } catch (e) { + let err = e as BusinessError; + hilog.error(DOMAIN, 'testTag', `failed code=${err.code}, message=${err.message}`); + } + } // [StartExclude onpage_show] diff --git a/ClickResponseOptimization/entry/src/main/resources/base/element/string.json b/ClickResponseOptimization/entry/src/main/resources/base/element/string.json index f94595515a99e0c828807e243494f57f09251930..c622bd7ced26f4ec40d3baefc11a90f1502469db 100644 --- a/ClickResponseOptimization/entry/src/main/resources/base/element/string.json +++ b/ClickResponseOptimization/entry/src/main/resources/base/element/string.json @@ -10,7 +10,7 @@ }, { "name": "EntryAbility_label", - "value": "label" + "value": "ClickResponseOptimization" } ] } \ No newline at end of file diff --git a/ClickResponseOptimization/entry/src/main/resources/en_US/element/string.json b/ClickResponseOptimization/entry/src/main/resources/en_US/element/string.json index f94595515a99e0c828807e243494f57f09251930..c622bd7ced26f4ec40d3baefc11a90f1502469db 100644 --- a/ClickResponseOptimization/entry/src/main/resources/en_US/element/string.json +++ b/ClickResponseOptimization/entry/src/main/resources/en_US/element/string.json @@ -10,7 +10,7 @@ }, { "name": "EntryAbility_label", - "value": "label" + "value": "ClickResponseOptimization" } ] } \ No newline at end of file diff --git a/ClickResponseOptimization/entry/src/main/resources/zh_CN/element/string.json b/ClickResponseOptimization/entry/src/main/resources/zh_CN/element/string.json index 597ecf95e61d7e30367c22fe2f8638008361b044..c999478abae583b3eaa8c936905ab327cb3d5127 100644 --- a/ClickResponseOptimization/entry/src/main/resources/zh_CN/element/string.json +++ b/ClickResponseOptimization/entry/src/main/resources/zh_CN/element/string.json @@ -10,7 +10,7 @@ }, { "name": "EntryAbility_label", - "value": "label" + "value": "点击响应优化" } ] } \ No newline at end of file diff --git a/ComponentEncapsulation/README.md b/ComponentEncapsulation/README.md index 93420a375eca3eaad8685b0600b9693b6a0bffe0..fe88e79f131c18cdc7d2be627c0d081d44282841 100644 --- a/ComponentEncapsulation/README.md +++ b/ComponentEncapsulation/README.md @@ -4,7 +4,7 @@ 本示例展示组件封装中的常见问题代码。 -##### 使用说明 +### 使用说明 进入首面,点击按钮,分别进入示例页面。 @@ -42,4 +42,15 @@ 3. DevEco Studio版本:DevEco Studio 5.1.0 Release及以上。 -4. HarmonyOS SDK版本:HarmonyOS 5.1.0 Release SDK及以上。 \ No newline at end of file +4. HarmonyOS SDK版本:HarmonyOS 5.1.0 Release SDK及以上。 + +### 下载 + +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set ComponentEncapsulation +git checkout +``` \ No newline at end of file diff --git a/ComponentEncapsulation/entry/src/main/ets/entryability/EntryAbility.ets b/ComponentEncapsulation/entry/src/main/ets/entryability/EntryAbility.ets index 2dae1b50919e646712c2dea0429b084b1ab2647b..89f547e65f66f3007f43211a90c5fc4753004bce 100644 --- a/ComponentEncapsulation/entry/src/main/ets/entryability/EntryAbility.ets +++ b/ComponentEncapsulation/entry/src/main/ets/entryability/EntryAbility.ets @@ -13,6 +13,7 @@ * limitations under the License. */ import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { BusinessError } from '@kit.BasicServicesKit'; import { hilog } from '@kit.PerformanceAnalysisKit'; import { window } from '@kit.ArkUI'; @@ -20,7 +21,12 @@ const DOMAIN = 0x0000; export default class EntryAbility extends UIAbility { onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { - this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + try { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + } catch (error) { + let err = error as BusinessError; + hilog.warn(0x000, 'testTag', `setColorMode failed, code=${err.code}, message=${err.message}`); + } hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); } diff --git a/ComponentEncapsulation/entry/src/main/ets/pages/Index.ets b/ComponentEncapsulation/entry/src/main/ets/pages/Index.ets index 550bf16fdb7463f5b865a6e1c8c172d31f91b5d4..9730d0f240a698ef07319ad9749bd1942fe92c65 100644 --- a/ComponentEncapsulation/entry/src/main/ets/pages/Index.ets +++ b/ComponentEncapsulation/entry/src/main/ets/pages/Index.ets @@ -1,3 +1,5 @@ +import { hilog } from '@kit.PerformanceAnalysisKit'; + /* * Copyright (c) 2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); @@ -12,6 +14,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +import { BusinessError } from '@kit.BasicServicesKit'; + @Entry @Component struct Index { @@ -21,26 +26,56 @@ struct Index { .width(120).margin({ top: 16 }) .onClick(() => { this.getUIContext().getRouter().pushUrl({ url: 'pages/BuilderParamPage' }) + .then(() => { + hilog.info(0x000, 'testTag', 'pushUrl success'); + }) + .catch((err: BusinessError) => { + hilog.error(0x000, 'testTag', `pushUrl failed, code=${err.code}, message=${err.message}`); + }) }) Button('ControllerCallPage') .width(120).margin({ top: 16 }) .onClick(() => { this.getUIContext().getRouter().pushUrl({ url: 'pages/ControllerCallPage' }) + .then(() => { + hilog.info(0x000, 'testTag', 'pushUrl success'); + }) + .catch((err: BusinessError) => { + hilog.error(0x000, 'testTag', `pushUrl failed, code=${err.code}, message=${err.message}`); + }) }) Button('EmitterCallPage') .width(120).margin({ top: 16 }) .onClick(() => { this.getUIContext().getRouter().pushUrl({ url: 'pages/EmitterCallPage' }) + .then(() => { + hilog.info(0x000, 'testTag', 'pushUrl success'); + }) + .catch((err: BusinessError) => { + hilog.error(0x000, 'testTag', `pushUrl failed, code=${err.code}, message=${err.message}`); + }) }) Button('ParentCallPage') .width(120).margin({ top: 16 }) .onClick(() => { this.getUIContext().getRouter().pushUrl({ url: 'pages/ParentCallPage' }) + .then(() => { + hilog.info(0x000, 'testTag', 'pushUrl success'); + }) + .catch((err: BusinessError) => { + hilog.error(0x000, 'testTag', `pushUrl failed, code=${err.code}, message=${err.message}`); + }) }) Button('WatchCallPage') .width(120).margin({ top: 16 }) .onClick(() => { this.getUIContext().getRouter().pushUrl({ url: 'pages/WatchCallPage' }) + .then(() => { + hilog.info(0x000, 'testTag', 'pushUrl success'); + }) + .catch((err: BusinessError) => { + hilog.error(0x000, 'testTag', `pushUrl failed, code=${err.code}, message=${err.message}`); + }) }) } .height('100%') diff --git a/ComponentEncapsulation/entry/src/main/ets/pages/ParentCallPage.ets b/ComponentEncapsulation/entry/src/main/ets/pages/ParentCallPage.ets index c906ba0533a646335f32094dd6543fb57fbab681..2f5cc59d3d73c40abfa591ae70422ebbb56710bf 100644 --- a/ComponentEncapsulation/entry/src/main/ets/pages/ParentCallPage.ets +++ b/ComponentEncapsulation/entry/src/main/ets/pages/ParentCallPage.ets @@ -13,6 +13,9 @@ * limitations under the License. */ // [Start parent_call] +import { BusinessError } from '@kit.BasicServicesKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; + @Component export struct ChildComponent { call = () => { @@ -32,7 +35,12 @@ export struct ChildComponent { @Component struct Index { parentAction() { - this.getUIContext().getPromptAction().showToast({ message: 'Parent Action' }) + try { + this.getUIContext().getPromptAction().showToast({ message: 'Parent Action' }); + } catch (error) { + let err = error as BusinessError; + hilog.warn(0x000, 'testTag', `showToast failed, code=${err.code}, message=${err.message}`); + } } build() { diff --git a/ComponentReuse/.idea/vcs.xml b/ComponentReuse/.idea/vcs.xml deleted file mode 100644 index 6c0b8635858dc7ad44b93df54b762707ce49eefc..0000000000000000000000000000000000000000 --- a/ComponentReuse/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/ComponentReuse/.idea/workspace.xml b/ComponentReuse/.idea/workspace.xml deleted file mode 100644 index aa7035bfde535a189ae87072a34953d6ce847616..0000000000000000000000000000000000000000 --- a/ComponentReuse/.idea/workspace.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/ComponentReuse/README.md b/ComponentReuse/README.md index a80fde3f487d85235cdb2e2edab05d2797607aa7..44865381250786e2c8d1a788e74d4f9f812ab21a 100644 --- a/ComponentReuse/README.md +++ b/ComponentReuse/README.md @@ -3,8 +3,7 @@ ### 介绍 HarmonyOS应用框架提供了组件复用能力:可复用组件树上移除时,会进入一个回收缓存区,后续创建新组件节点时,会复用缓存区中的节点,节约组件重新创建的时间。 -本工程配套官网[组件复用最佳实践](https://developer.huawei.com/consumer/cn/doc/best-practices/bpta-component-reuse), -文章介绍如何使用组件复用机制提升应用帧率。 + ### 预览效果 @@ -16,18 +15,24 @@ HarmonyOS应用框架提供了组件复用能力:可复用组件树上移除 |-----------------------------------------|-----------------------------------------| | ![image](screenshots/device/mode_3.gif) | ![image](screenshots/device/mode_4.gif) | -#### 使用说明 +### 使用说明 -1. 点击“减少组件复用的嵌套层级”按钮,进入二级页面“附近的人”, 滑动列表。 -2. 点击“精准控制组件刷新范围”按钮,进入二级页面“附近的人”, 滑动列表。 -3. 点击“使用reuseId标记不同的组件”按钮,进入二级页面“附近的人”, 滑动列表。 -4. 点击“复用组件创建时的@State变量入参”按钮,进入二级页面“附近的人”, 滑动列表。 +#### 选择entry模块运行 +1. 点击“减少组件复用的嵌套层级”按钮,进入二级页面, 滑动列表。 +2. 点击“精准控制组件刷新范围”按钮,进入二级页面, 滑动列表。 +3. 点击“使用reuseId标记不同的组件”按钮,进入二级页面, 滑动列表。 +4. 点击“复用组件创建时的@State变量入参”按钮,进入二级页面, 滑动列表。 +#### 选择negative或positive模块运行 +可使用Tools-AppAnalyzer体检工具, +验证最佳实践[组件复用问题诊断分析](https://developer.huawei.com/consumer/cn/doc/best-practices/bpta-component-reuse-issue-diagnosis-and-analysis) +中的反例或正例代码。 -## 工程目录 +### 工程目录 ``` ├──entry/src/main/ets │ ├──common +│ │ ├──CommonConstants.ets // 组件复用DataSource类 │ │ ├──Constants.ets // 公共常量 │ │ └──GlobalBuilderContext.ets // 缓存全局@Builder │ ├──entryability @@ -38,8 +43,11 @@ HarmonyOS应用框架提供了组件复用能力:可复用组件树上移除 │ │ ├──BasicDataSource.ets // 数据适配器基类 │ │ ├──ColorData.ets // 二级页面“文字列表”的数据适配器 │ │ └──FriendMomentData.ets // 二级页面“附近的人”/“图文列表”/“网名列表”的数据适配器 -│ ├──pages.ets -│ │ └──Index.ets // 首页 +│ ├──pages +│ │ ├──ImproveReuseHitRate.ets // 提升复用命中率 +│ │ ├──Index.ets // 首页 +│ │ ├──ReuseNested.ets // 复用嵌套 +│ │ └──UseComponentReuse.ets // 使用组件复用 │ └──view │ ├──OneMoment.ets // 二级页面“附近的人”中列表的每条item UI │ ├──PageListSlideToHistory.ets // 二级页面“附近的人”UI @@ -53,9 +61,20 @@ HarmonyOS应用框架提供了组件复用能力:可复用组件树上移除 不涉及 -## 约束与限制 +### 约束与限制 * 本示例仅支持标准系统上运行,支持设备:华为手机。 -* HarmonyOS系统:HarmonyOS 5.0.0 Release及以上。 -* DevEco Studio版本:DevEco Studio 5.0.0 Release及以上。 -* HarmonyOS SDK版本:HarmonyOS 5.0.0 Release SDK及以上。 \ No newline at end of file +* HarmonyOS系统:HarmonyOS 5.0.5 Release及以上。 +* DevEco Studio版本:DevEco Studio 5.0.5 Release及以上。 +* HarmonyOS SDK版本:HarmonyOS 5.0.5 Release SDK及以上。 + +### 下载 + +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set ComponentReuse +git checkout +``` \ No newline at end of file diff --git a/ComponentReuse/README_EN.md b/ComponentReuse/README_EN.md index 4d88d2be83056664679bb05eb24534489fa18e88..199a8821a476bc7e8bd6c056b53125fa7bd57945 100644 --- a/ComponentReuse/README_EN.md +++ b/ComponentReuse/README_EN.md @@ -3,8 +3,6 @@ ### Overview The HarmonyOS application framework provides the component reuse capability. When a reusable component is removed from the component tree, it enters a recycling buffer. When a new component node is created, the node in the buffer is reused, saving the time for recreating the component. -This sample is used with the [Best Practices for Component Reuse](https://developer.huawei.com/consumer/en/doc/best-practices/bpta-component-reuse). -The practices describe how to use the component reuse mechanism to improve the application frame rate. ### Preview @@ -18,16 +16,23 @@ The practices describe how to use the component reuse mechanism to improve the a #### How to Use +#### Choose entry module to Run 1. Tap **Reducing component reuse nesting** to enter **Nearby people** on the level-2 page, and slide the list. 2. Tap **Precisely controlling the component update scope** to enter **Text list** on the level-2 page, and slide the list. 3. Tap **Using reuseId to mark different components** to enter **Image-text list** on the level-2 page, and slide the list. 4. Tap **Using @State as input parameter for reusable components** to enter **Username list** on the level-2 page, and slide the list. -## Project Directory +#### Choose negative or positive module to Run +You can use the Tools-AppAnalyzer health check tool, +Verification Best Practices [Component Reuse Issue Diagnosis and Analysis](https://developer.huawei.com/consumer/cn/doc/best-practices/bpta-component-reuse-issue-diagnosis-and-analysis) +negative examples or positive examples in code. + +### Project Directory ``` ├──entry/src/main/ets │ ├──common +│ │ ├──CommonConstants.ets // Component reuse DataSource class │ │ ├──Constants.ets // Common constants │ │ └──GlobalBuilderContext.ets // Caching the global @Builder │ ├──entryability @@ -38,8 +43,11 @@ The practices describe how to use the component reuse mechanism to improve the a │ │ ├──BasicDataSource.ets // Basic data adapter │ │ ├──ColorData.ets // Data adapter of Text list on the level-2 page │ │ └──FriendMomentData.ets // Data adapter of Nearby people, Image-text list, and Username list on the level-2 page -│ ├──pages.ets -│ │ └──Index.ets // Home page +│ ├──pages +│ │ ├──ImproveReuseHitRate.ets // Improve reuse HitRate +│ │ ├──Index.ets // Home page +│ │ ├──ReuseNested.ets // Reuse nested +│ │ └──UseComponentReuse.ets // Use component reuse │ └──view │ ├──OneMoment.ets // Each item UI in Nearby people on the level-2 page │ ├──PageListSlideToHistory.ets // Nearby people UI on the level-2 page @@ -53,9 +61,20 @@ The practices describe how to use the component reuse mechanism to improve the a N/A -## Constraints +### Constraints * This sample is supported only on Huawei phones running the standard system. -* The HarmonyOS version must be HarmonyOS 5.0.0 Release or later. -* The DevEco Studio version must be DevEco Studio 5.0.0 Release or later. -* The HarmonyOS SDK version must be HarmonyOS 5.0.0 Release SDK or later. +* The HarmonyOS version must be HarmonyOS 5.0.5 Release or later. +* The DevEco Studio version must be DevEco Studio 5.0.5 Release or later. +* The HarmonyOS SDK version must be HarmonyOS 5.0.5 Release SDK or later. + +### Download + +To download this project separately, execute the following command: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set ComponentReuse +git checkout +``` diff --git a/ComponentReuse/build-profile.json5 b/ComponentReuse/build-profile.json5 index 90a9741e1b74bdafe09b7e6574aa2a84ee331425..2b8af09623cb36fb810098e4a4569d99d2132f98 100644 --- a/ComponentReuse/build-profile.json5 +++ b/ComponentReuse/build-profile.json5 @@ -4,7 +4,8 @@ { "name": "default", "signingConfig": "default", - "compatibleSdkVersion": "5.0.0(12)", + "compatibleSdkVersion": "5.0.5(17)", + "targetSdkVersion": "5.0.5(17)", "runtimeOS": "HarmonyOS", "buildOption": { "strictMode": { @@ -21,7 +22,8 @@ { "name": "release" } - ] + ], + "signingConfigs": [] }, "modules": [ { @@ -35,6 +37,30 @@ ] } ] + }, + { + "name": "negative", + "srcPath": "./negative", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + }, + { + "name": "positive", + "srcPath": "./positive", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] } ] } \ No newline at end of file diff --git a/ComponentReuse/entry/src/main/ets/entryability/EntryAbility.ets b/ComponentReuse/entry/src/main/ets/entryability/EntryAbility.ets index 658b37ad825e994dbaae500a620986562981d06a..deafa0de972ea9cbb2c0be9cc2804c480e63dc4d 100644 --- a/ComponentReuse/entry/src/main/ets/entryability/EntryAbility.ets +++ b/ComponentReuse/entry/src/main/ets/entryability/EntryAbility.ets @@ -38,6 +38,8 @@ export default class EntryAbility extends UIAbility { hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); return; } + let uiContext: UIContext | undefined = windowStage.getMainWindowSync().getUIContext(); + AppStorage.setOrCreate('uiContext', uiContext); this.windowClass = windowStage.getMainWindowSync(); this.windowClass.setWindowLayoutFullScreen(true).then(() => { hilog.info(0x0000, 'testTag', 'Success in setting the window layout to full-screen mode.'); @@ -52,13 +54,18 @@ export default class EntryAbility extends UIAbility { private immersive(): void { let type: window.AvoidAreaType = window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR; - let avoidArea: window.AvoidArea = this.windowClass?.getWindowAvoidArea(type) as window.AvoidArea; - let bottomRectHeight: number = avoidArea.bottomRect.height; - AppStorage.setOrCreate('bottomRectHeight', bottomRectHeight); - type = window.AvoidAreaType.TYPE_SYSTEM; - avoidArea = this.windowClass?.getWindowAvoidArea(type) as window.AvoidArea; - let topRectHeight: number = avoidArea.topRect.height; - AppStorage.setOrCreate('topRectHeight', topRectHeight); + try { + let avoidArea: window.AvoidArea = this.windowClass?.getWindowAvoidArea(type) as window.AvoidArea; + let bottomRectHeight: number = avoidArea.bottomRect.height; + AppStorage.setOrCreate('bottomRectHeight', bottomRectHeight); + type = window.AvoidAreaType.TYPE_SYSTEM; + avoidArea = this.windowClass?.getWindowAvoidArea(type) as window.AvoidArea; + let topRectHeight: number = avoidArea.topRect.height; + AppStorage.setOrCreate('topRectHeight', topRectHeight); + } catch (e) { + let err = e as BusinessError; + hilog.error(0x0000, 'testTag', `failed code=${err.code}, message=${err.message}`); + } } onWindowStageDestroy(): void { diff --git a/ComponentReuse/entry/src/main/ets/model/ColorData.ets b/ComponentReuse/entry/src/main/ets/model/ColorData.ets index 2477328f8f42ba7e28b93ca08a37ec7b22bb90b5..1133c0c78374e460d26e26e0c67f5bece3b9914b 100644 --- a/ComponentReuse/entry/src/main/ets/model/ColorData.ets +++ b/ComponentReuse/entry/src/main/ets/model/ColorData.ets @@ -14,9 +14,17 @@ */ import { BasicDataSource, ColorModel } from './BasicDataSource'; +import { BusinessError } from '@kit.BasicServicesKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; export class ColorData extends BasicDataSource { textColorData: Array = []; + private context: Context | undefined = undefined; + + constructor(context?: Context) { + super(); + this.context = context; + } public totalCount(): number { return this.textColorData.length; @@ -38,13 +46,19 @@ export class ColorData extends BasicDataSource { let color: Color[] = [Color.Black, Color.Blue, Color.Red, Color.Green, Color.Pink, Color.Black, Color.Blue, Color.Red, Color.Green, Color.Pink]; - for (let i = 0; i < 10; i++) { - let colorModel: ColorModel = new ColorModel('', '', Color.White); - colorModel.id = Math.floor(this.totalCount() / 10) + i.toString(); - colorModel.text = - getContext().resourceManager.getStringSync($r('app.string.update_component_title'), parseInt(colorModel.id) + 1); - colorModel.color = color[i]; - this.pushData(colorModel); + try { + for (let i = 0; i < 10; i++) { + let colorModel: ColorModel = new ColorModel('', '', Color.White); + colorModel.id = Math.floor(this.totalCount() / 10) + i.toString(); + colorModel.text = + this.context!.resourceManager.getStringSync($r('app.string.update_component_title').id, parseInt(colorModel.id) + 1); + colorModel.color = color[i]; + this.pushData(colorModel); + } + } catch (e) { + let err = e as BusinessError; + hilog.error(0x0000, 'testTag', `failed code=${err.code}, message=${err.message}`); } + } } \ No newline at end of file diff --git a/ComponentReuse/entry/src/main/ets/model/FriendMomentData.ets b/ComponentReuse/entry/src/main/ets/model/FriendMomentData.ets index d7cdbaef9672f94331277a89eae619a0646059bb..6a7970f12c877329fe0ebff97a4719f888a8b2d9 100644 --- a/ComponentReuse/entry/src/main/ets/model/FriendMomentData.ets +++ b/ComponentReuse/entry/src/main/ets/model/FriendMomentData.ets @@ -16,13 +16,17 @@ import { BasicDataSource, FriendMoment } from './BasicDataSource'; import { util } from '@kit.ArkTS'; import { Constants } from '../common/Constants'; +import { BusinessError } from '@kit.BasicServicesKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; export class FriendMomentsData extends BasicDataSource { private friendMoments: Array = []; private mode: string | undefined = ''; + private context: Context | undefined = undefined; - constructor(mode?: string) { + constructor(context?: Context,mode?: string) { super(); + this.context = context; this.mode = mode; } @@ -43,22 +47,26 @@ export class FriendMomentsData extends BasicDataSource { } public async getFriendMomentFromRawFile(): Promise { - const resourceManager = getContext().resourceManager; - const res = await resourceManager.getRawFileContent('mockFriendMomentOneModelData.json'); - const textDecoder = util.TextDecoder.create(); - const friendMomentArray = (JSON.parse(textDecoder.decodeToString(res)) as FriendMomentsData).friendMoments; - - friendMomentArray.forEach(item => { - if (item.id) { - item.id = Math.floor(this.totalCount() / 10) + item.id; - } - item.userName = resourceManager.getStringSync($r('app.string.userName').id, parseInt(item.id) + 1); - if (this.mode === Constants.NAV_DESTINATION_ITEM_3) { - item.text = resourceManager.getStringSync($r('app.string.with_func_title'), parseInt(item.id) + 1); - } else { - item.text = resourceManager.getStringSync($r('app.string.jump_text_one'), parseInt(item.id) + 1); - } - this.pushData(item); - }) + const resourceManager = this.context!.resourceManager; + try { + const res = await resourceManager.getRawFileContent('mockFriendMomentOneModelData.json'); + const textDecoder = util.TextDecoder.create(); + const friendMomentArray = (JSON.parse(textDecoder.decodeToString(res)) as FriendMomentsData).friendMoments; + friendMomentArray.forEach(item => { + if (item.id) { + item.id = Math.floor(this.totalCount() / 10) + item.id; + } + item.userName = resourceManager.getStringSync($r('app.string.userName').id, parseInt(item.id) + 1); + if (this.mode === Constants.NAV_DESTINATION_ITEM_3) { + item.text = resourceManager.getStringSync($r('app.string.with_func_title').id, parseInt(item.id) + 1); + } else { + item.text = resourceManager.getStringSync($r('app.string.jump_text_one').id, parseInt(item.id) + 1); + } + this.pushData(item); + }) + } catch (e) { + let err = e as BusinessError; + hilog.error(0x0000, 'testTag', `failed code=${err.code}, message=${err.message}`); + } } } \ No newline at end of file diff --git a/ComponentReuse/entry/src/main/ets/model/ItemData.ets b/ComponentReuse/entry/src/main/ets/model/ItemData.ets new file mode 100644 index 0000000000000000000000000000000000000000..313d871f343d0f3ab383041b8f3f0807af9a6da6 --- /dev/null +++ b/ComponentReuse/entry/src/main/ets/model/ItemData.ets @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + +@Observed +export class ItemData { + id: string = ''; + title: string | Resource = ''; + content: string = ''; + from: string | Resource = ''; + tail: string | Resource = ''; + type: number = 0; + pics: Resource[] = []; + preview: Resource | string = ''; + duration: string = ''; + isShowTitle?: Visibility = Visibility.Hidden; + + constructor(id: string, type: number) { + this.id = id; + this.type = type; + } +} \ No newline at end of file diff --git a/ComponentReuse/entry/src/main/ets/model/ItemDataSource.ets b/ComponentReuse/entry/src/main/ets/model/ItemDataSource.ets new file mode 100644 index 0000000000000000000000000000000000000000..0056109375c97c16fa7075b877c94013a6d7fa4a --- /dev/null +++ b/ComponentReuse/entry/src/main/ets/model/ItemDataSource.ets @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + +import { ItemData } from './ItemData'; + +export class ItemDataSource implements IDataSource { + private listeners: DataChangeListener[] = []; + private originDataArray: ItemData[] = []; + + public totalCount(): number { + return this.originDataArray.length; + } + + public getData(index: number): ItemData { + return this.originDataArray[index]; + } + + registerDataChangeListener(listener: DataChangeListener): void { + if (this.listeners.indexOf(listener) < 0) { + this.listeners.push(listener); + } + } + + unregisterDataChangeListener(listener: DataChangeListener): void { + const pos = this.listeners.indexOf(listener); + if (pos >= 0) { + this.listeners.splice(pos, 1); + } + } + + notifyDataReload(): void { + this.listeners.forEach(listener => { + listener.onDataReloaded(); + }); + } + + notifyDataAdd(index: number): void { + this.listeners.forEach(listener => { + listener.onDataAdd(index); + }); + } + + notifyDataChange(index: number): void { + this.listeners.forEach(listener => { + listener.onDataChange(index); + }); + } + + notifyDataDelete(index: number): void { + this.listeners.forEach(listener => { + listener.onDataDelete(index); + }); + } + + notifyDataMove(from: number, to: number): void { + this.listeners.forEach(listener => { + listener.onDataMove(from, to); + }); + } + + notifyDatasetChange(operations: DataOperation[]): void { + this.listeners.forEach(listener => { + listener.onDatasetChange(operations); + }); + } + + public pushArray(newData: ItemData[]): void { + this.originDataArray.push(...newData); + this.notifyDataReload(); + } + + public addItems(items: ItemData[]) { + this.originDataArray.push(...items); + this.notifyDataReload(); + } + + public add1stItem(item: ItemData): void { + this.originDataArray.splice(0, 0, item); + this.notifyDataAdd(0); + } + + public addLastItem(item: ItemData): void { + this.originDataArray.splice(this.originDataArray.length, 0, item); + this.notifyDataAdd(this.originDataArray.length - 1); + } + + public addItem(index: number, item: ItemData): void { + this.originDataArray.splice(index, 0, item); + this.notifyDataAdd(index); + } + + public delete1stItem(): void { + this.originDataArray.splice(0, 1); + this.notifyDataDelete(0); + } + + public delete2ndItem(): void { + this.originDataArray.splice(1, 1); + this.notifyDataDelete(1); + } + + public deleteLastItem(): void { + this.originDataArray.splice(-1, 1); + this.notifyDataDelete(this.originDataArray.length); + } + + public reload() { + this.originDataArray.splice(1, 1); + this.originDataArray.splice(3, 2); + this.reload(); + } +} \ No newline at end of file diff --git a/ComponentReuse/entry/src/main/ets/view/NoComponentReuseSceneOnePositiveExample.ets b/ComponentReuse/entry/src/main/ets/view/NoComponentReuseSceneOnePositiveExample.ets new file mode 100644 index 0000000000000000000000000000000000000000..56596d9e5ff91ac152ca7e3adc6710bb4c5c282a --- /dev/null +++ b/ComponentReuse/entry/src/main/ets/view/NoComponentReuseSceneOnePositiveExample.ets @@ -0,0 +1,86 @@ +import { ItemDataSource } from '../model/ItemDataSource'; +import { ItemData } from '../model/ItemData'; + +@Entry +@Component +struct NoComponentReuseSceneOnePositiveExample { + private dataSource: ItemDataSource = new ItemDataSource(); + + build() { + Column() { + List() { + LazyForEach(this.dataSource, (item: ItemData) => { + ListItem() { + NewsContent({ item: item }) + } + }, (item: ItemData) => item.id.toString()) + } + } + } +} + +// [Start NoComponentReuseSceneOnePositiveExample] +@Reusable +@Component +struct NewsContent { + // [StartExclude NoComponentReuseSceneOnePositiveExample] + @ObjectLink item: ItemData; + + @Builder + myBuilder(item: ItemData) { + TopView({ item: item }) + MiddleSingleImageView({ item: item }) + BottomView({ item: item }) + } + + build() { + Column() { + this.myBuilder(this.item) + } + + // ... + } + + // [EndExclude NoComponentReuseSceneOnePositiveExample] +} + +// [End NoComponentReuseSceneOnePositiveExample] + +// [Start ComponentReuseImproperUseSceneTwoPositiveExample] +@Component +struct TopView { + // [StartExclude ComponentReuseImproperUseSceneTwoPositiveExample] + @ObjectLink item: ItemData; + + build() { + // ... + } + + // [EndExclude ComponentReuseImproperUseSceneTwoPositiveExample] +} + +@Component +struct BottomView { + // [StartExclude ComponentReuseImproperUseSceneTwoPositiveExample] + @ObjectLink item: ItemData; + + build() { + // ... + } + + // [EndExclude ComponentReuseImproperUseSceneTwoPositiveExample] +} + +@Component +struct MiddleSingleImageView { + // [StartExclude ComponentReuseImproperUseSceneTwoPositiveExample] + @ObjectLink item: ItemData; + + build() { + // ... + } + + // [EndExclude ComponentReuseImproperUseSceneTwoPositiveExample] +} + +// [End ComponentReuseImproperUseSceneTwoPositiveExample] \ No newline at end of file diff --git a/ComponentReuse/entry/src/main/ets/view/NoComponentReuseSceneThreePositiveExample.ets b/ComponentReuse/entry/src/main/ets/view/NoComponentReuseSceneThreePositiveExample.ets new file mode 100644 index 0000000000000000000000000000000000000000..10b5b5bf45896addd454fdfd06b24eb775b90d90 --- /dev/null +++ b/ComponentReuse/entry/src/main/ets/view/NoComponentReuseSceneThreePositiveExample.ets @@ -0,0 +1,121 @@ +import { ItemDataSource } from '../model/ItemDataSource'; +import { ItemData } from '../model/ItemData'; + +@Entry +@Component +struct NoComponentReuseSceneThreePositiveExample { + private dataSource: ItemDataSource = new ItemDataSource(); + + @Builder + itemBuilderSingleImage(item: ItemData) { + Column() { + TopView({ item: item }) + MiddleSingleImageView({ item: item }) + BottomView({ item: item }) + } + } + + @Builder + itemBuilderThreeImage(item: ItemData) { + Column() { + TopView({ item: item }) + MiddleSingleImageView({ item: item }) + BottomView({ item: item }) + } + } + + @Builder + itemBuilderVideo(item: ItemData) { + Column() { + TopView({ item: item }) + MiddleSingleImageView({ item: item }) + BottomView({ item: item }) + } + } + + build() { + Column() { + List() { + LazyForEach(this.dataSource, (item: ItemData) => { + ListItem() { + if (item.type === 0) { + this.itemBuilderSingleImage(item) + } else if (item.type === 1) { + this.itemBuilderThreeImage(item) + } else { + this.itemBuilderVideo(item) + } + } + }, (item: ItemData) => item.id.toString()) + } + } + } +} + +// [Start NoComponentReuseSceneTwoSubPositiveExample] +@Reusable +@Component +struct TopView { + // [StartExclude NoComponentReuseSceneTwoSubPositiveExample] + @ObjectLink item: ItemData; + + build() { + // ... + } + + // [EndExclude NoComponentReuseSceneTwoSubPositiveExample] +} + +@Reusable +@Component +struct BottomView { + // [StartExclude NoComponentReuseSceneTwoSubPositiveExample] + @ObjectLink item: ItemData; + + build() { + // ... + } + + // [EndExclude NoComponentReuseSceneTwoSubPositiveExample] +} + +@Reusable +@Component +struct MiddleSingleImageView { + // [StartExclude NoComponentReuseSceneTwoSubPositiveExample] + @ObjectLink item: ItemData; + + build() { + // ... + } + + // [EndExclude NoComponentReuseSceneTwoSubPositiveExample] +} + +@Reusable +@Component +struct MiddleThreeImageView { + // [StartExclude NoComponentReuseSceneTwoSubPositiveExample] + @ObjectLink item: ItemData; + + build() { + // ... + } + + // [EndExclude NoComponentReuseSceneTwoSubPositiveExample] +} + +@Reusable +@Component +struct MiddleVideoView { + // [StartExclude NoComponentReuseSceneTwoSubPositiveExample] + @ObjectLink item: ItemData; + + build() { + // ... + } + + // [EndExclude NoComponentReuseSceneTwoSubPositiveExample] +} + +// [End NoComponentReuseSceneTwoSubPositiveExample] \ No newline at end of file diff --git a/ComponentReuse/entry/src/main/ets/view/NoComponentReuseSceneTwoPositiveExample.ets b/ComponentReuse/entry/src/main/ets/view/NoComponentReuseSceneTwoPositiveExample.ets new file mode 100644 index 0000000000000000000000000000000000000000..71d7554eab96423346d32660d1cf60cabd2793ef --- /dev/null +++ b/ComponentReuse/entry/src/main/ets/view/NoComponentReuseSceneTwoPositiveExample.ets @@ -0,0 +1,101 @@ +import { ItemDataSource } from '../model/ItemDataSource'; +import { ItemData } from '../model/ItemData'; + +@Entry +@Component +struct NoComponentReuseSceneTwoPositiveExample { + private dataSource: ItemDataSource = new ItemDataSource(); + + build() { + Column() { + // [Start NoComponentReuseSceneTwoPositiveExample01] + List() { + LazyForEach(this.dataSource, (item: ItemData) => { + ListItem() { + NewsContent({ item: item }).reuseId(`${item.type}`) + } + }, (item: ItemData) => item.id.toString()) + } + + // [Start NoComponentReuseSceneTwoPositiveExample01] + } + } +} + +// [Start NoComponentReuseSceneTwoPositiveExample02] +@Reusable +@Component +struct NewsContent { + // [StartExclude NoComponentReuseSceneTwoPositiveExample02] + @ObjectLink item: ItemData; + + @Builder + myBuilder(item: ItemData) { + TopView({ item: item }) + if (item.type === 0) { + MiddleSingleImageView({ item: item }) + } else if (item.type === 1) { + MiddleThreeImageView({ item: item }) + } else { + MiddleVideoView({ item: item }) + } + BottomView({ item: item }) + } + + build() { + Column() { + this.myBuilder(this.item) + } + + // ... + } + + // [EndExclude NoComponentReuseSceneTwoPositiveExample02] +} + +// [End NoComponentReuseSceneTwoPositiveExample02] + +@Component +struct TopView { + @ObjectLink item: ItemData; + + build() { + // ... + } +} + +@Component +struct BottomView { + @ObjectLink item: ItemData; + + build() { + // ... + } +} + +@Component +struct MiddleSingleImageView { + @ObjectLink item: ItemData; + + build() { + // ... + } +} + +@Component +struct MiddleThreeImageView { + @ObjectLink item: ItemData; + + build() { + // ... + } +} + +@Component +struct MiddleVideoView { + @ObjectLink item: ItemData; + + build() { + // ... + } +} \ No newline at end of file diff --git a/ComponentReuse/entry/src/main/ets/view/NoComponentReuseSceneTwoSubPositiveExample.ets b/ComponentReuse/entry/src/main/ets/view/NoComponentReuseSceneTwoSubPositiveExample.ets new file mode 100644 index 0000000000000000000000000000000000000000..43f9a1b39cf43b183daa2c15edb696e0386ad491 --- /dev/null +++ b/ComponentReuse/entry/src/main/ets/view/NoComponentReuseSceneTwoSubPositiveExample.ets @@ -0,0 +1,146 @@ +import { ItemDataSource } from '../model/ItemDataSource'; +import { ItemData } from '../model/ItemData'; + +@Entry +@Component +struct NoComponentReuseSceneTwoSubPositiveExample { + private dataSource: ItemDataSource = new ItemDataSource(); + + build() { + Column() { + List() { + LazyForEach(this.dataSource, (item: ItemData) => { + ListItem() { + if (item.type === 0) { + SingleImageNewsContent({ item: item }) + } else if (item.type === 1) { + ThreeImageNewsContent({ item: item }) + } else { + VideoNewsContent({ item: item }) + } + } + }, (item: ItemData) => item.id.toString()) + } + } + } +} + +// [Start NoComponentReuseSceneTwoSubPositiveExample] +@Reusable +@Component +struct SingleImageNewsContent { + // [StartExclude NoComponentReuseSceneTwoSubPositiveExample] + @ObjectLink item: ItemData; + + @Builder + myBuilder(item: ItemData) { + TopView({ item: item }) + MiddleSingleImageView({ item: item }) + BottomView({ item: item }) + } + + build() { + Column() { + this.myBuilder(this.item) + } + + // ... + } + + // [EndExclude NoComponentReuseSceneTwoSubPositiveExample] +} + +@Reusable +@Component +struct ThreeImageNewsContent { + // [StartExclude NoComponentReuseSceneTwoSubPositiveExample] + @ObjectLink item: ItemData; + + @Builder + myBuilder(item: ItemData) { + TopView({ item: item }) + MiddleThreeImageView({ item: item }) + BottomView({ item: item }) + } + + build() { + Column() { + this.myBuilder(this.item) + } + + // ... + } + + // [EndExclude NoComponentReuseSceneTwoSubPositiveExample] +} + +@Reusable +@Component +struct VideoNewsContent { + // [StartExclude NoComponentReuseSceneTwoSubPositiveExample] + @ObjectLink item: ItemData; + + @Builder + myBuilder(item: ItemData) { + TopView({ item: item }) + MiddleVideoView({ item: item }) + BottomView({ item: item }) + } + + build() { + Column() { + this.myBuilder(this.item) + } + + // ... + } + + // [EndExclude NoComponentReuseSceneTwoSubPositiveExample] +} + +// [End NoComponentReuseSceneTwoSubPositiveExample] + +@Component +struct TopView { + @ObjectLink item: ItemData; + + build() { + // ... + } +} + +@Component +struct BottomView { + @ObjectLink item: ItemData; + + build() { + // ... + } +} + +@Component +struct MiddleSingleImageView { + @ObjectLink item: ItemData; + + build() { + // ... + } +} + +@Component +struct MiddleThreeImageView { + @ObjectLink item: ItemData; + + build() { + // ... + } +} + +@Component +struct MiddleVideoView { + @ObjectLink item: ItemData; + + build() { + // ... + } +} \ No newline at end of file diff --git a/ComponentReuse/entry/src/main/ets/view/PageListSlideToHistory.ets b/ComponentReuse/entry/src/main/ets/view/PageListSlideToHistory.ets index cc35bc15018a5fec9b0f7591b96c3b816221287c..fe641679fcb3fcf0e359a75db0d7e38850cfede2 100644 --- a/ComponentReuse/entry/src/main/ets/view/PageListSlideToHistory.ets +++ b/ComponentReuse/entry/src/main/ets/view/PageListSlideToHistory.ets @@ -25,7 +25,7 @@ export struct PageListSlideToHistory { private readonly ANIMATION_DURATION: number = 500; private readonly DEFAULT_VISIBLE_BTN_INDEX: number = 3; // Show jump history button when scroll more than 3 item private readonly LIST_CACHE_COUNT: number = 3; - private momentData: FriendMomentsData = new FriendMomentsData(); + private momentData: FriendMomentsData = new FriendMomentsData(this.getUIContext().getHostContext()); private listScroller: ListScroller = new ListScroller(); private historyOffset: number = 0; private isHistoricalRecord: boolean = false; diff --git a/ComponentReuse/entry/src/main/ets/view/ReuseIdClassificationIsTooDetailedScenePositiveExample.ets b/ComponentReuse/entry/src/main/ets/view/ReuseIdClassificationIsTooDetailedScenePositiveExample.ets new file mode 100644 index 0000000000000000000000000000000000000000..184843e204f1e42aed0c5acbc38edc89515bf35e --- /dev/null +++ b/ComponentReuse/entry/src/main/ets/view/ReuseIdClassificationIsTooDetailedScenePositiveExample.ets @@ -0,0 +1,127 @@ +import { ItemDataSource } from '../model/ItemDataSource'; +import { ItemData } from '../model/ItemData'; + +@Entry +@Component +struct NoComponentReuseSceneTwoPositiveExample { + private dataSource: ItemDataSource = new ItemDataSource(); + + build() { + Column() { + List() { + LazyForEach(this.dataSource, (item: ItemData) => { + ListItem() { + NewsContent({ item: item }).reuseId(`${item.type}`) + } + }, (item: ItemData) => item.id.toString()) + } + } + } +} + +@Reusable +@Component +struct NewsContent { + @ObjectLink item: ItemData; + + @Builder + myBuilder(item: ItemData) { + TopView({ item: item }) + if (item.type === 0) { + MiddleTextView({ item: item }) + } else if (item.type === 1) { + MiddleTextNoTitleView({ item: item }) + } else if (item.type === 2) { + MiddleSingleImageView({ item: item }) + } else if (item.type === 3) { + MiddleThreeImageView({ item: item }) + } else if (item.type === 4) { + MiddleVideoView({ item: item }) + } else if (item.type === 5) { + // ... + } else { + // ... + } + BottomView({ item: item }) + } + + build() { + Column() { + this.myBuilder(this.item) + } + + // ... + } +} + +@Component +struct TopView { + @ObjectLink item: ItemData; + + build() { + // ... + } +} + +@Component +struct BottomView { + @ObjectLink item: ItemData; + + build() { + // ... + } +} + +@Component +struct MiddleSingleImageView { + @ObjectLink item: ItemData; + + build() { + // ... + } +} + +@Component +struct MiddleThreeImageView { + @ObjectLink item: ItemData; + + build() { + // ... + } +} + +@Component +struct MiddleVideoView { + @ObjectLink item: ItemData; + + build() { + // ... + } +} + +// [Start ReuseIdClassificationIsTooDetailedScenePositiveExample] +@Component +struct MiddleTextView { + @ObjectLink item: ItemData; + + build() { + Column() { + Text('title') + .visibility(this.item.isShowTitle) // Switch effects through the visibility property. + Text() + } + + // ... + } +} + +// [Start ReuseIdClassificationIsTooDetailedScenePositiveExample] + +@Component +struct MiddleTextNoTitleView { + @ObjectLink item: ItemData; + + build() { + // ... + } +} \ No newline at end of file diff --git a/ComponentReuse/entry/src/main/ets/view/UpdaterComponent.ets b/ComponentReuse/entry/src/main/ets/view/UpdaterComponent.ets index 8dc2597a837b51e6b95a44d2f414ebfa3a680af0..b8843afbe2952840a1350d1461eb42c94f35bcf6 100644 --- a/ComponentReuse/entry/src/main/ets/view/UpdaterComponent.ets +++ b/ComponentReuse/entry/src/main/ets/view/UpdaterComponent.ets @@ -39,7 +39,7 @@ export class MyTextUpdater extends AttributeUpdater { // [StartExclude opt_updater] @Component export struct UpdaterComponent { - private colorData: ColorData = new ColorData(); + private colorData: ColorData = new ColorData(this.getUIContext().getHostContext()); private readonly LIST_CACHE_COUNT: number = 5; private readonly LIST_SPACE: number = 18; diff --git a/ComponentReuse/entry/src/main/ets/view/WithFuncParam.ets b/ComponentReuse/entry/src/main/ets/view/WithFuncParam.ets index 963ea7b67ec78ccc03d80bb29cd94fed420cdc72..2c8ff2a9373281b2cd43c82819909c155bafa3f4 100644 --- a/ComponentReuse/entry/src/main/ets/view/WithFuncParam.ets +++ b/ComponentReuse/entry/src/main/ets/view/WithFuncParam.ets @@ -24,7 +24,8 @@ import { FriendMomentsData } from '../model/FriendMomentData'; struct WithFuncParam { @State sum: number = 0; // [StartExclude opt_funcParam] - private momentData: FriendMomentsData = new FriendMomentsData(Constants.NAV_DESTINATION_ITEM_3); + private momentData: FriendMomentsData = + new FriendMomentsData(this.getUIContext().getHostContext(), Constants.NAV_DESTINATION_ITEM_3); private readonly LIST_CACHE_COUNT: number = 5; private readonly LIST_SPACE: number = 18; // [EndExclude opt_funcParam] diff --git a/ComponentReuse/entry/src/main/ets/view/WithReuseId.ets b/ComponentReuse/entry/src/main/ets/view/WithReuseId.ets index 462b1a7afa32b27d0d3f5914fb1435c749538d96..c702345d2244c108315602c26532671871144874 100644 --- a/ComponentReuse/entry/src/main/ets/view/WithReuseId.ets +++ b/ComponentReuse/entry/src/main/ets/view/WithReuseId.ets @@ -23,7 +23,7 @@ import { FriendMomentsData } from '../model/FriendMomentData' @Component struct WithReuseId { // [StartExclude opt_reuseId] - private momentData: FriendMomentsData = new FriendMomentsData(); + private momentData: FriendMomentsData = new FriendMomentsData(this.getUIContext().getHostContext()); private readonly LIST_CACHE_COUNT: number = 5; private readonly LIST_SPACE: number = 18; diff --git a/ComponentReuse/entry/src/main/resources/base/element/string.json b/ComponentReuse/entry/src/main/resources/base/element/string.json index 1c04e82de4ae97336282418d1fad24937a2689c0..02cb0a9a0dc390b10bb7c79737968c21db6bb6cc 100644 --- a/ComponentReuse/entry/src/main/resources/base/element/string.json +++ b/ComponentReuse/entry/src/main/resources/base/element/string.json @@ -10,7 +10,7 @@ }, { "name": "EntryAbility_label", - "value": "label" + "value": "ComponentReuse" }, { "name": "nav_destination_item0", diff --git a/ComponentReuse/entry/src/main/resources/en_US/element/string.json b/ComponentReuse/entry/src/main/resources/en_US/element/string.json index 1c04e82de4ae97336282418d1fad24937a2689c0..02cb0a9a0dc390b10bb7c79737968c21db6bb6cc 100644 --- a/ComponentReuse/entry/src/main/resources/en_US/element/string.json +++ b/ComponentReuse/entry/src/main/resources/en_US/element/string.json @@ -10,7 +10,7 @@ }, { "name": "EntryAbility_label", - "value": "label" + "value": "ComponentReuse" }, { "name": "nav_destination_item0", diff --git a/ComponentReuse/negative/build-profile.json5 b/ComponentReuse/negative/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..6bd6457a2fed846cc10698666fa1268219f1bee1 --- /dev/null +++ b/ComponentReuse/negative/build-profile.json5 @@ -0,0 +1,33 @@ +{ + "apiType": "stageMode", + "buildOption": { + "resOptions": { + "copyCodeResource": { + "enable": false + } + } + }, + "buildOptionSet": [ + { + "name": "release", + "arkOptions": { + "obfuscation": { + "ruleOptions": { + "enable": false, + "files": [ + "./obfuscation-rules.txt" + ] + } + } + } + }, + ], + "targets": [ + { + "name": "default" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/ComponentReuse/negative/hvigorfile.ts b/ComponentReuse/negative/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..b0e3a1ab98a91bc918d6404b2413111a5011f14a --- /dev/null +++ b/ComponentReuse/negative/hvigorfile.ts @@ -0,0 +1,6 @@ +import { hapTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins: [] /* Custom plugin to extend the functionality of Hvigor. */ +} \ No newline at end of file diff --git a/ComponentReuse/negative/oh-package.json5 b/ComponentReuse/negative/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..3c409fae6359c99d9e16e6933be27125bd4a0c6d --- /dev/null +++ b/ComponentReuse/negative/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "name": "negative", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "", + "author": "", + "license": "", + "dependencies": {} +} + diff --git a/ComponentReuse/negative/src/main/ets/common/CommonConstants.ets b/ComponentReuse/negative/src/main/ets/common/CommonConstants.ets new file mode 100644 index 0000000000000000000000000000000000000000..eacde21b6eb129221c51fc97d32907706c03e926 --- /dev/null +++ b/ComponentReuse/negative/src/main/ets/common/CommonConstants.ets @@ -0,0 +1,24 @@ +/* +* Copyright (c) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + +export class CommonConstants { + static readonly Full_WIDTH: string = '100%'; + static readonly Full_HIIGHT: string = '100%'; + static readonly INDEX_CONTENT_WIDTH: string = '91.1%'; + static readonly DIVIDER_HEIGHT: number = 0.5; + static readonly DIVIDER_WIDTH: string = '93%'; + static readonly INDEX_TITLE_HEIGHT: number = 112; + static readonly LIST_CONTENT_HEIGHT: string = '110%'; +} \ No newline at end of file diff --git a/ComponentReuse/negative/src/main/ets/common/CustomRoutes.ets b/ComponentReuse/negative/src/main/ets/common/CustomRoutes.ets new file mode 100644 index 0000000000000000000000000000000000000000..90dd397157be51de3e416c59e918373e64559ca4 --- /dev/null +++ b/ComponentReuse/negative/src/main/ets/common/CustomRoutes.ets @@ -0,0 +1,48 @@ +/* +* Copyright (c) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + +export class CustomRoutes { + static readonly ROUTES: Route[] = [ + { + title: '未使用组件复用', + child: [ + { text: '场景1', title: '列表项结构类型相同', to: 'NoReuseScene1' }, + { text: '场景2', title: '列表项结构类型相同-结构一', to: 'NoReuseScene2_StructureOne' }, + { text: '场景2', title: '列表项结构类型相同-结构二', to: 'NoReuseScene2_StructureTwo' }, + { text: '场景3', title: '列表项内子组件可拆分组合', to: 'NoReuseScene3' } + ] + }, + { + title: '组件复用使用不当', + child: [ + { text: '场景1', title: '父组件未使用复用,子组件使用复用', to: 'ImproperReuseOfComponentsScene1' }, + { text: '场景2', title: '复用嵌套', to: 'ImproperReuseOfComponentsScene2' }, + { text: '场景3', title: 'reuseId分类过粗', to: 'ImproperReuseOfComponentsScene3' } + ] + } + ] +} + +export interface Route { + title: string | Resource; + child: Array; +} + +export interface ChildRoute { + text: string | Resource; + title?: string | Resource | null; + description?: string; + to: string; +} \ No newline at end of file diff --git a/ComponentReuse/negative/src/main/ets/common/MockData.ets b/ComponentReuse/negative/src/main/ets/common/MockData.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e0a668e5ea427987d431575ec7f3dfcbb2df81e --- /dev/null +++ b/ComponentReuse/negative/src/main/ets/common/MockData.ets @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + +import { ItemData } from '../model/ItemData'; + +export const TAB_TITLES: string[] = ['News', 'Hot', 'Video', 'Tech', 'Travel']; + +const NEWS_TITLES: string[] = + ['Embark on the journey of integrating intelligence and innovation, join hands to build a new generation of demonstration cities, collaborate on creation, provide new solutions, and create a new era', + 'In the era of data awakening, redefining data storage', + 'High end all flash memory won the top recommendation on annual storage data list, ranking first in the recommendation list', + 'Deeply integrating new technologies with the aviation industry, based on cloud, data, and intelligence as the core of the digital base, jointly cooperating to create solutions to help aviation efficiency', + 'Innovation leads, with actions and words, to jointly build new high-quality communication and new development', + 'To jointly build new high-quality communication and new development']; + +const NEWS_FROMS: string[] = ['Comment', 'News', 'Discuss']; + +let imageArray: Resource[] = [$r("app.media.img0"), $r("app.media.img1"), + $r("app.media.img2"), $r("app.media.img3"), $r("app.media.img4"), $r("app.media.img5")]; + +let PREVIEW_IMAGES: Resource[] = [$r("app.media.img6"), $r("app.media.img7"), + $r("app.media.img8")]; + +export function genMockItemData(size: number): ItemData[] { + const res: ItemData[] = []; + for (let i = 0; i < size; i++) { + const data = new ItemData('' + i, i % 3); + data.title = NEWS_TITLES[Math.floor(Math.random() * NEWS_TITLES.length)]; + data.from = NEWS_FROMS[Math.floor(Math.random() * NEWS_FROMS.length)]; + data.tail = '15 minutes ago'; + imageArray = shuffleArray(imageArray); + data.pics = imageArray; + data.preview = PREVIEW_IMAGES[Math.floor(Math.random() * PREVIEW_IMAGES.length)]; + data.duration = '03:12'; + res.push(data); + } + return res; +} + +function shuffleArray(array: T[]): T[] { + const shuffled = [...array]; + for (let i = shuffled.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)); + const tmp = shuffled[i]; + shuffled[i] = shuffled[j]; + shuffled[j] = tmp; + } + return shuffled; +} diff --git a/ComponentReuse/negative/src/main/ets/model/ItemData.ets b/ComponentReuse/negative/src/main/ets/model/ItemData.ets new file mode 100644 index 0000000000000000000000000000000000000000..113eccbd7bde15caefdabb51720ec150931bf0a4 --- /dev/null +++ b/ComponentReuse/negative/src/main/ets/model/ItemData.ets @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + +@Observed +export class ItemData { + id: string = ''; + title: string | Resource = ''; + content: string = ''; + from: string | Resource = ''; + tail: string | Resource = ''; + type: number = 0; + pics: Resource[] = []; + preview: Resource | string = ''; + duration: string = ''; + + constructor(id: string, type: number) { + this.id = id; + this.type = type; + } +} \ No newline at end of file diff --git a/ComponentReuse/negative/src/main/ets/model/ItemDataSource.ets b/ComponentReuse/negative/src/main/ets/model/ItemDataSource.ets new file mode 100644 index 0000000000000000000000000000000000000000..0056109375c97c16fa7075b877c94013a6d7fa4a --- /dev/null +++ b/ComponentReuse/negative/src/main/ets/model/ItemDataSource.ets @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + +import { ItemData } from './ItemData'; + +export class ItemDataSource implements IDataSource { + private listeners: DataChangeListener[] = []; + private originDataArray: ItemData[] = []; + + public totalCount(): number { + return this.originDataArray.length; + } + + public getData(index: number): ItemData { + return this.originDataArray[index]; + } + + registerDataChangeListener(listener: DataChangeListener): void { + if (this.listeners.indexOf(listener) < 0) { + this.listeners.push(listener); + } + } + + unregisterDataChangeListener(listener: DataChangeListener): void { + const pos = this.listeners.indexOf(listener); + if (pos >= 0) { + this.listeners.splice(pos, 1); + } + } + + notifyDataReload(): void { + this.listeners.forEach(listener => { + listener.onDataReloaded(); + }); + } + + notifyDataAdd(index: number): void { + this.listeners.forEach(listener => { + listener.onDataAdd(index); + }); + } + + notifyDataChange(index: number): void { + this.listeners.forEach(listener => { + listener.onDataChange(index); + }); + } + + notifyDataDelete(index: number): void { + this.listeners.forEach(listener => { + listener.onDataDelete(index); + }); + } + + notifyDataMove(from: number, to: number): void { + this.listeners.forEach(listener => { + listener.onDataMove(from, to); + }); + } + + notifyDatasetChange(operations: DataOperation[]): void { + this.listeners.forEach(listener => { + listener.onDatasetChange(operations); + }); + } + + public pushArray(newData: ItemData[]): void { + this.originDataArray.push(...newData); + this.notifyDataReload(); + } + + public addItems(items: ItemData[]) { + this.originDataArray.push(...items); + this.notifyDataReload(); + } + + public add1stItem(item: ItemData): void { + this.originDataArray.splice(0, 0, item); + this.notifyDataAdd(0); + } + + public addLastItem(item: ItemData): void { + this.originDataArray.splice(this.originDataArray.length, 0, item); + this.notifyDataAdd(this.originDataArray.length - 1); + } + + public addItem(index: number, item: ItemData): void { + this.originDataArray.splice(index, 0, item); + this.notifyDataAdd(index); + } + + public delete1stItem(): void { + this.originDataArray.splice(0, 1); + this.notifyDataDelete(0); + } + + public delete2ndItem(): void { + this.originDataArray.splice(1, 1); + this.notifyDataDelete(1); + } + + public deleteLastItem(): void { + this.originDataArray.splice(-1, 1); + this.notifyDataDelete(this.originDataArray.length); + } + + public reload() { + this.originDataArray.splice(1, 1); + this.originDataArray.splice(3, 2); + this.reload(); + } +} \ No newline at end of file diff --git a/ComponentReuse/negative/src/main/ets/model/TitleDataSource.ets b/ComponentReuse/negative/src/main/ets/model/TitleDataSource.ets new file mode 100644 index 0000000000000000000000000000000000000000..d37993baa67ef5cbe2331a50ded9a41334922b00 --- /dev/null +++ b/ComponentReuse/negative/src/main/ets/model/TitleDataSource.ets @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + +export class TitleDataSource implements IDataSource { + private listeners: DataChangeListener[] = []; + private originDataArray: string[] = []; + + totalCount(): number { + return this.originDataArray.length; + } + + getData(index: number): string { + return this.originDataArray[index]; + } + + public addItem(title: string): void { + this.originDataArray.push(title); + this.notifyDataAdd(this.originDataArray.length - 1); + } + + notifyDataAdd(index: number): void { + this.listeners.forEach(listener => { + listener.onDataAdd(index); + }) + } + + registerDataChangeListener(listener: DataChangeListener): void { + if (this.listeners.indexOf(listener) < 0) { + this.listeners.push(listener); + } + } + + unregisterDataChangeListener(listener: DataChangeListener): void { + const pos = this.listeners.indexOf(listener); + if (pos > 0) { + this.listeners.splice(pos, 1); + } + } +} \ No newline at end of file diff --git a/ComponentReuse/negative/src/main/ets/negativeability/NegativeAbility.ets b/ComponentReuse/negative/src/main/ets/negativeability/NegativeAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..2552addcb41de9903218efb5fb112591ec844ef9 --- /dev/null +++ b/ComponentReuse/negative/src/main/ets/negativeability/NegativeAbility.ets @@ -0,0 +1,58 @@ +/* +* Copyright (c) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + +import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; + +const DOMAIN = 0x0000; + +export default class NegativeAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onDestroy(): void { + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + // Main window is created, set main page for this ability + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + windowStage.loadContent('pages/Index', (err) => { + if (err.code) { + hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err)); + return; + } + hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.'); + }); + } + + onWindowStageDestroy(): void { + // Main window is destroyed, release UI related resources + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground(): void { + // Ability has brought to foreground + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground(): void { + // Ability has back to background + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground'); + } +} diff --git a/ComponentReuse/negative/src/main/ets/pages/ImproperReuseOfComponentsScene1.ets b/ComponentReuse/negative/src/main/ets/pages/ImproperReuseOfComponentsScene1.ets new file mode 100644 index 0000000000000000000000000000000000000000..135c64880b2e58ef49f1960100cdc204433373b3 --- /dev/null +++ b/ComponentReuse/negative/src/main/ets/pages/ImproperReuseOfComponentsScene1.ets @@ -0,0 +1,132 @@ +/* +* Copyright (c) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + +import { ItemDataSource } from '../model/ItemDataSource'; +import { ItemData } from '../model/ItemData'; +import { genMockItemData } from '../common/MockData'; + +@Builder +function buildImproperReuseOfComponentsScene1() { + ImproperReuseOfComponentsScene1() +} + +// 父组件未使用复用,子组件使用复用 +@Component +struct ImproperReuseOfComponentsScene1 { + private dataSource: ItemDataSource = new ItemDataSource(); + + aboutToAppear(): void { + this.dataSource.pushArray(genMockItemData(1000)); + } + + build() { + NavDestination() { + Column() { + List() { + LazyForEach(this.dataSource, (item: ItemData) => { + ListItem() { + NewsContent({ item: item }) + } + }, (item: ItemData) => item.id.toString()) + } + .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM]) + .cachedCount(1) + .width('100%') + .height('100%') + } + .width('100%') + .height('100%') + } + } +} + +@Component +struct NewsContent { + @ObjectLink item: ItemData; + + @Builder + myBuilder(item: ItemData) { + TopView({ item: item }) + MiddleSingleImageView({ item: item }) + BottomView({ item: item }) + } + + build() { + Column() { + this.myBuilder(this.item) + } + .alignItems(HorizontalAlign.Start) + .padding({ + top: 16, + bottom: 12, + left: 16, + right: 16 + }) + .margin({ + top: 12, + left: 16, + right: 16 + }) + .borderRadius(12) + .backgroundColor(Color.White) + } +} + +@Reusable +@Component +struct TopView { + @ObjectLink item: ItemData; + + build() { + Text(this.item.title) + .fontSize(16) + .fontWeight(FontWeight.Medium) + .fontColor(Color.Black) + .maxLines(2) + .lineHeight(22) + .opacity(0.9) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .width('100%') + } +} + +@Reusable +@Component +struct BottomView { + @ObjectLink item: ItemData; + + build() { + Text(this.item.tail) + .fontSize(12) + .opacity(0.4) + .fontWeight(FontWeight.Regular) + .margin({ left: 6, top: 12 }) + .width('100%') + } +} + +@Reusable +@Component +struct MiddleSingleImageView { + @ObjectLink item: ItemData; + + build() { + Image(this.item.preview) + .width(158) + .height(96) + .borderRadius(8) + .margin({ top: 8 }) + } +} \ No newline at end of file diff --git a/ComponentReuse/negative/src/main/ets/pages/ImproperReuseOfComponentsScene2.ets b/ComponentReuse/negative/src/main/ets/pages/ImproperReuseOfComponentsScene2.ets new file mode 100644 index 0000000000000000000000000000000000000000..68a4636fb3f4e74dfa17fda4f0ddccc11f5681c3 --- /dev/null +++ b/ComponentReuse/negative/src/main/ets/pages/ImproperReuseOfComponentsScene2.ets @@ -0,0 +1,133 @@ +/* +* Copyright (c) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + +import { ItemDataSource } from '../model/ItemDataSource'; +import { ItemData } from '../model/ItemData'; +import { genMockItemData } from '../common/MockData'; + +@Builder +function buildImproperReuseOfComponentsScene2() { + ImproperReuseOfComponentsScene2() +} + +// 复用嵌套 +@Component +struct ImproperReuseOfComponentsScene2 { + private dataSource: ItemDataSource = new ItemDataSource(); + + aboutToAppear(): void { + this.dataSource.pushArray(genMockItemData(1000)); + } + + build() { + NavDestination() { + Column() { + List() { + LazyForEach(this.dataSource, (item: ItemData) => { + ListItem() { + NewsContent({ item: item }) + } + }, (item: ItemData) => item.id.toString()) + } + .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM]) + .cachedCount(1) + .width('100%') + .height('100%') + } + .width('100%') + .height('100%') + } + } +} + +@Reusable +@Component +struct NewsContent { + @ObjectLink item: ItemData; + + @Builder + myBuilder(item: ItemData) { + TopView({ item: item }) + MiddleSingleImageView({ item: item }) + BottomView({ item: item }) + } + + build() { + Column() { + this.myBuilder(this.item) + } + .alignItems(HorizontalAlign.Start) + .padding({ + top: 16, + bottom: 12, + left: 16, + right: 16 + }) + .margin({ + top: 12, + left: 16, + right: 16 + }) + .borderRadius(12) + .backgroundColor(Color.White) + } +} + +@Reusable +@Component +struct TopView { + @ObjectLink item: ItemData; + + build() { + Text(this.item.title) + .fontSize(16) + .fontWeight(FontWeight.Medium) + .fontColor(Color.Black) + .maxLines(2) + .lineHeight(22) + .opacity(0.9) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .width('100%') + } +} + +@Reusable +@Component +struct BottomView { + @ObjectLink item: ItemData; + + build() { + Text(this.item.tail) + .fontSize(12) + .opacity(0.4) + .fontWeight(FontWeight.Regular) + .margin({ left: 6, top: 12 }) + .width('100%') + } +} + +@Reusable +@Component +struct MiddleSingleImageView { + @ObjectLink item: ItemData; + + build() { + Image(this.item.preview) + .width(158) + .height(96) + .borderRadius(8) + .margin({ top: 8 }) + } +} \ No newline at end of file diff --git a/ComponentReuse/negative/src/main/ets/pages/ImproperReuseOfComponentsScene3.ets b/ComponentReuse/negative/src/main/ets/pages/ImproperReuseOfComponentsScene3.ets new file mode 100644 index 0000000000000000000000000000000000000000..cf5480258732bc1e5006946102767ce2ee7b91ce --- /dev/null +++ b/ComponentReuse/negative/src/main/ets/pages/ImproperReuseOfComponentsScene3.ets @@ -0,0 +1,188 @@ +/* +* Copyright (c) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + +import { ItemDataSource } from '../model/ItemDataSource'; +import { ItemData } from '../model/ItemData'; +import { genMockItemData } from '../common/MockData'; + +@Builder +function buildImproperReuseOfComponentsScene3() { + ImproperReuseOfComponentsScene3() +} + +// reuseId分类过粗 +@Component +struct ImproperReuseOfComponentsScene3 { + private dataSource: ItemDataSource = new ItemDataSource(); + + aboutToAppear(): void { + this.dataSource.pushArray(genMockItemData(1000)); + } + + build() { + NavDestination() { + Column() { + List() { + LazyForEach(this.dataSource, (item: ItemData) => { + ListItem() { + NewsContent({ item: item }) + } + }, (item: ItemData) => item.id.toString()) + } + .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM]) + .cachedCount(1) + .width('100%') + .height('100%') + } + .width('100%') + .height('100%') + } + } +} + +@Reusable +@Component +struct NewsContent { + @ObjectLink item: ItemData; + + @Builder + myBuilder(item: ItemData) { + TopView({ item: item }) + // MiddleSingleImageView({ item: item }) + if (item.type === 0) { + MiddleSingleImageView({ item: item }) + } else if (item.type === 1) { + MiddleThreeImageView({ item: item }) + } else { + MiddleVideoView({ item: item }) + } + BottomView({ item: item }) + } + + build() { + Column() { + this.myBuilder(this.item) + } + .alignItems(HorizontalAlign.Start) + .padding({ + top: 16, + bottom: 12, + left: 16, + right: 16 + }) + .margin({ + top: 12, + left: 16, + right: 16 + }) + .borderRadius(12) + .backgroundColor(Color.White) + } +} + +@Component +struct TopView { + @ObjectLink item: ItemData; + + build() { + Text(this.item.title) + .fontSize(16) + .fontWeight(FontWeight.Medium) + .fontColor(Color.Black) + .maxLines(2) + .lineHeight(22) + .opacity(0.9) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .width('100%') + } +} + +@Component +struct BottomView { + @ObjectLink item: ItemData; + + build() { + Text(this.item.tail) + .fontSize(12) + .opacity(0.4) + .fontWeight(FontWeight.Regular) + .margin({ left: 6, top: 12 }) + .width('100%') + } +} + +@Component +struct MiddleSingleImageView { + @ObjectLink item: ItemData; + + build() { + Image(this.item.preview) + .width(158) + .height(96) + .borderRadius(8) + .margin({ top: 8 }) + } +} + +@Component +struct MiddleThreeImageView { + @ObjectLink item: ItemData; + + build() { + Row() { + Image(this.item.pics[0]) + .layoutWeight(1) + .height(98) + .borderRadius({ topLeft: 8, bottomLeft: 8 }) + Divider().width(2) + Image(this.item.pics[1]) + .layoutWeight(1) + .height(98) + .borderRadius({ topLeft: 8, bottomLeft: 8 }) + Divider().width(2) + Image(this.item.pics[2]) + .layoutWeight(1) + .height(98) + .borderRadius({ topLeft: 8, bottomLeft: 8 }) + } + .margin({ top: 8 }) + } +} + +@Component +struct MiddleVideoView { + @ObjectLink item: ItemData; + + build() { + Stack() { + Image(this.item.preview) + .width(112) + .height(112) + .borderRadius(8) + .margin({ top: 8 }) + + Row() { + Image($r('app.media.play_fill')) + .width(12).height(12) + Text(this.item.duration) + .fontColor(Color.White) + .fontSize(11) + .margin({ left: 2 }) + .fontWeight(FontWeight.Medium) + } + .margin(6) + } + } +} \ No newline at end of file diff --git a/ComponentReuse/negative/src/main/ets/pages/Index.ets b/ComponentReuse/negative/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..a26dc549f1f79a93a247824a332b7dd3bda60cef --- /dev/null +++ b/ComponentReuse/negative/src/main/ets/pages/Index.ets @@ -0,0 +1,126 @@ +/* +* Copyright (c) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + +import { CustomRoutes, Route, ChildRoute } from '../common/CustomRoutes'; +import { CommonConstants } from '../common/CommonConstants'; + +@Entry +@Component +struct Index { + private routes: Route[] = CustomRoutes.ROUTES; + pathStack: NavPathStack = new NavPathStack(); + + @Builder + buildList() { + ForEach(this.routes, (item: Route) => { + Row() { + Text(item.title) + .width(CommonConstants.INDEX_CONTENT_WIDTH) + .fontSize(18) + .fontColor(Color.Black) + } + .height(20) + + Column() { + ForEach(item.child, (itemChild: ChildRoute, index: number) => { + Column() { + Row() { + Text(itemChild.text) + .height(48) + .fontWeight(FontWeight.Medium) + .padding({ left: 12 }) + .fontSize(16) + .fontColor($r('app.color.black_E6')) + Column().layoutWeight(1) + + Text(itemChild.title ?? '') + .height(48) + .textAlign(TextAlign.End) + .fontWeight(FontWeight.Normal) + .fontSize(14) + .fontColor($r('app.color.black_99')) + + Image($r('app.media.chevron_right')) + .width(24) + .height(24) + .margin({ right: 8 }) + .fillColor($r('app.color.black_33')) + } + .justifyContent(FlexAlign.Start) + .alignItems(VerticalAlign.Center) + + Text(itemChild.description) + .fontWeight(FontWeight.Medium) + .fontColor($r('app.color.gray_3')) + .padding({ + left: 12, + right: 12, + bottom: (itemChild.description ?? '').length > 0 ? 10 : 0 + }) + .fontSize(12) + + Stack() { + if (item.child.length - 1 !== index) { + Row() + .backgroundColor($r('app.color.gray_6')) + .width(CommonConstants.DIVIDER_WIDTH) + .height(CommonConstants.DIVIDER_HEIGHT) + } + } + } + .onClick(() => { + this.pathStack.pushPathByName(itemChild.to, null); + }) + .width(CommonConstants.INDEX_CONTENT_WIDTH) + }, (item: ChildRoute, index: number) => JSON.stringify(item) + index) + } + .margin({ top: 14, bottom: 18 }) + .borderRadius(18) + .backgroundColor(Color.White) + }, (item: Route, index: number) => JSON.stringify(item) + index) + } + + build() { + Navigation(this.pathStack) { + Column() { + Row() { + Text('组件复用使用示例') + .fontWeight(FontWeight.Bold) + .fontSize(30) + .width('100%') + .fontColor('#FF333333') + } + .width(CommonConstants.INDEX_CONTENT_WIDTH) + .height(CommonConstants.INDEX_TITLE_HEIGHT) + + Scroll() { + Column() { + this.buildList() + } + .padding({ bottom: 200 }) + } + .scrollBar(BarState.Off) + .width(CommonConstants.Full_WIDTH) + .scrollable(ScrollDirection.Vertical) + } + .alignItems(HorizontalAlign.Center) + } + .hideNavBar(false) + .backgroundColor('#FFF5F5F5') + .mode(NavigationMode.Stack) + .width(CommonConstants.Full_WIDTH) + .height(CommonConstants.Full_HIIGHT) + } +} \ No newline at end of file diff --git a/ComponentReuse/negative/src/main/ets/pages/NoReuseScene1.ets b/ComponentReuse/negative/src/main/ets/pages/NoReuseScene1.ets new file mode 100644 index 0000000000000000000000000000000000000000..815d6283d02d69fdb84dc038122ee41543af7488 --- /dev/null +++ b/ComponentReuse/negative/src/main/ets/pages/NoReuseScene1.ets @@ -0,0 +1,129 @@ +/* +* Copyright (c) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + +import { ItemDataSource } from '../model/ItemDataSource'; +import { ItemData } from '../model/ItemData'; +import { genMockItemData } from '../common/MockData'; + +@Builder +function buildNoReuseScene1() { + NoReuseScene1() +} + +// 未使用组件复用:场景1 +@Component +struct NoReuseScene1 { + private dataSource: ItemDataSource = new ItemDataSource(); + + aboutToAppear(): void { + this.dataSource.pushArray(genMockItemData(1000)); + } + + build() { + NavDestination() { + Column() { + List() { + LazyForEach(this.dataSource, (item: ItemData) => { + ListItem() { + NewsContent({ item: item }) + } + }, (item: ItemData) => item.id.toString()) + } + .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM]) + .cachedCount(1) + .width('100%') + .height('100%') + } + .width('100%') + .height('100%') + } + } +} + +@Component +struct NewsContent { + @ObjectLink item: ItemData; + + @Builder + myBuilder(item: ItemData) { + TopView({ item: item }) + MiddleSingleImageView({ item: item }) + BottomView({ item: item }) + } + + build() { + Column() { + this.myBuilder(this.item) + } + .alignItems(HorizontalAlign.Start) + .padding({ + top: 16, + bottom: 12, + left: 16, + right: 16 + }) + .margin({ + top: 12, + left: 16, + right: 16 + }) + .borderRadius(12) + .backgroundColor(Color.White) + } +} + +@Component +struct TopView { + @ObjectLink item: ItemData; + + build() { + Text(this.item.title) + .fontSize(16) + .fontWeight(FontWeight.Medium) + .fontColor(Color.Black) + .maxLines(2) + .lineHeight(22) + .opacity(0.9) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .width('100%') + } +} + +@Component +struct BottomView { + @ObjectLink item: ItemData; + + build() { + Text(this.item.tail) + .fontSize(12) + .opacity(0.4) + .fontWeight(FontWeight.Regular) + .margin({ left: 6, top: 12 }) + .width('100%') + } +} + +@Component +struct MiddleSingleImageView { + @ObjectLink item: ItemData; + + build() { + Image(this.item.preview) + .width(158) + .height(96) + .borderRadius(8) + .margin({ top: 8 }) + } +} \ No newline at end of file diff --git a/ComponentReuse/negative/src/main/ets/pages/NoReuseScene2_StructureOne.ets b/ComponentReuse/negative/src/main/ets/pages/NoReuseScene2_StructureOne.ets new file mode 100644 index 0000000000000000000000000000000000000000..57b482db2aa0d784e0873ea6420262f1c6d953e0 --- /dev/null +++ b/ComponentReuse/negative/src/main/ets/pages/NoReuseScene2_StructureOne.ets @@ -0,0 +1,187 @@ +/* +* Copyright (c) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + +import { ItemDataSource } from '../model/ItemDataSource'; +import { ItemData } from '../model/ItemData'; +import { genMockItemData } from '../common/MockData'; + +@Builder +function buildNoReuseScene2_StructureOne() { + NoReuseScene2_StructureOne() +} + +// 未使用组件复用:场景2 结构一 +@Component +struct NoReuseScene2_StructureOne { + private dataSource: ItemDataSource = new ItemDataSource(); + + aboutToAppear(): void { + this.dataSource.pushArray(genMockItemData(1000)); + } + + build() { + NavDestination() { + Column() { + List() { + LazyForEach(this.dataSource, (item: ItemData) => { + ListItem() { + NewsContent({ item: item }) + } + }, (item: ItemData) => item.id.toString()) + } + .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM]) + .cachedCount(1) + .width('100%') + .height('100%') + } + .width('100%') + .height('100%') + } + } +} + +@Component +struct NewsContent { + @ObjectLink item: ItemData; + + @Builder + myBuilder(item: ItemData) { + TopView({ item: item }) + // MiddleSingleImageView({ item: item }) + if (item.type === 0) { + MiddleSingleImageView({ item: item }) + } else if (item.type === 1) { + MiddleThreeImageView({ item: item }) + } else { + MiddleVideoView({ item: item }) + } + BottomView({ item: item }) + } + + build() { + Column() { + this.myBuilder(this.item) + } + .alignItems(HorizontalAlign.Start) + .padding({ + top: 16, + bottom: 12, + left: 16, + right: 16 + }) + .margin({ + top: 12, + left: 16, + right: 16 + }) + .borderRadius(12) + .backgroundColor(Color.White) + } +} + +@Component +struct TopView { + @ObjectLink item: ItemData; + + build() { + Text(this.item.title) + .fontSize(16) + .fontWeight(FontWeight.Medium) + .fontColor(Color.Black) + .maxLines(2) + .lineHeight(22) + .opacity(0.9) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .width('100%') + } +} + +@Component +struct BottomView { + @ObjectLink item: ItemData; + + build() { + Text(this.item.tail) + .fontSize(12) + .opacity(0.4) + .fontWeight(FontWeight.Regular) + .margin({ left: 6, top: 12 }) + .width('100%') + } +} + +@Component +struct MiddleSingleImageView { + @ObjectLink item: ItemData; + + build() { + Image(this.item.preview) + .width(158) + .height(96) + .borderRadius(8) + .margin({ top: 8 }) + } +} + +@Component +struct MiddleThreeImageView { + @ObjectLink item: ItemData; + + build() { + Row() { + Image(this.item.pics[0]) + .layoutWeight(1) + .height(98) + .borderRadius({ topLeft: 8, bottomLeft: 8 }) + Divider().width(2) + Image(this.item.pics[1]) + .layoutWeight(1) + .height(98) + .borderRadius({ topLeft: 8, bottomLeft: 8 }) + Divider().width(2) + Image(this.item.pics[2]) + .layoutWeight(1) + .height(98) + .borderRadius({ topLeft: 8, bottomLeft: 8 }) + } + .margin({ top: 8 }) + } +} + +@Component +struct MiddleVideoView { + @ObjectLink item: ItemData; + + build() { + Stack() { + Image(this.item.preview) + .width(112) + .height(112) + .borderRadius(8) + .margin({ top: 8 }) + + Row() { + Image($r('app.media.play_fill')) + .width(12).height(12) + Text(this.item.duration) + .fontColor(Color.White) + .fontSize(11) + .margin({ left: 2 }) + .fontWeight(FontWeight.Medium) + } + .margin(6) + } + } +} \ No newline at end of file diff --git a/ComponentReuse/negative/src/main/ets/pages/NoReuseScene2_StructureTwo.ets b/ComponentReuse/negative/src/main/ets/pages/NoReuseScene2_StructureTwo.ets new file mode 100644 index 0000000000000000000000000000000000000000..8eaad66ba7c3098156cd48728df2e216bce95da8 --- /dev/null +++ b/ComponentReuse/negative/src/main/ets/pages/NoReuseScene2_StructureTwo.ets @@ -0,0 +1,250 @@ +/* +* Copyright (c) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + +import { ItemDataSource } from '../model/ItemDataSource'; +import { ItemData } from '../model/ItemData'; +import { genMockItemData } from '../common/MockData'; + +@Builder +function buildNoReuseScene2_StructureTwo() { + NoReuseScene2_StructureTwo() +} + +// 未使用组件复用:场景2 结构二 +@Component +struct NoReuseScene2_StructureTwo { + private dataSource: ItemDataSource = new ItemDataSource(); + + aboutToAppear(): void { + this.dataSource.pushArray(genMockItemData(1000)); + } + + build() { + NavDestination() { + Column() { + List() { + LazyForEach(this.dataSource, (item: ItemData) => { + ListItem() { + if (item.type === 0) { + SingleImageNewsContent({ item: item }) + } else if (item.type === 1) { + ThreeImageNewsContent({ item: item }) + } else { + VideoNewsContent({ item: item }) + } + } + }, (item: ItemData) => item.id.toString()) + } + .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM]) + .cachedCount(1) + .width('100%') + .height('100%') + } + .width('100%') + .height('100%') + } + } +} + +@Component +struct SingleImageNewsContent { + @ObjectLink item: ItemData; + + @Builder + myBuilder(item: ItemData) { + TopView({ item: item }) + MiddleSingleImageView({ item: item }) + BottomView({ item: item }) + } + + build() { + Column() { + this.myBuilder(this.item) + } + .alignItems(HorizontalAlign.Start) + .padding({ + top: 16, + bottom: 12, + left: 16, + right: 16 + }) + .margin({ + top: 12, + left: 16, + right: 16 + }) + .borderRadius(12) + .backgroundColor(Color.White) + } +} + +@Component +struct ThreeImageNewsContent { + @ObjectLink item: ItemData; + + @Builder + myBuilder(item: ItemData) { + TopView({ item: item }) + MiddleThreeImageView({ item: item }) + BottomView({ item: item }) + } + + build() { + Column() { + this.myBuilder(this.item) + } + .alignItems(HorizontalAlign.Start) + .padding({ + top: 16, + bottom: 12, + left: 16, + right: 16 + }) + .margin({ + top: 12, + left: 16, + right: 16 + }) + .borderRadius(12) + .backgroundColor(Color.White) + } +} + +@Component +struct VideoNewsContent { + @ObjectLink item: ItemData; + + @Builder + myBuilder(item: ItemData) { + TopView({ item: item }) + MiddleVideoView({ item: item }) + BottomView({ item: item }) + } + + build() { + Column() { + this.myBuilder(this.item) + } + .alignItems(HorizontalAlign.Start) + .padding({ + top: 16, + bottom: 12, + left: 16, + right: 16 + }) + .margin({ + top: 12, + left: 16, + right: 16 + }) + .borderRadius(12) + .backgroundColor(Color.White) + } +} + +@Component +struct TopView { + @ObjectLink item: ItemData; + + build() { + Text(this.item.title) + .fontSize(16) + .fontWeight(FontWeight.Medium) + .fontColor(Color.Black) + .maxLines(2) + .lineHeight(22) + .opacity(0.9) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .width('100%') + } +} + +@Component +struct BottomView { + @ObjectLink item: ItemData; + + build() { + Text(this.item.tail) + .fontSize(12) + .opacity(0.4) + .fontWeight(FontWeight.Regular) + .margin({ left: 6, top: 12 }) + .width('100%') + } +} + +@Component +struct MiddleSingleImageView { + @ObjectLink item: ItemData; + + build() { + Image(this.item.preview) + .width(158) + .height(96) + .borderRadius(8) + .margin({ top: 8 }) + } +} + +@Component +struct MiddleThreeImageView { + @ObjectLink item: ItemData; + + build() { + Row() { + Image(this.item.pics[0]) + .layoutWeight(1) + .height(98) + .borderRadius({ topLeft: 8, bottomLeft: 8 }) + Divider().width(2) + Image(this.item.pics[1]) + .layoutWeight(1) + .height(98) + .borderRadius({ topLeft: 8, bottomLeft: 8 }) + Divider().width(2) + Image(this.item.pics[2]) + .layoutWeight(1) + .height(98) + .borderRadius({ topLeft: 8, bottomLeft: 8 }) + } + .margin({ top: 8 }) + } +} + +@Component +struct MiddleVideoView { + @ObjectLink item: ItemData; + + build() { + Stack() { + Image(this.item.preview) + .width(112) + .height(112) + .borderRadius(8) + .margin({ top: 8 }) + + Row() { + Image($r('app.media.play_fill')) + .width(12).height(12) + Text(this.item.duration) + .fontColor(Color.White) + .fontSize(11) + .margin({ left: 2 }) + .fontWeight(FontWeight.Medium) + } + .margin(6) + } + } +} \ No newline at end of file diff --git a/ComponentReuse/negative/src/main/ets/pages/NoReuseScene3.ets b/ComponentReuse/negative/src/main/ets/pages/NoReuseScene3.ets new file mode 100644 index 0000000000000000000000000000000000000000..85697a4a48669f7c64045d709011f06c26866a53 --- /dev/null +++ b/ComponentReuse/negative/src/main/ets/pages/NoReuseScene3.ets @@ -0,0 +1,224 @@ +/* +* Copyright (c) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + +import { ItemDataSource } from '../model/ItemDataSource'; +import { ItemData } from '../model/ItemData'; +import { genMockItemData } from '../common/MockData'; + +@Builder +function buildNoReuseScene3() { + NoReuseScene3() +} + +// 未使用组件复用:场景3 +@Component +struct NoReuseScene3 { + private dataSource: ItemDataSource = new ItemDataSource(); + + aboutToAppear(): void { + this.dataSource.pushArray(genMockItemData(1000)); + } + + @Builder + itemBuilderSingleImage(item: ItemData) { + Column() { + TopView({ item: item }) + MiddleSingleImageView({ item: item }) + BottomView({ item: item }) + } + .alignItems(HorizontalAlign.Start) + .padding({ + top: 16, + bottom: 12, + left: 16, + right: 16 + }) + .margin({ + top: 12, + left: 16, + right: 16 + }) + .borderRadius(12) + .backgroundColor(Color.White) + } + + @Builder + itemBuilderThreeImage(item: ItemData) { + Column() { + TopView({ item: item }) + MiddleThreeImageView({ item: item }) + BottomView({ item: item }) + } + .alignItems(HorizontalAlign.Start) + .padding({ + top: 16, + bottom: 12, + left: 16, + right: 16 + }) + .margin({ + top: 12, + left: 16, + right: 16 + }) + .borderRadius(12) + .backgroundColor(Color.White) + } + + @Builder + itemBuilderVideo(item: ItemData) { + Column() { + TopView({ item: item }) + MiddleVideoView({ item: item }) + BottomView({ item: item }) + } + .alignItems(HorizontalAlign.Start) + .padding({ + top: 16, + bottom: 12, + left: 16, + right: 16 + }) + .margin({ + top: 12, + left: 16, + right: 16 + }) + .borderRadius(12) + .backgroundColor(Color.White) + } + + build() { + NavDestination() { + Column() { + List() { + LazyForEach(this.dataSource, (item: ItemData) => { + ListItem() { + if (item.type === 0) { + this.itemBuilderSingleImage(item) + } else if (item.type === 1) { + this.itemBuilderThreeImage(item) + } else { + this.itemBuilderVideo(item) + } + } + }, (item: ItemData) => item.id.toString()) + } + .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM]) + .cachedCount(1) + .width('100%') + .height('100%') + } + .width('100%') + .height('100%') + } + } +} + + +@Component +struct TopView { + @ObjectLink item: ItemData; + + build() { + Text(this.item.title) + .fontSize(16) + .fontWeight(FontWeight.Medium) + .fontColor(Color.Black) + .maxLines(2) + .lineHeight(22) + .opacity(0.9) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .width('100%') + } +} + +@Component +struct BottomView { + @ObjectLink item: ItemData; + + build() { + Text(this.item.tail) + .fontSize(12) + .opacity(0.4) + .fontWeight(FontWeight.Regular) + .margin({ left: 6, top: 12 }) + .width('100%') + } +} + +@Component +struct MiddleSingleImageView { + @ObjectLink item: ItemData; + + build() { + Image(this.item.preview) + .width(158) + .height(96) + .borderRadius(8) + .margin({ top: 8 }) + } +} + +@Component +struct MiddleThreeImageView { + @ObjectLink item: ItemData; + + build() { + Row() { + Image(this.item.pics[0]) + .layoutWeight(1) + .height(98) + .borderRadius({ topLeft: 8, bottomLeft: 8 }) + Divider().width(2) + Image(this.item.pics[1]) + .layoutWeight(1) + .height(98) + .borderRadius({ topLeft: 8, bottomLeft: 8 }) + Divider().width(2) + Image(this.item.pics[2]) + .layoutWeight(1) + .height(98) + .borderRadius({ topLeft: 8, bottomLeft: 8 }) + } + .margin({ top: 8 }) + } +} + +@Component +struct MiddleVideoView { + @ObjectLink item: ItemData; + + build() { + Stack() { + Image(this.item.preview) + .width(112) + .height(112) + .borderRadius(8) + .margin({ top: 8 }) + + Row() { + Image($r('app.media.play_fill')) + .width(12).height(12) + Text(this.item.duration) + .fontColor(Color.White) + .fontSize(11) + .margin({ left: 2 }) + .fontWeight(FontWeight.Medium) + } + .margin(6) + } + } +} \ No newline at end of file diff --git a/ComponentReuse/negative/src/main/module.json5 b/ComponentReuse/negative/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a3ef12ce150d60ec34a2e6c16469b94d6920fa47 --- /dev/null +++ b/ComponentReuse/negative/src/main/module.json5 @@ -0,0 +1,27 @@ +{ + "module": { + "name": "negative", + "type": "feature", + "description": "$string:module_desc", + "mainElement": "NegativeAbility", + "deviceTypes": [ + "phone" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "routerMap": "$profile:route_map", + "abilities": [ + { + "name": "NegativeAbility", + "srcEntry": "./ets/negativeability/NegativeAbility.ets", + "description": "$string:NegativeAbility_desc", + "icon": "$media:layered_image", + "label": "$string:NegativeAbility_label", + "startWindowIcon": "$media:startIcon", + "startWindowBackground": "$color:start_window_background", + "exported": true + } + ] + } +} \ No newline at end of file diff --git a/ComponentReuse/negative/src/main/resources/base/element/color.json b/ComponentReuse/negative/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3a0c6cea26e20e4f98146759d70e7e24da0e1d83 --- /dev/null +++ b/ComponentReuse/negative/src/main/resources/base/element/color.json @@ -0,0 +1,60 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + }, + { + "name": "text", + "value": "#2c2c2c" + }, + { + "name": "home_background_color", + "value": "#F1F3F5" + }, + { + "name": "gray_3", + "value": "#FF333333" + }, + { + "name": "gray_6", + "value": "#FF666666" + }, + { + "name": "gray_9", + "value": "#FF999999" + }, + { + "name": "black_03", + "value": "#0D000000" + }, + { + "name": "black_0D", + "value": "#0D000000" + }, + { + "name": "black_12", + "value": "#12000000" + }, + { + "name": "black_33", + "value": "#33000000" + }, + { + "name": "black_66", + "value": "#66000000" + }, + { + "name": "black_80", + "value": "#80000000" + }, + { + "name": "black_99", + "value": "#99000000" + }, + { + "name": "black_E6", + "value": "#E6000000" + } + ] +} \ No newline at end of file diff --git a/Privacy/ContactData/src/main/resources/base/element/float.json b/ComponentReuse/negative/src/main/resources/base/element/float.json similarity index 100% rename from Privacy/ContactData/src/main/resources/base/element/float.json rename to ComponentReuse/negative/src/main/resources/base/element/float.json diff --git a/ComponentReuse/negative/src/main/resources/base/element/string.json b/ComponentReuse/negative/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..08a0271a9ca15cb687d645897035e239ccab8e1a --- /dev/null +++ b/ComponentReuse/negative/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "NegativeAbility_desc", + "value": "description" + }, + { + "name": "NegativeAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/NativeSoIntegration/Ndk/src/main/resources/base/media/background.png b/ComponentReuse/negative/src/main/resources/base/media/background.png similarity index 100% rename from NativeSoIntegration/Ndk/src/main/resources/base/media/background.png rename to ComponentReuse/negative/src/main/resources/base/media/background.png diff --git a/ComponentReuse/negative/src/main/resources/base/media/chevron_right.png b/ComponentReuse/negative/src/main/resources/base/media/chevron_right.png new file mode 100644 index 0000000000000000000000000000000000000000..4844d0b25d462fb2168b96efd9b6ae3c641e8bf9 Binary files /dev/null and b/ComponentReuse/negative/src/main/resources/base/media/chevron_right.png differ diff --git a/Privacy/ContactData/src/main/resources/base/media/foreground.png b/ComponentReuse/negative/src/main/resources/base/media/foreground.png similarity index 100% rename from Privacy/ContactData/src/main/resources/base/media/foreground.png rename to ComponentReuse/negative/src/main/resources/base/media/foreground.png diff --git a/ComponentReuse/negative/src/main/resources/base/media/img0.png b/ComponentReuse/negative/src/main/resources/base/media/img0.png new file mode 100644 index 0000000000000000000000000000000000000000..1d967400f83bb0f5e2df4581415ed2e4cbb564d4 Binary files /dev/null and b/ComponentReuse/negative/src/main/resources/base/media/img0.png differ diff --git a/ComponentReuse/negative/src/main/resources/base/media/img1.png b/ComponentReuse/negative/src/main/resources/base/media/img1.png new file mode 100644 index 0000000000000000000000000000000000000000..b254fba00dcee070e90baf945e920a8f2f0646c6 Binary files /dev/null and b/ComponentReuse/negative/src/main/resources/base/media/img1.png differ diff --git a/ComponentReuse/negative/src/main/resources/base/media/img2.jpg b/ComponentReuse/negative/src/main/resources/base/media/img2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4d36c1f9f8435424323ff12df2b0992bb09f8af5 Binary files /dev/null and b/ComponentReuse/negative/src/main/resources/base/media/img2.jpg differ diff --git a/ComponentReuse/negative/src/main/resources/base/media/img3.png b/ComponentReuse/negative/src/main/resources/base/media/img3.png new file mode 100644 index 0000000000000000000000000000000000000000..89214745c537495119e0e78c49e602f1c4933baa Binary files /dev/null and b/ComponentReuse/negative/src/main/resources/base/media/img3.png differ diff --git a/ComponentReuse/negative/src/main/resources/base/media/img4.png b/ComponentReuse/negative/src/main/resources/base/media/img4.png new file mode 100644 index 0000000000000000000000000000000000000000..54e59fc403d92d11911498f7d3c7d39d6e437cf5 Binary files /dev/null and b/ComponentReuse/negative/src/main/resources/base/media/img4.png differ diff --git a/ComponentReuse/negative/src/main/resources/base/media/img5.png b/ComponentReuse/negative/src/main/resources/base/media/img5.png new file mode 100644 index 0000000000000000000000000000000000000000..a38a0eaab71c8c6ba4b94bff09b7d86e96510043 Binary files /dev/null and b/ComponentReuse/negative/src/main/resources/base/media/img5.png differ diff --git a/ComponentReuse/negative/src/main/resources/base/media/img6.png b/ComponentReuse/negative/src/main/resources/base/media/img6.png new file mode 100644 index 0000000000000000000000000000000000000000..c1175890f2f43f92082e40299d7bda81094e9c06 Binary files /dev/null and b/ComponentReuse/negative/src/main/resources/base/media/img6.png differ diff --git a/ComponentReuse/negative/src/main/resources/base/media/img7.png b/ComponentReuse/negative/src/main/resources/base/media/img7.png new file mode 100644 index 0000000000000000000000000000000000000000..cd29997cfc3b0f30e1d393d49961da58d691ab2f Binary files /dev/null and b/ComponentReuse/negative/src/main/resources/base/media/img7.png differ diff --git a/ComponentReuse/negative/src/main/resources/base/media/img8.png b/ComponentReuse/negative/src/main/resources/base/media/img8.png new file mode 100644 index 0000000000000000000000000000000000000000..1cff5e45d286fb3bc058d326fc9b31caf690ac63 Binary files /dev/null and b/ComponentReuse/negative/src/main/resources/base/media/img8.png differ diff --git a/MultiFinancialManagement/product/phone/src/main/resources/base/media/layered_image.json b/ComponentReuse/negative/src/main/resources/base/media/layered_image.json similarity index 100% rename from MultiFinancialManagement/product/phone/src/main/resources/base/media/layered_image.json rename to ComponentReuse/negative/src/main/resources/base/media/layered_image.json diff --git a/ComponentReuse/negative/src/main/resources/base/media/play_fill.svg b/ComponentReuse/negative/src/main/resources/base/media/play_fill.svg new file mode 100644 index 0000000000000000000000000000000000000000..d1750a9cc4dc77103c03b7e11674b4e0b2b278d9 --- /dev/null +++ b/ComponentReuse/negative/src/main/resources/base/media/play_fill.svg @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/MultiCommunityApplication/products/phone/src/main/resources/base/media/startIcon.png b/ComponentReuse/negative/src/main/resources/base/media/startIcon.png similarity index 100% rename from MultiCommunityApplication/products/phone/src/main/resources/base/media/startIcon.png rename to ComponentReuse/negative/src/main/resources/base/media/startIcon.png diff --git a/MultiDeviceCommunication/common/base/src/main/resources/base/profile/main_pages.json b/ComponentReuse/negative/src/main/resources/base/profile/main_pages.json similarity index 100% rename from MultiDeviceCommunication/common/base/src/main/resources/base/profile/main_pages.json rename to ComponentReuse/negative/src/main/resources/base/profile/main_pages.json diff --git a/ComponentReuse/negative/src/main/resources/base/profile/route_map.json b/ComponentReuse/negative/src/main/resources/base/profile/route_map.json new file mode 100644 index 0000000000000000000000000000000000000000..96d1b687ea92dc43fb6985b9c69dc89711a5b930 --- /dev/null +++ b/ComponentReuse/negative/src/main/resources/base/profile/route_map.json @@ -0,0 +1,39 @@ +{ + "routerMap": [ + { + "name": "NoReuseScene1", + "pageSourceFile": "src/main/ets/pages/NoReuseScene1.ets", + "buildFunction": "buildNoReuseScene1" + }, + { + "name": "NoReuseScene2_StructureOne", + "pageSourceFile": "src/main/ets/pages/NoReuseScene2_StructureOne.ets", + "buildFunction": "buildNoReuseScene2_StructureOne" + }, + { + "name": "NoReuseScene2_StructureTwo", + "pageSourceFile": "src/main/ets/pages/NoReuseScene2_StructureTwo.ets", + "buildFunction": "buildNoReuseScene2_StructureTwo" + }, + { + "name": "NoReuseScene3", + "pageSourceFile": "src/main/ets/pages/NoReuseScene3.ets", + "buildFunction": "buildNoReuseScene3" + }, + { + "name": "ImproperReuseOfComponentsScene1", + "pageSourceFile": "src/main/ets/pages/ImproperReuseOfComponentsScene1.ets", + "buildFunction": "buildImproperReuseOfComponentsScene1" + }, + { + "name": "ImproperReuseOfComponentsScene2", + "pageSourceFile": "src/main/ets/pages/ImproperReuseOfComponentsScene2.ets", + "buildFunction": "buildImproperReuseOfComponentsScene2" + }, + { + "name": "ImproperReuseOfComponentsScene3", + "pageSourceFile": "src/main/ets/pages/ImproperReuseOfComponentsScene3.ets", + "buildFunction": "buildImproperReuseOfComponentsScene3" + } + ] +} \ No newline at end of file diff --git a/ComponentReuse/positive/build-profile.json5 b/ComponentReuse/positive/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..6bd6457a2fed846cc10698666fa1268219f1bee1 --- /dev/null +++ b/ComponentReuse/positive/build-profile.json5 @@ -0,0 +1,33 @@ +{ + "apiType": "stageMode", + "buildOption": { + "resOptions": { + "copyCodeResource": { + "enable": false + } + } + }, + "buildOptionSet": [ + { + "name": "release", + "arkOptions": { + "obfuscation": { + "ruleOptions": { + "enable": false, + "files": [ + "./obfuscation-rules.txt" + ] + } + } + } + }, + ], + "targets": [ + { + "name": "default" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/ComponentReuse/positive/hvigorfile.ts b/ComponentReuse/positive/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..b0e3a1ab98a91bc918d6404b2413111a5011f14a --- /dev/null +++ b/ComponentReuse/positive/hvigorfile.ts @@ -0,0 +1,6 @@ +import { hapTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins: [] /* Custom plugin to extend the functionality of Hvigor. */ +} \ No newline at end of file diff --git a/ComponentReuse/positive/oh-package.json5 b/ComponentReuse/positive/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a7cfe7716ef3bd24bea42826906c685fdcab50a9 --- /dev/null +++ b/ComponentReuse/positive/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "name": "positive", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "", + "author": "", + "license": "", + "dependencies": {} +} + diff --git a/ComponentReuse/positive/src/main/ets/common/CommonConstants.ets b/ComponentReuse/positive/src/main/ets/common/CommonConstants.ets new file mode 100644 index 0000000000000000000000000000000000000000..eacde21b6eb129221c51fc97d32907706c03e926 --- /dev/null +++ b/ComponentReuse/positive/src/main/ets/common/CommonConstants.ets @@ -0,0 +1,24 @@ +/* +* Copyright (c) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + +export class CommonConstants { + static readonly Full_WIDTH: string = '100%'; + static readonly Full_HIIGHT: string = '100%'; + static readonly INDEX_CONTENT_WIDTH: string = '91.1%'; + static readonly DIVIDER_HEIGHT: number = 0.5; + static readonly DIVIDER_WIDTH: string = '93%'; + static readonly INDEX_TITLE_HEIGHT: number = 112; + static readonly LIST_CONTENT_HEIGHT: string = '110%'; +} \ No newline at end of file diff --git a/ComponentReuse/positive/src/main/ets/common/CustomRoutes.ets b/ComponentReuse/positive/src/main/ets/common/CustomRoutes.ets new file mode 100644 index 0000000000000000000000000000000000000000..a545a5adf2f74112e7aacf66069943a6d42c2366 --- /dev/null +++ b/ComponentReuse/positive/src/main/ets/common/CustomRoutes.ets @@ -0,0 +1,48 @@ +/* +* Copyright (c) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + +export class CustomRoutes { + static readonly ROUTES: Route[] = [ + { + title: '未使用组件复用', + child: [ + { text: '场景1', title: '列表项结构类型相同', to: 'NoReuseScene1Positive' }, + { text: '场景2', title: '列表项结构类型相同-结构一', to: 'NoReuseScene2_StructureOnePositive' }, + { text: '场景2', title: '列表项结构类型相同-结构二', to: 'NoReuseScene2_StructureTwoPositive' }, + { text: '场景3', title: '列表项内子组件可拆分组合', to: 'NoReuseScene3Positive' } + ] + }, + { + title: '组件复用使用不当', + child: [ + { text: '场景1', title: '父组件未使用复用,子组件使用复用', to: 'ImproperReuseOfComponentsScene1Positive' }, + { text: '场景2', title: '复用嵌套', to: 'ImproperReuseOfComponentsScene2Positive' }, + { text: '场景3', title: 'reuseId分类过粗', to: 'ImproperReuseOfComponentsScene3Positive' } + ] + } + ] +} + +export interface Route { + title: string | Resource; + child: Array; +} + +export interface ChildRoute { + text: string | Resource; + title?: string | Resource | null; + description?: string; + to: string; +} \ No newline at end of file diff --git a/ComponentReuse/positive/src/main/ets/common/MockData.ets b/ComponentReuse/positive/src/main/ets/common/MockData.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e0a668e5ea427987d431575ec7f3dfcbb2df81e --- /dev/null +++ b/ComponentReuse/positive/src/main/ets/common/MockData.ets @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + +import { ItemData } from '../model/ItemData'; + +export const TAB_TITLES: string[] = ['News', 'Hot', 'Video', 'Tech', 'Travel']; + +const NEWS_TITLES: string[] = + ['Embark on the journey of integrating intelligence and innovation, join hands to build a new generation of demonstration cities, collaborate on creation, provide new solutions, and create a new era', + 'In the era of data awakening, redefining data storage', + 'High end all flash memory won the top recommendation on annual storage data list, ranking first in the recommendation list', + 'Deeply integrating new technologies with the aviation industry, based on cloud, data, and intelligence as the core of the digital base, jointly cooperating to create solutions to help aviation efficiency', + 'Innovation leads, with actions and words, to jointly build new high-quality communication and new development', + 'To jointly build new high-quality communication and new development']; + +const NEWS_FROMS: string[] = ['Comment', 'News', 'Discuss']; + +let imageArray: Resource[] = [$r("app.media.img0"), $r("app.media.img1"), + $r("app.media.img2"), $r("app.media.img3"), $r("app.media.img4"), $r("app.media.img5")]; + +let PREVIEW_IMAGES: Resource[] = [$r("app.media.img6"), $r("app.media.img7"), + $r("app.media.img8")]; + +export function genMockItemData(size: number): ItemData[] { + const res: ItemData[] = []; + for (let i = 0; i < size; i++) { + const data = new ItemData('' + i, i % 3); + data.title = NEWS_TITLES[Math.floor(Math.random() * NEWS_TITLES.length)]; + data.from = NEWS_FROMS[Math.floor(Math.random() * NEWS_FROMS.length)]; + data.tail = '15 minutes ago'; + imageArray = shuffleArray(imageArray); + data.pics = imageArray; + data.preview = PREVIEW_IMAGES[Math.floor(Math.random() * PREVIEW_IMAGES.length)]; + data.duration = '03:12'; + res.push(data); + } + return res; +} + +function shuffleArray(array: T[]): T[] { + const shuffled = [...array]; + for (let i = shuffled.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)); + const tmp = shuffled[i]; + shuffled[i] = shuffled[j]; + shuffled[j] = tmp; + } + return shuffled; +} diff --git a/ComponentReuse/positive/src/main/ets/model/ItemData.ets b/ComponentReuse/positive/src/main/ets/model/ItemData.ets new file mode 100644 index 0000000000000000000000000000000000000000..113eccbd7bde15caefdabb51720ec150931bf0a4 --- /dev/null +++ b/ComponentReuse/positive/src/main/ets/model/ItemData.ets @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + +@Observed +export class ItemData { + id: string = ''; + title: string | Resource = ''; + content: string = ''; + from: string | Resource = ''; + tail: string | Resource = ''; + type: number = 0; + pics: Resource[] = []; + preview: Resource | string = ''; + duration: string = ''; + + constructor(id: string, type: number) { + this.id = id; + this.type = type; + } +} \ No newline at end of file diff --git a/ComponentReuse/positive/src/main/ets/model/ItemDataSource.ets b/ComponentReuse/positive/src/main/ets/model/ItemDataSource.ets new file mode 100644 index 0000000000000000000000000000000000000000..0056109375c97c16fa7075b877c94013a6d7fa4a --- /dev/null +++ b/ComponentReuse/positive/src/main/ets/model/ItemDataSource.ets @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + +import { ItemData } from './ItemData'; + +export class ItemDataSource implements IDataSource { + private listeners: DataChangeListener[] = []; + private originDataArray: ItemData[] = []; + + public totalCount(): number { + return this.originDataArray.length; + } + + public getData(index: number): ItemData { + return this.originDataArray[index]; + } + + registerDataChangeListener(listener: DataChangeListener): void { + if (this.listeners.indexOf(listener) < 0) { + this.listeners.push(listener); + } + } + + unregisterDataChangeListener(listener: DataChangeListener): void { + const pos = this.listeners.indexOf(listener); + if (pos >= 0) { + this.listeners.splice(pos, 1); + } + } + + notifyDataReload(): void { + this.listeners.forEach(listener => { + listener.onDataReloaded(); + }); + } + + notifyDataAdd(index: number): void { + this.listeners.forEach(listener => { + listener.onDataAdd(index); + }); + } + + notifyDataChange(index: number): void { + this.listeners.forEach(listener => { + listener.onDataChange(index); + }); + } + + notifyDataDelete(index: number): void { + this.listeners.forEach(listener => { + listener.onDataDelete(index); + }); + } + + notifyDataMove(from: number, to: number): void { + this.listeners.forEach(listener => { + listener.onDataMove(from, to); + }); + } + + notifyDatasetChange(operations: DataOperation[]): void { + this.listeners.forEach(listener => { + listener.onDatasetChange(operations); + }); + } + + public pushArray(newData: ItemData[]): void { + this.originDataArray.push(...newData); + this.notifyDataReload(); + } + + public addItems(items: ItemData[]) { + this.originDataArray.push(...items); + this.notifyDataReload(); + } + + public add1stItem(item: ItemData): void { + this.originDataArray.splice(0, 0, item); + this.notifyDataAdd(0); + } + + public addLastItem(item: ItemData): void { + this.originDataArray.splice(this.originDataArray.length, 0, item); + this.notifyDataAdd(this.originDataArray.length - 1); + } + + public addItem(index: number, item: ItemData): void { + this.originDataArray.splice(index, 0, item); + this.notifyDataAdd(index); + } + + public delete1stItem(): void { + this.originDataArray.splice(0, 1); + this.notifyDataDelete(0); + } + + public delete2ndItem(): void { + this.originDataArray.splice(1, 1); + this.notifyDataDelete(1); + } + + public deleteLastItem(): void { + this.originDataArray.splice(-1, 1); + this.notifyDataDelete(this.originDataArray.length); + } + + public reload() { + this.originDataArray.splice(1, 1); + this.originDataArray.splice(3, 2); + this.reload(); + } +} \ No newline at end of file diff --git a/ComponentReuse/positive/src/main/ets/model/TitleDataSource.ets b/ComponentReuse/positive/src/main/ets/model/TitleDataSource.ets new file mode 100644 index 0000000000000000000000000000000000000000..d37993baa67ef5cbe2331a50ded9a41334922b00 --- /dev/null +++ b/ComponentReuse/positive/src/main/ets/model/TitleDataSource.ets @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + +export class TitleDataSource implements IDataSource { + private listeners: DataChangeListener[] = []; + private originDataArray: string[] = []; + + totalCount(): number { + return this.originDataArray.length; + } + + getData(index: number): string { + return this.originDataArray[index]; + } + + public addItem(title: string): void { + this.originDataArray.push(title); + this.notifyDataAdd(this.originDataArray.length - 1); + } + + notifyDataAdd(index: number): void { + this.listeners.forEach(listener => { + listener.onDataAdd(index); + }) + } + + registerDataChangeListener(listener: DataChangeListener): void { + if (this.listeners.indexOf(listener) < 0) { + this.listeners.push(listener); + } + } + + unregisterDataChangeListener(listener: DataChangeListener): void { + const pos = this.listeners.indexOf(listener); + if (pos > 0) { + this.listeners.splice(pos, 1); + } + } +} \ No newline at end of file diff --git a/ComponentReuse/positive/src/main/ets/pages/ImproperReuseOfComponentsScene1Positive.ets b/ComponentReuse/positive/src/main/ets/pages/ImproperReuseOfComponentsScene1Positive.ets new file mode 100644 index 0000000000000000000000000000000000000000..23ba2254217f616caf97cbf79dda173745401569 --- /dev/null +++ b/ComponentReuse/positive/src/main/ets/pages/ImproperReuseOfComponentsScene1Positive.ets @@ -0,0 +1,130 @@ +/* +* Copyright (c) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + +import { ItemDataSource } from '../model/ItemDataSource'; +import { ItemData } from '../model/ItemData'; +import { genMockItemData } from '../common/MockData'; + +@Builder +function buildImproperReuseOfComponentsScene1Positive() { + ImproperReuseOfComponentsScene1Positive() +} + +// 父组件未使用复用,子组件使用复用 +@Component +struct ImproperReuseOfComponentsScene1Positive { + private dataSource: ItemDataSource = new ItemDataSource(); + + aboutToAppear(): void { + this.dataSource.pushArray(genMockItemData(1000)); + } + + build() { + NavDestination() { + Column() { + List() { + LazyForEach(this.dataSource, (item: ItemData) => { + ListItem() { + NewsContent({ item: item }) + } + }, (item: ItemData) => item.id.toString()) + } + .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM]) + .cachedCount(1) + .width('100%') + .height('100%') + } + .width('100%') + .height('100%') + } + } +} + +@Reusable +@Component +struct NewsContent { + @ObjectLink item: ItemData; + + @Builder + myBuilder(item: ItemData) { + TopView({ item: item }) + MiddleSingleImageView({ item: item }) + BottomView({ item: item }) + } + + build() { + Column() { + this.myBuilder(this.item) + } + .alignItems(HorizontalAlign.Start) + .padding({ + top: 16, + bottom: 12, + left: 16, + right: 16 + }) + .margin({ + top: 12, + left: 16, + right: 16 + }) + .borderRadius(12) + .backgroundColor(Color.White) + } +} + +@Component +struct TopView { + @ObjectLink item: ItemData; + + build() { + Text(this.item.title) + .fontSize(16) + .fontWeight(FontWeight.Medium) + .fontColor(Color.Black) + .maxLines(2) + .lineHeight(22) + .opacity(0.9) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .width('100%') + } +} + +@Component +struct BottomView { + @ObjectLink item: ItemData; + + build() { + Text(this.item.tail) + .fontSize(12) + .opacity(0.4) + .fontWeight(FontWeight.Regular) + .margin({ left: 6, top: 12 }) + .width('100%') + } +} + +@Component +struct MiddleSingleImageView { + @ObjectLink item: ItemData; + + build() { + Image(this.item.preview) + .width(158) + .height(96) + .borderRadius(8) + .margin({ top: 8 }) + } +} \ No newline at end of file diff --git a/ComponentReuse/positive/src/main/ets/pages/ImproperReuseOfComponentsScene2Positive.ets b/ComponentReuse/positive/src/main/ets/pages/ImproperReuseOfComponentsScene2Positive.ets new file mode 100644 index 0000000000000000000000000000000000000000..e6e02d6b022d02c8db19562409f5b171382f8159 --- /dev/null +++ b/ComponentReuse/positive/src/main/ets/pages/ImproperReuseOfComponentsScene2Positive.ets @@ -0,0 +1,130 @@ +/* +* Copyright (c) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + +import { ItemDataSource } from '../model/ItemDataSource'; +import { ItemData } from '../model/ItemData'; +import { genMockItemData } from '../common/MockData'; + +@Builder +function buildImproperReuseOfComponentsScene2Positive() { + ImproperReuseOfComponentsScene2Positive() +} + +// 复用嵌套 +@Component +struct ImproperReuseOfComponentsScene2Positive { + private dataSource: ItemDataSource = new ItemDataSource(); + + aboutToAppear(): void { + this.dataSource.pushArray(genMockItemData(1000)); + } + + build() { + NavDestination() { + Column() { + List() { + LazyForEach(this.dataSource, (item: ItemData) => { + ListItem() { + NewsContent({ item: item }) + } + }, (item: ItemData) => item.id.toString()) + } + .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM]) + .cachedCount(1) + .width('100%') + .height('100%') + } + .width('100%') + .height('100%') + } + } +} + +@Reusable +@Component +struct NewsContent { + @ObjectLink item: ItemData; + + @Builder + myBuilder(item: ItemData) { + TopView({ item: item }) + MiddleSingleImageView({ item: item }) + BottomView({ item: item }) + } + + build() { + Column() { + this.myBuilder(this.item) + } + .alignItems(HorizontalAlign.Start) + .padding({ + top: 16, + bottom: 12, + left: 16, + right: 16 + }) + .margin({ + top: 12, + left: 16, + right: 16 + }) + .borderRadius(12) + .backgroundColor(Color.White) + } +} + +@Component +struct TopView { + @ObjectLink item: ItemData; + + build() { + Text(this.item.title) + .fontSize(16) + .fontWeight(FontWeight.Medium) + .fontColor(Color.Black) + .maxLines(2) + .lineHeight(22) + .opacity(0.9) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .width('100%') + } +} + +@Component +struct BottomView { + @ObjectLink item: ItemData; + + build() { + Text(this.item.tail) + .fontSize(12) + .opacity(0.4) + .fontWeight(FontWeight.Regular) + .margin({ left: 6, top: 12 }) + .width('100%') + } +} + +@Component +struct MiddleSingleImageView { + @ObjectLink item: ItemData; + + build() { + Image(this.item.preview) + .width(158) + .height(96) + .borderRadius(8) + .margin({ top: 8 }) + } +} \ No newline at end of file diff --git a/ComponentReuse/positive/src/main/ets/pages/ImproperReuseOfComponentsScene3Positive.ets b/ComponentReuse/positive/src/main/ets/pages/ImproperReuseOfComponentsScene3Positive.ets new file mode 100644 index 0000000000000000000000000000000000000000..edbe5aba6cbf7d6bed341fb21ebe2ae54351e1ab --- /dev/null +++ b/ComponentReuse/positive/src/main/ets/pages/ImproperReuseOfComponentsScene3Positive.ets @@ -0,0 +1,188 @@ +/* +* Copyright (c) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + +import { ItemDataSource } from '../model/ItemDataSource'; +import { ItemData } from '../model/ItemData'; +import { genMockItemData } from '../common/MockData'; + +@Builder +function buildImproperReuseOfComponentsScene3Positive() { + ImproperReuseOfComponentsScene3Positive() +} + +// reuseId分类过粗 +@Component +struct ImproperReuseOfComponentsScene3Positive { + private dataSource: ItemDataSource = new ItemDataSource(); + + aboutToAppear(): void { + this.dataSource.pushArray(genMockItemData(1000)); + } + + build() { + NavDestination() { + Column() { + List() { + LazyForEach(this.dataSource, (item: ItemData) => { + ListItem() { + NewsContent({ item: item }).reuseId(`${item.type}`) + } + }, (item: ItemData) => item.id.toString()) + } + .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM]) + .cachedCount(1) + .width('100%') + .height('100%') + } + .width('100%') + .height('100%') + } + } +} + +@Reusable +@Component +struct NewsContent { + @ObjectLink item: ItemData; + + @Builder + myBuilder(item: ItemData) { + TopView({ item: item }) + // MiddleSingleImageView({ item: item }) + if (item.type === 0) { + MiddleSingleImageView({ item: item }) + } else if (item.type === 1) { + MiddleThreeImageView({ item: item }) + } else { + MiddleVideoView({ item: item }) + } + BottomView({ item: item }) + } + + build() { + Column() { + this.myBuilder(this.item) + } + .alignItems(HorizontalAlign.Start) + .padding({ + top: 16, + bottom: 12, + left: 16, + right: 16 + }) + .margin({ + top: 12, + left: 16, + right: 16 + }) + .borderRadius(12) + .backgroundColor(Color.White) + } +} + +@Component +struct TopView { + @ObjectLink item: ItemData; + + build() { + Text(this.item.title) + .fontSize(16) + .fontWeight(FontWeight.Medium) + .fontColor(Color.Black) + .maxLines(2) + .lineHeight(22) + .opacity(0.9) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .width('100%') + } +} + +@Component +struct BottomView { + @ObjectLink item: ItemData; + + build() { + Text(this.item.tail) + .fontSize(12) + .opacity(0.4) + .fontWeight(FontWeight.Regular) + .margin({ left: 6, top: 12 }) + .width('100%') + } +} + +@Component +struct MiddleSingleImageView { + @ObjectLink item: ItemData; + + build() { + Image(this.item.preview) + .width(158) + .height(96) + .borderRadius(8) + .margin({ top: 8 }) + } +} + +@Component +struct MiddleThreeImageView { + @ObjectLink item: ItemData; + + build() { + Row() { + Image(this.item.pics[0]) + .layoutWeight(1) + .height(98) + .borderRadius({ topLeft: 8, bottomLeft: 8 }) + Divider().width(2) + Image(this.item.pics[1]) + .layoutWeight(1) + .height(98) + .borderRadius({ topLeft: 8, bottomLeft: 8 }) + Divider().width(2) + Image(this.item.pics[2]) + .layoutWeight(1) + .height(98) + .borderRadius({ topLeft: 8, bottomLeft: 8 }) + } + .margin({ top: 8 }) + } +} + +@Component +struct MiddleVideoView { + @ObjectLink item: ItemData; + + build() { + Stack() { + Image(this.item.preview) + .width(112) + .height(112) + .borderRadius(8) + .margin({ top: 8 }) + + Row() { + Image($r('app.media.play_fill')) + .width(12).height(12) + Text(this.item.duration) + .fontColor(Color.White) + .fontSize(11) + .margin({ left: 2 }) + .fontWeight(FontWeight.Medium) + } + .margin(6) + } + } +} \ No newline at end of file diff --git a/ComponentReuse/positive/src/main/ets/pages/Index.ets b/ComponentReuse/positive/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..a26dc549f1f79a93a247824a332b7dd3bda60cef --- /dev/null +++ b/ComponentReuse/positive/src/main/ets/pages/Index.ets @@ -0,0 +1,126 @@ +/* +* Copyright (c) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + +import { CustomRoutes, Route, ChildRoute } from '../common/CustomRoutes'; +import { CommonConstants } from '../common/CommonConstants'; + +@Entry +@Component +struct Index { + private routes: Route[] = CustomRoutes.ROUTES; + pathStack: NavPathStack = new NavPathStack(); + + @Builder + buildList() { + ForEach(this.routes, (item: Route) => { + Row() { + Text(item.title) + .width(CommonConstants.INDEX_CONTENT_WIDTH) + .fontSize(18) + .fontColor(Color.Black) + } + .height(20) + + Column() { + ForEach(item.child, (itemChild: ChildRoute, index: number) => { + Column() { + Row() { + Text(itemChild.text) + .height(48) + .fontWeight(FontWeight.Medium) + .padding({ left: 12 }) + .fontSize(16) + .fontColor($r('app.color.black_E6')) + Column().layoutWeight(1) + + Text(itemChild.title ?? '') + .height(48) + .textAlign(TextAlign.End) + .fontWeight(FontWeight.Normal) + .fontSize(14) + .fontColor($r('app.color.black_99')) + + Image($r('app.media.chevron_right')) + .width(24) + .height(24) + .margin({ right: 8 }) + .fillColor($r('app.color.black_33')) + } + .justifyContent(FlexAlign.Start) + .alignItems(VerticalAlign.Center) + + Text(itemChild.description) + .fontWeight(FontWeight.Medium) + .fontColor($r('app.color.gray_3')) + .padding({ + left: 12, + right: 12, + bottom: (itemChild.description ?? '').length > 0 ? 10 : 0 + }) + .fontSize(12) + + Stack() { + if (item.child.length - 1 !== index) { + Row() + .backgroundColor($r('app.color.gray_6')) + .width(CommonConstants.DIVIDER_WIDTH) + .height(CommonConstants.DIVIDER_HEIGHT) + } + } + } + .onClick(() => { + this.pathStack.pushPathByName(itemChild.to, null); + }) + .width(CommonConstants.INDEX_CONTENT_WIDTH) + }, (item: ChildRoute, index: number) => JSON.stringify(item) + index) + } + .margin({ top: 14, bottom: 18 }) + .borderRadius(18) + .backgroundColor(Color.White) + }, (item: Route, index: number) => JSON.stringify(item) + index) + } + + build() { + Navigation(this.pathStack) { + Column() { + Row() { + Text('组件复用使用示例') + .fontWeight(FontWeight.Bold) + .fontSize(30) + .width('100%') + .fontColor('#FF333333') + } + .width(CommonConstants.INDEX_CONTENT_WIDTH) + .height(CommonConstants.INDEX_TITLE_HEIGHT) + + Scroll() { + Column() { + this.buildList() + } + .padding({ bottom: 200 }) + } + .scrollBar(BarState.Off) + .width(CommonConstants.Full_WIDTH) + .scrollable(ScrollDirection.Vertical) + } + .alignItems(HorizontalAlign.Center) + } + .hideNavBar(false) + .backgroundColor('#FFF5F5F5') + .mode(NavigationMode.Stack) + .width(CommonConstants.Full_WIDTH) + .height(CommonConstants.Full_HIIGHT) + } +} \ No newline at end of file diff --git a/ComponentReuse/positive/src/main/ets/pages/NoReuseScene1Positive.ets b/ComponentReuse/positive/src/main/ets/pages/NoReuseScene1Positive.ets new file mode 100644 index 0000000000000000000000000000000000000000..093206de353b19686644af81451daf8b3e826c89 --- /dev/null +++ b/ComponentReuse/positive/src/main/ets/pages/NoReuseScene1Positive.ets @@ -0,0 +1,130 @@ +/* +* Copyright (c) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + +import { ItemDataSource } from '../model/ItemDataSource'; +import { ItemData } from '../model/ItemData'; +import { genMockItemData } from '../common/MockData'; + +@Builder +function buildNoReuseScene1Positive() { + NoReuseScene1Positive() +} + +// 未使用组件复用:场景1 +@Component +struct NoReuseScene1Positive { + private dataSource: ItemDataSource = new ItemDataSource(); + + aboutToAppear(): void { + this.dataSource.pushArray(genMockItemData(1000)); + } + + build() { + NavDestination() { + Column() { + List() { + LazyForEach(this.dataSource, (item: ItemData) => { + ListItem() { + NewsContent({ item: item }) + } + }, (item: ItemData) => item.id.toString()) + } + .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM]) + .cachedCount(1) + .width('100%') + .height('100%') + } + .width('100%') + .height('100%') + } + } +} + +@Reusable +@Component +struct NewsContent { + @ObjectLink item: ItemData; + + @Builder + myBuilder(item: ItemData) { + TopView({ item: item }) + MiddleSingleImageView({ item: item }) + BottomView({ item: item }) + } + + build() { + Column() { + this.myBuilder(this.item) + } + .alignItems(HorizontalAlign.Start) + .padding({ + top: 16, + bottom: 12, + left: 16, + right: 16 + }) + .margin({ + top: 12, + left: 16, + right: 16 + }) + .borderRadius(12) + .backgroundColor(Color.White) + } +} + +@Component +struct TopView { + @ObjectLink item: ItemData; + + build() { + Text(this.item.title) + .fontSize(16) + .fontWeight(FontWeight.Medium) + .fontColor(Color.Black) + .maxLines(2) + .lineHeight(22) + .opacity(0.9) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .width('100%') + } +} + +@Component +struct BottomView { + @ObjectLink item: ItemData; + + build() { + Text(this.item.tail) + .fontSize(12) + .opacity(0.4) + .fontWeight(FontWeight.Regular) + .margin({ left: 6, top: 12 }) + .width('100%') + } +} + +@Component +struct MiddleSingleImageView { + @ObjectLink item: ItemData; + + build() { + Image(this.item.preview) + .width(158) + .height(96) + .borderRadius(8) + .margin({ top: 8 }) + } +} \ No newline at end of file diff --git a/ComponentReuse/positive/src/main/ets/pages/NoReuseScene2_StructureOnePositive.ets b/ComponentReuse/positive/src/main/ets/pages/NoReuseScene2_StructureOnePositive.ets new file mode 100644 index 0000000000000000000000000000000000000000..bfefc19df708df5b784a5faf11f36ae8f90e070d --- /dev/null +++ b/ComponentReuse/positive/src/main/ets/pages/NoReuseScene2_StructureOnePositive.ets @@ -0,0 +1,187 @@ +/* +* Copyright (c) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + +import { ItemDataSource } from '../model/ItemDataSource'; +import { ItemData } from '../model/ItemData'; +import { genMockItemData } from '../common/MockData'; + +@Builder +function buildNoReuseScene2_StructureOnePositive() { + NoReuseScene2_StructureOnePositive() +} + +// 未使用组件复用:场景2 结构一 +@Component +struct NoReuseScene2_StructureOnePositive { + private dataSource: ItemDataSource = new ItemDataSource(); + + aboutToAppear(): void { + this.dataSource.pushArray(genMockItemData(1000)); + } + + build() { + NavDestination() { + Column() { + List() { + LazyForEach(this.dataSource, (item: ItemData) => { + ListItem() { + NewsContent({ item: item }).reuseId(`${item.type}`) + } + }, (item: ItemData) => item.id.toString()) + } + .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM]) + .cachedCount(1) + .width('100%') + .height('100%') + } + .width('100%') + .height('100%') + } + } +} + +@Component +struct NewsContent { + @ObjectLink item: ItemData; + + @Builder + myBuilder(item: ItemData) { + TopView({ item: item }) + // MiddleSingleImageView({ item: item }) + if (item.type === 0) { + MiddleSingleImageView({ item: item }) + } else if (item.type === 1) { + MiddleThreeImageView({ item: item }) + } else { + MiddleVideoView({ item: item }) + } + BottomView({ item: item }) + } + + build() { + Column() { + this.myBuilder(this.item) + } + .alignItems(HorizontalAlign.Start) + .padding({ + top: 16, + bottom: 12, + left: 16, + right: 16 + }) + .margin({ + top: 12, + left: 16, + right: 16 + }) + .borderRadius(12) + .backgroundColor(Color.White) + } +} + +@Component +struct TopView { + @ObjectLink item: ItemData; + + build() { + Text(this.item.title) + .fontSize(16) + .fontWeight(FontWeight.Medium) + .fontColor(Color.Black) + .maxLines(2) + .lineHeight(22) + .opacity(0.9) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .width('100%') + } +} + +@Component +struct BottomView { + @ObjectLink item: ItemData; + + build() { + Text(this.item.tail) + .fontSize(12) + .opacity(0.4) + .fontWeight(FontWeight.Regular) + .margin({ left: 6, top: 12 }) + .width('100%') + } +} + +@Component +struct MiddleSingleImageView { + @ObjectLink item: ItemData; + + build() { + Image(this.item.preview) + .width(158) + .height(96) + .borderRadius(8) + .margin({ top: 8 }) + } +} + +@Component +struct MiddleThreeImageView { + @ObjectLink item: ItemData; + + build() { + Row() { + Image(this.item.pics[0]) + .layoutWeight(1) + .height(98) + .borderRadius({ topLeft: 8, bottomLeft: 8 }) + Divider().width(2) + Image(this.item.pics[1]) + .layoutWeight(1) + .height(98) + .borderRadius({ topLeft: 8, bottomLeft: 8 }) + Divider().width(2) + Image(this.item.pics[2]) + .layoutWeight(1) + .height(98) + .borderRadius({ topLeft: 8, bottomLeft: 8 }) + } + .margin({ top: 8 }) + } +} + +@Component +struct MiddleVideoView { + @ObjectLink item: ItemData; + + build() { + Stack() { + Image(this.item.preview) + .width(112) + .height(112) + .borderRadius(8) + .margin({ top: 8 }) + + Row() { + Image($r('app.media.play_fill')) + .width(12).height(12) + Text(this.item.duration) + .fontColor(Color.White) + .fontSize(11) + .margin({ left: 2 }) + .fontWeight(FontWeight.Medium) + } + .margin(6) + } + } +} \ No newline at end of file diff --git a/ComponentReuse/positive/src/main/ets/pages/NoReuseScene2_StructureTwoPositive.ets b/ComponentReuse/positive/src/main/ets/pages/NoReuseScene2_StructureTwoPositive.ets new file mode 100644 index 0000000000000000000000000000000000000000..6457b5a7b2e3b569cd42643aaaee6b6c514ab523 --- /dev/null +++ b/ComponentReuse/positive/src/main/ets/pages/NoReuseScene2_StructureTwoPositive.ets @@ -0,0 +1,253 @@ +/* +* Copyright (c) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + +import { ItemDataSource } from '../model/ItemDataSource'; +import { ItemData } from '../model/ItemData'; +import { genMockItemData } from '../common/MockData'; + +@Builder +function buildNoReuseScene2_StructureTwoPositive() { + NoReuseScene2_StructureTwoPositive() +} + +// 未使用组件复用:场景2 结构二 +@Component +struct NoReuseScene2_StructureTwoPositive { + private dataSource: ItemDataSource = new ItemDataSource(); + + aboutToAppear(): void { + this.dataSource.pushArray(genMockItemData(1000)); + } + + build() { + NavDestination() { + Column() { + List() { + LazyForEach(this.dataSource, (item: ItemData) => { + ListItem() { + if (item.type === 0) { + SingleImageNewsContent({ item: item }) + } else if (item.type === 1) { + ThreeImageNewsContent({ item: item }) + } else { + VideoNewsContent({ item: item }) + } + } + }, (item: ItemData) => item.id.toString()) + } + .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM]) + .cachedCount(1) + .width('100%') + .height('100%') + } + .width('100%') + .height('100%') + } + } +} + +@Reusable +@Component +struct SingleImageNewsContent { + @ObjectLink item: ItemData; + + @Builder + myBuilder(item: ItemData) { + TopView({ item: item }) + MiddleSingleImageView({ item: item }) + BottomView({ item: item }) + } + + build() { + Column() { + this.myBuilder(this.item) + } + .alignItems(HorizontalAlign.Start) + .padding({ + top: 16, + bottom: 12, + left: 16, + right: 16 + }) + .margin({ + top: 12, + left: 16, + right: 16 + }) + .borderRadius(12) + .backgroundColor(Color.White) + } +} + +@Reusable +@Component +struct ThreeImageNewsContent { + @ObjectLink item: ItemData; + + @Builder + myBuilder(item: ItemData) { + TopView({ item: item }) + MiddleThreeImageView({ item: item }) + BottomView({ item: item }) + } + + build() { + Column() { + this.myBuilder(this.item) + } + .alignItems(HorizontalAlign.Start) + .padding({ + top: 16, + bottom: 12, + left: 16, + right: 16 + }) + .margin({ + top: 12, + left: 16, + right: 16 + }) + .borderRadius(12) + .backgroundColor(Color.White) + } +} + +@Reusable +@Component +struct VideoNewsContent { + @ObjectLink item: ItemData; + + @Builder + myBuilder(item: ItemData) { + TopView({ item: item }) + MiddleVideoView({ item: item }) + BottomView({ item: item }) + } + + build() { + Column() { + this.myBuilder(this.item) + } + .alignItems(HorizontalAlign.Start) + .padding({ + top: 16, + bottom: 12, + left: 16, + right: 16 + }) + .margin({ + top: 12, + left: 16, + right: 16 + }) + .borderRadius(12) + .backgroundColor(Color.White) + } +} + +@Component +struct TopView { + @ObjectLink item: ItemData; + + build() { + Text(this.item.title) + .fontSize(16) + .fontWeight(FontWeight.Medium) + .fontColor(Color.Black) + .maxLines(2) + .lineHeight(22) + .opacity(0.9) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .width('100%') + } +} + +@Component +struct BottomView { + @ObjectLink item: ItemData; + + build() { + Text(this.item.tail) + .fontSize(12) + .opacity(0.4) + .fontWeight(FontWeight.Regular) + .margin({ left: 6, top: 12 }) + .width('100%') + } +} + +@Component +struct MiddleSingleImageView { + @ObjectLink item: ItemData; + + build() { + Image(this.item.preview) + .width(158) + .height(96) + .borderRadius(8) + .margin({ top: 8 }) + } +} + +@Component +struct MiddleThreeImageView { + @ObjectLink item: ItemData; + + build() { + Row() { + Image(this.item.pics[0]) + .layoutWeight(1) + .height(98) + .borderRadius({ topLeft: 8, bottomLeft: 8 }) + Divider().width(2) + Image(this.item.pics[1]) + .layoutWeight(1) + .height(98) + .borderRadius({ topLeft: 8, bottomLeft: 8 }) + Divider().width(2) + Image(this.item.pics[2]) + .layoutWeight(1) + .height(98) + .borderRadius({ topLeft: 8, bottomLeft: 8 }) + } + .margin({ top: 8 }) + } +} + +@Component +struct MiddleVideoView { + @ObjectLink item: ItemData; + + build() { + Stack() { + Image(this.item.preview) + .width(112) + .height(112) + .borderRadius(8) + .margin({ top: 8 }) + + Row() { + Image($r('app.media.play_fill')) + .width(12).height(12) + Text(this.item.duration) + .fontColor(Color.White) + .fontSize(11) + .margin({ left: 2 }) + .fontWeight(FontWeight.Medium) + } + .margin(6) + } + } +} \ No newline at end of file diff --git a/ComponentReuse/positive/src/main/ets/pages/NoReuseScene3Positive.ets b/ComponentReuse/positive/src/main/ets/pages/NoReuseScene3Positive.ets new file mode 100644 index 0000000000000000000000000000000000000000..a6247d555077583335632d142a239ba07e2b7da4 --- /dev/null +++ b/ComponentReuse/positive/src/main/ets/pages/NoReuseScene3Positive.ets @@ -0,0 +1,228 @@ +/* +* Copyright (c) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + +import { ItemDataSource } from '../model/ItemDataSource'; +import { ItemData } from '../model/ItemData'; +import { genMockItemData } from '../common/MockData'; + +@Builder +function buildNoReuseScene3Positive() { + NoReuseScene3Positive() +} + +// 未使用组件复用:场景3 +@Component +struct NoReuseScene3Positive { + private dataSource: ItemDataSource = new ItemDataSource(); + + aboutToAppear(): void { + this.dataSource.pushArray(genMockItemData(1000)); + } + + @Builder + itemBuilderSingleImage(item: ItemData) { + Column() { + TopView({ item: item }) + MiddleSingleImageView({ item: item }) + BottomView({ item: item }) + } + .alignItems(HorizontalAlign.Start) + .padding({ + top: 16, + bottom: 12, + left: 16, + right: 16 + }) + .margin({ + top: 12, + left: 16, + right: 16 + }) + .borderRadius(12) + .backgroundColor(Color.White) + } + + @Builder + itemBuilderThreeImage(item: ItemData) { + Column() { + TopView({ item: item }) + MiddleThreeImageView({ item: item }) + BottomView({ item: item }) + } + .alignItems(HorizontalAlign.Start) + .padding({ + top: 16, + bottom: 12, + left: 16, + right: 16 + }) + .margin({ + top: 12, + left: 16, + right: 16 + }) + .borderRadius(12) + .backgroundColor(Color.White) + } + + @Builder + itemBuilderVideo(item: ItemData) { + Column() { + TopView({ item: item }) + MiddleVideoView({ item: item }) + BottomView({ item: item }) + } + .alignItems(HorizontalAlign.Start) + .padding({ + top: 16, + bottom: 12, + left: 16, + right: 16 + }) + .margin({ + top: 12, + left: 16, + right: 16 + }) + .borderRadius(12) + .backgroundColor(Color.White) + } + + build() { + NavDestination() { + Column() { + List() { + LazyForEach(this.dataSource, (item: ItemData) => { + ListItem() { + if (item.type === 0) { + this.itemBuilderSingleImage(item) + } else if (item.type === 1) { + this.itemBuilderThreeImage(item) + } else { + this.itemBuilderVideo(item) + } + } + }, (item: ItemData) => item.id.toString()) + } + .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM]) + .cachedCount(1) + .width('100%') + .height('100%') + } + .width('100%') + .height('100%') + } + } +} + +@Reusable +@Component +struct TopView { + @ObjectLink item: ItemData; + + build() { + Text(this.item.title) + .fontSize(16) + .fontWeight(FontWeight.Medium) + .fontColor(Color.Black) + .maxLines(2) + .lineHeight(22) + .opacity(0.9) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .width('100%') + } +} + +@Reusable +@Component +struct BottomView { + @ObjectLink item: ItemData; + + build() { + Text(this.item.tail) + .fontSize(12) + .opacity(0.4) + .fontWeight(FontWeight.Regular) + .margin({ left: 6, top: 12 }) + .width('100%') + } +} + +@Reusable +@Component +struct MiddleSingleImageView { + @ObjectLink item: ItemData; + + build() { + Image(this.item.preview) + .width(158) + .height(96) + .borderRadius(8) + .margin({ top: 8 }) + } +} + +@Reusable +@Component +struct MiddleThreeImageView { + @ObjectLink item: ItemData; + + build() { + Row() { + Image(this.item.pics[0]) + .layoutWeight(1) + .height(98) + .borderRadius({ topLeft: 8, bottomLeft: 8 }) + Divider().width(2) + Image(this.item.pics[1]) + .layoutWeight(1) + .height(98) + .borderRadius({ topLeft: 8, bottomLeft: 8 }) + Divider().width(2) + Image(this.item.pics[2]) + .layoutWeight(1) + .height(98) + .borderRadius({ topLeft: 8, bottomLeft: 8 }) + } + .margin({ top: 8 }) + } +} + +@Reusable +@Component +struct MiddleVideoView { + @ObjectLink item: ItemData; + + build() { + Stack() { + Image(this.item.preview) + .width(112) + .height(112) + .borderRadius(8) + .margin({ top: 8 }) + + Row() { + Image($r('app.media.play_fill')) + .width(12).height(12) + Text(this.item.duration) + .fontColor(Color.White) + .fontSize(11) + .margin({ left: 2 }) + .fontWeight(FontWeight.Medium) + } + .margin(6) + } + } +} \ No newline at end of file diff --git a/ComponentReuse/positive/src/main/ets/positiveability/PositiveAbility.ets b/ComponentReuse/positive/src/main/ets/positiveability/PositiveAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..c6c34586a69ccdff9727bc0ca43a9052a81618e7 --- /dev/null +++ b/ComponentReuse/positive/src/main/ets/positiveability/PositiveAbility.ets @@ -0,0 +1,58 @@ +/* +* Copyright (c) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + +import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; + +const DOMAIN = 0x0000; + +export default class PositiveAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onDestroy(): void { + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + // Main window is created, set main page for this ability + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + windowStage.loadContent('pages/Index', (err) => { + if (err.code) { + hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err)); + return; + } + hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.'); + }); + } + + onWindowStageDestroy(): void { + // Main window is destroyed, release UI related resources + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground(): void { + // Ability has brought to foreground + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground(): void { + // Ability has back to background + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground'); + } +} diff --git a/ComponentReuse/positive/src/main/module.json5 b/ComponentReuse/positive/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..3f84b258f76f6a25277fbb69ec1847c15759a34b --- /dev/null +++ b/ComponentReuse/positive/src/main/module.json5 @@ -0,0 +1,27 @@ +{ + "module": { + "name": "positive", + "type": "feature", + "description": "$string:module_desc", + "mainElement": "PositiveAbility", + "deviceTypes": [ + "phone" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "routerMap": "$profile:route_map", + "abilities": [ + { + "name": "PositiveAbility", + "srcEntry": "./ets/positiveability/PositiveAbility.ets", + "description": "$string:PositiveAbility_desc", + "icon": "$media:layered_image", + "label": "$string:PositiveAbility_label", + "startWindowIcon": "$media:startIcon", + "startWindowBackground": "$color:start_window_background", + "exported": true + } + ] + } +} \ No newline at end of file diff --git a/ComponentReuse/positive/src/main/resources/base/element/color.json b/ComponentReuse/positive/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3a0c6cea26e20e4f98146759d70e7e24da0e1d83 --- /dev/null +++ b/ComponentReuse/positive/src/main/resources/base/element/color.json @@ -0,0 +1,60 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + }, + { + "name": "text", + "value": "#2c2c2c" + }, + { + "name": "home_background_color", + "value": "#F1F3F5" + }, + { + "name": "gray_3", + "value": "#FF333333" + }, + { + "name": "gray_6", + "value": "#FF666666" + }, + { + "name": "gray_9", + "value": "#FF999999" + }, + { + "name": "black_03", + "value": "#0D000000" + }, + { + "name": "black_0D", + "value": "#0D000000" + }, + { + "name": "black_12", + "value": "#12000000" + }, + { + "name": "black_33", + "value": "#33000000" + }, + { + "name": "black_66", + "value": "#66000000" + }, + { + "name": "black_80", + "value": "#80000000" + }, + { + "name": "black_99", + "value": "#99000000" + }, + { + "name": "black_E6", + "value": "#E6000000" + } + ] +} \ No newline at end of file diff --git a/Privacy/ContactDataError/src/main/resources/base/element/float.json b/ComponentReuse/positive/src/main/resources/base/element/float.json similarity index 100% rename from Privacy/ContactDataError/src/main/resources/base/element/float.json rename to ComponentReuse/positive/src/main/resources/base/element/float.json diff --git a/ComponentReuse/positive/src/main/resources/base/element/string.json b/ComponentReuse/positive/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..9457c23ad27ff744455cace91589c49dd8ad0d55 --- /dev/null +++ b/ComponentReuse/positive/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "PositiveAbility_desc", + "value": "description" + }, + { + "name": "PositiveAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/Privacy/ContactData/src/main/resources/base/media/background.png b/ComponentReuse/positive/src/main/resources/base/media/background.png similarity index 100% rename from Privacy/ContactData/src/main/resources/base/media/background.png rename to ComponentReuse/positive/src/main/resources/base/media/background.png diff --git a/ComponentReuse/positive/src/main/resources/base/media/chevron_right.png b/ComponentReuse/positive/src/main/resources/base/media/chevron_right.png new file mode 100644 index 0000000000000000000000000000000000000000..4844d0b25d462fb2168b96efd9b6ae3c641e8bf9 Binary files /dev/null and b/ComponentReuse/positive/src/main/resources/base/media/chevron_right.png differ diff --git a/Privacy/ContactDataError/src/main/resources/base/media/foreground.png b/ComponentReuse/positive/src/main/resources/base/media/foreground.png similarity index 100% rename from Privacy/ContactDataError/src/main/resources/base/media/foreground.png rename to ComponentReuse/positive/src/main/resources/base/media/foreground.png diff --git a/ComponentReuse/positive/src/main/resources/base/media/img0.png b/ComponentReuse/positive/src/main/resources/base/media/img0.png new file mode 100644 index 0000000000000000000000000000000000000000..1d967400f83bb0f5e2df4581415ed2e4cbb564d4 Binary files /dev/null and b/ComponentReuse/positive/src/main/resources/base/media/img0.png differ diff --git a/ComponentReuse/positive/src/main/resources/base/media/img1.png b/ComponentReuse/positive/src/main/resources/base/media/img1.png new file mode 100644 index 0000000000000000000000000000000000000000..b254fba00dcee070e90baf945e920a8f2f0646c6 Binary files /dev/null and b/ComponentReuse/positive/src/main/resources/base/media/img1.png differ diff --git a/ComponentReuse/positive/src/main/resources/base/media/img2.jpg b/ComponentReuse/positive/src/main/resources/base/media/img2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4d36c1f9f8435424323ff12df2b0992bb09f8af5 Binary files /dev/null and b/ComponentReuse/positive/src/main/resources/base/media/img2.jpg differ diff --git a/ComponentReuse/positive/src/main/resources/base/media/img3.png b/ComponentReuse/positive/src/main/resources/base/media/img3.png new file mode 100644 index 0000000000000000000000000000000000000000..89214745c537495119e0e78c49e602f1c4933baa Binary files /dev/null and b/ComponentReuse/positive/src/main/resources/base/media/img3.png differ diff --git a/ComponentReuse/positive/src/main/resources/base/media/img4.png b/ComponentReuse/positive/src/main/resources/base/media/img4.png new file mode 100644 index 0000000000000000000000000000000000000000..54e59fc403d92d11911498f7d3c7d39d6e437cf5 Binary files /dev/null and b/ComponentReuse/positive/src/main/resources/base/media/img4.png differ diff --git a/ComponentReuse/positive/src/main/resources/base/media/img5.png b/ComponentReuse/positive/src/main/resources/base/media/img5.png new file mode 100644 index 0000000000000000000000000000000000000000..a38a0eaab71c8c6ba4b94bff09b7d86e96510043 Binary files /dev/null and b/ComponentReuse/positive/src/main/resources/base/media/img5.png differ diff --git a/ComponentReuse/positive/src/main/resources/base/media/img6.png b/ComponentReuse/positive/src/main/resources/base/media/img6.png new file mode 100644 index 0000000000000000000000000000000000000000..c1175890f2f43f92082e40299d7bda81094e9c06 Binary files /dev/null and b/ComponentReuse/positive/src/main/resources/base/media/img6.png differ diff --git a/ComponentReuse/positive/src/main/resources/base/media/img7.png b/ComponentReuse/positive/src/main/resources/base/media/img7.png new file mode 100644 index 0000000000000000000000000000000000000000..cd29997cfc3b0f30e1d393d49961da58d691ab2f Binary files /dev/null and b/ComponentReuse/positive/src/main/resources/base/media/img7.png differ diff --git a/ComponentReuse/positive/src/main/resources/base/media/img8.png b/ComponentReuse/positive/src/main/resources/base/media/img8.png new file mode 100644 index 0000000000000000000000000000000000000000..1cff5e45d286fb3bc058d326fc9b31caf690ac63 Binary files /dev/null and b/ComponentReuse/positive/src/main/resources/base/media/img8.png differ diff --git a/MultiVideoApplication/AppScope/resources/base/media/layered_image.json b/ComponentReuse/positive/src/main/resources/base/media/layered_image.json similarity index 100% rename from MultiVideoApplication/AppScope/resources/base/media/layered_image.json rename to ComponentReuse/positive/src/main/resources/base/media/layered_image.json diff --git a/ComponentReuse/positive/src/main/resources/base/media/play_fill.svg b/ComponentReuse/positive/src/main/resources/base/media/play_fill.svg new file mode 100644 index 0000000000000000000000000000000000000000..d1750a9cc4dc77103c03b7e11674b4e0b2b278d9 --- /dev/null +++ b/ComponentReuse/positive/src/main/resources/base/media/play_fill.svg @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/MultiFinancialManagement/product/phone/src/main/resources/base/media/startIcon.png b/ComponentReuse/positive/src/main/resources/base/media/startIcon.png similarity index 100% rename from MultiFinancialManagement/product/phone/src/main/resources/base/media/startIcon.png rename to ComponentReuse/positive/src/main/resources/base/media/startIcon.png diff --git a/MultiDeviceCommunication/features/home/src/main/resources/base/profile/main_pages.json b/ComponentReuse/positive/src/main/resources/base/profile/main_pages.json similarity index 100% rename from MultiDeviceCommunication/features/home/src/main/resources/base/profile/main_pages.json rename to ComponentReuse/positive/src/main/resources/base/profile/main_pages.json diff --git a/ComponentReuse/positive/src/main/resources/base/profile/route_map.json b/ComponentReuse/positive/src/main/resources/base/profile/route_map.json new file mode 100644 index 0000000000000000000000000000000000000000..15c6ca4fc92f90d395073d9f1e7d274f81077150 --- /dev/null +++ b/ComponentReuse/positive/src/main/resources/base/profile/route_map.json @@ -0,0 +1,39 @@ +{ + "routerMap": [ + { + "name": "NoReuseScene1Positive", + "pageSourceFile": "src/main/ets/pages/NoReuseScene1Positive.ets", + "buildFunction": "buildNoReuseScene1Positive" + }, + { + "name": "NoReuseScene2_StructureOnePositive", + "pageSourceFile": "src/main/ets/pages/NoReuseScene2_StructureOnePositive.ets", + "buildFunction": "buildNoReuseScene2_StructureOnePositive" + }, + { + "name": "NoReuseScene2_StructureTwoPositive", + "pageSourceFile": "src/main/ets/pages/NoReuseScene2_StructureTwoPositive.ets", + "buildFunction": "buildNoReuseScene2_StructureTwoPositive" + }, + { + "name": "NoReuseScene3Positive", + "pageSourceFile": "src/main/ets/pages/NoReuseScene3Positive.ets", + "buildFunction": "buildNoReuseScene3Positive" + }, + { + "name": "ImproperReuseOfComponentsScene1Positive", + "pageSourceFile": "src/main/ets/pages/ImproperReuseOfComponentsScene1Positive.ets", + "buildFunction": "buildImproperReuseOfComponentsScene1Positive" + }, + { + "name": "ImproperReuseOfComponentsScene2Positive", + "pageSourceFile": "src/main/ets/pages/ImproperReuseOfComponentsScene2Positive.ets", + "buildFunction": "buildImproperReuseOfComponentsScene2Positive" + }, + { + "name": "ImproperReuseOfComponentsScene3Positive", + "pageSourceFile": "src/main/ets/pages/ImproperReuseOfComponentsScene3Positive.ets", + "buildFunction": "buildImproperReuseOfComponentsScene3Positive" + } + ] +} \ No newline at end of file diff --git a/CppCrash/README.md b/CppCrash/README.md new file mode 100644 index 0000000000000000000000000000000000000000..db47470722e62a89946960bb8e3844f16a4a034a --- /dev/null +++ b/CppCrash/README.md @@ -0,0 +1,73 @@ +# Native崩溃(Cpp Crash)样例代码工程 + +### 介绍 + +本示例为Native崩溃(Cpp Crash)样例代码工程,包含最佳实践文档中涉及的分析方法、优化建议、问题案例等内容的局部样例代码。工程本身不具备实际功能,开发者请直接阅读具体源码结合文档来理解Native崩溃(Cpp Crash)类问题的产生原因,规避方法等。 + + +### 效果预览 + +不涉及 + +### 工程目录 +``` +├──entry/src/main/ +│ └──cpp +│ │ ├── CMakeLists.txt +│ │ ├── CppCrashAdvise1.cpp // C++ 样例代码 +│ │ ├── CppCrashAdvise2.cpp // C++ 样例代码 +│ │ ├── CppCrashAdvise3.cpp // C++ 样例代码 +│ │ ├── CppCrashAdvise4.cpp // C++ 样例代码 +│ │ ├── CppCrashCaseAnalyse1.cpp // C++ 样例代码 +│ │ ├── CppCrashCaseAnalyse2.cpp // C++ 样例代码 +│ │ ├── CppCrashCaseAnalyse3.cpp // C++ 样例代码 +│ │ ├── CppCrashCaseAnalyse4.cpp // C++ 样例代码 +│ │ ├── CppCrashCaseAnalyse5.cpp // C++ 样例代码 +│ │ ├── CppCrashCaseAnalyse6.cpp // C++ 样例代码 +│ │ ├── CppCrashCaseAnalyse7.cpp // C++ 样例代码 +│ │ ├── CppCrashCaseAnalysis8.cpp // C++ 样例代码 +│ │ ├── CppCrashQuestionCheck1.cpp // C++ 样例代码 +│ │ ├── CppCrashQuestionCheck2.cpp // C++ 样例代码 +│ │ └── napi_init.cpp // C++ 样例代码 +│ └──ets +│ ├──pages +│ │ └──Index.ets // 首页 +│ ├──entryability +│ │ └──EntryAbility.ets // Ability的生命周期回调内容 +│ └──entrybackupability +│ └──EntryBackupAbility.ets // 应用数据备份恢复类 +└──entry/src/main/resources // 应用资源目录 +``` + +### 具体实现 + +不涉及。 + +### 相关权限 + +不涉及。 + +### 依赖 + +不涉及。 + +### 约束与限制 + +1. 本示例仅支持标准系统上运行,支持设备:华为手机、华为PC/2in1设备、华为平板。 + +2. HarmonyOS系统:HarmonyOS NEXT 5.0.5 Release及以上。 + +3. DevEco Studio版本:DevEco Studio 5.0.5 Release及以上。 + +4. HarmonyOS SDK版本:HarmonyOS NEXT 5.0.5 Release SDK及以上。 + +### 下载 + +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set CppCrash +git checkout +``` \ No newline at end of file diff --git a/CppCrash/build-profile.json5 b/CppCrash/build-profile.json5 index adff6a0e3095f2c79f2fede08f299e7658c3dbca..9e87e7e6f19020fe21192844709f192cec80fd44 100644 --- a/CppCrash/build-profile.json5 +++ b/CppCrash/build-profile.json5 @@ -6,7 +6,7 @@ "name": "default", "signingConfig": "default", "targetSdkVersion": "5.0.5(17)", - "compatibleSdkVersion": "5.0.0(12)", + "compatibleSdkVersion": "5.0.5(17)", "runtimeOS": "HarmonyOS", "buildOption": { "strictMode": { diff --git a/CppCrash/entry/src/main/cpp/CMakeLists.txt b/CppCrash/entry/src/main/cpp/CMakeLists.txt index 1acd3ec1c568e86cb70911ecc57edfbb21bcd1ea..a5c06660812f7ed74934a6a93282d445f974a451 100644 --- a/CppCrash/entry/src/main/cpp/CMakeLists.txt +++ b/CppCrash/entry/src/main/cpp/CMakeLists.txt @@ -2,6 +2,9 @@ cmake_minimum_required(VERSION 3.5.0) project(CppCrash) +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}) if(DEFINED PACKAGE_FIND_FILE) @@ -11,5 +14,10 @@ endif() include_directories(${NATIVERENDER_ROOT_PATH} ${NATIVERENDER_ROOT_PATH}/include) -add_library(entry SHARED napi_init.cpp) +#add_library(entry SHARED napi_init.cpp CppCrashAdvise1.cpp CppCrashCaseAnalyse1.cpp CppCrashCaseAnalyse2.cpp +# CppCrashCaseAnalyse3.cpp CppCrashCaseAnalyse4.cpp CppCrashCaseAnalyse5.cpp CppCrashCaseAnalyse6.cpp +# CppCrashCaseAnalyse7.cpp CppCrashCaseAnalysis8.cpp CppCrashQuestionCheck1.cpp CppCrashQuestionCheck2.cpp) +add_library(entry SHARED napi_init.cpp CppCrashAdvise1.cpp CppCrashAdvise2.cpp CppCrashAdvise3.cpp CppCrashAdvise4.cpp + CppCrashQuestionCheck1.cpp CppCrashQuestionCheck2.cpp CppCrashCaseAnalyse5.cpp CppCrashCaseAnalyse6.cpp + CppCrashCaseAnalyse7.cpp CppCrashCaseAnalysis8.cpp) target_link_libraries(entry PUBLIC libace_napi.z.so) \ No newline at end of file diff --git a/CppCrash/entry/src/main/cpp/CppCrashAdvise1.cpp b/CppCrash/entry/src/main/cpp/CppCrashAdvise1.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c8ff6d68c40f0f5626466352a55d8fcb0dd3a705 --- /dev/null +++ b/CppCrash/entry/src/main/cpp/CppCrashAdvise1.cpp @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ +/** + * 最佳实践:CppCrash类问题优化建议 + */ + +#include +#include +#include +#include +#include + +struct Item { + int id; +}; + +struct Object { + int id; +}; + +std::map appRunningRecordMap_; +std::mutex mutex_; + +// [Start cppcrash_advise_1_negative] +void EraseMapItem1(int key) +{ + appRunningRecordMap_.erase(key); +} +// [End cppcrash_advise_1_negative] + +// [Start cppcrash_advise_1_positive] +void EraseMapItem2(int key) +{ + // 加锁 + std::lock_guard lock(mutex_); + appRunningRecordMap_.erase(key); +} + +void FindMapItem(int key) +{ + // 加锁 + std::lock_guard lock(mutex_); + appRunningRecordMap_.find(key); +} +// [End cppcrash_advise_1_positive] \ No newline at end of file diff --git a/CppCrash/entry/src/main/cpp/CppCrashAdvise2.cpp b/CppCrash/entry/src/main/cpp/CppCrashAdvise2.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9ee059cc448c3c763c4e36430679044cf60a2d9a --- /dev/null +++ b/CppCrash/entry/src/main/cpp/CppCrashAdvise2.cpp @@ -0,0 +1,224 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + /** + * 最佳实践:CppCrash类问题优化建议 + */ + +#include +#include +#include +#include +#include + +struct Object { + int id; + void method() {} +}; + +std::mutex mutexEx_; + +// [Start cppcrash_advise_2_negative] +std::list> g_list; + +void MainFunc() +{ + auto xxx = std::make_shared(); + g_list.push_back(xxx); +} + +// 线程1 +void Thread1Func() +{ + for (auto &ptr : g_list) { + ptr->method(); + } +} + +// 线程2 +void Thread2Func() +{ + g_list.clear(); // 此处清空list,可能会造成线程1使用g_list时发生崩溃 +} +// [End cppcrash_advise_2_negative] + +// [Start cppcrash_advise_2_positive] +// 线程1 +void Thread1FuncEx() +{ + std::lock_guard lock(mutexEx_); + for (auto &ptr : g_list) { + ptr->method(); + } +} + +// 线程2 +void Thread2FuncEx() +{ + std::lock_guard lock(mutexEx_); + g_list.clear(); +} +// [End cppcrash_advise_2_positive] + +class EventHandler { +public: + template + void PostAsyncTask(Func&& func) { + // 实际异步投递实现 + func(); + } +}; + +class Checker { +public: + void Detection(std::string& url); + void Detection2(std::string& url); + static bool DoCheck(const std::string& url); + +private: + EventHandler handler; +}; + +// [Start cppcrash_advise_3_negative] +void Checker::Detection(std::string& url) +{ + handler.PostAsyncTask( + [this, &url]() { + if (!Checker::DoCheck(url)) { + // ... + } + } + ); + // 这里url变量即将析构 +} + +bool Checker::DoCheck(const std::string& url) +{ + // ... + return true; +} +// [End cppcrash_advise_3_negative] + +// [Start cppcrash_advise_3_positive] +void Checker::Detection2(std::string& url) +{ + handler.PostAsyncTask( + [this, url]() { + if (!Checker::DoCheck(url)) { + // ... + } + } + ); + // 这里url变量即将析构,但lambda已经有自己的拷贝 +} +// [End cppcrash_advise_3_positive] + +void Advise4Negative() +{ +// [Start cppcrash_advise_4_negative] + std::shared_ptr smartPointer = nullptr; + smartPointer->method(); +// [End cppcrash_advise_4_negative] +} + +void Advise4Positive() +{ +// [Start cppcrash_advise_4_positive] + std::shared_ptr smartPointer = nullptr; + if (smartPointer != nullptr) { + smartPointer->method(); + } +// [End cppcrash_advise_4_positive] +} + +void Advise5Negative() +{ +// [Start cppcrash_advise_5_negative] + Object* xxx = new Object(); + std::shared_ptr xxx1(xxx); // xxx1引用计数减为0时析构一次xxx + std::shared_ptr xxx2(xxx); // xxx2引用计数减为0时析构一次xxx +// [End cppcrash_advise_5_negative] +} + +void Advise5Positive() +{ +// [Start cppcrash_advise_5_positive] + std::shared_ptr xxx = std::make_shared(); +// [End cppcrash_advise_5_positive] +} + +void Advise6Negative() +{ +// [Start cppcrash_advise_6_negative] + auto smartPointer = std::make_shared(); // smartPointer引用计数减为0时析构 + auto pointer = smartPointer.get(); + pointer->method(); // 当smartPinter析构后继续使用pointer可能发生crash +// [End cppcrash_advise_6_negative] +} + +void Advise6Positive() +{ +// [Start cppcrash_advise_6_positive] + auto smartPointer = std::make_shared(); + smartPointer->method(); +// [End cppcrash_advise_6_positive] +} + +void Advise7Negative() +{ +// [Start cppcrash_advise_7_negative] + Object* pointer = new Object(); + std::shared_ptr smartPointer(pointer); // smartPointer引用计数减为0时析构 + pointer->method(); // 当smartPointer析构后继续使用pointer可能发生crash + delete pointer; // 主动释放裸指针发生crash +// [End cppcrash_advise_7_negative] +} + +void Advise7Positive() +{ +// [Start cppcrash_advise_7_positive] + auto smartPointer = std::make_shared(); + smartPointer->method(); +// [End cppcrash_advise_7_positive] +} + +// [Start cppcrash_advise_8_negative] +static void SignalHandler(int signo, siginfo_t* si, void* context) // 信号处理函数 +{ + char *c = (char*)malloc(10); // 禁止使用malloc,malloc是非异步安全函数 +} +// [End cppcrash_advise_8_negative] + +// [Start cppcrash_advise_8_positive] +static void SignalHandlerEx(int signo, siginfo_t* si, void* context) // 信号处理函数 +{ + char c[10] = {0}; +} +// [End cppcrash_advise_8_positive] + +// [Start cppcrash_advise_10_negative] +std::string& GetString() +{ + std::string result = "this is string"; + return result; // 禁止返回局部变量result的引用 +} +// [End cppcrash_advise_10_negative] + +// [Start cppcrash_advise_10_positive] +std::string GetStringEx() +{ + std::string result = "this is string"; + return result; // 返回局部变量的值 +} +// [End cppcrash_advise_10_positive] \ No newline at end of file diff --git a/CppCrash/entry/src/main/cpp/CppCrashAdvise3.cpp b/CppCrash/entry/src/main/cpp/CppCrashAdvise3.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0103e2c5d984eafa68bb75969695b16fb19dbfb4 --- /dev/null +++ b/CppCrash/entry/src/main/cpp/CppCrashAdvise3.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ +/** + * 最佳实践:CppCrash类问题优化建议 + */ + +#include +#include + +// [Start cppcrash_advise_9_positive] +class Object2 : public std::enable_shared_from_this { +public: + void Run(); + void GetInfo() {} + // ... + +private: + std::shared_ptr startThread_; + // ... +}; + +void Object2::Run() +{ + std::weak_ptr weakPtr = shared_from_this(); // 调用shared_from_this捕获this(c++17开始可使用waek_form_this) + startThread_ = std::shared_ptr(new std::thread([weakPtr] { // weakPtr传递给其他线程 + auto ptr = weakPtr.lock(); + if (ptr == nullptr) { + return; + } + ptr->GetInfo(); + // ... + })); + // ... +} + +void MainFuncEx() +{ + auto object = std::make_shared(); // 必须使用智能指针初始化Object对象 + object->Run(); +} +// [End cppcrash_advise_9_positive] \ No newline at end of file diff --git a/CppCrash/entry/src/main/cpp/CppCrashAdvise4.cpp b/CppCrash/entry/src/main/cpp/CppCrashAdvise4.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b2f36b0fee9b6d6c55062a54a62e9ba23e153f92 --- /dev/null +++ b/CppCrash/entry/src/main/cpp/CppCrashAdvise4.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ +/** + * 最佳实践:CppCrash类问题优化建议 + */ + +#include +#include + +class Object1 { +public: + void Run(); + void GetInfo() {} + +private: + std::shared_ptr startThread_; +}; + +// [Start cppcrash_advise_9_negative] +void Object1::Run() +{ + startThread_ = std::shared_ptr(new std::thread([this] { // 将this指针传递给其他线程 + if (this == nullptr) { + return; + } + this->GetInfo(); + // ... + })); + // ... +} +// [End cppcrash_advise_9_negative] \ No newline at end of file diff --git a/CppCrash/entry/src/main/cpp/CppCrashCaseAnalyse1.cpp b/CppCrash/entry/src/main/cpp/CppCrashCaseAnalyse1.cpp index c1f95605b420cb22e313bc257263f1f952b3484c..ef8210d5d23351718515c1119b50b1aca9b3bf21 100644 --- a/CppCrash/entry/src/main/cpp/CppCrashCaseAnalyse1.cpp +++ b/CppCrash/entry/src/main/cpp/CppCrashCaseAnalyse1.cpp @@ -1,3 +1,17 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ // // Created on 2025/5/20. // diff --git a/CppCrash/entry/src/main/cpp/CppCrashCaseAnalyse2.cpp b/CppCrash/entry/src/main/cpp/CppCrashCaseAnalyse2.cpp index 5bd9cd2fcbdfb35fc1e78aa26ff6fa517c4e393a..23597d368f26c1faf45a6e77045b7898cf0ec378 100644 --- a/CppCrash/entry/src/main/cpp/CppCrashCaseAnalyse2.cpp +++ b/CppCrash/entry/src/main/cpp/CppCrashCaseAnalyse2.cpp @@ -1,3 +1,17 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ // // Created on 2025/5/20. // diff --git a/CppCrash/entry/src/main/cpp/CppCrashCaseAnalyse3.cpp b/CppCrash/entry/src/main/cpp/CppCrashCaseAnalyse3.cpp index ef27751c70c71c84e953426a2970f0a607e0cd58..07542259f083a6e9e40e8c299bc1a4886c6dd2dd 100644 --- a/CppCrash/entry/src/main/cpp/CppCrashCaseAnalyse3.cpp +++ b/CppCrash/entry/src/main/cpp/CppCrashCaseAnalyse3.cpp @@ -1,3 +1,17 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ // // Created on 2025/5/20. // diff --git a/CppCrash/entry/src/main/cpp/CppCrashCaseAnalyse4.cpp b/CppCrash/entry/src/main/cpp/CppCrashCaseAnalyse4.cpp index 6470aca3eb6fe4c54bb53e0156c05175a576e0fb..051d22645dd1f3630c332306c1567d2b031c91bd 100644 --- a/CppCrash/entry/src/main/cpp/CppCrashCaseAnalyse4.cpp +++ b/CppCrash/entry/src/main/cpp/CppCrashCaseAnalyse4.cpp @@ -1,3 +1,17 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ // // Created on 2025/5/20. // diff --git a/CppCrash/entry/src/main/cpp/CppCrashCaseAnalyse5.cpp b/CppCrash/entry/src/main/cpp/CppCrashCaseAnalyse5.cpp index 1b98e3e434f21736d8f820423bb220737d023c15..b08255b45a434d513474b4c0c9caddaa3547c8f7 100644 --- a/CppCrash/entry/src/main/cpp/CppCrashCaseAnalyse5.cpp +++ b/CppCrash/entry/src/main/cpp/CppCrashCaseAnalyse5.cpp @@ -1,3 +1,17 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ // // Created on 2025/5/20. // diff --git a/CppCrash/entry/src/main/cpp/CppCrashCaseAnalyse6.cpp b/CppCrash/entry/src/main/cpp/CppCrashCaseAnalyse6.cpp index 8c86cf54a774ae8d5b03c0556c7181024e4d3f50..497b2548e68a8856d10e5510d18efe3f7f5bebad 100644 --- a/CppCrash/entry/src/main/cpp/CppCrashCaseAnalyse6.cpp +++ b/CppCrash/entry/src/main/cpp/CppCrashCaseAnalyse6.cpp @@ -1,3 +1,17 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ // // Created on 2025/5/20. // diff --git a/CppCrash/entry/src/main/cpp/CppCrashCaseAnalyse7.cpp b/CppCrash/entry/src/main/cpp/CppCrashCaseAnalyse7.cpp index 083ef52030d321c36ff5a0db238bd3749551d20d..bea460a3fe27c0a3278435a87cace9050b5307ef 100644 --- a/CppCrash/entry/src/main/cpp/CppCrashCaseAnalyse7.cpp +++ b/CppCrash/entry/src/main/cpp/CppCrashCaseAnalyse7.cpp @@ -1,3 +1,17 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ // // Created on 2025/7/17. // @@ -6,7 +20,14 @@ * 最佳实践:CppCrash类问题案例 */ -// [Start TriggerCrash7] +#include +#include + +struct SupportPac { + static void SupportPacPrint() {}; +}; + +// [Start trigger_crash_7] char g_ori[12] = "hello!"; int main() @@ -15,10 +36,12 @@ int main() void *addr = (void*)(&SupportPac::SupportPacPrint); char a[8] = {}; memcpy(a, &g_ori, sizeof(g_ori)); // 伪造内存溢出攻击,篡改addr内容 +#ifdef __ARM_FEATURE_PAUTH __asm__ __volatile__("autia %0, %1\n\t" "blr %0\n\t" : "+r"(addr) : "r"(context):); - print("%s\n", a); +#endif + std::cout << a; return 0; } -// [End TriggerCrash7] \ No newline at end of file +// [End trigger_crash_7] \ No newline at end of file diff --git a/CppCrash/entry/src/main/cpp/CppCrashCaseAnalysis8.cpp b/CppCrash/entry/src/main/cpp/CppCrashCaseAnalysis8.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7d0fd92f0a505e0b3e7e3dfccc47c8154e227962 --- /dev/null +++ b/CppCrash/entry/src/main/cpp/CppCrashCaseAnalysis8.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ +/** + * 最佳实践:CppCrash类问题案例 + */ +#include +#include + +char cache[128]; +uint32_t appendOffset = 128; + +// [Start trigger_crash_8] +static int xxxFunc(const uint8_t *buf, uint32_t bufSize) +{ + // ... + uint32_t srcOffset = appendOffset - bufSize; + auto ret = memcpy(cache + srcOffset, buf, bufSize); + if (ret == nullptr) { + return -1; + } + // ... +} +// [End trigger_crash_8] \ No newline at end of file diff --git a/CppCrash/entry/src/main/cpp/CppCrashQuestionCheck1.cpp b/CppCrash/entry/src/main/cpp/CppCrashQuestionCheck1.cpp index 576a776ce752591e6c62287bd3cb93f4b0568619..4fda3d978ae3bfad0b04707a5643994433e46de0 100644 --- a/CppCrash/entry/src/main/cpp/CppCrashQuestionCheck1.cpp +++ b/CppCrash/entry/src/main/cpp/CppCrashQuestionCheck1.cpp @@ -1,3 +1,17 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ // // Created on 2025/5/20. // @@ -17,7 +31,7 @@ int &getStackReference() { } -int main() { +int Run1() { int &ref = getStackReference(); // Obtain the reference of x // x is released after the getStackReference function returns // ref is now a dangling reference. Continuing to access it will result in undefined behavior diff --git a/CppCrash/entry/src/main/cpp/CppCrashQuestionCheck2.cpp b/CppCrash/entry/src/main/cpp/CppCrashQuestionCheck2.cpp index 719e6ee8fb8a03a6dd2e58a059481b098b267849..87750a9dc4578b80e6161233e04ba87610c57667 100644 --- a/CppCrash/entry/src/main/cpp/CppCrashQuestionCheck2.cpp +++ b/CppCrash/entry/src/main/cpp/CppCrashQuestionCheck2.cpp @@ -1,3 +1,17 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ // // Created on 2025/5/20. // @@ -26,7 +40,7 @@ public: }; -int main() { +int Run2() { RecursiveClass obj; return 0; } diff --git a/CppCrash/entry/src/main/cpp/napi_init.cpp b/CppCrash/entry/src/main/cpp/napi_init.cpp index 85330e3e84d1f6c8a82e544fb315483ca597d23d..cd551ed9666be7454a1e63ae0bed3a5aa751a41e 100644 --- a/CppCrash/entry/src/main/cpp/napi_init.cpp +++ b/CppCrash/entry/src/main/cpp/napi_init.cpp @@ -1,5 +1,21 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + #include "napi/native_api.h" +// [Start cppcrash_case_4] static napi_value Add(napi_env env, napi_callback_info info) { size_t argc = 2; @@ -23,8 +39,8 @@ static napi_value Add(napi_env env, napi_callback_info info) napi_create_double(env, value0 + value1, &sum); return sum; - } +// [End cppcrash_case_4] EXTERN_C_START static napi_value Init(napi_env env, napi_value exports) diff --git a/CppCrash/entry/src/main/ets/entryability/EntryAbility.ets b/CppCrash/entry/src/main/ets/entryability/EntryAbility.ets index 508880af8c33aa838016d1cd4b2c68be2f447540..a7e8ad07979614ccfe122b70e0ccd7306acaef68 100644 --- a/CppCrash/entry/src/main/ets/entryability/EntryAbility.ets +++ b/CppCrash/entry/src/main/ets/entryability/EntryAbility.ets @@ -6,7 +6,11 @@ const DOMAIN = 0x0000; export default class EntryAbility extends UIAbility { onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { - this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + try { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + } catch (err) { + hilog.info(DOMAIN, 'testTag', '%{public}s', 'setColorMode fail'); + } hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); } diff --git a/CrossPlatformCompatibility/AppScope/app.json5 b/CrossPlatformCompatibility/AppScope/app.json5 deleted file mode 100644 index 2f107af747986a2e6650b2b6c31b0239f291462c..0000000000000000000000000000000000000000 --- a/CrossPlatformCompatibility/AppScope/app.json5 +++ /dev/null @@ -1,10 +0,0 @@ -{ - "app": { - "bundleName": "com.hauwei.cryptocollection", - "vendor": "example", - "versionCode": 1000000, - "versionName": "1.0.0", - "icon": "$media:app_icon", - "label": "$string:app_name" - } -} diff --git a/CrossPlatformCompatibility/AppScope/resources/base/element/string.json b/CrossPlatformCompatibility/AppScope/resources/base/element/string.json deleted file mode 100644 index 110c35d1eb145367afbd5df4272dff9ddf7791cc..0000000000000000000000000000000000000000 --- a/CrossPlatformCompatibility/AppScope/resources/base/element/string.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "string": [ - { - "name": "app_name", - "value": "cryptoDemo" - } - ] -} diff --git a/CrossPlatformCompatibility/README.en.md b/CrossPlatformCompatibility/README.en.md deleted file mode 100644 index 0dc76483f0ffd3f08a3c39d2da8100ee40661c74..0000000000000000000000000000000000000000 --- a/CrossPlatformCompatibility/README.en.md +++ /dev/null @@ -1,98 +0,0 @@ -# Crypto Collection (ArkTS) - -### Overview - -This sample shows how to use the APIs provided by **cryptoFramework** to encrypt/decrypt text, generate and verify a -digital signature, and generate a message digest (MD) and message authentication code (MAC). Algorithms such as AES, -3DES, SM4, RSA, SM2, ECDSA, SHA-256, MD5, SM3, and HMAC are used. - -### Preview - -| Home Page | Encryption/Decryption Page | Encryption/Decryption Details Page | Signing & Signature Verification Page | Signing & Signature Verification Details Page | -|----------------------------------------------|----------------------------------------------------|---------------------------------------------------|-------------------------------------------------|------------------------------------------------------| -| ![image](screenshots/devices/index.en.png) | ![image](screenshots/devices/crypto.en.png) | ![image](screenshots/devices/cryptoDetail.en.png) | ![image](screenshots/devices/signature.en.png) | ![image](screenshots/devices/signatureDetail.en.png) | -|
MD Page
|
MD Details Page
|
MAC Page
|
MAC Details Page
| | -| ![image](screenshots/devices/summary.en.png) | ![image](screenshots/devices/summaryDetail.en.png) | ![image](screenshots/devices/code.en.png) | ![image](screenshots/devices/codeDetail.en.png) | | - -### How to Use - -1. Tap the button on the home page to go to the functional page, and tap the list items on the function page to go to - the related details page. - -2. Encrypt and decrypte data. - - On the encryption/decryption details page, enter the string to be encrypted and tap the **Encrypt with *algorithm*** - button to encrypt the string. A Base64-encoded string is generated. - - Tap the **Decrypt with *algorithm*** button to decrypt the Base64-encoded string. - -3. Generate and verify a digital signature. - - On the signing & signature verification details page, enter the data to be signed and tap the **Sign** button to - generate a signature. - - Tap the **Verify** button to verify the signature. - -4. Generate a MD. - - On the MD details page, enter the raw data, and tap the **MD with *algorithm*** button. The MD generated is displayed - in the **MD** text box. - -5. Generate a MAC. - - On the MAC details page, enter the raw data and tap **MAC with *algorithm*** to generate a MAC. - -### Project Directory - -``` - -├──entry/src/main/ets/ -│ ├──constants -│ │ └──CommonConstants.ets // Common constants -│ ├──entryability -│ │ └──EntryAbility.ets // Entry ability -│ ├──pages -│ │ ├──EncryptionAndDecryption.ets // Encryption and decryption page -│ │ ├──Index.ets // Home page entry -│ │ ├──MessageAuthenticationCode.ets // MAC page -│ │ ├──MessageSummary.ets // MD page -│ │ └──SignatureVerification.ets // Signing and signature verification page -│ ├──utils -│ │ ├──CryptoUtil.ets // Encryption and decryption utility -│ │ └──Logger.ets // Logging utility -│ │ └──SignatureUtil.ets // Signing and signature verification utility -│ ├──view -│ │ ├──AuthCodeDetail.ets // MAC details page -│ │ ├──CryptoDetail.ets // Encryption and decryption details page -│ │ ├──SignatureDetail.ets // Signing and signature verification details page -│ │ └──SummaryDetail.ets // MD details page -│ └──viewmodel -│ ├──AuthCodeItem.ets // Entity for MAC items -│ ├──AuthCodeViewModel.ets // Data and logic for obtaining the MAC list -│ ├──CryptoItem.ets // Entity for encryption/decryption items -│ ├──CryptoViewModel.ets // Data and logic for obtaining the encryption/decryption list -│ ├──SignatureItem.ets // Entity for signing & signature verification items -│ ├──SignatureViewModel.ets // Data and logic for obtaining the signing & signature verification list -│ ├──SummaryItem.ets // Entity for MD items -│ └──SummaryViewModel.ets // Data and logic for obtaining the MD list -└──entry/src/main/resources // Static resources of the app - -``` - -### Required Permissions - -N/A - -### Dependencies - -N/A - -### Constraints - -1. The sample app is supported only on Huawei phones running the standard system. - -2. The HarmonyOS version must be HarmonyOS NEXT Developer Beta1 or later. - -3. The DevEco Studio version must be DevEco Studio NEXT Developer Beta1 or later. - -4. The HarmonyOS SDK version must be HarmonyOS NEXT Developer Beta1 or later. diff --git a/CrossPlatformCompatibility/README.md b/CrossPlatformCompatibility/README.md deleted file mode 100644 index d551985d7097150ca1a30c29f075c4ccf278c53b..0000000000000000000000000000000000000000 --- a/CrossPlatformCompatibility/README.md +++ /dev/null @@ -1,80 +0,0 @@ -# 加解密算法合集 - -### 介绍 - -本示例使用cryptoFramework接口的相关方法实现字符串加解密、签名验签、消息摘要、消息认证码等功能,使用了AES、3DES、SM4、RSA、SM2、ECDSA、SHA256、MD5、SM3、HMAC等算法。 - -### 效果预览 - -| 首页 | 加解密页面 | 加解密详情页 | 签名验签页面 | 签名验签详情页 | -|-------------------------------------------|-------------------------------------------------|------------------------------------------------|----------------------------------------------|-----------------------------------------------------| -| ![image](screenshots/devices/index.png) | ![image](screenshots/devices/crypto.png) | ![image](screenshots/devices/cryptoDetail.png) | ![image](screenshots/devices/signature.png) | ![image](screenshots/devices/signatureDetail.png) | -|
消息摘要页面
|
消息摘要详情页
|
消息认证码页面
|
消息认证码详情页
|
SM2密钥格式转换
| -| ![image](screenshots/devices/summary.png) | ![image](screenshots/devices/summaryDetail.png) | ![image](screenshots/devices/code.png) | ![image](screenshots/devices/codeDetail.png) | ![image](screenshots/devices/format_conversion.png) | - -### 使用说明 - -1. 点击按钮跳转到各个算法页面,点击列表项跳转到各个详情页面。 -2. 加解密详情页:输入待加密字符串后点击加密即可加密字符串,输出加密后的Base64编码的字符串,点击解密将加密后的Base64编码的字符串解密。 -3. SM2密钥格式转换:展示不可修改的16进制公私钥。输入待加密字符串后点击加密即可加密字符串,输出加密后的ASN.1格式Base64编码的字符串和16进制的裸密文,点击解密将加密后的Base64编码的字符串解密。 -4. 签名验签详情页:输入待签名的数据,点击签名按钮生成签名,再点击验签按钮进行验签。 -5. 消息摘要详情页:输入待摘要的数据,点击按钮计算摘要结果。 -6. 消息认证码详情页:输入需要HMAC的数据,点击按钮计算结果。 - -### 工程目录 - -``` - -├──entry/src/main/ets/ -│ ├──constants -│ │ └──CommonConstants.ets // 常量类 -│ ├──entryability -│ │ └──EntryAbility.ets // 程序入口类 -│ ├──pages -│ │ ├──EncryptionAndDecryption.ets // 加解密算法页面 -│ │ ├──Index.ets // 主页入口 -│ │ ├──MessageAuthenticationCode.ets // 消息认证码页面 -│ │ ├──MessageSummary.ets // 消息摘要页面 -│ │ └──SignatureVerification.ets // 签名验签页面 -│ ├──utils -│ │ ├──CryptoUtil.ets // 加解密算法工具类 -│ │ ├──DataConversion.ets // SM2数据格式转换工具类 -│ │ ├──Logger.ets // 日志类 -│ │ ├──ResourceString.ets // 资源文件转字符串 -│ │ ├──SignatureUtil.ets // 签名验签工具类 -│ │ └──SM2Sequence.ets // SM2Sequence类 -│ ├──view -│ │ ├──AuthCodeDetail.ets // 消息认证码详情页面 -│ │ ├──CryptoDetail.ets // 加解密详情页面 -│ │ ├──SignatureDetail.ets // 签名验签详情页面 -│ │ └──SummaryDetail.ets // 消息摘要详情页面 -│ └──viewmodel -│ ├──AuthCodeItem.ets // 消息认证码列表项实体类 -│ ├──AuthCodeViewModel.ets // 消息认证码列表项获取类 -│ ├──CryptoItem.ets // 加解密列表项实体类 -│ ├──CryptoViewModel.ets // 加解密数据获取类 -│ ├──SignatureItem.ets // 签名验签列表项实体类 -│ ├──SignatureViewModel.ets // 签名验签列表项获取类 -│ ├──SummaryItem.ets // 消息摘要列表项实体类 -│ └──SummaryViewModel.ets // 消息摘要列表项获取类 -└──entry/src/main/resources // 应用静态资源目录 - -``` - -### 相关权限 - -不涉及。 - -### 依赖 - -不涉及。 - -### 约束与限制 - -1.本示例仅支持标准系统上运行,支持设备:华为手机。 - -2.HarmonyOS系统:HarmonyOS 5.0.0 Release及以上。 - -3.DevEco Studio版本:DevEco Studio 5.0.0 Release及以上。 - -4.HarmonyOS SDK版本:HarmonyOS 5.0.0 Release SDK及以上。 diff --git a/CrossPlatformCompatibility/entry/obfuscation-rules.txt b/CrossPlatformCompatibility/entry/obfuscation-rules.txt deleted file mode 100644 index 985b2aeb7658286b17bd26eab8f217c3fe75ea8b..0000000000000000000000000000000000000000 --- a/CrossPlatformCompatibility/entry/obfuscation-rules.txt +++ /dev/null @@ -1,18 +0,0 @@ -# Define project specific obfuscation rules here. -# You can include the obfuscation configuration files in the current module's build-profile.json5. -# -# For more details, see -# https://gitee.com/openharmony/arkcompiler_ets_frontend/blob/master/arkguard/README.md - -# Obfuscation options: -# -disable-obfuscation: disable all obfuscations -# -enable-property-obfuscation: obfuscate the property names -# -enable-toplevel-obfuscation: obfuscate the names in the global scope -# -compact: remove unnecessary blank spaces and all line feeds -# -remove-log: remove all console.* statements -# -print-namecache: print the name cache that contains the mapping from the old names to new names -# -apply-namecache: reuse the given cache file - -# Keep options: -# -keep-property-name: specifies property names that you want to keep -# -keep-global-name: specifies names that you want to keep in the global scope \ No newline at end of file diff --git a/CrossPlatformCompatibility/entry/src/main/ets/constants/CommonConstants.ets b/CrossPlatformCompatibility/entry/src/main/ets/constants/CommonConstants.ets deleted file mode 100644 index c14e8ce6b19b87ab6c3ae7ed8838a2b1b1967951..0000000000000000000000000000000000000000 --- a/CrossPlatformCompatibility/entry/src/main/ets/constants/CommonConstants.ets +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -export default class CommonConstants { - /** - * Hundred percent. - */ - static readonly FULL_PERCENT: string = '100%'; - - /** - * Column space. - */ - static readonly COLUMN_SPACE: number = 12; - - /** - * Text font weight. - */ - static readonly TEXT_FONT_WEIGHT: number = 700; - - /** - * Font weight. - */ - static readonly FONT_WIGHT_500: number = 500; - - /** - * Font weight. - */ - static readonly FONT_WIGHT_400: number = 400; - - /** - * Font family. - */ - static readonly FONT_FAMILY_BLACK: string = '鸿蒙黑体'; - - /** - * NavDestination title. - */ - static readonly NAV_DESTINATION_TITLE: string = '详情'; - - /** - * NavDestination encryption title. - */ - static readonly NAV_ENCRYPTION_TITLE: string = '加解密'; - - /** - * NavDestination signature title. - */ - static readonly NAV_SIGNATURE_TITLE: string = '签名验签'; - - /** - * NavDestination message summary title. - */ - static readonly NAV_MESSAGE_SUMMARY_TITLE: string = '消息摘要'; - - /** - * NavDestination message auth code title. - */ - static readonly NAV_MESSAGE_AUTH_CODE_TITLE: string = '消息认证码'; -} \ No newline at end of file diff --git a/CrossPlatformCompatibility/entry/src/main/ets/entryability/EntryAbility.ets b/CrossPlatformCompatibility/entry/src/main/ets/entryability/EntryAbility.ets deleted file mode 100644 index 7a1e9bf2883629c82e7a0da288c326015aab93eb..0000000000000000000000000000000000000000 --- a/CrossPlatformCompatibility/entry/src/main/ets/entryability/EntryAbility.ets +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; -import { hilog } from '@kit.PerformanceAnalysisKit'; -import { window } from '@kit.ArkUI'; - -export default class EntryAbility extends UIAbility { - onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { - hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate'); - } - - onDestroy(): void { - hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy'); - } - - onWindowStageCreate(windowStage: window.WindowStage): void { - // Main window is created, set main page for this ability - hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); - - windowStage.loadContent('pages/Index', (err) => { - if (err.code) { - hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); - return; - } - hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.'); - let uiContext: UIContext | undefined = windowStage.getMainWindowSync().getUIContext() - AppStorage.setOrCreate('uiContext', uiContext); - }); - } - - onWindowStageDestroy(): void { - // Main window is destroyed, release UI related resources - hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); - } - - onForeground(): void { - // Ability has brought to foreground - hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground'); - } - - onBackground(): void { - // Ability has back to background - hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground'); - } -} \ No newline at end of file diff --git a/CrossPlatformCompatibility/entry/src/main/ets/pages/EncryptionAndDecryption.ets b/CrossPlatformCompatibility/entry/src/main/ets/pages/EncryptionAndDecryption.ets deleted file mode 100644 index 70901898bb5bf16135e13c8233427444ff2c96b5..0000000000000000000000000000000000000000 --- a/CrossPlatformCompatibility/entry/src/main/ets/pages/EncryptionAndDecryption.ets +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -import { CryptoViewModel } from '../viewmodel/CryptoViewModel'; -import { CryptoItem } from '../viewmodel/CryptoItem'; -import CommonConstants from '../constants/CommonConstants'; -import { getResourceString } from '../utils/ResourceString'; - -@Builder -export function EncryptionAndDecryptionBuilder() { - EncryptionAndDecryption(); -} - -@Entry -@Component -struct EncryptionAndDecryption { - @Consume('pageInfos') pageInfos: NavPathStack; - - build() { - NavDestination() { - Column() { - Text($r('app.string.total_count', CryptoViewModel.getCryptoList().length)) - .fontSize($r('app.float.count_size')) - .fontWeight(CommonConstants.FONT_WIGHT_500) - .fontFamily(CommonConstants.FONT_FAMILY_BLACK) - .fontColor($r('sys.color.mask_secondary')) - .margin({ - bottom: $r('app.float.count_margin_bottom') - }) - List() { - ForEach(CryptoViewModel.getCryptoList(), (item: CryptoItem) => { - ListItem() { - Row() { - Text(item.name) - .fontSize($r('app.float.common_font')) - .fontWeight(CommonConstants.FONT_WIGHT_500) - .fontFamily(CommonConstants.FONT_FAMILY_BLACK) - Image($r('app.media.ic_public_arrow_right')) - .width($r('app.float.arrow_width')) - .height($r('app.float.common_image')) - } - .width(CommonConstants.FULL_PERCENT) - .justifyContent(FlexAlign.SpaceBetween) - } - .height($r('app.float.list_item_height')) - .onClick(() => { - this.pageInfos.pushPathByName('CryptoDetail', item); - }) - }, (item: CryptoItem, index: number) => index + JSON.stringify(item)) - } - .backgroundColor(Color.White) - .borderRadius($r('sys.float.corner_radius_level8')) - .divider({ - strokeWidth: $r('app.float.stroke_width'), - color: $r('app.color.five_black') - }) - .padding({ - left: $r('app.float.small_padding'), - right: $r('app.float.small_padding') - }) - } - .alignItems(HorizontalAlign.Start) - .padding({ - top: $r('app.float.list_padding'), - left: $r('app.float.medium_padding'), - right: $r('app.float.medium_padding') - }) - } - .title(getResourceString($r('app.string.encrypt_btn'), this)) - .backgroundColor($r('app.color.background_page')) - } -} \ No newline at end of file diff --git a/CrossPlatformCompatibility/entry/src/main/ets/pages/Index.ets b/CrossPlatformCompatibility/entry/src/main/ets/pages/Index.ets deleted file mode 100644 index e379ec40ddfd8c75a0cbb55ffe4747ce2f46f4fc..0000000000000000000000000000000000000000 --- a/CrossPlatformCompatibility/entry/src/main/ets/pages/Index.ets +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -import CommonConstants from '../constants/CommonConstants'; - -@Entry -@Component -struct Index { - @Provide('pageInfos') pageInfos: NavPathStack = new NavPathStack(); - - @Builder - NavigationTitle() { - Column() { - Text($r('app.string.encrypt_sample')) - .fontSize($r('app.float.text_fontsize')) - .lineHeight($r('app.float.text_lineHeight')) - .fontWeight(CommonConstants.TEXT_FONT_WEIGHT) - } - .width(CommonConstants.FULL_PERCENT) - } - - build() { - Navigation(this.pageInfos) { - Column({ space: CommonConstants.COLUMN_SPACE }) { - Button($r('app.string.encrypt_btn'), { stateEffect: true, type: ButtonType.Capsule }) - .onClick(() => { - this.pageInfos.pushPathByName('EncryptionAndDecryption', null, false); - }) - .width(CommonConstants.FULL_PERCENT) - - Button($r('app.string.signature_btn'), { stateEffect: true, type: ButtonType.Capsule }) - .onClick(() => { - this.pageInfos.pushPathByName('SignatureVerification', null, false); - }) - .width(CommonConstants.FULL_PERCENT) - - Button($r('app.string.message_btn'), { stateEffect: true, type: ButtonType.Capsule }) - .onClick(() => { - this.pageInfos.pushPathByName('MessageSummary', null, false); - }) - .width(CommonConstants.FULL_PERCENT) - - Button($r('app.string.code_btn'), { stateEffect: true, type: ButtonType.Capsule }) - .onClick(() => { - this.pageInfos.pushPathByName('MessageAuthenticationCode', null, false); - }) - .width(CommonConstants.FULL_PERCENT) - } - .justifyContent(FlexAlign.End) - .width(CommonConstants.FULL_PERCENT) - .height(CommonConstants.FULL_PERCENT) - .padding($r('app.float.medium_padding')) - } - .title(this.NavigationTitle) - .backgroundColor($r('app.color.background_page')) - .mode(NavigationMode.Stack) - } -} \ No newline at end of file diff --git a/CrossPlatformCompatibility/entry/src/main/ets/pages/MessageAuthenticationCode.ets b/CrossPlatformCompatibility/entry/src/main/ets/pages/MessageAuthenticationCode.ets deleted file mode 100644 index d1908ef2a8c2c85dca48cc9fd76a6e0c4f9eb6e6..0000000000000000000000000000000000000000 --- a/CrossPlatformCompatibility/entry/src/main/ets/pages/MessageAuthenticationCode.ets +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -import { AuthCodeViewModel } from '../viewmodel/AuthCodeViewModel'; -import { AuthCodeItem } from '../viewmodel/AuthCodeItem'; -import CommonConstants from '../constants/CommonConstants'; -import { getResourceString } from '../utils/ResourceString'; - -@Builder -export function MessageAuthenticationCodeBuilder() { - MessageAuthenticationCode(); -} - -@Entry -@Component -struct MessageAuthenticationCode { - @Consume('pageInfos') pageInfos: NavPathStack; - - build() { - NavDestination() { - Column() { - Text($r('app.string.total_count', AuthCodeViewModel.getCodeList().length)) - .fontSize($r('app.float.count_size')) - .fontWeight(CommonConstants.FONT_WIGHT_500) - .fontFamily(CommonConstants.FONT_FAMILY_BLACK) - .fontColor($r('sys.color.mask_secondary')) - .margin({ - bottom: $r('app.float.count_margin_bottom') - }) - List() { - ForEach(AuthCodeViewModel.getCodeList(), (item: AuthCodeItem) => { - ListItem() { - Row() { - Text(item.name) - .fontSize($r('app.float.common_font')) - .fontWeight(CommonConstants.FONT_WIGHT_500) - .fontFamily(CommonConstants.FONT_FAMILY_BLACK) - Image($r('app.media.ic_public_arrow_right')) - .width($r('app.float.arrow_width')) - .height($r('app.float.common_image')) - } - .width(CommonConstants.FULL_PERCENT) - .justifyContent(FlexAlign.SpaceBetween) - } - .height($r('app.float.list_item_height')) - .onClick(() => { - this.pageInfos.pushPathByName('AuthCodeDetail', item); - }) - }, (item: AuthCodeItem, index: number) => index + JSON.stringify(item)) - } - .backgroundColor(Color.White) - .borderRadius($r('sys.float.corner_radius_level8')) - .divider({ - strokeWidth: $r('app.float.stroke_width'), - color: $r('app.color.five_black') - }) - .padding({ - left: $r('app.float.small_padding'), - right: $r('app.float.small_padding') - }) - } - .alignItems(HorizontalAlign.Start) - .padding({ - top: $r('app.float.list_padding'), - left: $r('app.float.medium_padding'), - right: $r('app.float.medium_padding') - }) - } - .title(getResourceString($r('app.string.code_btn'), this)) - .backgroundColor($r('app.color.background_page')) - } -} \ No newline at end of file diff --git a/CrossPlatformCompatibility/entry/src/main/ets/pages/MessageSummary.ets b/CrossPlatformCompatibility/entry/src/main/ets/pages/MessageSummary.ets deleted file mode 100644 index 402e5466bc230b66ebfe7a6ef991481c7418fb57..0000000000000000000000000000000000000000 --- a/CrossPlatformCompatibility/entry/src/main/ets/pages/MessageSummary.ets +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -import { SummaryViewModel } from '../viewmodel/SummaryViewModel'; -import { SummaryItem } from '../viewmodel/SummaryItem'; -import CommonConstants from '../constants/CommonConstants'; -import { getResourceString } from '../utils/ResourceString'; - -@Builder -export function MessageSummaryBuilder() { - MessageSummary(); -} - -@Entry -@Component -struct MessageSummary { - @Consume('pageInfos') pageInfos: NavPathStack; - - build() { - NavDestination() { - Column() { - Text($r('app.string.total_count', SummaryViewModel.getSummaryList().length)) - .fontSize($r('app.float.count_size')) - .fontWeight(CommonConstants.FONT_WIGHT_500) - .fontFamily(CommonConstants.FONT_FAMILY_BLACK) - .fontColor($r('sys.color.mask_secondary')) - .margin({ - bottom: $r('app.float.count_margin_bottom') - }) - List() { - ForEach(SummaryViewModel.getSummaryList(), (item: SummaryItem) => { - ListItem() { - Row() { - Text(item.name) - .fontSize($r('app.float.common_font')) - .fontWeight(CommonConstants.FONT_WIGHT_500) - .fontFamily(CommonConstants.FONT_FAMILY_BLACK) - Image($r('app.media.ic_public_arrow_right')) - .width($r('app.float.arrow_width')) - .height($r('app.float.common_image')) - } - .width(CommonConstants.FULL_PERCENT) - .justifyContent(FlexAlign.SpaceBetween) - } - .height($r('app.float.list_item_height')) - .onClick(() => { - this.pageInfos.pushPathByName('SummaryDetail', item); - }) - }, (item: SummaryItem, index: number) => index + JSON.stringify(item)) - } - .backgroundColor(Color.White) - .borderRadius($r('sys.float.corner_radius_level8')) - .divider({ - strokeWidth: $r('app.float.stroke_width'), - color: $r('app.color.five_black') - }) - .padding({ - left: $r('app.float.small_padding'), - right: $r('app.float.small_padding') - }) - } - .alignItems(HorizontalAlign.Start) - .padding({ - top: $r('app.float.list_padding'), - left: $r('app.float.medium_padding'), - right: $r('app.float.medium_padding') - }) - } - .title(getResourceString($r('app.string.message_btn'), this)) - .backgroundColor($r('app.color.background_page')) - } -} \ No newline at end of file diff --git a/CrossPlatformCompatibility/entry/src/main/ets/pages/SignatureVerification.ets b/CrossPlatformCompatibility/entry/src/main/ets/pages/SignatureVerification.ets deleted file mode 100644 index 60a994a236151373ac90d2663ccc7e696270d3fa..0000000000000000000000000000000000000000 --- a/CrossPlatformCompatibility/entry/src/main/ets/pages/SignatureVerification.ets +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -import { SignatureViewModel } from '../viewmodel/SignatureViewModel'; -import { SignatureItem } from '../viewmodel/SignatureItem'; -import CommonConstants from '../constants/CommonConstants'; -import { getResourceString } from '../utils/ResourceString'; - -@Builder -export function SignatureVerificationBuilder() { - SignatureVerification(); -} - -@Entry -@Component -struct SignatureVerification { - @Consume('pageInfos') pageInfos: NavPathStack; - - build() { - NavDestination() { - Column() { - Text($r('app.string.total_count', SignatureViewModel.getSignatureList().length)) - .fontSize($r('app.float.count_size')) - .fontWeight(CommonConstants.FONT_WIGHT_500) - .fontFamily(CommonConstants.FONT_FAMILY_BLACK) - .fontColor($r('sys.color.mask_secondary')) - .margin({ - bottom: $r('app.float.count_margin_bottom') - }) - List() { - ForEach(SignatureViewModel.getSignatureList(), (item: SignatureItem) => { - ListItem() { - Row() { - Text(item.name) - .fontSize($r('app.float.common_font')) - .fontWeight(CommonConstants.FONT_WIGHT_500) - .fontFamily(CommonConstants.FONT_FAMILY_BLACK) - Image($r('app.media.ic_public_arrow_right')) - .width($r('app.float.arrow_width')) - .height($r('app.float.common_image')) - } - .width(CommonConstants.FULL_PERCENT) - .justifyContent(FlexAlign.SpaceBetween) - } - .height($r('app.float.list_item_height')) - .onClick(() => { - this.pageInfos.pushPathByName('SignatureDetail', item); - }) - }, (item: SignatureItem, index: number) => index + JSON.stringify(item)) - } - .backgroundColor(Color.White) - .borderRadius($r('sys.float.corner_radius_level8')) - .divider({ - strokeWidth: $r('app.float.stroke_width'), - color: $r('app.color.five_black') - }) - .padding({ - left: $r('app.float.small_padding'), - right: $r('app.float.small_padding') - }) - } - .alignItems(HorizontalAlign.Start) - .padding({ - top: $r('app.float.list_padding'), - left: $r('app.float.medium_padding'), - right: $r('app.float.medium_padding') - }) - } - .title(getResourceString($r('app.string.signature_btn'), this)) - .backgroundColor($r('app.color.background_page')) - } -} \ No newline at end of file diff --git a/CrossPlatformCompatibility/entry/src/main/ets/utils/CryptoUtil.ets b/CrossPlatformCompatibility/entry/src/main/ets/utils/CryptoUtil.ets deleted file mode 100644 index 4356e829aa428078d5508eeaf1dffb2784fc0f4a..0000000000000000000000000000000000000000 --- a/CrossPlatformCompatibility/entry/src/main/ets/utils/CryptoUtil.ets +++ /dev/null @@ -1,354 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -import { cryptoFramework } from '@kit.CryptoArchitectureKit'; -import { logger } from './Logger'; - -export class CryptoUtil { - /** - * GCM parameters generated in AES GCM mode. - * - * @returns cryptoFramework.GcmParamsSpec. - */ - public static genGcmParamsSpec(): cryptoFramework.GcmParamsSpec { - let arr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - let dataIv = new Uint8Array(arr); - let ivBlob: cryptoFramework.DataBlob = { data: dataIv }; - arr = [0, 0, 0, 0, 0, 0, 0, 0]; - let dataAad = new Uint8Array(arr); - let aadBlob: cryptoFramework.DataBlob = { data: dataAad }; - arr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - let dataTag = new Uint8Array(arr); - let tagBlob: cryptoFramework.DataBlob = { - data: dataTag - }; - // The value of authTag of the GCM is obtained from the doFinal result during encryption - // and is set to the value of params of the init function during decryption. - let gcmParamsSpec: cryptoFramework.GcmParamsSpec = { - iv: ivBlob, - aad: aadBlob, - authTag: tagBlob, - algName: 'GcmParamsSpec' - }; - return gcmParamsSpec; - } - - /** - * AES GCM encryption mode. - * - * @param cipherParam Algorithm name. - * @param gcmParams cryptoFramework.GcmParamsSpec. - * @param symKey cryptoFramework.SymKey. - * @param plainText Character string to be encrypted. - * @returns Promise. - */ - public static async encryptAESGCMMessagePromise(cipherParam: string, gcmParams: cryptoFramework.GcmParamsSpec, - symKey: cryptoFramework.SymKey, plainText: cryptoFramework.DataBlob): Promise { - let cipher = cryptoFramework.createCipher(cipherParam); - await cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, symKey, gcmParams); - let encryptUpdate = await cipher.update(plainText); - gcmParams.authTag = await cipher.doFinal(null); - return encryptUpdate; - } - - /** - * AES GCM decryption mode. - * - * @param cipherParam algorithm name. - * @param gcmParams cryptoFramework.GcmParamsSpec. - * @param symKey cryptoFramework.SymKey. - * @param cipherText character string to be decrypted. - * @returns Promise. - */ - public static async decryptAESGCMMessagePromise(cipherParam: string, gcmParams: cryptoFramework.GcmParamsSpec, - symKey: cryptoFramework.SymKey, cipherText: cryptoFramework.DataBlob): Promise { - let decoder = cryptoFramework.createCipher(cipherParam); - await decoder.init(cryptoFramework.CryptoMode.DECRYPT_MODE, symKey, gcmParams); - let decryptUpdate = await decoder.update(cipherText); - // When doFinal is decrypted in GCM mode, no data is transferred. - // The tag data transferred during initialization is verified. If the verification fails, an exception is thrown. - let decryptData = await decoder.doFinal(null); - if (decryptData === null) { - logger.info('GCM decrypt success, decryptData is null'); - } - return decryptUpdate; - } - - /** - * Create a symmetric key generator according to the given algorithm name. - * - * @param symKeyData the key data blob. - * @param algName algorithm name. - * @returns cryptoFramework.SymKey - */ - public static genSymKeyByData(symKeyData: Uint8Array, algName: string): cryptoFramework.SymKey { - let symKeyBlob: cryptoFramework.DataBlob = { data: symKeyData }; - let aesGenerator = cryptoFramework.createSymKeyGenerator(algName); - let symKey = aesGenerator.convertKeySync(symKeyBlob); - logger.info('convertKey success'); - return symKey; - } - - /** - * Provides the IvParamsSpec type, including the parameter iv. - * - * @returns cryptoFramework.IvParamsSpec. - */ - public static genIvParamsSpec(): cryptoFramework.IvParamsSpec { - let arr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - let dataIv = new Uint8Array(arr); - let ivBlob: cryptoFramework.DataBlob = { data: dataIv }; - let ivParamsSpec: cryptoFramework.IvParamsSpec = { - algName: 'IvParamsSpec', - iv: ivBlob - }; - return ivParamsSpec; - } - - /** - * CBC encryption mode. - * - * @param cipherParam algorithm name. - * @param ivParams cryptoFramework.IvParamsSpec. - * @param symKey cryptoFramework.SymKey. - * @param plainText character string to be encrypted. - * @returns Promise. - */ - public static async encryptCBCMessagePromise(cipherParam: string, ivParams: cryptoFramework.IvParamsSpec, - symKey: cryptoFramework.SymKey, plainText: cryptoFramework.DataBlob): Promise { - let cipher = cryptoFramework.createCipher(cipherParam); - await cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, symKey, ivParams); - let cipherData = await cipher.doFinal(plainText); - return cipherData; - } - - /** - * CBC decryption mode. - * - * @param cipherParam algorithm name. - * @param ivParams cryptoFramework.IvParamsSpec. - * @param symKey cryptoFramework.SymKey. - * @param cipherText character string to be encrypted. - * @returns Promise. - */ - public static async decryptCBCMessagePromise(cipherParam: string, ivParams: cryptoFramework.IvParamsSpec, - symKey: cryptoFramework.SymKey, cipherText: cryptoFramework.DataBlob): Promise { - let decoder = cryptoFramework.createCipher(cipherParam); - await decoder.init(cryptoFramework.CryptoMode.DECRYPT_MODE, symKey, ivParams); - let decryptData = await decoder.doFinal(cipherText); - return decryptData; - } - - /** - * Encryption mode. - * - * @param cipherParam algorithm name. - * @param symKey cryptoFramework.SymKey. - * @param plainText character string to be encrypted. - * @returns Promise - */ - public static async encryptMessagePromise(cipherParam: string, symKey: cryptoFramework.SymKey, - plainText: cryptoFramework.DataBlob): Promise { - let cipher = cryptoFramework.createCipher(cipherParam); - await cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, symKey, null); - let cipherData = await cipher.doFinal(plainText); - return cipherData; - } - - /** - * Decryption mode. - * - * @param cipherParam algorithm name. - * @param symKey cryptoFramework.SymKey. - * @param cipherText character string to be decrypted. - * @returns Promise. - */ - public static async decryptMessagePromise(cipherParam: string, symKey: cryptoFramework.SymKey, - cipherText: cryptoFramework.DataBlob) { - let decoder = cryptoFramework.createCipher(cipherParam); - await decoder.init(cryptoFramework.CryptoMode.DECRYPT_MODE, symKey, null); - let decryptData = await decoder.doFinal(cipherText); - return decryptData; - } - - /** - * Create the asymmetric key generator instance according to the given algorithm name. - * - * @param algName algorithm name. - * @param pubKeyData the key data blob. - * @param priKeyData the key data blob. - * @returns cryptoFramework.KeyPair. - */ - public static genKeyPairByData(algName: string, pubKeyData: Uint8Array, - priKeyData: Uint8Array): cryptoFramework.KeyPair { - let pubKeyBlob: cryptoFramework.DataBlob = { data: pubKeyData }; - let priKeyBlob: cryptoFramework.DataBlob = { data: priKeyData }; - let rsaGenerator = cryptoFramework.createAsyKeyGenerator(algName); - let keyPair = rsaGenerator.convertKeySync(pubKeyBlob, priKeyBlob); - return keyPair; - } - - /** - * Encrypted by public key. - * - * @param cipherParam algorithm name. - * @param publicKey Provides the public key interface for asymmetric keys. - * @param plainText character string to be encrypted. - * @returns Promise. - */ - public static async encryptPublicKeyMessagePromise(cipherParam: string, publicKey: cryptoFramework.PubKey, - plainText: cryptoFramework.DataBlob): Promise { - let cipher = cryptoFramework.createCipher(cipherParam); - await cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, publicKey, null); - let cipherData = await cipher.doFinal(plainText); - return cipherData; - } - - /** - * Decrypted by private key. - * - * @param cipherParam algorithm name. - * @param privateKey provides the private key type. - * @param cipherText character string to be decrypted. - * @returns Promise. - */ - public static async decryptPrivateKeyMessagePromise(cipherParam: string, privateKey: cryptoFramework.PriKey, - cipherText: cryptoFramework.DataBlob): Promise { - let decoder = cryptoFramework.createCipher(cipherParam); - await decoder.init(cryptoFramework.CryptoMode.DECRYPT_MODE, privateKey, null); - let decryptData = await decoder.doFinal(cipherText); - return decryptData; - } - - /** - * Generating an RSA stack key. - * - * @param nIn Indicates the modulus n. - * @param eIn Indicates the public exponent e. - * @param dIn Indicates the private exponent d. - * @returns cryptoFramework.RSAKeyPairSpec. - */ - public static genRsaKeyPairSpec(nIn: bigint, eIn: bigint, dIn: bigint): cryptoFramework.RSAKeyPairSpec { - let rsaCommSpec: cryptoFramework.RSACommonParamsSpec = { - n: nIn, - algName: 'RSA', - specType: cryptoFramework.AsyKeySpecType.COMMON_PARAMS_SPEC - }; - let rsaKeyPairSpec: cryptoFramework.RSAKeyPairSpec = { - params: rsaCommSpec, - sk: dIn, - pk: eIn, - algName: 'RSA', - specType: cryptoFramework.AsyKeySpecType.KEY_PAIR_SPEC - }; - return rsaKeyPairSpec; - } - - /** - * RSA PKCS1_OAEP mode encryption. - * - * @param cipherParam algorithm name. - * @param publicKey Provides the public key interface for asymmetric keys. - * @param itemValue the value of the specified parameter. - * @param plainText character string to be encrypted. - * @returns cryptoFramework.DataBlob. - */ - public static encryptOAEPPublicKeyMessagePromise(cipherParam: string, publicKey: cryptoFramework.PubKey, - itemValue: Uint8Array, plainText: cryptoFramework.DataBlob): cryptoFramework.DataBlob { - let cipher = cryptoFramework.createCipher(cipherParam); - cipher.initSync(cryptoFramework.CryptoMode.ENCRYPT_MODE, publicKey, null); - cipher.setCipherSpec(cryptoFramework.CipherSpecItem.OAEP_MGF1_PSRC_UINT8ARR, itemValue) - let cipherData = cipher.doFinalSync(plainText); - return cipherData; - } - - /** - * RSA PKCS1_OAEP mode decryption. - * - * @param cipherParam algorithm name. - * @param privateKey Provides the public key interface for asymmetric keys. - * @param itemValue the value of the specified parameter. - * @param cipherText character string to be decrypted. - * @returns cryptoFramework.DataBlob. - */ - public static decryptOAEPPrivateKeyMessagePromise(cipherParam: string, privateKey: cryptoFramework.PriKey, - itemValue: Uint8Array, cipherText: cryptoFramework.DataBlob): cryptoFramework.DataBlob { - let decoder = cryptoFramework.createCipher(cipherParam); - decoder.initSync(cryptoFramework.CryptoMode.DECRYPT_MODE, privateKey, null); - decoder.setCipherSpec(cryptoFramework.CipherSpecItem.OAEP_MGF1_PSRC_UINT8ARR, itemValue); - let decryptData = decoder.doFinalSync(cipherText); - return decryptData; - } - - /** - * RSA segment encryption. - * - * @param cipherParam algorithm name. - * @param pubKey Provides the public key interface for asymmetric keys. - * @param plainText character string to be encrypted. - * @returns cryptoFramework.DataBlob. - */ - public static rsaEncryptBySegment(cipherParam: string, pubKey: cryptoFramework.PubKey, - plainText: cryptoFramework.DataBlob): cryptoFramework.DataBlob { - let cipher = cryptoFramework.createCipher(cipherParam); - cipher.initSync(cryptoFramework.CryptoMode.ENCRYPT_MODE, pubKey, null); - let plainTextSplitLen = 64; - let cipherText = new Uint8Array(); - for (let i = 0; i < plainText.data.length; i += plainTextSplitLen) { - let updateMessage = plainText.data.subarray(i, i + plainTextSplitLen); - let updateMessageBlob: cryptoFramework.DataBlob = { data: updateMessage }; - // Split the original text by 64 characters and call doFinal to encrypt the text. - // When the 1024-bit key is used, a 128-byte ciphertext is generated each time. - let updateOutput = cipher.doFinalSync(updateMessageBlob); - let mergeText = new Uint8Array(cipherText.length + updateOutput.data.length); - mergeText.set(cipherText); - mergeText.set(updateOutput.data, cipherText.length); - cipherText = mergeText; - } - let cipherBlob: cryptoFramework.DataBlob = { data: cipherText }; - return cipherBlob; - } - - /** - * RSA segment decryption. - * - * @param cipherParam algorithm name. - * @param priKey Provides the public key interface for asymmetric keys. - * @param cipherText character string to be decrypted. - * @returns cryptoFramework.DataBlob. - */ - public static rsaDecryptBySegment(cipherParam: string, priKey: cryptoFramework.PriKey, - cipherText: cryptoFramework.DataBlob): cryptoFramework.DataBlob { - let decoder = cryptoFramework.createCipher(cipherParam); - decoder.initSync(cryptoFramework.CryptoMode.DECRYPT_MODE, priKey, null); - // Length of ciphertext bytes generated by the RSA key during each encryption, which is calculated as follows:\ - // Length of ciphertext bytes generated by the RSA key during each encryption = Number of key bits/8 - let cipherTextSplitLen = 128; - let decryptText = new Uint8Array(); - for (let i = 0; i < cipherText.data.length; i += cipherTextSplitLen) { - let updateMessage = cipherText.data.subarray(i, i + cipherTextSplitLen); - let updateMessageBlob: cryptoFramework.DataBlob = { data: updateMessage }; - // Split the ciphertext by 128 bytes, decrypt the ciphertext, obtain the original text, - // and concatenate the original text. - let updateOutput = decoder.doFinalSync(updateMessageBlob); - let mergeText = new Uint8Array(decryptText.length + updateOutput.data.length); - mergeText.set(decryptText); - mergeText.set(updateOutput.data, decryptText.length); - decryptText = mergeText; - } - let decryptBlob: cryptoFramework.DataBlob = { data: decryptText }; - return decryptBlob; - } -} \ No newline at end of file diff --git a/CrossPlatformCompatibility/entry/src/main/ets/utils/DataConversion.ets b/CrossPlatformCompatibility/entry/src/main/ets/utils/DataConversion.ets deleted file mode 100644 index cf4270b8e7ca85530ec0a68d2ef33012d78136d9..0000000000000000000000000000000000000000 --- a/CrossPlatformCompatibility/entry/src/main/ets/utils/DataConversion.ets +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -import { cryptoFramework } from '@kit.CryptoArchitectureKit'; -import { hilog } from '@kit.PerformanceAnalysisKit'; -import { buffer, util } from '@kit.ArkTS'; -import { SM2Sequence } from './SM2Sequence'; - -const uiContext: UIContext | undefined = AppStorage.get('uiContext'); -let context = uiContext!.getHostContext()!; - -export class DataConversion { - // [Start cover_str_pubkey] - // Generate SM2 public key according to key parameters - public static async convertStrToPubKey(keyStr: string): Promise { - const puKeyStr = keyStr.startsWith('04') ? keyStr.slice(2) : keyStr; - const pkPart1 = puKeyStr.slice(0, puKeyStr.length / 2); - const pkPart2 = puKeyStr.slice(puKeyStr.length / 2); - // Put hexadecimal in the corresponding position - const pks: cryptoFramework.Point = { - x: BigInt('0x' + pkPart1), - y: BigInt('0x' + pkPart2) - }; - // Public key object parameters - const pubKeySpec: cryptoFramework.ECCPubKeySpec = { - params: cryptoFramework.ECCKeyUtil.genECCCommonParamsSpec('NID_sm2'), - pk: pks, - algName: 'SM2', - specType: cryptoFramework.AsyKeySpecType.PUBLIC_KEY_SPEC - }; - const keypairGenerator = cryptoFramework.createAsyKeyGeneratorBySpec(pubKeySpec); - let pksData = keypairGenerator.generatePubKeySync(); - return pksData; - } - // [End cover_str_pubkey] - - // [Start cover_str_to_prikey] - // Generate sm2 private key according to key parameters - public static async convertStrToPriKey(keyStr: string): Promise { - const sks = BigInt('0x' + keyStr); - // Private key object parameters - const priKeySpec: cryptoFramework.ECCPriKeySpec = { - params: cryptoFramework.ECCKeyUtil.genECCCommonParamsSpec('NID_sm2'), - sk: sks, - algName: 'SM2', - specType: cryptoFramework.AsyKeySpecType.PRIVATE_KEY_SPEC - }; - const priKeypairGenerator = cryptoFramework.createAsyKeyGeneratorBySpec(priKeySpec); - let sksData = priKeypairGenerator.generatePriKeySync(); - return sksData; - } - // [End cover_str_to_prikey] - - getLenHex(data: string): string { - let byte: number = Number.parseInt('0x' + data.slice(0, 2)); - let len_size: number = byte > 127 ? byte - 0x80 + 1 : 1; - return data.slice(0, len_size * 2); - } - - lenHex2number(lenHex: string): number { - if (lenHex.length === 2) { - return Number.parseInt('0x' + lenHex); - } - return Number.parseInt('0x' + lenHex.slice(2, lenHex.length)); - } - - readC1(sm2_sequence: SM2Sequence, data: string): string { - let xy: string[] = []; - for (let i = 0; i < 2; i++) { - if (data.startsWith('0220')) { - xy[i] = data.slice(4, 68); - data = data.slice(68, data.length); - } else if (data.startsWith('022100')) { - xy[i] = data.slice(6, 70); - data = data.slice(70, data.length); - } else { - hilog.error(0, 'd2i_SM2_Ciphertext', - context.resourceManager.getStringSync($r('app.string.format_error').id)); - } - } - sm2_sequence.C1x = xy[0]; - sm2_sequence.C1y = xy[1]; - return data; - } - - readC2(sm2_sequence: SM2Sequence, data: string): string { - if (data.startsWith('04')) { - data = data.slice('04'.length, data.length); - let C2_lenHex = this.getLenHex(data); - data = data.slice(C2_lenHex.length, data.length); - if (this.lenHex2number(C2_lenHex) !== data.length / 2) { - hilog.error(0, 'd2i_SM2_Ciphertext', - context.resourceManager.getStringSync($r('app.string.format_error').id)); - } - sm2_sequence.C2 = data; - } else { - hilog.error(0, 'd2i_SM2_Ciphertext', - context.resourceManager.getStringSync($r('app.string.format_error').id)); - } - return data; - } - - readC3(sm2_sequence: SM2Sequence, data: string): string { - if (data.startsWith('0420')) { - sm2_sequence.C3 = data.slice(4, 68); - data = data.slice(68, data.length); - } else { - hilog.error(0, 'd2i_SM2_Ciphertext', - context.resourceManager.getStringSync($r('app.string.format_error').id)); - } - return data; - } - - genLenHex(content: string): string { - let size: number = content.length / 2; - let lenHex: string; - if (size.toString(16).length % 2 === 1) { - lenHex = '0' + size.toString(16); - } else { - lenHex = size.toString(16); - } - - if (size < 0x80) { - return lenHex; - } - let lenHex_size: number = lenHex.length / 2; - return (lenHex_size | 0x80).toString(16) + lenHex; - } - - // [Start sm2_cipher_text] - // SM2 ciphertext in ASN,1 format is converted into C1C3C2 naked ciphertext. - d2i_SM2_Ciphertext(standard_data: string): string { - let message: string = standard_data; - // The starting mark is 30 - if (!message.startsWith('30')) { - hilog.error(0, 'd2i_SM2_Ciphertext', - context.resourceManager.getStringSync($r('app.string.format_error').id)); - } - message = message.slice('30'.length, message.length); - - // The length of SM2 sequence content. - let sequence_lexHex: string = this.getLenHex(message); - message = message.slice(sequence_lexHex.length, message.length); - let sequence_len: number = this.lenHex2number(sequence_lexHex); - - if (sequence_len !== message.length / 2) { - hilog.error(0x0000, 'd2i_SM2_Ciphertext', - context.resourceManager.getStringSync($r('app.string.format_error').id)); - } - - let sm2_sequence = new SM2Sequence(); - message = this.readC1(sm2_sequence, message); - message = this.readC3(sm2_sequence, message); - message = this.readC2(sm2_sequence, message); - hilog.info(0x0000, 'sm2_sequence', sm2_sequence.toString()); - - let primal_data: string = sm2_sequence.C1x + sm2_sequence.C1y + sm2_sequence.C3 + sm2_sequence.C2; - return primal_data; - } - // [End sm2_cipher_text] - - // [Start i2d_sm2_cipher_text] - // The original naked ciphertext is converted into ASN.1 format ciphertext - i2dSM2CipherText(primal_data: string): string { - let sm2_sequence = new SM2Sequence(); - sm2_sequence.C1x = primal_data.slice(0, 64); - primal_data = primal_data.slice(64, primal_data.length); - sm2_sequence.C1y = primal_data.slice(0, 64); - primal_data = primal_data.slice(64, primal_data.length); - sm2_sequence.C3 = primal_data.slice(0, 64); - primal_data = primal_data.slice(64, primal_data.length); - sm2_sequence.C2 = primal_data; - - let C1x_title: string = (Number.parseInt('0x' + sm2_sequence.C1x.slice(0, 2)) > 127) ? '022100' : '0220'; - let C1y_title: string = (Number.parseInt('0x' + sm2_sequence.C1y.slice(0, 2)) > 127) ? '022100' : '0220'; - let C3_title: string = '0420'; - let C2_title: string = '04' + this.genLenHex(sm2_sequence.C2); - let sequence_message: string = - C1x_title + sm2_sequence.C1x + C1y_title + sm2_sequence.C1y + C2_title + sm2_sequence.C2 + C3_title + - sm2_sequence.C3; - let sequence_lenHex: string = this.genLenHex(sequence_message); - - let standard_data = '30' + sequence_lenHex + sequence_message; - return standard_data; - } - // [End i2d_sm2_cipher_text] - - // [Start string_to_unit8array] - // ets/utils/DataConversion.ets - // String into byte stream - public static stringToUint8Array(str: string): Uint8Array { - let textEncoder = util.TextEncoder.create('utf-8'); - return textEncoder.encodeInto(str); - } - - // The byte stream is converted into an understandable string - public static uint8ArrayToString(input: Uint8Array): string { - let textDecoder = util.TextDecoder.create('utf-8'); - return textDecoder.decodeToString(input); - } - // [End string_to_unit8array] - - // [Start base64_unit_array] - // Base64转Uint8Array - public static base64ToUint8Array(str: string): Uint8Array { - let base64Helper = new util.Base64Helper(); - return base64Helper.decodeSync(str); - } - - // Uint8Array转Base64 - public static uint8ArrayToBase64(input: Uint8Array): string { - let base64Helper = new util.Base64Helper(); - return base64Helper.encodeToStringSync(input); - } - // [End base64_unit_array] - - // [Start hex_str_to_unit8array] - // hexadecimal To Uint8Array - public static hexStrToUint8Array(data: string): Uint8Array { - return new Uint8Array(buffer.from(data, 'hex').buffer); - } - - // Uint8Array To hexadecimal - public static uint8ArrayToHexStr(input: Uint8Array): string { - let bufferStr = buffer.from(input).toString('hex'); - return bufferStr; - } - // [End hex_str_to_unit8array] -} \ No newline at end of file diff --git a/CrossPlatformCompatibility/entry/src/main/ets/utils/Logger.ets b/CrossPlatformCompatibility/entry/src/main/ets/utils/Logger.ets deleted file mode 100644 index e2927283e2e7e197faa9e3bfbf3387b780628f52..0000000000000000000000000000000000000000 --- a/CrossPlatformCompatibility/entry/src/main/ets/utils/Logger.ets +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -import { hilog } from '@kit.PerformanceAnalysisKit'; - -const LOG_DOMAIN: number = 0xFF00; - -class Logger { - private domain: number; - private prefix: string; - private format: string = '%{public}s, %{public}s'; - - constructor(prefix: string, domain: number) { - this.prefix = prefix; - this.domain = domain; - } - - debug(...args: string[]): void { - hilog.debug(this.domain, this.prefix, this.format, args); - } - - info(...args: string[]): void { - hilog.info(this.domain, this.prefix, this.format, args); - } - - warn(...args: string[]): void { - hilog.warn(this.domain, this.prefix, this.format, args); - } - - error(...args: string[]): void { - hilog.error(this.domain, this.prefix, this.format, args); - } -} - -export const logger = new Logger('Crypto', LOG_DOMAIN); \ No newline at end of file diff --git a/CrossPlatformCompatibility/entry/src/main/ets/utils/ResourceString.ets b/CrossPlatformCompatibility/entry/src/main/ets/utils/ResourceString.ets deleted file mode 100644 index 5675c4af0840dd13a4cc144a022967581c39a339..0000000000000000000000000000000000000000 --- a/CrossPlatformCompatibility/entry/src/main/ets/utils/ResourceString.ets +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ -const uiContext: UIContext | undefined = AppStorage.get('uiContext'); -let context = uiContext!.getHostContext()!; - -export function getResourceString(resource: Resource, __this: object): string { - let resourceString = context.resourceManager.getStringSync(resource.id); - return resourceString; -} \ No newline at end of file diff --git a/CrossPlatformCompatibility/entry/src/main/ets/utils/SM2Sequence.ets b/CrossPlatformCompatibility/entry/src/main/ets/utils/SM2Sequence.ets deleted file mode 100644 index d02f7b3b88478f9fb2e8268af145375067e0edcb..0000000000000000000000000000000000000000 --- a/CrossPlatformCompatibility/entry/src/main/ets/utils/SM2Sequence.ets +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -export class SM2Sequence { - private c1x: string = ''; - - public set C1x(value: string) { - this.c1x = value; - } - - public get C1x(): string { - return this.c1x; - } - - private c1y: string = ''; - - public set C1y(value: string) { - this.c1y = value; - } - - public get C1y(): string { - return this.c1y; - } - - private c2: string = ''; - - public set C2(value: string) { - this.c2 = value; - } - - public get C2(): string { - return this.c2; - } - - private c3: string = ''; - - public set C3(value: string) { - this.c3 = value; - } - - public get C3(): string { - return this.c3; - } - - public toString(): string { - return JSON.stringify(this); - } -} \ No newline at end of file diff --git a/CrossPlatformCompatibility/entry/src/main/ets/utils/SignatureUtil.ets b/CrossPlatformCompatibility/entry/src/main/ets/utils/SignatureUtil.ets deleted file mode 100644 index 0574598c67a5661722ae967bc4d6a82bf8adc2e3..0000000000000000000000000000000000000000 --- a/CrossPlatformCompatibility/entry/src/main/ets/utils/SignatureUtil.ets +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -import { cryptoFramework } from '@kit.CryptoArchitectureKit'; - -// Constructs key parameters of an RSA asymmetric key pair based on key parameter attributes. -function genRsaKeyPairSpec(nIn: bigint, eIn: bigint, dIn: bigint) { - let rsaCommSpec: cryptoFramework.RSACommonParamsSpec = { - n: nIn, - algName: "RSA", - specType: cryptoFramework.AsyKeySpecType.COMMON_PARAMS_SPEC - }; - let rsaKeyPairSpec: cryptoFramework.RSAKeyPairSpec = { - params: rsaCommSpec, - sk: dIn, - pk: eIn, - algName: "RSA", - specType: cryptoFramework.AsyKeySpecType.KEY_PAIR_SPEC - }; - return rsaKeyPairSpec; -} - -// Parameters for generating an RSA2048 key pair. -export function genRsa2048KeyPairSpec(): cryptoFramework.RSAKeyPairSpec { - let nIn = - BigInt("0x9260d0750ae117eee55c3f3deaba74917521a262ee76007cdf8a56755ad73a1598a1408410a01434c3f5bc54a88b57fa19fc" + - "4328daea0750a4c44e88cff3b2382621b80f670464433e4336e6d003e8cd65bff211da144b88291c2259a00a72b711c116ef7686e8f" + - "ee34e4d933c868187bdc26f7be071493c86f7a5941c3510806ad67b0f94d88f5cf5c02a092821d8626e8932b65c5bd8c92049c21093" + - "2b7afa7ac59c0e886ae5c1edb00d8ce2c57633db26bd6639bff73cee82be9275c402b4cf2a4388da8cf8c64eefe1c5a0f5ab8057c39" + - "fa5c0589c3e253f0960332300f94bea44877b588e1edbde97cf2360727a09b775262d7ee552b3319b9266f05a25"); - let eIn = BigInt("0x010001"); - let dIn = - BigInt("0x6a7df2ca63ead4dda191d614b6b385e0d9056a3d6d5cfe07db1daabee022db08212d97613d3328e0267c9dd23d787abde2afc" + - "b306aeb7dfce69246cc73f5c87fdf06030179a2114b767db1f083ff841c025d7dc00cd82435b9a90f695369e94df23d2ce458bc3b328" + - "3ad8bba2b8fa1ba62e2dce9accff3799aae7c840016f3ba8e0048c0b6cc4339af7161003a5beb864a0164b2c1c9237b64bc875569943" + - "51b27506c33d4bcdfce0f9c491a7d6b0628c7c852be4f0a9c3132b2ed3a2c8881e9aab07e20e17deb074691be677776a78b5c502e05d" + - "9bdde72126b3738695e2dd1a0a98a14247c65d8a7ee79432a092cb0721a12df798e44f7cfce0c498147a9b1"); - return genRsaKeyPairSpec(nIn, eIn, dIn); -} \ No newline at end of file diff --git a/CrossPlatformCompatibility/entry/src/main/ets/view/AuthCodeDetail.ets b/CrossPlatformCompatibility/entry/src/main/ets/view/AuthCodeDetail.ets deleted file mode 100644 index 21064a151cf10c889fa0b3013a36ac381231422f..0000000000000000000000000000000000000000 --- a/CrossPlatformCompatibility/entry/src/main/ets/view/AuthCodeDetail.ets +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -import { cryptoFramework } from '@kit.CryptoArchitectureKit'; -import { buffer } from '@kit.ArkTS'; -import CommonConstants from '../constants/CommonConstants'; -import { AuthCodeItem } from '../viewmodel/AuthCodeItem'; -import { getResourceString } from '../utils/ResourceString'; - -@Builder -export function AuthCodeDetailBuilder() { - AuthCodeDetail(); -} - -@Component -export struct AuthCodeDetail { - @Consume('pageInfos') pageInfos: NavPathStack; - @State AuthCodeItem: AuthCodeItem = new AuthCodeItem($r('app.string.empty')); - @State message: string = ''; - @State MessageResult: string = ''; - - aboutToAppear(): void { - this.AuthCodeItem = this.pageInfos.getParamByName('AuthCodeDetail')[0] as AuthCodeItem; - } - - async genSymKeyByData(symKeyData: Uint8Array) { - let symKeyBlob: cryptoFramework.DataBlob = { data: symKeyData }; - let aesGenerator = cryptoFramework.createSymKeyGenerator('HMAC'); - let symKey = await aesGenerator.convertKey(symKeyBlob); - return symKey; - } - - async doHmac() { - // Decode the string in utf-8 to Uint8Array, using a fixed 128-bit key,i.e. 16 bytes. - let keyData = new Uint8Array(buffer.from('12345678abcdefgh', 'utf-8').buffer); - let key = await this.genSymKeyByData(keyData); - let macAlgName = 'SHA256'; // Digest algorithm name. - let mac = cryptoFramework.createMac(macAlgName); - await mac.init(key); - if (this.AuthCodeItem.name === $r('app.string.calculate_seg_code')) { - let messageData = new Uint8Array(buffer.from(this.message, 'utf-8').buffer); - // Assume that the segment update is performed in the unit of 20 bytes. in practice,there is no requirement. - let updateLength = 20; - for (let i = 0; i < messageData.length; i += updateLength) { - let updateMessage = messageData.subarray(i, i + updateLength); - let updateMessageBlob: cryptoFramework.DataBlob = { data: updateMessage }; - await mac.update(updateMessageBlob); - } - } else { - await mac.update({ data: new Uint8Array(buffer.from(this.message, 'utf-8').buffer) }); - } - let macResult = await mac.doFinal(); - this.MessageResult = `${macResult.data}`; - } - - build() { - NavDestination() { - Column() { - Column() { - TextInput({ text: this.message, placeholder: $r('app.string.text_message_code') }) - .margin({ top: $r('app.float.margin_top_sixteen') }) - .backgroundColor(Color.White) - .onChange((value) => { - this.message = value; - }) - - Column() { - Text($r('app.string.message_code_result')) - .margin({ left: $r('app.float.margin_left_five') }) - - TextArea({ text: this.MessageResult }) - .height($r('app.float.textarea_height')) - .margin({ top: $r('app.float.margin_top_sixteen') }) - .backgroundColor(Color.White) - .enabled(false) - } - .alignItems(HorizontalAlign.Start) - .margin({ top: $r('app.float.margin_top_sixteen') }) - } - - Button() { - Text(this.AuthCodeItem.name) - .fontSize($r('app.float.common_font')) - .fontColor(Color.White) - } - .onClick(() => { - this.doHmac(); - }) - .enabled(this.message ? true : false) - .width(CommonConstants.FULL_PERCENT) - .height($r('app.float.button_height')) - .margin({ top: $r('app.float.margin_top_sixteen') }) - } - .padding({ - left: $r('app.float.medium_padding'), - right: $r('app.float.medium_padding'), - bottom: $r('app.float.medium_padding') - }) - .height(CommonConstants.FULL_PERCENT) - .justifyContent(FlexAlign.SpaceBetween) - } - .title(getResourceString(this.AuthCodeItem.name, this)) - .backgroundColor($r('app.color.background_page')) - } -} \ No newline at end of file diff --git a/CrossPlatformCompatibility/entry/src/main/ets/view/CryptoDetail.ets b/CrossPlatformCompatibility/entry/src/main/ets/view/CryptoDetail.ets deleted file mode 100644 index d510f0541bd7c8afe289fe0b9f90a11f3e9aeb49..0000000000000000000000000000000000000000 --- a/CrossPlatformCompatibility/entry/src/main/ets/view/CryptoDetail.ets +++ /dev/null @@ -1,513 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -import { cryptoFramework } from '@kit.CryptoArchitectureKit'; -import { buffer, util } from '@kit.ArkTS'; -import { CryptoUtil } from '../utils/CryptoUtil'; -import { CryptoItem } from '../viewmodel/CryptoItem'; -import CommonConstants from '../constants/CommonConstants'; -import { logger } from '../utils/Logger'; -import { CryptoViewModel } from '../viewmodel/CryptoViewModel'; -import { getResourceString } from '../utils/ResourceString'; -import { DataConversion } from '../utils/DataConversion'; - -@Builder -export function CryptoDetailBuilder() { - CryptoDetail(); -} - -@Component -export struct CryptoDetail { - @Consume('pageInfos') pageInfos: NavPathStack; - @State cryptoItem: CryptoItem = - new CryptoItem($r('app.string.empty'), $r('app.string.empty'), $r('app.string.empty'), ''); - @State original: string = ''; - @State encrypt: string = getResourceString($r('app.string.encrypted_text'), this); - @State isCrypto: boolean = false; - @State decrypt: string | Resource = getResourceString($r('app.string.decrypted_text'), this); - @State pk: string = - '04F848A2FC3CAAEE6976100EA9C33D3AC91CACC33B68D03C2EFDB99CDDC203AAFE977071F34339A9CB8C0E0CD3A93D18E839D4E6469581B6F5A666A34C0B8EFD1B'; - @State sk: string = '0575D0ECB625C99672FE860B777CC1DD547057B903C2D4033D21DC016D3838AF'; - @State encryptTextJava: string = getResourceString($r('app.string.encrypted_text'), this); - private cipherParam: string = ''; - private gcmParamsSpec?: cryptoFramework.GcmParamsSpec; - private ivParamsSpec?: cryptoFramework.IvParamsSpec; - private symKey?: cryptoFramework.SymKey; - private keyPair?: cryptoFramework.KeyPair; - private pSource?: Uint8Array; - - aboutToAppear(): void { - this.cryptoItem = this.pageInfos.getParamByName('CryptoDetail')[0] as CryptoItem; - } - - build() { - NavDestination() { - Scroll() { - Column() { - if (getResourceString(this.cryptoItem.name, this) === - getResourceString($r('app.string.format_conversion'), this)) { - Row() { - Text($r('app.string.private_key')) - .fontSize($r('app.float.count_size')) - .fontWeight(CommonConstants.FONT_WIGHT_500) - .fontFamily(CommonConstants.FONT_FAMILY_BLACK) - .lineHeight($r('app.float.common_line_height')) - .margin({ bottom: $r('app.float.small_padding') }) - } - .width(CommonConstants.FULL_PERCENT) - .justifyContent(FlexAlign.Start) - - TextArea({ text: this.sk }) - .backgroundColor(Color.White) - .enabled(false) - .margin({ bottom: $r('app.float.small_padding') }) - - Row() { - Text($r('app.string.public_key')) - .fontSize($r('app.float.count_size')) - .fontWeight(CommonConstants.FONT_WIGHT_500) - .fontFamily(CommonConstants.FONT_FAMILY_BLACK) - .lineHeight($r('app.float.common_line_height')) - .margin({ bottom: $r('app.float.small_padding') }) - } - .width(CommonConstants.FULL_PERCENT) - .justifyContent(FlexAlign.Start) - - TextArea({ text: this.pk }) - .backgroundColor(Color.White) - .enabled(false) - } - - TextArea({ placeholder: $r('app.string.text_encrypted') }) - .backgroundColor(Color.White) - .onChange((value: string) => { - this.original = value; - }) - .margin({ top: $r('app.float.small_padding') }) - Button(this.cryptoItem.encrypted) - .width(CommonConstants.FULL_PERCENT) - .fontSize($r('app.float.common_font')) - .enabled(this.original === '' ? false : true) - .margin({ - top: $r('app.float.small_padding'), - bottom: $r('app.float.small_padding') - }) - .onClick(async () => { - if (this.cryptoItem.type === 'AES_GCM') { - this.gcmParamsSpec = CryptoUtil.genGcmParamsSpec(); - this.cipherParam = 'AES128|GCM|PKCS7'; - let keyData = new Uint8Array([83, 217, 231, 76, 28, 113, 23, 219, 250, 71, 209, 210, 205, 97, 32, 159]); - this.symKey = CryptoUtil.genSymKeyByData(keyData, 'AES128'); - let plainText: cryptoFramework.DataBlob = { - data: new Uint8Array(buffer.from(this.original, 'utf-8').buffer) - }; - let encryptText = await CryptoUtil.encryptAESGCMMessagePromise(this.cipherParam, this.gcmParamsSpec, - this.symKey, plainText); - let base = new util.Base64Helper(); - let encodeString = base.encodeToStringSync(encryptText.data); - this.encrypt = encodeString; - logger.info(encodeString); - this.isCrypto = true; - } else if (this.cryptoItem.type === 'AES_CBC') { - this.ivParamsSpec = CryptoUtil.genIvParamsSpec(); - this.cipherParam = 'AES128|CBC|PKCS7'; - let keyData = new Uint8Array([83, 217, 231, 76, 28, 113, 23, 219, 250, 71, 209, 210, 205, 97, 32, 159]); - this.symKey = CryptoUtil.genSymKeyByData(keyData, 'AES128'); - let plainText: cryptoFramework.DataBlob = { - data: new Uint8Array(buffer.from(this.original, 'utf-8').buffer) - }; - let encryptText = await CryptoUtil.encryptCBCMessagePromise(this.cipherParam, this.ivParamsSpec, - this.symKey, plainText); - let base = new util.Base64Helper(); - let encodeString = base.encodeToStringSync(encryptText.data); - this.encrypt = encodeString; - logger.info(encodeString); - this.isCrypto = true; - } else if (this.cryptoItem.type === 'AES_ECB') { - this.cipherParam = 'AES128|ECB|PKCS7'; - let keyData = new Uint8Array([83, 217, 231, 76, 28, 113, 23, 219, 250, 71, 209, 210, 205, 97, 32, 159]); - this.symKey = CryptoUtil.genSymKeyByData(keyData, 'AES128'); - let plainText: cryptoFramework.DataBlob = { - data: new Uint8Array(buffer.from(this.original, 'utf-8').buffer) - }; - let encryptText = await CryptoUtil.encryptMessagePromise(this.cipherParam, this.symKey, plainText); - let base = new util.Base64Helper(); - let encodeString = base.encodeToStringSync(encryptText.data); - this.encrypt = encodeString; - logger.info(encodeString); - this.isCrypto = true; - } else if (this.cryptoItem.type === '3DES_ECB') { - this.cipherParam = '3DES192|ECB|PKCS7'; - let keyData = new Uint8Array([238, 249, 61, 55, 128, 220, 183, 224, 139, 253, 248, 239, 239, 41, 71, 25, - 235, 206, 230, 162, 249, 27, 234, 114]); - this.symKey = CryptoUtil.genSymKeyByData(keyData, '3DES192'); - let plainText: cryptoFramework.DataBlob = { - data: new Uint8Array(buffer.from(this.original, 'utf-8').buffer) - }; - let encryptText = await CryptoUtil.encryptMessagePromise(this.cipherParam, this.symKey, plainText); - let base = new util.Base64Helper(); - let encodeString = base.encodeToStringSync(encryptText.data); - this.encrypt = encodeString; - logger.info(encodeString); - this.isCrypto = true; - } else if (this.cryptoItem.type === 'SM4_ECB') { - this.cipherParam = 'SM4_128|ECB|PKCS7'; - let keyData = new Uint8Array([7, 154, 52, 176, 4, 236, 150, 43, 237, 9, 145, 166, 141, 174, 224, 131]); - this.symKey = CryptoUtil.genSymKeyByData(keyData, 'SM4_128'); - let plainText: cryptoFramework.DataBlob = { - data: new Uint8Array(buffer.from(this.original, 'utf-8').buffer) - }; - let encryptText = await CryptoUtil.encryptMessagePromise(this.cipherParam, this.symKey, plainText); - let base = new util.Base64Helper(); - let encodeString = base.encodeToStringSync(encryptText.data); - this.encrypt = encodeString; - logger.info(encodeString); - this.isCrypto = true; - } else if (this.cryptoItem.type === 'SM4_CBC') { - this.ivParamsSpec = CryptoUtil.genIvParamsSpec(); - this.cipherParam = 'SM4_128|CBC|PKCS7'; - let keyData = new Uint8Array([7, 154, 52, 176, 4, 236, 150, 43, 237, 9, 145, 166, 141, 174, 224, 131]); - this.symKey = CryptoUtil.genSymKeyByData(keyData, 'SM4_128'); - let plainText: cryptoFramework.DataBlob = { - data: new Uint8Array(buffer.from(this.original, 'utf-8').buffer) - }; - let encryptText = await CryptoUtil.encryptCBCMessagePromise(this.cipherParam, this.ivParamsSpec, - this.symKey, plainText); - let base = new util.Base64Helper(); - let encodeString = base.encodeToStringSync(encryptText.data); - this.encrypt = encodeString; - logger.info(encodeString); - this.isCrypto = true; - } else if (this.cryptoItem.type === 'RSA_PKCS1') { - let pkData = CryptoViewModel.pkData; - let skData = CryptoViewModel.skData; - this.keyPair = CryptoUtil.genKeyPairByData('RSA1024', pkData, skData); - this.cipherParam = 'RSA1024|PKCS1'; - let plainText: cryptoFramework.DataBlob = { - data: new Uint8Array(buffer.from(this.original, 'utf-8').buffer) - }; - let encryptText = await CryptoUtil.encryptPublicKeyMessagePromise(this.cipherParam, this.keyPair.pubKey, - plainText); - let base = new util.Base64Helper(); - let encodeString = base.encodeToStringSync(encryptText.data); - this.encrypt = encodeString; - logger.info(encodeString); - this.isCrypto = true; - } else if (this.cryptoItem.type === 'RSA_PKCS1_OAEP') { - let rsaKeyPair = CryptoUtil.genRsaKeyPairSpec(CryptoViewModel.rsaKeyNin, BigInt('0x010001'), - CryptoViewModel.rsaKeyDIn); - let rsaGeneratorSpec = cryptoFramework.createAsyKeyGeneratorBySpec(rsaKeyPair); - this.pSource = new Uint8Array([1, 2, 3, 4]); - this.cipherParam = 'RSA2048|PKCS1_OAEP|SHA256|MGF1_SHA1'; - this.keyPair = await rsaGeneratorSpec.generateKeyPair(); - let plainText: cryptoFramework.DataBlob = { - data: new Uint8Array(buffer.from(this.original, 'utf-8').buffer) - }; - let encryptText = CryptoUtil.encryptOAEPPublicKeyMessagePromise(this.cipherParam, this.keyPair.pubKey, - this.pSource, plainText); - let base = new util.Base64Helper(); - let encodeString = base.encodeToStringSync(encryptText.data); - this.encrypt = encodeString; - logger.info(encodeString); - this.isCrypto = true; - } else if (this.cryptoItem.type === 'SM2') { - let pkData = - new Uint8Array([48, 89, 48, 19, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 8, 42, 129, 28, 207, 85, - 1, 130, 45, 3, 66, 0, 4, 90, 3, 58, 157, 190, 248, 76, 7, 132, 200, 151, 208, 112, 230, 96, 140, 90, - 238, 211, 155, 128, 109, 248, 40, 83, 214, 78, 42, 104, 106, 55, 148, 249, 35, 61, 32, 221, 135, - 143, - 100, 45, 97, 194, 176, 52, 73, 136, 174, 40, 70, 70, 34, 103, 103, 161, 99, 27, 187, 13, 187, 109, - 244, - 13, 7]); - let skData: Uint8Array = - new Uint8Array([48, 49, 2, 1, 1, 4, 32, 54, 41, 239, 240, 63, 188, 134, 113, 31, 102, 149, - 203, 245, 89, 15, 15, 47, 202, 170, 60, 38, 154, 28, 169, 189, 100, 251, 76, 112, 223, 156, 159, - 160, - 10, 6, 8, 42, 129, 28, 207, 85, 1, 130, 45]); - // Public key, private key u8 type - if (getResourceString(this.cryptoItem.name, this) === - getResourceString($r('app.string.format_conversion'), this)) { - // Public key conversion to SM2 key. - let pksData = await DataConversion.convertStrToPubKey(this.pk) - // Private key conversion to SM2 key. - let sksData = await DataConversion.convertStrToPriKey(this.sk) - // Generate SM2 key. - this.keyPair = - CryptoUtil.genKeyPairByData('SM2_256', pksData.getEncoded().data, sksData.getEncoded().data); - } else { - this.keyPair = CryptoUtil.genKeyPairByData('SM2_256', pkData, skData); - } - this.cipherParam = 'SM2_256|SM3'; - let plainText: cryptoFramework.DataBlob = { - data: new Uint8Array(buffer.from(this.original, 'utf-8').buffer) - }; - // Encrypt messages. - let encryptText = await CryptoUtil.encryptPublicKeyMessagePromise(this.cipherParam, this.keyPair.pubKey, - plainText); - this.encryptTextJava = - new DataConversion().d2i_SM2_Ciphertext(buffer.from(encryptText.data).toString('hex')) - let base = new util.Base64Helper(); - let encodeString = base.encodeToStringSync(encryptText.data); - this.encrypt = encodeString; - logger.info(encodeString); - this.isCrypto = true; - } else if (this.cryptoItem.type === 'RSA_PKCS1_BIG') { - let pkData = CryptoViewModel.pkData; - let skData = CryptoViewModel.skData; - this.keyPair = CryptoUtil.genKeyPairByData('RSA1024', pkData, skData); - this.cipherParam = 'RSA1024|PKCS1'; - let plainText: cryptoFramework.DataBlob = { - data: new Uint8Array(buffer.from(this.original, 'utf-8').buffer) - }; - let encryptText = CryptoUtil.rsaEncryptBySegment(this.cipherParam, this.keyPair.pubKey, plainText); - let base = new util.Base64Helper(); - let encodeString = base.encodeToStringSync(encryptText.data); - this.encrypt = encodeString; - logger.info(encodeString); - this.isCrypto = true; - } else { - logger.error('this.cryptoItem.type error' + this.cryptoItem.type) - } - }) - - Row() { - Text($r('app.string.after_encryption')) - .fontSize($r('app.float.count_size')) - .fontWeight(CommonConstants.FONT_WIGHT_500) - .fontFamily(CommonConstants.FONT_FAMILY_BLACK) - .lineHeight($r('app.float.common_line_height')) - } - .margin({ bottom: $r('app.float.small_padding') }) - .width(CommonConstants.FULL_PERCENT) - .justifyContent(FlexAlign.Start) - - if (getResourceString(this.cryptoItem.name, this) === - getResourceString($r('app.string.format_conversion'), this)) { - Row() { - Text($r('app.string.ASN_1')) - .fontSize($r('app.float.count_size')) - .fontWeight(CommonConstants.FONT_WIGHT_500) - .fontFamily(CommonConstants.FONT_FAMILY_BLACK) - .lineHeight($r('app.float.common_line_height')) - } - .width(CommonConstants.FULL_PERCENT) - .justifyContent(FlexAlign.Start) - .margin({ - bottom: $r('app.float.small_padding') - }) - } - - Row() { - Text(this.encrypt) - .fontSize($r('app.float.common_font')) - .fontWeight(CommonConstants.FONT_WIGHT_400) - .fontFamily(CommonConstants.FONT_FAMILY_BLACK) - .fontColor($r('sys.color.mask_secondary')) - } - .borderRadius($r('sys.float.corner_radius_level8')) - .backgroundColor(Color.White) - .width(CommonConstants.FULL_PERCENT) - .justifyContent(FlexAlign.Start) - .padding({ - left: $r('app.float.encrypted_padding_lr'), - right: $r('app.float.encrypted_padding_lr'), - top: $r('app.float.encrypted_padding_tb'), - bottom: $r('app.float.encrypted_padding_tb') - }) - .margin({ - bottom: $r('app.float.small_padding') - }) - - if (getResourceString(this.cryptoItem.name, this) === - getResourceString($r('app.string.format_conversion'), this)) { - Row() { - Text($r('app.string.naked_ciphertext')) - .fontSize($r('app.float.count_size')) - .fontWeight(CommonConstants.FONT_WIGHT_500) - .fontFamily(CommonConstants.FONT_FAMILY_BLACK) - .lineHeight($r('app.float.common_line_height')) - } - .width(CommonConstants.FULL_PERCENT) - .justifyContent(FlexAlign.Start) - .margin({ - bottom: $r('app.float.small_padding') - }) - - Row() { - Text(this.encryptTextJava) - .fontSize($r('app.float.common_font')) - .fontWeight(CommonConstants.FONT_WIGHT_400) - .fontFamily(CommonConstants.FONT_FAMILY_BLACK) - .fontColor($r('sys.color.mask_secondary')) - } - .borderRadius($r('sys.float.corner_radius_level8')) - .backgroundColor(Color.White) - .width(CommonConstants.FULL_PERCENT) - .justifyContent(FlexAlign.Start) - .padding({ - left: $r('app.float.encrypted_padding_lr'), - right: $r('app.float.encrypted_padding_lr'), - top: $r('app.float.encrypted_padding_tb'), - bottom: $r('app.float.encrypted_padding_tb') - }) - .margin({ - bottom: $r('app.float.small_padding') - }) - } - - Button(this.cryptoItem.decrypted) - .width(CommonConstants.FULL_PERCENT) - .fontSize($r('app.float.common_font')) - .enabled(this.isCrypto ? true : false) - .onClick(async () => { - if (this.cryptoItem.type === 'AES_GCM') { - if (!this.gcmParamsSpec || !this.symKey) { - return; - } - let base = new util.Base64Helper(); - let plainText: cryptoFramework.DataBlob = { data: base.decodeSync(this.encrypt) }; - let encryptText = await CryptoUtil.decryptAESGCMMessagePromise(this.cipherParam, this.gcmParamsSpec, - this.symKey, plainText); - let textDecoder = util.TextDecoder.create('utf-8'); - this.decrypt = textDecoder.decodeToString(encryptText.data); - } else if (this.cryptoItem.type === 'AES_CBC') { - if (!this.ivParamsSpec || !this.symKey) { - return; - } - let base = new util.Base64Helper(); - let plainText: cryptoFramework.DataBlob = { data: base.decodeSync(this.encrypt) }; - let encryptText = await CryptoUtil.decryptCBCMessagePromise(this.cipherParam, this.ivParamsSpec, - this.symKey, plainText); - let textDecoder = util.TextDecoder.create('utf-8'); - this.decrypt = textDecoder.decodeToString(encryptText.data); - } else if (this.cryptoItem.type === 'AES_ECB') { - if (!this.symKey) { - return; - } - let base = new util.Base64Helper(); - let plainText: cryptoFramework.DataBlob = { data: base.decodeSync(this.encrypt) }; - let encryptText = await CryptoUtil.decryptMessagePromise(this.cipherParam, this.symKey, plainText); - let textDecoder = util.TextDecoder.create('utf-8'); - this.decrypt = textDecoder.decodeToString(encryptText.data); - } else if (this.cryptoItem.type === '3DES_ECB') { - if (!this.symKey) { - return; - } - let base = new util.Base64Helper(); - let plainText: cryptoFramework.DataBlob = { data: base.decodeSync(this.encrypt) }; - let encryptText = await CryptoUtil.decryptMessagePromise(this.cipherParam, this.symKey, plainText); - let textDecoder = util.TextDecoder.create('utf-8'); - this.decrypt = textDecoder.decodeToString(encryptText.data); - } else if (this.cryptoItem.type === 'SM4_ECB') { - if (!this.symKey) { - return; - } - let base = new util.Base64Helper(); - let plainText: cryptoFramework.DataBlob = { data: base.decodeSync(this.encrypt) }; - let encryptText = await CryptoUtil.decryptMessagePromise(this.cipherParam, this.symKey, plainText); - let textDecoder = util.TextDecoder.create('utf-8'); - this.decrypt = textDecoder.decodeToString(encryptText.data); - } else if (this.cryptoItem.type === 'SM4_CBC') { - if (!this.ivParamsSpec || !this.symKey) { - return; - } - let base = new util.Base64Helper(); - let plainText: cryptoFramework.DataBlob = { data: base.decodeSync(this.encrypt) }; - let encryptText = await CryptoUtil.decryptCBCMessagePromise(this.cipherParam, this.ivParamsSpec, - this.symKey, plainText); - let textDecoder = util.TextDecoder.create('utf-8'); - this.decrypt = textDecoder.decodeToString(encryptText.data); - } else if (this.cryptoItem.type === 'RSA_PKCS1') { - if (!this.keyPair) { - return; - } - let base = new util.Base64Helper(); - let plainText: cryptoFramework.DataBlob = { data: base.decodeSync(this.encrypt) }; - let encryptText = - await CryptoUtil.decryptPrivateKeyMessagePromise(this.cipherParam, this.keyPair.priKey, - plainText); - let textDecoder = util.TextDecoder.create('utf-8'); - this.decrypt = textDecoder.decodeToString(encryptText.data); - } else if (this.cryptoItem.type === 'RSA_PKCS1_OAEP') { - if (!this.keyPair || !this.pSource) { - return; - } - let base = new util.Base64Helper(); - let plainText: cryptoFramework.DataBlob = { data: base.decodeSync(this.encrypt) }; - let encryptText = CryptoUtil.decryptOAEPPrivateKeyMessagePromise(this.cipherParam, this.keyPair.priKey, - this.pSource, plainText); - let textDecoder = util.TextDecoder.create('utf-8'); - this.decrypt = textDecoder.decodeToString(encryptText.data); - } else if (this.cryptoItem.type === 'SM2') { - if (!this.keyPair) { - return; - } - let base = new util.Base64Helper(); - // Encrypted data - let plainText: cryptoFramework.DataBlob = { data: base.decodeSync(this.encrypt) }; - let encryptText = - await CryptoUtil.decryptPrivateKeyMessagePromise(this.cipherParam, this.keyPair.priKey, - plainText); - let textDecoder = util.TextDecoder.create('utf-8'); - this.decrypt = textDecoder.decodeToString(encryptText.data); - } else if (this.cryptoItem.type === 'RSA_PKCS1_BIG') { - if (!this.keyPair) { - return; - } - let base = new util.Base64Helper(); - let plainText: cryptoFramework.DataBlob = { data: base.decodeSync(this.encrypt) }; - let encryptText = CryptoUtil.rsaDecryptBySegment(this.cipherParam, this.keyPair.priKey, plainText); - let textDecoder = util.TextDecoder.create('utf-8'); - this.decrypt = textDecoder.decodeToString(encryptText.data); - } else { - logger.error('this.cryptoItem.type error' + this.cryptoItem.type) - } - }) - Row() { - Text(this.decrypt) - .fontSize($r('app.float.common_font')) - .fontWeight(CommonConstants.FONT_WIGHT_400) - .fontFamily(CommonConstants.FONT_FAMILY_BLACK) - .fontColor($r('sys.color.mask_secondary')) - } - .borderRadius($r('sys.float.corner_radius_level8')) - .backgroundColor(Color.White) - .width(CommonConstants.FULL_PERCENT) - .justifyContent(FlexAlign.Start) - .padding({ - left: $r('app.float.encrypted_padding_lr'), - right: $r('app.float.encrypted_padding_lr'), - top: $r('app.float.encrypted_padding_tb'), - bottom: $r('app.float.encrypted_padding_tb') - }) - .margin({ - top: $r('app.float.small_padding') - }) - } - .padding({ - left: $r('app.float.medium_padding'), - right: $r('app.float.medium_padding') - }) - } - .align(getResourceString(this.cryptoItem.name, this) === - getResourceString($r('app.string.format_conversion'), this) ? Alignment.TopStart : Alignment.Center) - .height(getResourceString(this.cryptoItem.name, this) === - getResourceString($r('app.string.format_conversion'), this) ? '100%' : '90%') - } - .padding({ bottom: 16 }) - .title(getResourceString(this.cryptoItem.name, this)) - .backgroundColor($r('app.color.background_page')) - } -} \ No newline at end of file diff --git a/CrossPlatformCompatibility/entry/src/main/ets/view/SignatureDetail.ets b/CrossPlatformCompatibility/entry/src/main/ets/view/SignatureDetail.ets deleted file mode 100644 index 39cf39169ece09574943aacf52c5fabc832d66ea..0000000000000000000000000000000000000000 --- a/CrossPlatformCompatibility/entry/src/main/ets/view/SignatureDetail.ets +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -import { cryptoFramework } from '@kit.CryptoArchitectureKit'; -import { buffer } from '@kit.ArkTS'; -import CommonConstants from '../constants/CommonConstants'; -import { SignatureItem } from '../viewmodel/SignatureItem'; -import { genRsa2048KeyPairSpec } from '../utils/SignatureUtil'; -import { getResourceString } from '../utils/ResourceString'; - -@Builder -export function SignatureDetailBuilder() { - SignatureDetail(); -} - -@Component -export struct SignatureDetail { - @Consume('pageInfos') pageInfos: NavPathStack; - @State sign: string = ''; - @State signResult: string = ''; - @State SignatureItem: SignatureItem = new SignatureItem($r('app.string.empty'), '', '', false); - @State input: cryptoFramework.DataBlob = { data: new Uint8Array(buffer.from(this.sign, 'utf8').buffer) }; - @State keyPair: cryptoFramework.KeyPair | undefined = undefined; - @State signData: cryptoFramework.DataBlob = { data: new Uint8Array(buffer.from('', 'utf8').buffer) }; - @State signFlag: boolean = false; - - aboutToAppear(): void { - this.SignatureItem = this.pageInfos.getParamByName('SignatureDetail')[0] as SignatureItem; - } - - async signMessagePromise() { - if (this.SignatureItem.type === 'RSA1024|PKCS1|SHA256' && this.SignatureItem.isSegment) { - // PKCS1 segment signature. - let signAlg = this.SignatureItem.type; - let signer = cryptoFramework.createSign(signAlg); - await this.generatorKey(); - let key = this.keyPair as cryptoFramework.KeyPair; - await signer.init(key.priKey); - let textSplitLen = 64; // User-defined data splitting length. The value is 64. - let plainText = new Uint8Array(buffer.from(this.sign, 'utf8').buffer) - for (let i = 0; i < plainText.length; i += textSplitLen) { - let updateMessage = plainText.subarray(i, i + textSplitLen); - let updateMessageBlob: cryptoFramework.DataBlob = { data: updateMessage }; - // Segment update. - await signer.update(updateMessageBlob); - } - let signData = await signer.sign(null); - this.signData = signData; - } else if (this.SignatureItem.type === 'RSA|PASS|SHA256|MGF1_SHA256') { - // Parameters for obtaining an RSA key pair. - let rsaKeyPairSpec = genRsa2048KeyPairSpec(); - // RSA key pair generator. - let rsaGeneratorSpec = cryptoFramework.createAsyKeyGeneratorBySpec(rsaKeyPairSpec); - // Both sign and verfiy support RSA keys with or without length. - let signer = cryptoFramework.createSign('RSA|PSS|SHA256|MGF1_SHA256'); - let keyPair = await rsaGeneratorSpec.generateKeyPair(); - await signer.init(keyPair.priKey); - // After the signature is initialized,perform the set and get operations on the PSS parameters. - let setN = 32; - signer.setSignSpec(cryptoFramework.SignSpecItem.PSS_SALT_LEN_NUM, setN); - signer.getSignSpec(cryptoFramework.SignSpecItem.PSS_SALT_LEN_NUM); - signer.getSignSpec(cryptoFramework.SignSpecItem.PSS_TRAILER_FIELD_NUM); - signer.getSignSpec(cryptoFramework.SignSpecItem.PSS_MD_NAME_STR); - signer.getSignSpec(cryptoFramework.SignSpecItem.PSS_MGF_NAME_STR); - signer.getSignSpec(cryptoFramework.SignSpecItem.PSS_MGF1_MD_STR); - await signer.update(this.input); - let signData = await signer.sign(null); - this.signData = signData; - } else { - let signAlg = this.SignatureItem.type; - let signer = cryptoFramework.createSign(signAlg); - await this.generatorKey(); - let key = this.keyPair as cryptoFramework.KeyPair; - await signer.init(key.priKey); - await signer.update(this.input); - let signData = await signer.sign(null); - this.signData = signData; - } - } - - async verifyMessagePromise() { - if (this.SignatureItem.type === 'RSA1024|PKCS1|SHA256' && this.SignatureItem.isSegment) { - let verifyAlg = this.SignatureItem.type; - let verifier = cryptoFramework.createVerify(verifyAlg); - let key = this.keyPair as cryptoFramework.KeyPair; - await verifier.init(key.pubKey); - let textSplitLen = 64; // User-defined data splitting length. The value is 64. - let plainText = new Uint8Array(buffer.from(this.sign, 'utf8').buffer) - for (let i = 0; i < plainText.length; i += textSplitLen) { - let updateMessage = plainText.subarray(i, i + textSplitLen); - let updateMessageBlob: cryptoFramework.DataBlob = { data: updateMessage }; - // Segment update. - await verifier.update(updateMessageBlob); - } - let res = await verifier.verify(null, this.signData); - res === true ? this.signResult = 'verify success' : this.signResult = 'verify failed'; - } else if (this.SignatureItem.type === 'RSA|PASS|SHA256|MGF1_SHA256') { - // Parameters for obtaining an RSA key pair. - let rsaKeyPairSpec = genRsa2048KeyPairSpec(); - // RSA key pair generator. - let rsaGeneratorSpec = cryptoFramework.createAsyKeyGeneratorBySpec(rsaKeyPairSpec); - let verifyer = cryptoFramework.createVerify("RSA2048|PSS|SHA256|MGF1_SHA256"); - let keyPair = await rsaGeneratorSpec.generateKeyPair(); - let setN = 32; - verifyer.setVerifySpec(cryptoFramework.SignSpecItem.PSS_SALT_LEN_NUM, setN); - verifyer.getVerifySpec(cryptoFramework.SignSpecItem.PSS_SALT_LEN_NUM); - verifyer.getVerifySpec(cryptoFramework.SignSpecItem.PSS_TRAILER_FIELD_NUM); - verifyer.getVerifySpec(cryptoFramework.SignSpecItem.PSS_MD_NAME_STR); - verifyer.getVerifySpec(cryptoFramework.SignSpecItem.PSS_MGF_NAME_STR); - verifyer.getVerifySpec(cryptoFramework.SignSpecItem.PSS_MGF1_MD_STR); - verifyer.initSync(keyPair.pubKey); - verifyer.updateSync(this.input); - let verifyResult = verifyer.verifySync(null, this.signData); - verifyResult === true ? this.signResult = 'verify success' : this.signResult = 'verify failed'; - } else { - let verifyAlg = this.SignatureItem.type; - let verifier = cryptoFramework.createVerify(verifyAlg); - let key = this.keyPair as cryptoFramework.KeyPair; - await verifier.init(key.pubKey); - await verifier.update(this.input); - let res = await verifier.verify(null, this.signData); - res === true ? this.signResult = 'verify success' : this.signResult = 'verify failed'; - } - } - - async generatorKey() { - let keyGenAlg = this.SignatureItem.keyGenAlg; - let generator = cryptoFramework.createAsyKeyGenerator(keyGenAlg); - let keyPair = await generator.generateKeyPair(); - this.keyPair = keyPair; - } - - build() { - NavDestination() { - Column() { - Column() { - TextInput({ text: this.sign, placeholder: $r('app.string.text_signature') }) - .margin({ top: $r('app.float.margin_top_sixteen') }) - .backgroundColor(Color.White) - .onChange((value) => { - this.sign = value; - this.input = { data: new Uint8Array(buffer.from(value, 'utf8').buffer) }; - }) - - Column() { - Text($r('app.string.signature_result')) - .margin({ left: $r('app.float.margin_left_five') }) - - TextInput({ text: this.signResult }) - .margin({ top: $r('app.float.margin_top_sixteen') }) - .backgroundColor(Color.White) - .enabled(false) - } - .alignItems(HorizontalAlign.Start) - .margin({ top: $r('app.float.margin_top_sixteen') }) - } - - Column() { - Button() { - Text($r('app.string.Signed')) - .fontSize($r('app.float.common_font')) - .fontColor(Color.White) - } - .onClick(() => { - this.signMessagePromise(); - this.signFlag = true; - }) - .enabled(this.sign ? true : false) - .width(CommonConstants.FULL_PERCENT) - .height($r('app.float.button_height')) - .margin({ top: $r('app.float.margin_top_sixteen') }) - - Button() { - Text($r('app.string.signature_verification')) - .fontSize($r('app.float.common_font')) - .fontColor(Color.White) - } - .onClick(() => { - this.verifyMessagePromise(); - this.signFlag = true; - }) - .enabled(this.signFlag ? true : false) - .width(CommonConstants.FULL_PERCENT) - .height($r('app.float.button_height')) - .margin({ top: $r('app.float.margin_top_sixteen') }) - } - } - .padding({ - left: $r('app.float.medium_padding'), - right: $r('app.float.medium_padding'), - bottom: $r('app.float.medium_padding') - }) - .height(CommonConstants.FULL_PERCENT) - .justifyContent(FlexAlign.SpaceBetween) - } - .title(getResourceString(this.SignatureItem.name, this)) - .backgroundColor($r('app.color.background_page')) - } -} \ No newline at end of file diff --git a/CrossPlatformCompatibility/entry/src/main/ets/view/SummaryDetail.ets b/CrossPlatformCompatibility/entry/src/main/ets/view/SummaryDetail.ets deleted file mode 100644 index 0d91cef9cd5f88e3c204c0ed6fe395a2f05492cb..0000000000000000000000000000000000000000 --- a/CrossPlatformCompatibility/entry/src/main/ets/view/SummaryDetail.ets +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -import { cryptoFramework } from '@kit.CryptoArchitectureKit'; -import { buffer } from '@kit.ArkTS'; -import CommonConstants from '../constants/CommonConstants'; -import { SummaryItem } from '../viewmodel/SummaryItem'; -import { getResourceString } from '../utils/ResourceString'; - -@Builder -export function SummaryDetailBuilder() { - SummaryDetail(); -} - -@Component -export struct SummaryDetail { - @Consume('pageInfos') pageInfos: NavPathStack; - @State SummaryItem: SummaryItem = new SummaryItem($r('app.string.empty'), ''); - @State message: string = ''; - @State MessageResult: string = ''; - - aboutToAppear(): void { - this.SummaryItem = this.pageInfos.getParamByName('SummaryDetail')[0] as SummaryItem; - } - - async doSummary(message: string, type: string) { - if (type === 'SHA256Segments') { - let mdAlgName = "SHA256"; // Digest algorithm name. - let md = cryptoFramework.createMd(mdAlgName); - let messageData = new Uint8Array(buffer.from(message, 'utf-8').buffer); - // Assume that the segment update is performed in the unit of 20 bytes. in practice,there is no requirement. - let updateLength = 20; - for (let i = 0; i < messageData.length; i += updateLength) { - let updateMessage = messageData.subarray(i, i + updateLength); - let updateMessageBlob: cryptoFramework.DataBlob = { data: updateMessage }; - await md.update(updateMessageBlob); - } - let mdOutput = await md.digest(); - this.MessageResult = `${mdOutput.data}`; - } else { - let mdAlgName = type; // Digest algorithm name. - let md = cryptoFramework.createMd(mdAlgName); - await md.update({ data: new Uint8Array(buffer.from(message, 'utf-8').buffer) }); - let mdResult = await md.digest(); - this.MessageResult = `${mdResult.data}`; - } - } - - build() { - NavDestination() { - Column() { - Column() { - TextInput({ text: this.message, placeholder: $r('app.string.text_summary') }) - .margin({ top: $r('app.float.margin_top_sixteen') }) - .backgroundColor(Color.White) - .onChange((value) => { - this.message = value; - }) - - Column() { - Text($r('app.string.summary_result')) - .margin({ left: $r('app.float.margin_left_five') }) - - TextArea({ text: this.MessageResult }) - .height($r('app.float.textarea_height')) - .margin({ top: $r('app.float.margin_top_sixteen') }) - .backgroundColor(Color.White) - .enabled(false) - } - .alignItems(HorizontalAlign.Start) - .margin({ top: $r('app.float.margin_top_sixteen') }) - } - - Button() { - Text(this.SummaryItem.name) - .fontSize($r('app.float.common_font')) - .fontColor(Color.White) - } - .onClick(() => { - this.doSummary(this.message, this.SummaryItem.type); - }) - .enabled(this.message ? true : false) - .width(CommonConstants.FULL_PERCENT) - .height($r('app.float.button_height')) - .margin({ top: $r('app.float.margin_top_sixteen') }) - } - .padding({ - left: $r('app.float.medium_padding'), - right: $r('app.float.medium_padding'), - bottom: $r('app.float.medium_padding') - }) - .height(CommonConstants.FULL_PERCENT) - .justifyContent(FlexAlign.SpaceBetween) - } - .title(getResourceString(this.SummaryItem.name, this)) - .backgroundColor($r('app.color.background_page')) - } -} \ No newline at end of file diff --git a/CrossPlatformCompatibility/entry/src/main/ets/viewmodel/AuthCodeItem.ets b/CrossPlatformCompatibility/entry/src/main/ets/viewmodel/AuthCodeItem.ets deleted file mode 100644 index 4085dacc6829c6e18011c91ea3e8e7fc5c1443f0..0000000000000000000000000000000000000000 --- a/CrossPlatformCompatibility/entry/src/main/ets/viewmodel/AuthCodeItem.ets +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -export class AuthCodeItem { - name: Resource = $r('app.string.empty'); - - constructor(name: Resource) { - this.name = name; - } -} \ No newline at end of file diff --git a/CrossPlatformCompatibility/entry/src/main/ets/viewmodel/AuthCodeViewModel.ets b/CrossPlatformCompatibility/entry/src/main/ets/viewmodel/AuthCodeViewModel.ets deleted file mode 100644 index d007512eb296ce881fc0ea73e28051a738df16ee..0000000000000000000000000000000000000000 --- a/CrossPlatformCompatibility/entry/src/main/ets/viewmodel/AuthCodeViewModel.ets +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -import { AuthCodeItem } from './AuthCodeItem'; - -export class AuthCodeViewModel { - public static getCodeList(): AuthCodeItem[] { - let AuthCodeList: AuthCodeItem[] = []; - AuthCodeList.push(new AuthCodeItem($r('app.string.calculate_code'))); - AuthCodeList.push(new AuthCodeItem($r('app.string.calculate_seg_code'))); - - return AuthCodeList; - } -} \ No newline at end of file diff --git a/CrossPlatformCompatibility/entry/src/main/ets/viewmodel/CryptoItem.ets b/CrossPlatformCompatibility/entry/src/main/ets/viewmodel/CryptoItem.ets deleted file mode 100644 index 98b904031a82d9a4e2eb34d0c6d325198d7f6068..0000000000000000000000000000000000000000 --- a/CrossPlatformCompatibility/entry/src/main/ets/viewmodel/CryptoItem.ets +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -export class CryptoItem { - name: Resource = $r('app.string.empty'); - encrypted: Resource = $r('app.string.empty'); - decrypted: Resource = $r('app.string.empty'); - type: string = ''; - - constructor(name: Resource, encrypted: Resource, decrypted: Resource, type: string) { - this.name = name; - this.encrypted = encrypted; - this.decrypted =decrypted; - this.type = type; - } -} \ No newline at end of file diff --git a/CrossPlatformCompatibility/entry/src/main/ets/viewmodel/CryptoViewModel.ets b/CrossPlatformCompatibility/entry/src/main/ets/viewmodel/CryptoViewModel.ets deleted file mode 100644 index e3a396ce3e25db395a23fcfd32ccd30d6c0c2622..0000000000000000000000000000000000000000 --- a/CrossPlatformCompatibility/entry/src/main/ets/viewmodel/CryptoViewModel.ets +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -import { CryptoItem } from './CryptoItem'; - -export class CryptoViewModel { - public static pkData = new Uint8Array([48, 129, 159, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 129, - 141, 0, 48, 129, 137, 2, 129, 129, 0, 197, 64, 10, 198, 14, 110, 65, 92, 206, 35, 28, 123, 153, 24, 134, 255, 145, - 74, 42, 173, 40, 215, 146, 58, 143, 46, 10, 195, 154, 160, 69, 196, 220, 152, 179, 44, 111, 200, 84, 78, 215, 73, - 210, 181, 12, 29, 70, 68, 36, 135, 153, 89, 230, 202, 130, 212, 111, 243, 234, 92, 131, 62, 145, 50, 73, 48, 104, - 245, 46, 70, 45, 157, 147, 143, 140, 162, 156, 216, 220, 49, 121, 142, 194, 33, 223, 201, 0, 16, 163, 210, 240, 118, - 92, 147, 121, 220, 17, 114, 24, 52, 125, 135, 176, 88, 21, 83, 86, 17, 156, 88, 250, 48, 79, 86, 128, 248, 105, 208, - 133, 140, 13, 153, 164, 191, 136, 164, 44, 53, 2, 3, 1, 0, 1]); - public static skData = new Uint8Array([48, 130, 2, 119, 2, 1, 0, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, - 0, 4, 130, 2, 97, 48, 130, 2, 93, 2, 1, 0, 2, 129, 129, 0, 197, 64, 10, 198, 14, 110, 65, 92, 206, 35, 28, 123, 153, - 24, 134, 255, 145, 74, 42, 173, 40, 215, 146, 58, 143, 46, 10, 195, 154, 160, 69, 196, 220, 152, 179, 44, 111, 200, - 84, 78, 215, 73, 210, 181, 12, 29, 70, 68, 36, 135, 153, 89, 230, 202, 130, 212, 111, 243, 234, 92, 131, 62, 145, - 50, 73, 48, 104, 245, 46, 70, 45, 157, 147, 143, 140, 162, 156, 216, 220, 49, 121, 142, 194, 33, 223, 201, 0, 16, - 163, 210, 240, 118, 92, 147, 121, 220, 17, 114, 24, 52, 125, 135, 176, 88, 21, 83, 86, 17, 156, 88, 250, 48, 79, 86, - 128, 248, 105, 208, 133, 140, 13, 153, 164, 191, 136, 164, 44, 53, 2, 3, 1, 0, 1, 2, 129, 128, 70, 75, 184, 139, 53, - 1, 94, 17, 240, 244, 218, 101, 193, 253, 215, 190, 164, 204, 197, 192, 200, 89, 107, 39, 171, 119, 65, 38, 204, 168, - 105, 180, 234, 217, 16, 161, 185, 132, 175, 103, 25, 154, 153, 153, 36, 36, 26, 178, 150, 66, 45, 8, 185, 19, 90, - 228, 210, 177, 30, 200, 177, 141, 78, 184, 248, 59, 113, 154, 145, 73, 160, 24, 73, 157, 86, 207, 186, 32, 95, 200, - 106, 252, 107, 69, 170, 193, 216, 196, 181, 142, 74, 203, 15, 18, 89, 228, 152, 19, 239, 21, 233, 98, 121, 214, 57, - 187, 111, 239, 223, 248, 199, 70, 223, 108, 108, 113, 234, 144, 155, 95, 246, 144, 244, 122, 39, 55, 127, 81, 2, 65, - 0, 246, 96, 188, 0, 0, 104, 221, 105, 139, 144, 63, 175, 209, 87, 179, 162, 88, 192, 99, 82, 125, 53, 54, 48, 70, - 245, 239, 37, 15, 242, 247, 84, 115, 187, 196, 95, 156, 40, 165, 60, 64, 102, 13, 229, 243, 2, 149, 0, 232, 226, - 221, 192, 95, 11, 12, 208, 5, 181, 98, 62, 210, 190, 141, 235, 2, 65, 0, 204, 244, 34, 10, 105, 80, 76, 116, 163, - 35, 231, 168, 187, 206, 189, 101, 215, 103, 80, 115, 86, 11, 34, 127, 203, 114, 84, 188, 121, 174, 169, 31, 142, 2, - 182, 27, 140, 225, 157, 227, 71, 98, 15, 203, 187, 213, 5, 190, 20, 121, 8, 30, 193, 100, 232, 101, 141, 8, 124, 20, - 29, 78, 6, 95, 2, 65, 0, 204, 43, 225, 224, 6, 118, 224, 117, 100, 200, 199, 94, 70, 23, 109, 175, 173, 232, 208, - 230, 61, 8, 105, 189, 156, 48, 150, 91, 154, 89, 248, 136, 173, 215, 254, 166, 84, 220, 130, 1, 234, 68, 40, 100, - 84, 251, 224, 202, 254, 51, 115, 28, 198, 38, 124, 25, 175, 129, 94, 199, 61, 17, 216, 189, 2, 64, 72, 230, 129, - 129, 48, 138, 134, 87, 106, 123, 231, 247, 165, 173, 216, 194, 115, 198, 228, 223, 209, 120, 46, 114, 68, 92, 75, - 117, 170, 214, 140, 131, 147, 208, 181, 19, 193, 157, 178, 186, 87, 246, 178, 101, 166, 79, 20, 54, 211, 51, 101, - 199, 2, 197, 48, 192, 134, 84, 193, 69, 170, 82, 201, 131, 2, 65, 0, 213, 165, 55, 166, 131, 210, 195, 56, 250, 147, - 195, 61, 205, 208, 189, 185, 40, 52, 50, 119, 137, 23, 246, 46, 220, 108, 52, 23, 152, 154, 94, 32, 144, 195, 184, - 249, 21, 168, 12, 57, 222, 18, 60, 117, 81, 157, 72, 30, 155, 190, 165, 242, 228, 139, 240, 184, 145, 170, 103, 210, - 160, 161, 135, 13]); - public static rsaKeyNin = BigInt('0x9260d0750ae117eee55c3f3deaba74917521a262ee76007cdf8a56755ad73a1598a1408410a' + - '01434c3f5bc54a88b57fa19fc4328daea0750a4c44e88cff3b2382621b80f670464433e4336e6d003e8cd65bff211da144b88291c2259a00' + - 'a72b711c116ef7686e8fee34e4d933c868187bdc26f7be071493c86f7a5941c3510806ad67b0f94d88f5cf5c02a092821d8626e8932b65c5' + - 'bd8c92049c210932b7afa7ac59c0e886ae5c1edb00d8ce2c57633db26bd6639bff73cee82be9275c402b4cf2a4388da8cf8c64eefe1c5a0f' + - '5ab8057c39fa5c0589c3e253f0960332300f94bea44877b588e1edbde97cf2360727a09b775262d7ee552b3319b9266f05a25'); - public static rsaKeyDIn = BigInt('0x6a7df2ca63ead4dda191d614b6b385e0d9056a3d6d5cfe07db1daabee022db08212d97613d3328e' + - '0267c9dd23d787abde2afcb306aeb7dfce69246cc73f5c87fdf06030179a2114b767db1f083ff841c025d7dc00cd82435b9a90f695369e94' + - 'df23d2ce458bc3b3283ad8bba2b8fa1ba62e2dce9accff3799aae7c840016f3ba8e0048c0b6cc4339af7161003a5beb864a0164b2c1c9237' + - 'b64bc87556994351b27506c33d4bcdfce0f9c491a7d6b0628c7c852be4f0a9c3132b2ed3a2c8881e9aab07e20e17deb074691be677776a78' + - 'b5c502e05d9bdde72126b3738695e2dd1a0a98a14247c65d8a7ee79432a092cb0721a12df798e44f7cfce0c498147a9b1'); - - public static getCryptoList(): CryptoItem[] { - let cryptoList: CryptoItem[] = []; - cryptoList.push(new CryptoItem($r('app.string.AES_GCM'), $r('app.string.encrypt'), - $r('app.string.decrypt'), 'AES_GCM')); - cryptoList.push(new CryptoItem($r('app.string.AES_CBC'), $r('app.string.encrypt'), - $r('app.string.decrypt'), 'AES_CBC')); - cryptoList.push(new CryptoItem($r('app.string.AES_EBC'), $r('app.string.encrypt'), - $r('app.string.decrypt'), 'AES_ECB')); - cryptoList.push(new CryptoItem($r('app.string.3DES_EBC'), $r('app.string.encrypt'), - $r('app.string.decrypt'), '3DES_ECB')); - cryptoList.push(new CryptoItem($r('app.string.SM4_EBC'), $r('app.string.encrypt'), - $r('app.string.decrypt'), 'SM4_ECB')); - cryptoList.push(new CryptoItem($r('app.string.SM4_CBC'), $r('app.string.encrypt'), - $r('app.string.decrypt'), 'SM4_CBC')); - cryptoList.push(new CryptoItem($r('app.string.RSA_PKCS1'), $r('app.string.encrypt'), - $r('app.string.decrypt'), 'RSA_PKCS1')); - cryptoList.push(new CryptoItem($r('app.string.RSA_PKCS1_OAEP'), $r('app.string.encrypt'), - $r('app.string.decrypt'), - 'RSA_PKCS1_OAEP')); - cryptoList.push(new CryptoItem($r('app.string.SM2_crypto'), $r('app.string.encrypt'), - $r('app.string.decrypt'), 'SM2')); - cryptoList.push(new CryptoItem($r('app.string.rsa_dissymmetry_pkcs1'), - $r('app.string.decrypt'), $r('app.string.encrypt'), - 'RSA_PKCS1_BIG')); - cryptoList.push(new CryptoItem($r('app.string.format_conversion'), - $r('app.string.encrypt'), $r('app.string.decrypt'), 'SM2')); - return cryptoList; - } -} \ No newline at end of file diff --git a/CrossPlatformCompatibility/entry/src/main/ets/viewmodel/SignatureItem.ets b/CrossPlatformCompatibility/entry/src/main/ets/viewmodel/SignatureItem.ets deleted file mode 100644 index ff8344090a5f4bde308c1a11f3488ffebf377365..0000000000000000000000000000000000000000 --- a/CrossPlatformCompatibility/entry/src/main/ets/viewmodel/SignatureItem.ets +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -export class SignatureItem { - name: Resource = $r('app.string.empty'); - type: string = ''; - keyGenAlg: string = ''; - isSegment: boolean = false; - - constructor(name: Resource, type: string, keyGenAlg: string, isSegment: boolean) { - this.name = name; - this.type = type; - this.keyGenAlg = keyGenAlg; - this.isSegment = isSegment; - } -} \ No newline at end of file diff --git a/CrossPlatformCompatibility/entry/src/main/ets/viewmodel/SignatureViewModel.ets b/CrossPlatformCompatibility/entry/src/main/ets/viewmodel/SignatureViewModel.ets deleted file mode 100644 index 4cc1da805626a0b14d856965ce5ecde307e3f713..0000000000000000000000000000000000000000 --- a/CrossPlatformCompatibility/entry/src/main/ets/viewmodel/SignatureViewModel.ets +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -import { SignatureItem } from './SignatureItem'; - -export class SignatureViewModel { - public static getSignatureList(): SignatureItem[] { - let SignatureList: SignatureItem[] = []; - SignatureList.push(new SignatureItem($r('app.string.rsa_pkcs1'), 'RSA1024|PKCS1|SHA256', 'RSA1024', false)); - SignatureList.push(new SignatureItem($r('app.string.rsa_pkcs1_seg'), 'RSA1024|PKCS1|SHA256', 'RSA1024', true)); - SignatureList.push(new SignatureItem($r('app.string.rsa_pass'), 'RSA|PASS|SHA256|MGF1_SHA256', '', false)); - SignatureList.push(new SignatureItem($r('app.string.ecdsa'), 'ECC256|SHA256', 'ECC256', false)); - SignatureList.push(new SignatureItem($r('app.string.sm2'), 'SM2_256|SM3', 'SM2_256', false)); - - return SignatureList; - } -} \ No newline at end of file diff --git a/CrossPlatformCompatibility/entry/src/main/ets/viewmodel/SummaryItem.ets b/CrossPlatformCompatibility/entry/src/main/ets/viewmodel/SummaryItem.ets deleted file mode 100644 index 1c3065dca4ebe0f911ed80625058e418d85e8784..0000000000000000000000000000000000000000 --- a/CrossPlatformCompatibility/entry/src/main/ets/viewmodel/SummaryItem.ets +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -export class SummaryItem { - name: Resource = $r('app.string.empty'); - type: string = ''; - - constructor(name: Resource, type: string) { - this.name = name; - this.type = type; - } -} \ No newline at end of file diff --git a/CrossPlatformCompatibility/entry/src/main/ets/viewmodel/SummaryViewModel.ets b/CrossPlatformCompatibility/entry/src/main/ets/viewmodel/SummaryViewModel.ets deleted file mode 100644 index 2828a4849d239e5f94201e7979017956ae107814..0000000000000000000000000000000000000000 --- a/CrossPlatformCompatibility/entry/src/main/ets/viewmodel/SummaryViewModel.ets +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -import { SummaryItem } from './SummaryItem'; - -export class SummaryViewModel { - public static getSummaryList(): SummaryItem[] { - let SummaryList: SummaryItem[] = []; - SummaryList.push(new SummaryItem($r('app.string.SHA256'), 'SHA256')); - SummaryList.push(new SummaryItem($r('app.string.SHA256Segments'), 'SHA256Segments')); - SummaryList.push(new SummaryItem($r('app.string.MD5'), 'MD5')); - SummaryList.push(new SummaryItem($r('app.string.SM3'), 'SM3')); - - return SummaryList; - } -} \ No newline at end of file diff --git a/CrossPlatformCompatibility/entry/src/main/module.json5 b/CrossPlatformCompatibility/entry/src/main/module.json5 deleted file mode 100644 index 4a3b5e15e45e58c87a37daef0dffe4fb4cdd4fec..0000000000000000000000000000000000000000 --- a/CrossPlatformCompatibility/entry/src/main/module.json5 +++ /dev/null @@ -1,39 +0,0 @@ -{ - "module": { - "name": "entry", - "type": "entry", - "description": "$string:module_desc", - "mainElement": "EntryAbility", - "deviceTypes": [ - "phone", - "tablet", - "2in1" - ], - "deliveryWithInstall": true, - "installationFree": false, - "pages": "$profile:main_pages", - "routerMap": "$profile:route_map", - "abilities": [ - { - "name": "EntryAbility", - "srcEntry": "./ets/entryability/EntryAbility.ets", - "description": "$string:EntryAbility_desc", - "icon": "$media:layered_image", - "label": "$string:EntryAbility_label", - "startWindowIcon": "$media:startIcon", - "startWindowBackground": "$color:start_window_background", - "exported": true, - "skills": [ - { - "entities": [ - "entity.system.home" - ], - "actions": [ - "action.system.home" - ] - } - ] - } - ] - } -} \ No newline at end of file diff --git a/CrossPlatformCompatibility/entry/src/main/resources/base/element/color.json b/CrossPlatformCompatibility/entry/src/main/resources/base/element/color.json deleted file mode 100644 index e0591d30d1e31b66e6b65dbe4604f867c86fd354..0000000000000000000000000000000000000000 --- a/CrossPlatformCompatibility/entry/src/main/resources/base/element/color.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "color": [ - { - "name": "start_window_background", - "value": "#FFFFFF" - }, - { - "name": "five_black", - "value": "#0d000000" - }, - { - "name": "background_page", - "value": "#ffefefef" - } - ] -} \ No newline at end of file diff --git a/CrossPlatformCompatibility/entry/src/main/resources/base/element/float.json b/CrossPlatformCompatibility/entry/src/main/resources/base/element/float.json deleted file mode 100644 index 9369ae1174bd6ce3323a68fb6bfc4742624329fe..0000000000000000000000000000000000000000 --- a/CrossPlatformCompatibility/entry/src/main/resources/base/element/float.json +++ /dev/null @@ -1,96 +0,0 @@ -{ - "float": [ - { - "name": "count_size", - "value": "18fp" - }, - { - "name": "count_margin_bottom", - "value": "14vp" - }, - { - "name": "common_font", - "value": "16fp" - }, - { - "name": "arrow_width", - "value": "12vp" - }, - { - "name": "common_image", - "value": "24vp" - }, - { - "name": "list_item_height", - "value": "48vp" - }, - { - "name": "stroke_width", - "value": "0.5vp" - }, - { - "name": "small_padding", - "value": "12vp" - }, - { - "name": "medium_padding", - "value": "16vp" - }, - { - "name": "list_padding", - "value": "18vp" - }, - { - "name": "encrypted_margin_bottom", - "value": "34vp" - }, - { - "name": "common_line_height", - "value": "24vp" - }, - { - "name": "encrypted_padding_lr", - "value": "14vp" - }, - { - "name": "encrypted_padding_tb", - "value": "13vp" - }, - { - "name": "row_margin_top", - "value": "14vp" - }, - { - "name": "row_margin_bottom", - "value": "40vp" - }, - { - "name": "detail_padding_top", - "value": "56vp" - }, - { - "name": "text_lineHeight", - "value": "40vp" - }, - { - "name": "text_fontsize", - "value": "30vp" - }, - { - "name": "margin_top_sixteen", - "value": "16vp" - }, - { - "name": "margin_left_five", - "value": "5vp" - }, - { - "name": "textarea_height", - "value": "124vp" - }, - { - "name": "button_height", - "value": "40vp" - } - ] -} \ No newline at end of file diff --git a/CrossPlatformCompatibility/entry/src/main/resources/base/element/string.json b/CrossPlatformCompatibility/entry/src/main/resources/base/element/string.json deleted file mode 100644 index e87c5fcdc47774f8b41c7abf3229a9a666c7bd02..0000000000000000000000000000000000000000 --- a/CrossPlatformCompatibility/entry/src/main/resources/base/element/string.json +++ /dev/null @@ -1,212 +0,0 @@ -{ - "string": [ - { - "name": "module_desc", - "value": "module description" - }, - { - "name": "EntryAbility_desc", - "value": "description" - }, - { - "name": "EntryAbility_label", - "value": "CryptoCollection" - }, - { - "name": "total_count", - "value": "%d types in total" - }, - { - "name": "encrypt_sample", - "value": "Crypto framework sample" - }, - { - "name": "text_encrypted", - "value": "Text to be encrypted" - }, - { - "name": "after_encryption", - "value": "Encrypted data" - }, - { - "name": "detail", - "value": "detail" - }, - { - "name": "encrypt_btn", - "value": "Encryption/Decryption" - }, - { - "name": "signature_btn", - "value": "Signing & signature verification" - }, - { - "name": "message_btn", - "value": "MD" - }, - { - "name": "code_btn", - "value": "MAC" - }, - { - "name": "text_message_code", - "value": "Enter the data to be hashed." - }, - { - "name": "message_code_result", - "value": "Calculation result:" - }, - { - "name": "text_signature", - "value": "Entering Data to Be Signed" - }, - { - "name": "signature_result", - "value": "Verification result:" - }, - { - "name": "Signed", - "value": "Sign" - }, - { - "name": "signature_verification", - "value": "Verify signature" - }, - { - "name": "text_summary", - "value": "Enter the data to be summarized." - }, - { - "name": "summary_result", - "value": "Result:" - }, - { - "name": "SHA256", - "value": "MD with SHA256" - }, - { - "name": "SHA256Segments", - "value": "MD with SHA256 segmentation calculation" - }, - { - "name": "MD5", - "value": "MD with MD5" - }, - { - "name": "SM3", - "value": "MD with SM3" - }, - { - "name": "empty", - "value": "" - }, - { - "name": "calculate_code", - "value": "MAC with AES128|SHA256" - }, - { - "name": "calculate_seg_code", - "value": "MAC with AES128|SHA256 Segmental calculation" - }, - { - "name": "rsa_pkcs1", - "value": "RSA PKCS1" - }, - { - "name": "rsa_pkcs1_seg", - "value": "RSA PKCS1 segmented" - }, - { - "name": "rsa_pass", - "value": "RSA PASS" - }, - { - "name": "ecdsa", - "value": "ECDSA" - }, - { - "name": "sm2", - "value": "SM2" - }, - { - "name": "AES_GCM", - "value": "AES GCM" - }, - { - "name": "AES_CBC", - "value": "AES CBC" - }, - { - "name": "AES_EBC", - "value": "AES ECB" - }, - { - "name": "3DES_EBC", - "value": "3DES ECB" - }, - { - "name": "SM4_EBC", - "value": "SM4 ECB" - }, - { - "name": "SM4_CBC", - "value": "SM4 CBC" - }, - { - "name": "RSA_PKCS1", - "value": "RSA PKCS1" - }, - { - "name": "RSA_PKCS1_OAEP", - "value": "RSA PKCS1_OAEP" - }, - { - "name": "SM2_crypto", - "value": "SM2" - }, - { - "name": "rsa_dissymmetry_pkcs1", - "value": "RSA PKCS1 Asymmetric key" - }, - { - "name": "encrypted_text", - "value": "Encrypted text" - }, - { - "name": "decrypted_text", - "value": "Decrypted text" - }, - { - "name": "encrypt", - "value": "Encrypt" - }, - { - "name": "decrypt", - "value": "Decrypt" - }, - { - "name": "format_conversion", - "value": "SM2 key format conversion" - }, - { - "name": "format_error", - "value": "Incorrect ciphertext format" - }, - { - "name": "private_key", - "value": "Hexadecimal private key" - }, - { - "name": "public_key", - "value": "Hexadecimal public key" - }, - { - "name": "ASN_1", - "value": "ASN.1 format ciphertext" - }, - { - "name": "naked_ciphertext", - "value": "Naked ciphertext" - } - ] -} \ No newline at end of file diff --git a/CrossPlatformCompatibility/entry/src/main/resources/base/media/ic_public_arrow_right.svg b/CrossPlatformCompatibility/entry/src/main/resources/base/media/ic_public_arrow_right.svg deleted file mode 100644 index 42058ef482d5414af33bf4767855a810d5143840..0000000000000000000000000000000000000000 --- a/CrossPlatformCompatibility/entry/src/main/resources/base/media/ic_public_arrow_right.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - Created with Pixso. - - - - diff --git a/CrossPlatformCompatibility/entry/src/main/resources/base/profile/main_pages.json b/CrossPlatformCompatibility/entry/src/main/resources/base/profile/main_pages.json deleted file mode 100644 index 55c3f007f87b7ce5206d325f968cc56f2f79441f..0000000000000000000000000000000000000000 --- a/CrossPlatformCompatibility/entry/src/main/resources/base/profile/main_pages.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "src": [ - "pages/Index" - ] -} \ No newline at end of file diff --git a/CrossPlatformCompatibility/entry/src/main/resources/base/profile/route_map.json b/CrossPlatformCompatibility/entry/src/main/resources/base/profile/route_map.json deleted file mode 100644 index ae7c1dde6cc33f9fdc287b57c3f7e03ec1d93722..0000000000000000000000000000000000000000 --- a/CrossPlatformCompatibility/entry/src/main/resources/base/profile/route_map.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "routerMap": [ - { - "name": "EncryptionAndDecryption", - "pageSourceFile": "src/main/ets/pages/EncryptionAndDecryption.ets", - "buildFunction": "EncryptionAndDecryptionBuilder", - "data": { - "description": "this is EncryptionAndDecryption" - } - }, - { - "name": "SignatureVerification", - "pageSourceFile": "src/main/ets/pages/SignatureVerification.ets", - "buildFunction": "SignatureVerificationBuilder", - "data": { - "description": "this is SignatureVerification" - } - }, - { - "name": "MessageSummary", - "pageSourceFile": "src/main/ets/pages/MessageSummary.ets", - "buildFunction": "MessageSummaryBuilder", - "data": { - "description": "this is MessageSummary" - } - }, - { - "name": "MessageAuthenticationCode", - "pageSourceFile": "src/main/ets/pages/MessageAuthenticationCode.ets", - "buildFunction": "MessageAuthenticationCodeBuilder", - "data": { - "description": "this is MessageAuthenticationCode" - } - }, - { - "name": "CryptoDetail", - "pageSourceFile": "src/main/ets/view/CryptoDetail.ets", - "buildFunction": "CryptoDetailBuilder", - "data": { - "description": "this is CryptoDetail" - } - }, - { - "name": "SignatureDetail", - "pageSourceFile": "src/main/ets/view/SignatureDetail.ets", - "buildFunction": "SignatureDetailBuilder", - "data": { - "description": "this is SignatureDetail" - } - }, - { - "name": "SummaryDetail", - "pageSourceFile": "src/main/ets/view/SummaryDetail.ets", - "buildFunction": "SummaryDetailBuilder", - "data": { - "description": "this is SummaryDetail" - } - }, - { - "name": "AuthCodeDetail", - "pageSourceFile": "src/main/ets/view/AuthCodeDetail.ets", - "buildFunction": "AuthCodeDetailBuilder", - "data": { - "description": "this is AuthCodeDetail" - } - } - ] -} \ No newline at end of file diff --git a/CrossPlatformCompatibility/entry/src/main/resources/en_US/element/string.json b/CrossPlatformCompatibility/entry/src/main/resources/en_US/element/string.json deleted file mode 100644 index e87c5fcdc47774f8b41c7abf3229a9a666c7bd02..0000000000000000000000000000000000000000 --- a/CrossPlatformCompatibility/entry/src/main/resources/en_US/element/string.json +++ /dev/null @@ -1,212 +0,0 @@ -{ - "string": [ - { - "name": "module_desc", - "value": "module description" - }, - { - "name": "EntryAbility_desc", - "value": "description" - }, - { - "name": "EntryAbility_label", - "value": "CryptoCollection" - }, - { - "name": "total_count", - "value": "%d types in total" - }, - { - "name": "encrypt_sample", - "value": "Crypto framework sample" - }, - { - "name": "text_encrypted", - "value": "Text to be encrypted" - }, - { - "name": "after_encryption", - "value": "Encrypted data" - }, - { - "name": "detail", - "value": "detail" - }, - { - "name": "encrypt_btn", - "value": "Encryption/Decryption" - }, - { - "name": "signature_btn", - "value": "Signing & signature verification" - }, - { - "name": "message_btn", - "value": "MD" - }, - { - "name": "code_btn", - "value": "MAC" - }, - { - "name": "text_message_code", - "value": "Enter the data to be hashed." - }, - { - "name": "message_code_result", - "value": "Calculation result:" - }, - { - "name": "text_signature", - "value": "Entering Data to Be Signed" - }, - { - "name": "signature_result", - "value": "Verification result:" - }, - { - "name": "Signed", - "value": "Sign" - }, - { - "name": "signature_verification", - "value": "Verify signature" - }, - { - "name": "text_summary", - "value": "Enter the data to be summarized." - }, - { - "name": "summary_result", - "value": "Result:" - }, - { - "name": "SHA256", - "value": "MD with SHA256" - }, - { - "name": "SHA256Segments", - "value": "MD with SHA256 segmentation calculation" - }, - { - "name": "MD5", - "value": "MD with MD5" - }, - { - "name": "SM3", - "value": "MD with SM3" - }, - { - "name": "empty", - "value": "" - }, - { - "name": "calculate_code", - "value": "MAC with AES128|SHA256" - }, - { - "name": "calculate_seg_code", - "value": "MAC with AES128|SHA256 Segmental calculation" - }, - { - "name": "rsa_pkcs1", - "value": "RSA PKCS1" - }, - { - "name": "rsa_pkcs1_seg", - "value": "RSA PKCS1 segmented" - }, - { - "name": "rsa_pass", - "value": "RSA PASS" - }, - { - "name": "ecdsa", - "value": "ECDSA" - }, - { - "name": "sm2", - "value": "SM2" - }, - { - "name": "AES_GCM", - "value": "AES GCM" - }, - { - "name": "AES_CBC", - "value": "AES CBC" - }, - { - "name": "AES_EBC", - "value": "AES ECB" - }, - { - "name": "3DES_EBC", - "value": "3DES ECB" - }, - { - "name": "SM4_EBC", - "value": "SM4 ECB" - }, - { - "name": "SM4_CBC", - "value": "SM4 CBC" - }, - { - "name": "RSA_PKCS1", - "value": "RSA PKCS1" - }, - { - "name": "RSA_PKCS1_OAEP", - "value": "RSA PKCS1_OAEP" - }, - { - "name": "SM2_crypto", - "value": "SM2" - }, - { - "name": "rsa_dissymmetry_pkcs1", - "value": "RSA PKCS1 Asymmetric key" - }, - { - "name": "encrypted_text", - "value": "Encrypted text" - }, - { - "name": "decrypted_text", - "value": "Decrypted text" - }, - { - "name": "encrypt", - "value": "Encrypt" - }, - { - "name": "decrypt", - "value": "Decrypt" - }, - { - "name": "format_conversion", - "value": "SM2 key format conversion" - }, - { - "name": "format_error", - "value": "Incorrect ciphertext format" - }, - { - "name": "private_key", - "value": "Hexadecimal private key" - }, - { - "name": "public_key", - "value": "Hexadecimal public key" - }, - { - "name": "ASN_1", - "value": "ASN.1 format ciphertext" - }, - { - "name": "naked_ciphertext", - "value": "Naked ciphertext" - } - ] -} \ No newline at end of file diff --git a/CrossPlatformCompatibility/entry/src/main/resources/zh_CN/element/string.json b/CrossPlatformCompatibility/entry/src/main/resources/zh_CN/element/string.json deleted file mode 100644 index 31e8c2d273be0766e007a2139bc0e1085b2676ea..0000000000000000000000000000000000000000 --- a/CrossPlatformCompatibility/entry/src/main/resources/zh_CN/element/string.json +++ /dev/null @@ -1,212 +0,0 @@ -{ - "string": [ - { - "name": "module_desc", - "value": "模块描述" - }, - { - "name": "EntryAbility_desc", - "value": "description" - }, - { - "name": "EntryAbility_label", - "value": "CryptoCollection" - }, - { - "name": "total_count", - "value": "共%d种" - }, - { - "name": "encrypt_sample", - "value": "加密算法的Sample样例" - }, - { - "name": "text_encrypted", - "value": "待加密文本" - }, - { - "name": "after_encryption", - "value": "加密后" - }, - { - "name": "detail", - "value": "详情" - }, - { - "name": "encrypt_btn", - "value": "加解密" - }, - { - "name": "signature_btn", - "value": "签名验签" - }, - { - "name": "message_btn", - "value": "消息摘要" - }, - { - "name": "code_btn", - "value": "消息认证码" - }, - { - "name": "text_message_code", - "value": "输入需要HMAC的数据" - }, - { - "name": "message_code_result", - "value": "计算结果:" - }, - { - "name": "text_signature", - "value": "输入需要签名的数据" - }, - { - "name": "signature_result", - "value": "验签结果:" - }, - { - "name": "Signed", - "value": "签名" - }, - { - "name": "signature_verification", - "value": "验签" - }, - { - "name": "text_summary", - "value": "输入需要摘要的数据" - }, - { - "name": "summary_result", - "value": "摘要结果:" - }, - { - "name": "SHA256", - "value": "SHA256计算摘要" - }, - { - "name": "SHA256Segments", - "value": "SHA256分段计算摘要" - }, - { - "name": "MD5", - "value": "MD5计算摘要" - }, - { - "name": "SM3", - "value": "SM3计算摘要" - }, - { - "name": "empty", - "value": "" - }, - { - "name": "calculate_code", - "value": "AES128|SHA256 计算消息认证码" - }, - { - "name": "calculate_seg_code", - "value": "AES128|SHA256 分段计算消息认证码" - }, - { - "name": "rsa_pkcs1", - "value": "RSA PKCS1模式 签名验签" - }, - { - "name": "rsa_pkcs1_seg", - "value": "RSA PKCS1模式 分段签名验签" - }, - { - "name": "rsa_pass", - "value": "RSA PASS模式 签名验签" - }, - { - "name": "ecdsa", - "value": "ECDSA密钥对签名验签" - }, - { - "name": "sm2", - "value": "SM2密钥对签名验签" - }, - { - "name": "AES_GCM", - "value": "AES GCM模式加解密" - }, - { - "name": "AES_CBC", - "value": "AES CBC模式加解密" - }, - { - "name": "AES_EBC", - "value": "AES ECB模式加解密" - }, - { - "name": "3DES_EBC", - "value": "3DES ECB模式加解密" - }, - { - "name": "SM4_EBC", - "value": "SM4 ECB模式加解密" - }, - { - "name": "SM4_CBC", - "value": "SM4 CBC模式加解密" - }, - { - "name": "RSA_PKCS1", - "value": "RSA PKCS1模式加解密" - }, - { - "name": "RSA_PKCS1_OAEP", - "value": "RSA PKCS1_OAEP模式加解密" - }, - { - "name": "SM2_crypto", - "value": "SM2 非对称密钥加解密" - }, - { - "name": "rsa_dissymmetry_pkcs1", - "value": "RSA PKCS1非对称密钥分段加解密" - }, - { - "name": "encrypted_text", - "value": "已加密文本" - }, - { - "name": "decrypted_text", - "value": "已解密文本" - }, - { - "name": "encrypt", - "value": "加密" - }, - { - "name": "decrypt", - "value": "解密" - }, - { - "name": "format_conversion", - "value": "SM2密钥格式转换" - }, - { - "name": "format_error", - "value": "密文格式错误" - }, - { - "name": "private_key", - "value": "16进制私钥" - }, - { - "name": "public_key", - "value": "16进制公钥" - }, - { - "name": "ASN_1", - "value": "ASN.1格式密文" - }, - { - "name": "naked_ciphertext", - "value": "裸密文" - } - ] -} \ No newline at end of file diff --git a/CrossPlatformCompatibility/screenshots/devices/code.en.png b/CrossPlatformCompatibility/screenshots/devices/code.en.png deleted file mode 100644 index 5a6ba52e6ef5895b2a8df83aa239f71da91f3a5d..0000000000000000000000000000000000000000 Binary files a/CrossPlatformCompatibility/screenshots/devices/code.en.png and /dev/null differ diff --git a/CrossPlatformCompatibility/screenshots/devices/code.png b/CrossPlatformCompatibility/screenshots/devices/code.png deleted file mode 100644 index 24fcb0cbb7bc1e5108a6299789640d5dd98bdbf5..0000000000000000000000000000000000000000 Binary files a/CrossPlatformCompatibility/screenshots/devices/code.png and /dev/null differ diff --git a/CrossPlatformCompatibility/screenshots/devices/codeDetail.en.png b/CrossPlatformCompatibility/screenshots/devices/codeDetail.en.png deleted file mode 100644 index f5d1d74ce599ee2dee22d85899d7e06bb45d16c9..0000000000000000000000000000000000000000 Binary files a/CrossPlatformCompatibility/screenshots/devices/codeDetail.en.png and /dev/null differ diff --git a/CrossPlatformCompatibility/screenshots/devices/codeDetail.png b/CrossPlatformCompatibility/screenshots/devices/codeDetail.png deleted file mode 100644 index 7cb53333350959e6c591b9974a3d9bf44414971c..0000000000000000000000000000000000000000 Binary files a/CrossPlatformCompatibility/screenshots/devices/codeDetail.png and /dev/null differ diff --git a/CrossPlatformCompatibility/screenshots/devices/crypto.en.png b/CrossPlatformCompatibility/screenshots/devices/crypto.en.png deleted file mode 100644 index af675bf0d8f156d6eed17b634305fd3e4437ad86..0000000000000000000000000000000000000000 Binary files a/CrossPlatformCompatibility/screenshots/devices/crypto.en.png and /dev/null differ diff --git a/CrossPlatformCompatibility/screenshots/devices/crypto.png b/CrossPlatformCompatibility/screenshots/devices/crypto.png deleted file mode 100644 index ab161396d2a6434e1eb7a82cfdfa24e86d3b8f07..0000000000000000000000000000000000000000 Binary files a/CrossPlatformCompatibility/screenshots/devices/crypto.png and /dev/null differ diff --git a/CrossPlatformCompatibility/screenshots/devices/cryptoDetail.en.png b/CrossPlatformCompatibility/screenshots/devices/cryptoDetail.en.png deleted file mode 100644 index b12532c687490bdce844f8f73529442eb80ee316..0000000000000000000000000000000000000000 Binary files a/CrossPlatformCompatibility/screenshots/devices/cryptoDetail.en.png and /dev/null differ diff --git a/CrossPlatformCompatibility/screenshots/devices/cryptoDetail.png b/CrossPlatformCompatibility/screenshots/devices/cryptoDetail.png deleted file mode 100644 index 5559189e1058f79467d9b5d75b32e1c3511df43e..0000000000000000000000000000000000000000 Binary files a/CrossPlatformCompatibility/screenshots/devices/cryptoDetail.png and /dev/null differ diff --git a/CrossPlatformCompatibility/screenshots/devices/format_conversion.png b/CrossPlatformCompatibility/screenshots/devices/format_conversion.png deleted file mode 100644 index b8e178f6200f67192d2f0510a553435e109910b1..0000000000000000000000000000000000000000 Binary files a/CrossPlatformCompatibility/screenshots/devices/format_conversion.png and /dev/null differ diff --git a/CrossPlatformCompatibility/screenshots/devices/index.en.png b/CrossPlatformCompatibility/screenshots/devices/index.en.png deleted file mode 100644 index 4e10cedc9551c3d116ed695cad94f2be10b831b6..0000000000000000000000000000000000000000 Binary files a/CrossPlatformCompatibility/screenshots/devices/index.en.png and /dev/null differ diff --git a/CrossPlatformCompatibility/screenshots/devices/index.png b/CrossPlatformCompatibility/screenshots/devices/index.png deleted file mode 100644 index cf439fb314d382acf2d3281d65eeb62911e07b9f..0000000000000000000000000000000000000000 Binary files a/CrossPlatformCompatibility/screenshots/devices/index.png and /dev/null differ diff --git a/CrossPlatformCompatibility/screenshots/devices/signature.en.png b/CrossPlatformCompatibility/screenshots/devices/signature.en.png deleted file mode 100644 index 2967f350ee8f0c0aa888bdea7c0671a53cc900c1..0000000000000000000000000000000000000000 Binary files a/CrossPlatformCompatibility/screenshots/devices/signature.en.png and /dev/null differ diff --git a/CrossPlatformCompatibility/screenshots/devices/signature.png b/CrossPlatformCompatibility/screenshots/devices/signature.png deleted file mode 100644 index 98c381d8b124563d5ddd34cd3728a485136e51bf..0000000000000000000000000000000000000000 Binary files a/CrossPlatformCompatibility/screenshots/devices/signature.png and /dev/null differ diff --git a/CrossPlatformCompatibility/screenshots/devices/signatureDetail.en.png b/CrossPlatformCompatibility/screenshots/devices/signatureDetail.en.png deleted file mode 100644 index a1a4ed1a538e27d13134c8f9b03ed2357b010b8d..0000000000000000000000000000000000000000 Binary files a/CrossPlatformCompatibility/screenshots/devices/signatureDetail.en.png and /dev/null differ diff --git a/CrossPlatformCompatibility/screenshots/devices/signatureDetail.png b/CrossPlatformCompatibility/screenshots/devices/signatureDetail.png deleted file mode 100644 index 414e60b807795bd9c5bd1a12f7e5a3c8b9c58f87..0000000000000000000000000000000000000000 Binary files a/CrossPlatformCompatibility/screenshots/devices/signatureDetail.png and /dev/null differ diff --git a/CrossPlatformCompatibility/screenshots/devices/summary.en.png b/CrossPlatformCompatibility/screenshots/devices/summary.en.png deleted file mode 100644 index fb08ac1fa9a2826f29f98b0d960b6cd6e4e2268a..0000000000000000000000000000000000000000 Binary files a/CrossPlatformCompatibility/screenshots/devices/summary.en.png and /dev/null differ diff --git a/CrossPlatformCompatibility/screenshots/devices/summary.png b/CrossPlatformCompatibility/screenshots/devices/summary.png deleted file mode 100644 index 5010d47127bcd9172db6d1a3c701f7212fe41bc3..0000000000000000000000000000000000000000 Binary files a/CrossPlatformCompatibility/screenshots/devices/summary.png and /dev/null differ diff --git a/CrossPlatformCompatibility/screenshots/devices/summaryDetail.en.png b/CrossPlatformCompatibility/screenshots/devices/summaryDetail.en.png deleted file mode 100644 index 5733964e69911307148eaf288ed46dc4a50f6e4e..0000000000000000000000000000000000000000 Binary files a/CrossPlatformCompatibility/screenshots/devices/summaryDetail.en.png and /dev/null differ diff --git a/CrossPlatformCompatibility/screenshots/devices/summaryDetail.png b/CrossPlatformCompatibility/screenshots/devices/summaryDetail.png deleted file mode 100644 index 59a52cbc2ae6e013ae6c4c1bc0061ec345d202d7..0000000000000000000000000000000000000000 Binary files a/CrossPlatformCompatibility/screenshots/devices/summaryDetail.png and /dev/null differ diff --git a/CustomDialogPractice/README.md b/CustomDialogPractice/README.md index 62351637f770d1357c6f25b73545a22c05aa289d..699cb32e3940ecea4c896896090bb5e6705356d2 100644 --- a/CustomDialogPractice/README.md +++ b/CustomDialogPractice/README.md @@ -55,8 +55,19 @@ ## 约束与限制 * 本示例仅支持标准系统上运行,支持设备:华为手机。 -* HarmonyOS系统:HarmonyOS NEXT Release及以上。 +* HarmonyOS系统:HarmonyOS 5.0.5 Release及以上。 -* DevEco Studio版本:DevEco Studio NEXT Release及以上。 +* DevEco Studio版本:DevEco Studio 5.0.5 Release及以上。 -* HarmonyOS SDK版本:HarmonyOS NEXT Release SDK及以上。 \ No newline at end of file +* HarmonyOS SDK版本:HarmonyOS 5.0.5 Release SDK及以上。 + +## 下载 + +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set CustomDialogPractice +git checkout +``` \ No newline at end of file diff --git a/CustomDialogPractice/README_EN.md b/CustomDialogPractice/README_EN.md index 45d4ced78882e091d62af3b60254a9d311c1e673..3fab6856f950f59011c0cbc70bc612ef855daa37 100644 --- a/CustomDialogPractice/README_EN.md +++ b/CustomDialogPractice/README_EN.md @@ -53,8 +53,19 @@ N/A ## Constraints * This sample is supported only on Huawei phones running the standard system. -* The HarmonyOS version must be HarmonyOS NEXT Release or later. +* The HarmonyOS version must be HarmonyOS 5.0.5 Release or later. -* The DevEco Studio version must be DevEco Studio NEXT Release or later. +* The DevEco Studio version must be DevEco Studio 5.0.5 Release or later. -* The HarmonyOS SDK version must be HarmonyOS NEXT Release SDK or later. +* The HarmonyOS SDK version must be HarmonyOS 5.0.5 Release SDK or later. + +## Download + +To download this project separately, execute the following command: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set CustomDialogPractice +git checkout +``` diff --git a/CustomDialogPractice/build-profile.json5 b/CustomDialogPractice/build-profile.json5 index c033ce4278fb0641d84107c3c134047ac487368e..b2ca56e35558b0dc7ca91989b68a1ea65b49a7a2 100644 --- a/CustomDialogPractice/build-profile.json5 +++ b/CustomDialogPractice/build-profile.json5 @@ -5,7 +5,8 @@ { "name": "default", "signingConfig": "default", - "compatibleSdkVersion": "5.0.0(12)", + "compatibleSdkVersion": "5.0.5(17)", + "targetSdkVersion": "5.0.5(17)", "runtimeOS": "HarmonyOS", } ], diff --git a/CustomTitleBarWindowDrag/README.md b/CustomTitleBarWindowDrag/README.md index b2ab422c7c8c1df41f84a169b5e47c402875fb4e..cd048f15c3b9fc24988defcdc4045947054967ea 100644 --- a/CustomTitleBarWindowDrag/README.md +++ b/CustomTitleBarWindowDrag/README.md @@ -8,6 +8,9 @@ ![](screenshots/windowDrag.gif) +### 使用说明 +- 点击应用中间的蓝色区域,可拖动应用。 + ### 工程目录 ``` @@ -21,6 +24,10 @@ └──entry/src/main/resources // 应用资源目录 ``` +### 具体实现 +1. 手指触摸动作触发onTouch()该方法。 +2. 使用startMoving()方法,指定鼠标在窗口内的位置并移动窗口。 + ### 相关权限 不涉及 @@ -32,6 +39,17 @@ ### 约束与限制 1. 本示例仅支持标准系统上运行,支持设备:华为PC/2in1设备、华为平板。 -2. HarmonyOS系统:HarmonyOS 5.0.2 Release及以上。 -3. DevEco Studio版本:DevEco Studio 5.0.2 Release及以上。 -4. HarmonyOS SDK版本:HarmonyOS 5.0.2 Release SDK及以上。 \ No newline at end of file +2. HarmonyOS系统:HarmonyOS 5.0.5 Release及以上。 +3. DevEco Studio版本:DevEco Studio 5.0.5 Release及以上。 +4. HarmonyOS SDK版本:HarmonyOS 5.0.5 Release SDK及以上。 + +### 下载 + +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set CustomTitleBarWindowDrag +git checkout +``` \ No newline at end of file diff --git a/CustomTitleBarWindowDrag/build-profile.json5 b/CustomTitleBarWindowDrag/build-profile.json5 index 30b3aa3b92da773d9bc28b812b92c6190be1fe4b..23ad76dd86e2cca98a368dff379e0853bf23807b 100644 --- a/CustomTitleBarWindowDrag/build-profile.json5 +++ b/CustomTitleBarWindowDrag/build-profile.json5 @@ -5,7 +5,7 @@ "name": "default", "signingConfig": "default", "targetSdkVersion": "5.0.5(17)", - "compatibleSdkVersion": "5.0.2(14)", + "compatibleSdkVersion": "5.0.5(17)", "runtimeOS": "HarmonyOS", "buildOption": { "strictMode": { diff --git a/CustomTitleBarWindowDrag/entry/src/main/ets/entryability/EntryAbility.ets b/CustomTitleBarWindowDrag/entry/src/main/ets/entryability/EntryAbility.ets index 77569cfe3babdcd0b4d008dd693d7aca52fb5d1a..46a56672db0fd3658e710fcd10c696bdcf41dc41 100644 --- a/CustomTitleBarWindowDrag/entry/src/main/ets/entryability/EntryAbility.ets +++ b/CustomTitleBarWindowDrag/entry/src/main/ets/entryability/EntryAbility.ets @@ -13,16 +13,21 @@ * limitations under the License. */ -import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { ConfigurationConstant, UIAbility } from '@kit.AbilityKit'; +import { BusinessError } from '@kit.BasicServicesKit'; import { hilog } from '@kit.PerformanceAnalysisKit'; import { window } from '@kit.ArkUI'; -import { BusinessError } from '@kit.BasicServicesKit'; const DOMAIN = 0x0000; export default class EntryAbility extends UIAbility { - onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { - this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + onCreate(): void { + try { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + } catch (error) { + let err = error as BusinessError; + hilog.warn(0x000, 'testTag', `setColorMode failed, code=${err.code}, message=${err.message}`); + } hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); } @@ -42,8 +47,8 @@ export default class EntryAbility extends UIAbility { hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.'); }); - try { - windowStage.getMainWindow().then((mainWindow: window.Window) => { + windowStage.getMainWindow() + .then((mainWindow: window.Window) => { try { mainWindow.resize(500, 400).then(() => { console.info('Succeeded in changing the window size.'); @@ -54,11 +59,11 @@ export default class EntryAbility extends UIAbility { console.error(`Failed to change the window size. Cause code: ${exception.code}, message: ${exception.message}`); } AppStorage.setOrCreate('mainWindow', mainWindow); - }); - } catch (exception) { - hilog.error(DOMAIN, 'testTag', 'Failed to set window system bar properties, Cause: %{public}s', - JSON.stringify(exception) ?? ''); - } + }) + .catch((err: BusinessError) => { + hilog.error(0x000, 'testTag', `getMainWindow failed, code=${err.code}, message=${err.message}`); + }) + // cache the window manager into AppStorage AppStorage.setOrCreate('window', windowStage); } diff --git a/CustomTitleBarWindowDrag/entry/src/main/ets/pages/Index.ets b/CustomTitleBarWindowDrag/entry/src/main/ets/pages/Index.ets index f48b004992d001bf13a88a75b454e2da6c3f7efb..62509d8daeb1dca35f235ce62a810dc948c4e81b 100644 --- a/CustomTitleBarWindowDrag/entry/src/main/ets/pages/Index.ets +++ b/CustomTitleBarWindowDrag/entry/src/main/ets/pages/Index.ets @@ -14,18 +14,18 @@ */ // [Start drag_sample] -import { window } from '@kit.ArkUI'; import { BusinessError } from '@kit.BasicServicesKit'; +import { window } from '@kit.ArkUI'; -const COLUMN_WIDTH = 108; -const COLUMN_TOP = 50; -const COLUMN_LEFT = 100; +const COLUMN_WIDTH: number = 108; +const COLUMN_TOP: number = 50; +const COLUMN_LEFT: number = 100; @Entry @Component struct Index { // get the window manager from AppStorage - private windowStage = AppStorage.get('window') as window.WindowStage; + windowStage: window.WindowStage = AppStorage.get('window') as window.WindowStage; build() { Column() { @@ -35,7 +35,7 @@ struct Index { if (event.type === TouchType.Down) { try { let wnd: window.Window = this.windowStage.getMainWindowSync(); - if (canIUse("SystemCapability.Window.SessionManager")) { + if (canIUse('SystemCapability.Window.SessionManager')) { wnd.startMoving().then(() => { console.info('wnd Succeeded in starting moving window'); }).catch((err: BusinessError) => { diff --git a/DealStrideSolution/README.en.md b/DealStrideSolution/README.en.md index 74b4d0f44e45d4fcff7636f9ccb556de69e4f9f7..a40c31651f968ffda5de86b75301f6c10acf556d 100644 --- a/DealStrideSolution/README.en.md +++ b/DealStrideSolution/README.en.md @@ -10,6 +10,9 @@ After obtaining the preview stream buffer of each frame, if the image is stacked |----------------------------------------------------------|----------------------------------------------------------| | | | + +The images are for reference only. The actual camera preview and captured images shall prevail. + ## How to Use 1. Tap the **Negative example: unprocessed stride** button to redirect to the child page **NoDealStride**. The camera preview stream is displayed on the child page, and an artifact appears. @@ -17,7 +20,7 @@ After obtaining the preview stream buffer of each frame, if the image is stacked 2. Tap **Process stride: solution 2** on the parent page to redirect to the child page **DealStrideTwo**. The camera preview stream is displayed on the child page, and no artifact appears. -### Project Directory +## Project Directory ``` ├──entry/src/main/ets/ @@ -148,20 +151,31 @@ function onImageArrival(receiver: image.ImageReceiver): void { }) } ``` -### Required Permissions +## Required Permissions **ohos.permission.CAMERA**: allows an application to use the camera. -### Dependencies +## Dependencies N/A -### Constraints +## Constraints 1. This sample is supported only on Huawei phones with standard systems. -2. The HarmonyOS version must be HarmonyOS 5.0.0 Release or later. +2. The HarmonyOS version must be HarmonyOS 5.0.5 Release or later. + +3. The DevEco Studio version must be DevEco Studio 5.0.5 Release or later. -3. The DevEco Studio version must be DevEco Studio 5.0.0 Release or later. +4. The HarmonyOS SDK version must be HarmonyOS 5.0.5 Release SDK or later. -4. The HarmonyOS SDK version must be HarmonyOS 5.0.0 Release SDK or later. \ No newline at end of file +## Download + +To download this project separately, execute the following command: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set DealStrideSolution +git checkout +``` \ No newline at end of file diff --git a/DealStrideSolution/README.md b/DealStrideSolution/README.md index de18509c1a1a7729755f116c46223af2cfda489d..267ca1d0874a85e7dbe1c1a3bffea5f0d8328323 100644 --- a/DealStrideSolution/README.md +++ b/DealStrideSolution/README.md @@ -10,6 +10,9 @@ |----------------------------------------------------------|----------------------------------------------------------| | | | + +图片仅作参考,具体相机预览效果,以实际使用时拍摄画面为主。 + ## 使用说明 1、父页面点击"反例:未处理stride"按钮,跳转子页面NoDealStride,子页面的预览界面展示相机预览流,出现花屏现象。 @@ -17,7 +20,7 @@ 2、父页面点击"处理stride:方案二"按钮,跳转子页面DealStrideTwo,子页面的预览界面展示相机预览流,无明显花屏现象。 -### 目录结构 +## 目录结构 ``` ├──entry/src/main/ets/ @@ -148,20 +151,31 @@ function onImageArrival(receiver: image.ImageReceiver): void { }) } ``` -### 相关权限 +## 相关权限 允许应用使用相机:ohos.permission.CAMERA -### 依赖 +## 依赖 不涉及。 -### 约束与限制 +## 约束与限制 1.本示例仅支持标准系统上运行,支持设备:华为手机。 -2.HarmonyOS系统:HarmonyOS 5.0.0 Release及以上。 +2.HarmonyOS系统:HarmonyOS 5.0.5 Release及以上。 + +3.DevEco Studio版本:DevEco Studio 5.0.5 Release及以上。 -3.DevEco Studio版本:DevEco Studio 5.0.0 Release及以上。 +4.HarmonyOS SDK版本:HarmonyOS 5.0.5 Release SDK及以上。 -4.HarmonyOS SDK版本:HarmonyOS 5.0.0 Release SDK及以上。 \ No newline at end of file +## 下载 + +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set DealStrideSolution +git checkout +``` \ No newline at end of file diff --git a/DealStrideSolution/build-profile.json5 b/DealStrideSolution/build-profile.json5 index 1e69556b3411622cb2e87a87389653bb34f1b148..492123c253881f5bbd9bc76553bfb74e842dfb40 100644 --- a/DealStrideSolution/build-profile.json5 +++ b/DealStrideSolution/build-profile.json5 @@ -5,7 +5,8 @@ { "name": "default", "signingConfig": "default", - "compatibleSdkVersion": "5.0.0(12)", + "compatibleSdkVersion": "5.0.5(17)", + "targetSdkVersion": "5.0.5(17)", "runtimeOS": "HarmonyOS", "buildOption": { "strictMode": { diff --git a/DealStrideSolution/entry/src/main/ets/common/Constants.ts b/DealStrideSolution/entry/src/main/ets/common/Constants.ts index 03df7571d5a91b53aa0db128f7ea8c9798272b81..caeead495d922b60357f8b0cdcdda68310521728 100644 --- a/DealStrideSolution/entry/src/main/ets/common/Constants.ts +++ b/DealStrideSolution/entry/src/main/ets/common/Constants.ts @@ -17,9 +17,9 @@ export class Constants { /** * Surface width in xComponent. */ - static readonly X_COMPONENT_SURFACE_WIDTH = 1080; // 1080*1080 stride->1088 + static readonly X_COMPONENT_SURFACE_WIDTH: number = 1080; // 1080*1080 stride->1088 /** * Surface height in xComponent. */ - static readonly X_COMPONENT_SURFACE_HEIGHT = 1080; + static readonly X_COMPONENT_SURFACE_HEIGHT: number = 1080; }; \ No newline at end of file diff --git a/DealStrideSolution/entry/src/main/ets/entryability/EntryAbility.ets b/DealStrideSolution/entry/src/main/ets/entryability/EntryAbility.ets index dd56c05a43816f0b1132df308769780b026caffd..e27cc9f8df919470b70675acba62219d560ccf09 100644 --- a/DealStrideSolution/entry/src/main/ets/entryability/EntryAbility.ets +++ b/DealStrideSolution/entry/src/main/ets/entryability/EntryAbility.ets @@ -33,16 +33,26 @@ export default class EntryAbility extends UIAbility { onWindowStageCreate(windowStage: window.WindowStage): void { // Main window is created, set main page for this ability Logger.info(TAG, 'Ability onWindowStageCreate'); - windowStage.getMainWindow().then((win: window.Window): void => { - win.setWindowLayoutFullScreen(true).then((): void => { - }); - win.setWindowSystemBarProperties({ - // Navigation bar color - navigationBarColor: '#F1F3F5', - // Status bar color - statusBarColor: '#F1F3F5' + windowStage.getMainWindow() + .then((win: window.Window): void => { + win.setWindowLayoutFullScreen(true).then((): void => { + }) + .catch((err: BusinessError) => { + hilog.error(0x000, 'testTag', `setWindowLayoutFullScreen failed, code=${err.code}, message=${err.message}`); + }) + win.setWindowSystemBarProperties({ + // Navigation bar color + navigationBarColor: '#F1F3F5', + // Status bar color + statusBarColor: '#F1F3F5' + }) + .catch((err: BusinessError) => { + hilog.error(0x000, 'testTag', `setWindowSystemBarProperties failed, code=${err.code}, message=${err.message}`); + }) + }) + .catch((err: BusinessError) => { + hilog.error(0x000, 'testTag', `getMainWindow failed, code=${err.code}, message=${err.message}`); }) - }); windowStage.loadContent('pages/Index', (err, data) => { if (err.code) { diff --git a/DealStrideSolution/entry/src/main/ets/pages/PageOne.ets b/DealStrideSolution/entry/src/main/ets/pages/PageOne.ets index a2145ff3b8fda8089cdd93b62ce49036d1e14ada..c50c265ecb190fcec6125fb7636605a7e2f05e47 100644 --- a/DealStrideSolution/entry/src/main/ets/pages/PageOne.ets +++ b/DealStrideSolution/entry/src/main/ets/pages/PageOne.ets @@ -14,9 +14,10 @@ */ import { image } from '@kit.ImageKit'; +import { BusinessError } from '@kit.BasicServicesKit'; import CameraService from '../utils/CameraServiceOne'; import { CommonConstants } from '../common/CommonConstants'; -import { promptAction } from '@kit.ArkUI'; +import { hilog } from '@kit.PerformanceAnalysisKit'; @Builder export function PageOneBuilder() { @@ -46,7 +47,7 @@ export struct PageOne { } @Builder - navDestinationTitleImg(res:Resource,fun:()=>void) { + navDestinationTitleImg(res: Resource, fun: () => void) { Image(res) .padding(8) .width(40) @@ -76,7 +77,12 @@ export struct PageOne { .layoutWeight(1) this.navDestinationTitleImg($r('app.media.more'), () => { - this.getUIContext().getPromptAction().showToast({ message: $r('app.string.only_show_for_ux') }) + try { + this.getUIContext().getPromptAction().showToast({ message: $r('app.string.only_show_for_ux') }) + } catch (error) { + let err = error as BusinessError; + hilog.warn(0x000, 'testTag', `showToast failed, code=${err.code}, message=${err.message}`); + } }) } .width('100%') @@ -150,7 +156,12 @@ export struct PublishView { right: 18 }) .onClick(() => { - this.getUIContext().getPromptAction().showToast({ message: $r('app.string.only_show_for_ux') }); + try { + this.getUIContext().getPromptAction().showToast({ message: $r('app.string.only_show_for_ux') }); + } catch (error) { + let err = error as BusinessError; + hilog.warn(0x000, 'testTag', `showToast failed, code=${err.code}, message=${err.message}`); + } }) } } \ No newline at end of file diff --git a/DealStrideSolution/entry/src/main/ets/pages/PageThree.ets b/DealStrideSolution/entry/src/main/ets/pages/PageThree.ets index 361dfdfb660d0d796d56b0deb7debb19ef9f2826..4a00c647de6fa9e0dd48ff9f5fb75f47d3632223 100644 --- a/DealStrideSolution/entry/src/main/ets/pages/PageThree.ets +++ b/DealStrideSolution/entry/src/main/ets/pages/PageThree.ets @@ -14,9 +14,10 @@ */ import { image } from '@kit.ImageKit'; +import { BusinessError } from '@kit.BasicServicesKit'; import CameraService from '../utils/CameraServiceThree'; import { CommonConstants } from '../common/CommonConstants'; -import { promptAction } from '@kit.ArkUI'; +import { hilog } from '@kit.PerformanceAnalysisKit'; @Builder export function PageThreeBuilder() { @@ -78,7 +79,12 @@ export struct PageThree { .layoutWeight(1) this.navDestinationTitleImg($r('app.media.more'), () => { - this.getUIContext().getPromptAction().showToast({ message: $r('app.string.only_show_for_ux') }) + try { + this.getUIContext().getPromptAction().showToast({ message: $r('app.string.only_show_for_ux') }) + } catch (error) { + let err = error as BusinessError; + hilog.warn(0x000, 'testTag', `showToast failed, code=${err.code}, message=${err.message}`); + } }) } .width('100%') @@ -158,7 +164,12 @@ export struct PublishView { right: 18 }) .onClick(() => { - this.getUIContext().getPromptAction().showToast({ message: $r('app.string.only_show_for_ux') }); + try { + this.getUIContext().getPromptAction().showToast({ message: $r('app.string.only_show_for_ux') }); + } catch (error) { + let err = error as BusinessError; + hilog.warn(0x000, 'testTag', `showToast failed, code=${err.code}, message=${err.message}`); + } }) } } \ No newline at end of file diff --git a/DealStrideSolution/entry/src/main/ets/pages/PageTwo.ets b/DealStrideSolution/entry/src/main/ets/pages/PageTwo.ets index 93c0fad3363e98afe1441481856261bd457a2502..d98c2c50d0593a40d53b06c11ac3bf780b6de501 100644 --- a/DealStrideSolution/entry/src/main/ets/pages/PageTwo.ets +++ b/DealStrideSolution/entry/src/main/ets/pages/PageTwo.ets @@ -14,9 +14,10 @@ */ import { image } from '@kit.ImageKit'; +import { BusinessError } from '@kit.BasicServicesKit'; import CameraService from '../utils/CameraServiceTwo'; import { CommonConstants } from '../common/CommonConstants'; -import { promptAction } from '@kit.ArkUI'; +import { hilog } from '@kit.PerformanceAnalysisKit'; @Builder export function PageTwoBuilder() { @@ -76,7 +77,12 @@ export struct PageTwo { .layoutWeight(1) this.navDestinationTitleImg($r('app.media.more'), () => { - this.getUIContext().getPromptAction().showToast({ message: $r('app.string.only_show_for_ux') }) + try { + this.getUIContext().getPromptAction().showToast({ message: $r('app.string.only_show_for_ux') }) + } catch (error) { + let err: BusinessError = error as BusinessError; + hilog.warn(0x000, 'testTag', `showToast failed, code=${err.code}, message=${err.message}`); + } }) } .width('100%') @@ -150,7 +156,13 @@ export struct PublishView { right: 18 }) .onClick(() => { - this.getUIContext().getPromptAction().showToast({ message: $r('app.string.only_show_for_ux') }); + try { + this.getUIContext().getPromptAction().showToast({ message: $r('app.string.only_show_for_ux') }); + + } catch (error) { + let err = error as BusinessError; + hilog.warn(0x000, 'testTag', `showToast failed, code=${err.code}, message=${err.message}`); + } }) } } \ No newline at end of file diff --git a/DealStrideSolution/entry/src/main/ets/utils/CameraServiceOne.ets b/DealStrideSolution/entry/src/main/ets/utils/CameraServiceOne.ets index 31a240f9a1b342a81fd559ad90b551ceb4dc988e..5f86078cbeca465dec51ea09ecaf9edaee9a756a 100644 --- a/DealStrideSolution/entry/src/main/ets/utils/CameraServiceOne.ets +++ b/DealStrideSolution/entry/src/main/ets/utils/CameraServiceOne.ets @@ -20,6 +20,7 @@ import { image } from '@kit.ImageKit'; import { JSON } from '@kit.ArkTS'; import { photoAccessHelper } from '@kit.MediaLibraryKit'; import Logger from './Logger'; +import { hilog } from '@kit.PerformanceAnalysisKit'; const TAG: string = 'CameraService'; @@ -29,7 +30,8 @@ class CameraService { private cameraInput: camera.CameraInput | undefined = undefined; private previewOutput: camera.PreviewOutput | undefined = undefined; private session: camera.PhotoSession | camera.VideoSession | undefined = undefined; - handlePhotoAssetCb: (photoAsset: photoAccessHelper.PhotoAsset) => void = () => {}; + handlePhotoAssetCb: (photoAsset: photoAccessHelper.PhotoAsset) => void = () => { + }; private curCameraDevice: camera.CameraDevice | undefined = undefined; private receiver: image.ImageReceiver | undefined = undefined; frameStartFlag: number = 0; @@ -42,6 +44,7 @@ class CameraService { } }; surfaceId: string = ''; + // [Start Case1_start] onImageArrival(receiver: image.ImageReceiver): void { // [StartExclude Case1_start] @@ -55,13 +58,13 @@ class CameraService { if (nextImage) { nextImage.getComponent(image.ComponentType.JPEG, async (err, component: image.Component) => { - let width = 1080; // Application create preview stream resolution corresponding to the width - let height = 1080; // Application create preview stream resolution corresponding to the height - let stride = component.rowStride; // Get stride by using component.rowStride + let width: number = 1080; // Application create preview stream resolution corresponding to the width + let height: number = 1080; // Application create preview stream resolution corresponding to the height + let stride: number = component.rowStride; // Get stride by using component.rowStride Logger.info(TAG, `receiver getComponent width:${width} height:${height} stride:${stride}`); // Positive example: Case 1.stride and width are equal. Reading buffer by width does not affect the result. if (stride === width) { - let pixelMap = await image.createPixelMap(component.byteBuffer, { + let pixelMap: image.PixelMap | undefined = await image.createPixelMap(component.byteBuffer, { size: { height: height, width: width }, srcPixelFormat: image.PixelMapFormat.NV21, }) @@ -70,17 +73,18 @@ class CameraService { // Positive example: Case 2.When width and stride are not equal, // At this time, the camera returned preview stream data component.byteBuffer to remove stride, // copy the new dstArr data, data processing to other do not support stride interface processing. - const dstBufferSize = width * height * 1.5; // Create a dstBufferSize space of width * height * 1.5. This is NV21 data format. - const dstArr = new Uint8Array(dstBufferSize); // Store the buffer after the stride is removed. + const dstBufferSize: number = width * height * + 1.5; // Create a dstBufferSize space of width * height * 1.5. This is NV21 data format. + const dstArr: Uint8Array = new Uint8Array(dstBufferSize); // Store the buffer after the stride is removed. // For each line of data read, the camera supports an even width and height profile, which does not involve rounding. for (let j = 0; j < height * 1.5; j++) { // Loop each row of dstArr data. // Copy the first width bytes of each line of data from component.byteBuffer into dstArr // (remove invalid pixels and get exactly an eight-byte array space of width*height per line). - const srcBuf = new Uint8Array(component.byteBuffer, j * stride, + const srcBuf: Uint8Array = new Uint8Array(component.byteBuffer, j * stride, width); // The buffer returned by component.byteBuffer traverses each line, starting at the top, with width bytes cut off each line. dstArr.set(srcBuf, j * width); // Store the width*height data in dstArr. } - let pixelMap = await image.createPixelMap(dstArr.buffer, { + let pixelMap: image.PixelMap | undefined = await image.createPixelMap(dstArr.buffer, { // The processed dstArr array buffer creates pixelMap directly by width and height, // and stores it in the global variable stridePixel and passes it to Image for display. size: { height: height, width: width }, @@ -94,14 +98,15 @@ class CameraService { }); }) } + // [End Case1_start] getPreviewProfile(cameraOutputCapability: camera.CameraOutputCapability): camera.Profile | undefined { - let previewProfiles = cameraOutputCapability.previewProfiles; + let previewProfiles: Array = cameraOutputCapability.previewProfiles; if (previewProfiles.length < 1) { return undefined; } - let index = previewProfiles.findIndex((previewProfile: camera.Profile) => { + let index: number = previewProfiles.findIndex((previewProfile: camera.Profile) => { return previewProfile.size.width === this.previewProfileObj.size.width && previewProfile.size.height === this.previewProfileObj.size.height && previewProfile.format === this.previewProfileObj.format; @@ -118,7 +123,7 @@ class CameraService { * @param cameraDeviceIndex - Camera equipment index * @returns No return value */ - async initCamera(cameraDeviceIndex: number, uiContext:UIContext): Promise { + async initCamera(cameraDeviceIndex: number, uiContext: UIContext): Promise { Logger.debug(TAG, `initCamera cameraDeviceIndex: ${cameraDeviceIndex}`); try { await this.releaseCamera(); @@ -141,7 +146,7 @@ class CameraService { return; } // Turn on the camera - let isOpenSuccess = await this.cameraInputOpenFn(this.cameraInput); + let isOpenSuccess: boolean = await this.cameraInputOpenFn(this.cameraInput); if (!isOpenSuccess) { Logger.error(TAG, 'Failed to open the camera.'); return; @@ -177,10 +182,15 @@ class CameraService { } } - getPreviewRotation() { + getPreviewRotation(): void { let previewRotation: camera.ImageRotation | undefined = camera.ImageRotation.ROTATION_0; - previewRotation = this.previewOutput?.getPreviewRotation(previewRotation); - AppStorage.set('previewRotation', previewRotation); + try { + previewRotation = this.previewOutput?.getPreviewRotation(previewRotation); + AppStorage.set('previewRotation', previewRotation); + } catch (error) { + let err: BusinessError = error as BusinessError; + hilog.warn(0x000, 'testTag', `setColorMode failed, code=${err.code}, message=${err.message}`); + } } /** @@ -220,7 +230,7 @@ class CameraService { /** * Get the Camera Manager instance */ - getCameraManagerFn(uiContext:UIContext): camera.CameraManager | undefined { + getCameraManagerFn(uiContext: UIContext): camera.CameraManager | undefined { if (this.cameraManager) { return this.cameraManager; } @@ -283,7 +293,7 @@ class CameraService { * Turn on the camera */ async cameraInputOpenFn(cameraInput: camera.CameraInput): Promise { - let isOpenSuccess = false; + let isOpenSuccess: boolean = false; try { await cameraInput.open(); isOpenSuccess = true; diff --git a/DealStrideSolution/entry/src/main/ets/utils/CameraServiceThree.ets b/DealStrideSolution/entry/src/main/ets/utils/CameraServiceThree.ets index 85035097c55caa70e5a109ce171dd7fce0ba7e4b..4e351e6ae24e52433c9027bf2659045e34c58242 100644 --- a/DealStrideSolution/entry/src/main/ets/utils/CameraServiceThree.ets +++ b/DealStrideSolution/entry/src/main/ets/utils/CameraServiceThree.ets @@ -20,6 +20,7 @@ import { image } from '@kit.ImageKit'; import { JSON } from '@kit.ArkTS'; import { photoAccessHelper } from '@kit.MediaLibraryKit'; import Logger from './Logger'; +import { hilog } from '@kit.PerformanceAnalysisKit'; const TAG: string = 'CameraService'; @@ -52,9 +53,9 @@ class CameraService { } if (nextImage) { nextImage.getComponent(image.ComponentType.JPEG, async (_err, component: image.Component) => { - let width = 1080; // Application create preview stream resolution corresponding to the width - let height = 1080; // Application create preview stream resolution corresponding to the height - let pixelMap = await image.createPixelMap(component.byteBuffer, { + let width: number = 1080; // Application create preview stream resolution corresponding to the width + let height: number = 1080; // Application create preview stream resolution corresponding to the height + let pixelMap: image.PixelMap | undefined = await image.createPixelMap(component.byteBuffer, { size: { height: height, width: width @@ -73,11 +74,11 @@ class CameraService { } // [End onImageArrival_start] getPreviewProfile(cameraOutputCapability: camera.CameraOutputCapability): camera.Profile | undefined { - let previewProfiles = cameraOutputCapability.previewProfiles; + let previewProfiles: Array = cameraOutputCapability.previewProfiles; if (previewProfiles.length < 1) { return undefined; } - let index = previewProfiles.findIndex((previewProfile: camera.Profile) => { + let index: number = previewProfiles.findIndex((previewProfile: camera.Profile) => { return previewProfile.size.width === this.previewProfileObj.size.width && previewProfile.size.height === this.previewProfileObj.size.height && previewProfile.format === this.previewProfileObj.format; @@ -117,7 +118,7 @@ class CameraService { return; } // Turn on the camera - let isOpenSuccess = await this.cameraInputOpenFn(this.cameraInput); + let isOpenSuccess: boolean = await this.cameraInputOpenFn(this.cameraInput); if (!isOpenSuccess) { Logger.error(TAG, 'Failed to open the camera.'); return; @@ -153,10 +154,15 @@ class CameraService { } } - getPreviewRotation() { + getPreviewRotation(): void { let previewRotation: camera.ImageRotation | undefined = camera.ImageRotation.ROTATION_0; - previewRotation = this.previewOutput?.getPreviewRotation(previewRotation); - AppStorage.set('previewRotation', previewRotation) + try { + previewRotation = this.previewOutput?.getPreviewRotation(previewRotation); + AppStorage.set('previewRotation', previewRotation); + } catch (error) { + let err: BusinessError = error as BusinessError; + hilog.warn(0x000, 'testTag', `setColorMode failed, code=${err.code}, message=${err.message}`); + } } /** @@ -259,7 +265,7 @@ class CameraService { * Turn on the camera */ async cameraInputOpenFn(cameraInput: camera.CameraInput): Promise { - let isOpenSuccess = false; + let isOpenSuccess: boolean = false; try { await cameraInput.open(); isOpenSuccess = true; diff --git a/DealStrideSolution/entry/src/main/ets/utils/CameraServiceTwo.ets b/DealStrideSolution/entry/src/main/ets/utils/CameraServiceTwo.ets index 36a1fe34aa945d7bf2a73e8cfe7b053187c259be..9a69a50386e584c2bfe90f2dd014eced655c5720 100644 --- a/DealStrideSolution/entry/src/main/ets/utils/CameraServiceTwo.ets +++ b/DealStrideSolution/entry/src/main/ets/utils/CameraServiceTwo.ets @@ -20,6 +20,7 @@ import { image } from '@kit.ImageKit'; import { JSON } from '@kit.ArkTS'; import { photoAccessHelper } from '@kit.MediaLibraryKit'; import Logger from './Logger'; +import { hilog } from '@kit.PerformanceAnalysisKit'; const TAG: string = 'CameraService'; @@ -29,7 +30,8 @@ class CameraService { private cameraInput: camera.CameraInput | undefined = undefined; private previewOutput: camera.PreviewOutput | undefined = undefined; private session: camera.PhotoSession | camera.VideoSession | undefined = undefined; - handlePhotoAssetCb: (photoAsset: photoAccessHelper.PhotoAsset) => void = () => {}; + handlePhotoAssetCb: (photoAsset: photoAccessHelper.PhotoAsset) => void = () => { + }; private curCameraDevice: camera.CameraDevice | undefined = undefined; private receiver: image.ImageReceiver | undefined = undefined; frameStartFlag: number = 0; @@ -42,6 +44,7 @@ class CameraService { } }; surfaceId: string = ''; + // [Start Case2_start] onImageArrival(receiver: image.ImageReceiver): void { receiver.on('imageArrival', () => { @@ -54,32 +57,37 @@ class CameraService { // [EndExclude Case2_start] if (nextImage) { nextImage.getComponent(image.ComponentType.JPEG, async (_err, component: image.Component) => { - let width = 1080; // Application create preview stream resolution corresponding to the width - let height = 1080; // Application create preview stream resolution corresponding to the height - let stride = component.rowStride; // Get stride by using component.rowStride + let width: number = 1080; // Application create preview stream resolution corresponding to the width + let height: number = 1080; // Application create preview stream resolution corresponding to the height + let stride: number = component.rowStride; // Get stride by using component.rowStride Logger.info(TAG, `receiver getComponent width:${width} height:${height} stride:${stride}`); // stride and width are equal. Reading buffer by width does not affect the result if (stride === width) { - let pixelMap = await image.createPixelMap(component.byteBuffer, { + let pixelMap: image.PixelMap | undefined = await image.createPixelMap(component.byteBuffer, { size: { height: height, width: width }, srcPixelFormat: image.PixelMapFormat.NV21, }) AppStorage.setOrCreate('stridePixel', pixelMap); } else { - let pixelMap = await image.createPixelMap(component.byteBuffer, { + let pixelMap: image.PixelMap | undefined = await image.createPixelMap(component.byteBuffer, { // Positive example: 1. width transmission stride when creating PixelMap. size: { height: height, width: stride }, srcPixelFormat: 8, }) // 2. then call the cropSync method of PixelMap to crop out the excess pixels. - pixelMap.cropSync({ - size: { width: width, height: height }, - x: 0, - y: 0 - }) // Crop the image according to the size entered, starting with (0,0), crop the area of width*height bytes. - let pixelBefore: PixelMap | undefined = AppStorage.get('stridePixel'); - await pixelBefore?.release(); - AppStorage.setOrCreate('stridePixel', pixelMap); + try { + pixelMap.cropSync({ + size: { width: width, height: height }, + x: 0, + y: 0 + }) // Crop the image according to the size entered, starting with (0,0), crop the area of width*height bytes. + let pixelBefore: PixelMap | undefined = AppStorage.get('stridePixel'); + await pixelBefore?.release(); + AppStorage.setOrCreate('stridePixel', pixelMap); + } catch (error) { + let err: BusinessError = error as BusinessError; + hilog.warn(0x000, 'testTag', `setColorMode failed, code=${err.code}, message=${err.message}`); + } } nextImage.release(); }) @@ -87,14 +95,15 @@ class CameraService { }); }) } + // [End Case2_start] getPreviewProfile(cameraOutputCapability: camera.CameraOutputCapability): camera.Profile | undefined { - let previewProfiles = cameraOutputCapability.previewProfiles; + let previewProfiles: Array = cameraOutputCapability.previewProfiles; if (previewProfiles.length < 1) { return undefined; } - let index = previewProfiles.findIndex((previewProfile: camera.Profile) => { + let index: number = previewProfiles.findIndex((previewProfile: camera.Profile) => { return previewProfile.size.width === this.previewProfileObj.size.width && previewProfile.size.height === this.previewProfileObj.size.height && previewProfile.format === this.previewProfileObj.format; @@ -111,7 +120,7 @@ class CameraService { * @param cameraDeviceIndex - Camera equipment index * @returns No return value */ - async initCamera(cameraDeviceIndex: number, uiContext:UIContext): Promise { + async initCamera(cameraDeviceIndex: number, uiContext: UIContext): Promise { Logger.debug(TAG, `initCamera cameraDeviceIndex: ${cameraDeviceIndex}`); try { await this.releaseCamera(); @@ -134,7 +143,7 @@ class CameraService { return; } // Turn on the camera - let isOpenSuccess = await this.cameraInputOpenFn(this.cameraInput); + let isOpenSuccess: boolean = await this.cameraInputOpenFn(this.cameraInput); if (!isOpenSuccess) { Logger.error(TAG, 'Failed to open the camera.'); return; @@ -170,10 +179,15 @@ class CameraService { } } - getPreviewRotation() { + getPreviewRotation(): void { let previewRotation: camera.ImageRotation | undefined = camera.ImageRotation.ROTATION_0; - previewRotation = this.previewOutput?.getPreviewRotation(previewRotation); - AppStorage.set('previewRotation', previewRotation) + try { + previewRotation = this.previewOutput?.getPreviewRotation(previewRotation); + AppStorage.set('previewRotation', previewRotation); + } catch (error) { + let err: BusinessError = error as BusinessError; + hilog.warn(0x000, 'testTag', `setColorMode failed, code=${err.code}, message=${err.message}`); + } } /** @@ -213,7 +227,7 @@ class CameraService { /** * Get the Camera Manager instance */ - getCameraManagerFn(uiContext:UIContext): camera.CameraManager | undefined { + getCameraManagerFn(uiContext: UIContext): camera.CameraManager | undefined { if (this.cameraManager) { return this.cameraManager; } @@ -276,7 +290,7 @@ class CameraService { * Turn on the camera */ async cameraInputOpenFn(cameraInput: camera.CameraInput): Promise { - let isOpenSuccess = false; + let isOpenSuccess: boolean = false; try { await cameraInput.open(); isOpenSuccess = true; diff --git a/DealStrideSolution/entry/src/main/ets/utils/Logger.ets b/DealStrideSolution/entry/src/main/ets/utils/Logger.ets index 9e7ae52b27eb0a3070f7946c57d0ce84540d29cd..bd50b48d92baf5cea809ac4aa91a8d0c87ecb2f4 100644 --- a/DealStrideSolution/entry/src/main/ets/utils/Logger.ets +++ b/DealStrideSolution/entry/src/main/ets/utils/Logger.ets @@ -15,7 +15,7 @@ import { hilog } from '@kit.PerformanceAnalysisKit'; -const TAG = 'DealStrideSolution'; +const TAG: string = 'DealStrideSolution'; class Logger { private domain: number; diff --git a/ExpandSafeArea/README_zh.md b/ExpandSafeArea/README_zh.md new file mode 100644 index 0000000000000000000000000000000000000000..4429a3de4df9f46ebd27eb78780e1cb9557aca56 --- /dev/null +++ b/ExpandSafeArea/README_zh.md @@ -0,0 +1,52 @@ +# 基于expandSafeArea实现自动避让挖孔区 + +### 介绍 + +本示例是[《窗口沉浸式》](https://developer.huawei.com/consumer/cn/doc/best-practices/bpta-multi-device-window-immersive)的配套示例代码,通过父子组件使用expandSafeArea属性,来动态实现避让挖孔区。 + +### 使用说明 + +1. 启动应用,首页为沉浸式效果,背景色可透过系统栏区域。 +2. 设备旋转后,子组件部分会自动避让系统挖孔区。 + +### 工程目录 +``` +├──entry/src/main/ets // 代码区 +│ ├──entryability +│ │ └──EntryAbility.ets // 程序入口类 +│ ├──entrybackupability +│ │ └──EntryBackupAbility.ets +│ └──pages +│ └──Index.ets // 首页 +└──entry/src/main/resources // 应用资源目录 +``` +### 具体实现 + +* 该示例使用为父组件添加expandSafeArea属性,使父组件拓展系统栏区域,实现父组件背景色可透过系统栏区域。 +* 为子组件添加expandSafeArea属性,参数为[],表示子组件将不拓展任何系统栏区域,从而达到无论屏幕如何旋转,子组件都会自动避让挖孔区。 + +### 相关权限 + +不涉及。 + +### 依赖 + +不涉及。 + +### 约束与限制 + +1. 本示例仅支持标准系统上运行,支持设备:华为手机。 +2. HarmonyOS系统:HarmonyOS 5.1.1 Release及以上。 +3. DevEco Studio版本:DevEco Studio 5.1.1 Release及以上。 +4. HarmonyOS SDK版本:HarmonyOS 5.1.1 Release SDK及以上。 + +### 下载 + +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set ExpandSafeArea +git checkout +``` \ No newline at end of file diff --git a/ExpandSafeArea/entry/src/main/ets/entryability/EntryAbility.ets b/ExpandSafeArea/entry/src/main/ets/entryability/EntryAbility.ets index d3ee54d2beea61d38866762868bd056d3e39e3c9..6e8ddad71a3f9ef705cc39a675342118ec298ffd 100644 --- a/ExpandSafeArea/entry/src/main/ets/entryability/EntryAbility.ets +++ b/ExpandSafeArea/entry/src/main/ets/entryability/EntryAbility.ets @@ -14,6 +14,7 @@ */ import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { BusinessError } from '@kit.BasicServicesKit'; import { hilog } from '@kit.PerformanceAnalysisKit'; import { window } from '@kit.ArkUI'; @@ -21,7 +22,12 @@ const DOMAIN = 0x0000; export default class EntryAbility extends UIAbility { onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { - this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + try { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + } catch (error) { + let err = error as BusinessError; + hilog.warn(0x000, 'testTag', `setColorMode failed, code=${err.code}, message=${err.message}`); + } hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); } diff --git a/ExpandSafeArea/entry/src/main/resources/base/element/string.json b/ExpandSafeArea/entry/src/main/resources/base/element/string.json index f94595515a99e0c828807e243494f57f09251930..ae0e1c9e5d9d2e884f606b3c454faad1e7a4b78f 100644 --- a/ExpandSafeArea/entry/src/main/resources/base/element/string.json +++ b/ExpandSafeArea/entry/src/main/resources/base/element/string.json @@ -10,7 +10,7 @@ }, { "name": "EntryAbility_label", - "value": "label" + "value": "ExpandSafeArea" } ] } \ No newline at end of file diff --git a/FileUploadAndDownloadSlow/README.md b/FileUploadAndDownloadSlow/README.md new file mode 100644 index 0000000000000000000000000000000000000000..cab34984e1913579fb9e241ac9fee4fb7aacbd63 --- /dev/null +++ b/FileUploadAndDownloadSlow/README.md @@ -0,0 +1,50 @@ +# 文件上传下载优化 + +## 项目简介 + +本示例是文件上传下载优化最佳实践中的代码示例片段。 + +## 效果预览 + + +## 使用说明 + +1. 本示例为最佳实践示例代码,开发者可以查阅官网最佳实践下文件上传下载优化最佳实践学习。 +2. 点击页面底部按钮Click me,查看日志打印压缩后的文件目录 + +## 工程目录 +``` +├──entry/src/main/ets // 代码区 +│ ├──entryability +│ │ └──EntryAbility.ets // 程序入口类 +│ ├──entrybackupability +│ │ └──EntryBackupAbility.ets // 备份能力 +│ └──pages +│ └──ZipUploadPage.ets // 数据压缩页面 +└──entry/src/main/resources // 应用资源目录 +``` + +### 相关权限 + +不涉及。 + +### 约束与限制 + +1. 本示例仅支持标准系统上运行,支持设备:华为手机。 + +2. HarmonyOS系统:HarmonyOS 5.0.5 Release及以上。 + +3. DevEco Studio版本:DevEco Studio 5.0.5 Release及以上。 + +4. HarmonyOS SDK版本:HarmonyOS 5.0.5 Release SDK及以上。 + +### 下载 + +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set FileUploadAndDownloadSlow +git checkout +``` \ No newline at end of file diff --git a/FileUploadAndDownloadSlow/entry/build-profile.json5 b/FileUploadAndDownloadSlow/entry/build-profile.json5 index 4d611879c7913fb0610c686e2399258ab3a6dad1..0311b505dbf43f0d22662c8d783c5f4464d15b15 100644 --- a/FileUploadAndDownloadSlow/entry/build-profile.json5 +++ b/FileUploadAndDownloadSlow/entry/build-profile.json5 @@ -20,9 +20,6 @@ "targets": [ { "name": "default" - }, - { - "name": "ohosTest", } ] } \ No newline at end of file diff --git a/FileUploadAndDownloadSlow/entry/src/main/ets/entryability/EntryAbility.ets b/FileUploadAndDownloadSlow/entry/src/main/ets/entryability/EntryAbility.ets index 508880af8c33aa838016d1cd4b2c68be2f447540..707ad84d4002b3c860e71d04a4c57bca2f2e630d 100644 --- a/FileUploadAndDownloadSlow/entry/src/main/ets/entryability/EntryAbility.ets +++ b/FileUploadAndDownloadSlow/entry/src/main/ets/entryability/EntryAbility.ets @@ -1,12 +1,33 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; import { hilog } from '@kit.PerformanceAnalysisKit'; import { window } from '@kit.ArkUI'; +import { BusinessError } from '@kit.BasicServicesKit'; const DOMAIN = 0x0000; export default class EntryAbility extends UIAbility { onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { - this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + try { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + } catch (err) { + let error = err as BusinessError; + hilog.error(DOMAIN, 'testTag', `Failed to set colorMode. code=${error.code}, message=${error.message}`); + } hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); } @@ -18,7 +39,7 @@ export default class EntryAbility extends UIAbility { // Main window is created, set main page for this ability hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); - windowStage.loadContent('pages/Index', (err) => { + windowStage.loadContent('pages/ZipUploadPage', (err) => { if (err.code) { hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err)); return; diff --git a/FileUploadAndDownloadSlow/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets b/FileUploadAndDownloadSlow/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets index 8e4de99282050bad799ac892eb85ac5449364a51..0a97e21bd7a15599af76a806695860ff1eb0ebfe 100644 --- a/FileUploadAndDownloadSlow/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets +++ b/FileUploadAndDownloadSlow/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + import { hilog } from '@kit.PerformanceAnalysisKit'; import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit'; diff --git a/FileUploadAndDownloadSlow/entry/src/main/ets/pages/FileUploadPage.ets b/FileUploadAndDownloadSlow/entry/src/main/ets/pages/FileUploadPage.ets deleted file mode 100644 index 386896914f1b51c4cacde2e76555a5696fe4b4c2..0000000000000000000000000000000000000000 --- a/FileUploadAndDownloadSlow/entry/src/main/ets/pages/FileUploadPage.ets +++ /dev/null @@ -1,83 +0,0 @@ -// [Start import_request] -import { common } from '@kit.AbilityKit'; -import { request } from '@kit.BasicServicesKit'; -// [End import_request] - -// [Start class_upload] -class Upload { - // Background tasks - private backgroundTask: request.agent.Task | undefined = undefined; - // The uri stored before creating the task - private waitList: Array = []; - // ... -} -// [End class_upload] - -@Component -struct FileUploadPage { - // [Start file_upload_page] - private config: request.agent.Config = { - action: request.agent.Action.UPLOAD, - headers: HEADER, - url: '', - mode: request.agent.Mode.BACKGROUND, - method: 'POST', - title: 'upload', - network: request.agent.Network.ANY, - data: [], - token: 'UPLOAD_TOKEN' - } - // ... - // Convert uri - private async getFilesAndData(cacheDir: string, fileUris: Array): Promise> { - // ... - } - // Create a file upload background task - async createBackgroundTask(fileUris: Array) { - if (this.context === undefined) { - return; - } - // Get the upload URL - this.config.url = await urlUtils.getUrl(this.context); - this.config.data = await this.getFilesAndData(this.context.cacheDir, fileUris); - this.config.mode = request.agent.Mode.BACKGROUND; - try { - this.backgroundTask = await request.agent.create(this.context, this.config); - // [Start background_task_start] - await this.backgroundTask.start(); - // [End background_task_start] - let state = AppStorage.get('backTaskState'); - if (state === BackgroundTaskState.PAUSE) { - await this.backgroundTask.pause(); - } - logger.info(TAG, `createBackgroundTask success`); - } catch (err) { - logger.error(TAG, `task err, err = ${JSON.stringify(err)}`); - } - } - // [End file_upload_page] - - // [Start background_task_pause] - async pause() { - // ... - if (this.backgroundTask === undefined) { - return; - } - await this.backgroundTask.pause(); - } - // [End background_task_pause] - - // [Start background_task_resume] - async resume() { - // ... - if (this.backgroundTask === undefined) { - return; - } - await this.backgroundTask.resume(); - } - // [End background_task_resume] - - build() { - - } -} \ No newline at end of file diff --git a/FileUploadAndDownloadSlow/entry/src/main/ets/pages/RequestDownloadPage.ets b/FileUploadAndDownloadSlow/entry/src/main/ets/pages/RequestDownloadPage.ets deleted file mode 100644 index 3a0f384ae22d48a42aa90a0bccb2491c187f1ba3..0000000000000000000000000000000000000000 --- a/FileUploadAndDownloadSlow/entry/src/main/ets/pages/RequestDownloadPage.ets +++ /dev/null @@ -1,55 +0,0 @@ -// [Start import_request_download] -import { common } from '@kit.AbilityKit'; -import { request } from '@kit.BasicServicesKit'; -// [End import_request_download] - -// [Start request_download] -class RequestDownload { - // Uri before the task is stored - private waitList: Array = []; - // Uri before the task is stored - private downloadTask: request.agent.Task | undefined = undefined; - // ... -} -// [End request_download] - -@Component -struct RequestDownloadPage { - // [Start request_download_page] - async createBackgroundTask(downloadList: Array) { - if (this.context === undefined) { - return; - } - for (let i = 0; i < downloadList.length; i++) { - try { - let splitUrl = downloadList[i][1].split('//')[1].split('/'); - let downloadConfig: request.agent.Config = { - action: request.agent.Action.DOWNLOAD, - url: downloadList[i][1], - method: 'POST', - title: 'download', - mode: request.agent.Mode.BACKGROUND, // It must be a background task to continue. - network: request.agent.Network.ANY, - saveas: `./${downloadList[i][0]}/${splitUrl[splitUrl.length-1]}`, - overwrite: true, - gauge: true - } - let downTask = await request.agent.create(this.context, downloadConfig); - // [Start down_task_start] - // [StartExclude down_task_start] - // [EndExclude down_task_start] - await downTask.start(); - // [StartExclude down_task_start] - // [EndExclude down_task_start] - // [End down_task_start] - } catch (err) { - logger.error(TAG, `task err, err = ${JSON.stringify(err)}`); - this.waitList.push(downloadList[i]); - } - } - } - // [End request_download_page] - build() { - - } -} \ No newline at end of file diff --git a/FileUploadAndDownloadSlow/entry/src/main/ets/pages/UploadAndDownloadPage.ets b/FileUploadAndDownloadSlow/entry/src/main/ets/pages/UploadAndDownloadPage.ets deleted file mode 100644 index 0dfec90f9122c91679fcec7cde869252c6a8a1de..0000000000000000000000000000000000000000 --- a/FileUploadAndDownloadSlow/entry/src/main/ets/pages/UploadAndDownloadPage.ets +++ /dev/null @@ -1,93 +0,0 @@ -// [Start create_config] -let config: request.agent.Config = { - action: request.agent.Action.DOWNLOAD, // Configure task options, which are configured as download tasks. - url: downloadUrl, // Configure the download task url - overwrite: true, // Solution selection when the path already exists during the download process. True means overwriting existing files. - method: 'GET', // HTTP standard method. When downloading, use GET or POST - saveas: './', // Here'. /' indicates that the download is downloaded to the current cache path of the application. - mode: request.agent.Mode.BACKGROUND, // Task mode setting background tasks - gauge: true // The process progress notification strategy of background tasks is only applicable to background tasks. True means to send a notification that each progress has been completed or failed. -}; -// [End create_config] - -@Component -struct UploadAndDownloadPage { - - create() { - // [Start request_agent_create] - request.agent.create(context, this.downloadConfig).then((task: request.agent.Task) => { - // Callbacks related to the registration download task - task.on('completed', this.completedCallback); // Complete the callback - task.on('failed', this.failedCallback); // Failed callback - task.on('pause', this.pauseCallback); // Pause the callback - task.on('resume', this.resumeCallback); // Restart the callback - task.on('progress', this.progressCallback); // Progress update callback - task.on('response', this.progressCallback); // Response header data callback - }).catch((err: BusinessError) => { - logger.error(TAG, `Failed to task create with error message: ${err.message}, error code: ${err.code}`); - }); - // [End request_agent_create] - } - - start() { - // [Start task_start] - task.start().then(() => { - this.downloadTask = task; - }).catch((err: Error) => { - logger.error(TAG, 'task start error:', err); - }) - // [End task_start] - } - - // [Start file_download_item] - FileDownloadItem() { - // Determine whether the current download task status meets the pause conditions - if (this.downloadTask && (taskInfo.progress.state === request.agent.State.WAITING || taskInfo.progress.state - === request.agent.State.RUNNING || taskInfo.progress.state === request.agent.State.RETRYING)) { - this.downloadTask.pause().then(() => { - }).catch((err: Error) => { - logger.error(TAG, 'task pause error:', err); - }); - } - - // Determine if the task is suspended, restart the download task. - if (this.downloadTask && taskInfo.progress.state === request.agent.State.PAUSED) { - this.downloadTask.resume().then(() => { - }).catch((err: Error) => { - logger.error(TAG, 'task resume error:', err); - }); - } - } - // [End file_download_item] - - - // [Start request_agent_create] - private completedCallback = (progress: request.agent.Progress) => { - // The download status is set to download completion. - this.state = "下载完成"; - if (this.sFileSize === '未知大小') { - this.nCurrentDownloadSize = 1; - } - // The file download is completed, and the number of tasks to be downloaded will be reduced by 1 - this.downloadCount--; - this.isShow = false; - } - // [End request_agent_create] - - build() { - Column() { - // [Start download_config_array] - ForEach(this.downloadConfigArray, (item: request.agent.Config) => { - ListItem() { - // Create a file download monitoring instance - FileDownloadItem({ - downloadConfig: item, // File download configuration - isStartAllDownload: this.isStartAllDownload, // Do you start downloading all? - downloadCount: this.downloadCount // Number of tasks to be downloaded - }) - } - }, (item: request.agent.Config) => JSON.stringify(item)) - // [End download_config_array] - } - } -} \ No newline at end of file diff --git a/FileUploadAndDownloadSlow/entry/src/main/ets/pages/ZipUploadPage.ets b/FileUploadAndDownloadSlow/entry/src/main/ets/pages/ZipUploadPage.ets index 24e3d55d41b69f123ee3e93dfeb47d1c50943aeb..0f99540fbe52afe507d04b3015a1c5f8ebbde672 100644 --- a/FileUploadAndDownloadSlow/entry/src/main/ets/pages/ZipUploadPage.ets +++ b/FileUploadAndDownloadSlow/entry/src/main/ets/pages/ZipUploadPage.ets @@ -1,7 +1,24 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + // [Start import_zlib] import { common } from '@kit.AbilityKit'; import { fileIo } from '@kit.CoreFileKit'; -import { zlib } from '@kit.BasicServicesKit'; +import { BusinessError, zlib } from '@kit.BasicServicesKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; + // [End import_zlib] // [Start zip_upload] @@ -14,35 +31,86 @@ class ZipUpload { } // [End zip_upload] +@Entry @Component struct ZipUploadPage { + private context: common.UIAbilityContext | undefined = undefined; + private waitList: Array = []; + private filePath: string = ''; + // [Start zip_upload_page] // Data compression processing async zipUploadFiles(fileUris: Array): Promise { - this.context = this.getUIContext().getHostContext() as common.UIAbilityContext; - let cacheDir = this.context.cacheDir; - let tempDir = fileIo.mkdtempSync(`${cacheDir}/XXXXXX`); - // Put the uri obtained from the library picture into fileUris and copy it to the temporary folder. - for (let i = 0; i < fileUris.length; i++) { - let fileName = fileUris[i].split('/').pop(); - let resourceFile: fileIo.File = fileIo.openSync(fileUris[i], fileIo.OpenMode.READ_ONLY); - fileIo.copyFileSync(resourceFile.fd, `${tempDir}/${fileName}`, 0); - fileIo.closeSync(resourceFile); + try { + this.context = this.getUIContext().getHostContext() as common.UIAbilityContext; + let cacheDir = this.context.cacheDir; + let tempDir = fileIo.mkdtempSync(`${cacheDir}/XXXXXX`); + // Put the uri obtained from the library picture into fileUris and copy it to the temporary folder. + for (let i = 0; i < fileUris.length; i++) { + let fileName = fileUris[i].split('/').pop(); + let resourceFile: fileIo.File = fileIo.openSync(fileUris[i], fileIo.OpenMode.READ_ONLY); + fileIo.copyFileSync(resourceFile.fd, `${tempDir}/${fileName}`, 0); + fileIo.closeSync(resourceFile); + } + // File compression, package the previously generated temporary folder into test.zip + let options: zlib.Options = { + level: zlib.CompressLevel.COMPRESS_LEVEL_DEFAULT_COMPRESSION, + memLevel: zlib.MemLevel.MEM_LEVEL_DEFAULT, + strategy: zlib.CompressStrategy.COMPRESS_STRATEGY_DEFAULT_STRATEGY + }; + let data = await zlib.compressFile(tempDir, `${cacheDir}/test.zip`, options); + // Delete temporary folders + fileIo.rmdirSync(tempDir); + // Put the generated zip package into the transmission queue. + this.waitList.push(`${cacheDir}/test.zip`); + } catch (err) { + let error = err as BusinessError; + hilog.error(0x0000, 'FileUploadAndDownloadSlow', `zipUploadFiles error ${error.code} ${error.message}`); } - // File compression, package the previously generated temporary folder into test.zip - let options: zlib.Options = { - level: zlib.CompressLevel.COMPRESS_LEVEL_DEFAULT_COMPRESSION, - memLevel: zlib.MemLevel.MEM_LEVEL_DEFAULT, - strategy: zlib.CompressStrategy.COMPRESS_STRATEGY_DEFAULT_STRATEGY - }; - let data = await zlib.compressFile(tempDir, `${cacheDir}/test.zip`, options); - // Delete temporary folders - fileIo.rmdirSync(tempDir); - // Put the generated zip package into the transmission queue. - this.waitList.push(`${cacheDir}/test.zip`); } // [End zip_upload_page] - build() { + async createSandboxFile() { + const context = this.getUIContext().getHostContext() as common.UIAbilityContext; + const dirPath = context.filesDir + '/myFiles'; + this.filePath = dirPath + '/data.txt'; + + try { + await fileIo.access(dirPath); + } catch { + await fileIo.mkdir(dirPath); + } + try { + const file = await fileIo.open(this.filePath, fileIo.OpenMode.CREATE | fileIo.OpenMode.READ_WRITE); + await fileIo.write(file.fd, 'Sandbox file content'); + await fileIo.close(file.fd); + } catch (err) { + let error = err as BusinessError; + hilog.error(0x0000, 'FileUploadAndDownloadSlow', `zipUploadFiles error ${error.code} ${error.message}`); + } + } + + aboutToAppear(): void { + this.createSandboxFile(); + } + + build() { + Column() { + Button('Click me') + .width('100%') + .onClick(async () => { + if (this.filePath !== '') { + await this.zipUploadFiles([this.filePath]); + } + hilog.info(0x0000, 'FileUploadAndDownloadSlow', `${JSON.stringify(this.waitList)}`) + }) + } + .justifyContent(FlexAlign.End) + .width('100%') + .height('100%') + .padding({ + left: 16, + right: 16 + }) } } \ No newline at end of file diff --git a/FileUploadAndDownloadSlow/entry/src/main/resources/base/profile/main_pages.json b/FileUploadAndDownloadSlow/entry/src/main/resources/base/profile/main_pages.json index 1898d94f58d6128ab712be2c68acc7c98e9ab9ce..7d89202cb7de621c9e94985ce1590b2e6d64b02c 100644 --- a/FileUploadAndDownloadSlow/entry/src/main/resources/base/profile/main_pages.json +++ b/FileUploadAndDownloadSlow/entry/src/main/resources/base/profile/main_pages.json @@ -1,5 +1,5 @@ { "src": [ - "pages/Index" + "pages/ZipUploadPage" ] } diff --git a/FileUploadAndDownloadSlow/entry/src/mock/mock-config.json5 b/FileUploadAndDownloadSlow/entry/src/mock/mock-config.json5 deleted file mode 100644 index 7a73a41bfdf76d6f793007240d80983a52f15f97..0000000000000000000000000000000000000000 --- a/FileUploadAndDownloadSlow/entry/src/mock/mock-config.json5 +++ /dev/null @@ -1,2 +0,0 @@ -{ -} \ No newline at end of file diff --git a/FileUploadAndDownloadSlow/entry/src/ohosTest/ets/test/Ability.test.ets b/FileUploadAndDownloadSlow/entry/src/ohosTest/ets/test/Ability.test.ets deleted file mode 100644 index 85c78f67579d6e31b5f5aeea463e216b9b141048..0000000000000000000000000000000000000000 --- a/FileUploadAndDownloadSlow/entry/src/ohosTest/ets/test/Ability.test.ets +++ /dev/null @@ -1,35 +0,0 @@ -import { hilog } from '@kit.PerformanceAnalysisKit'; -import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; - -export default function abilityTest() { - describe('ActsAbilityTest', () => { - // Defines a test suite. Two parameters are supported: test suite name and test suite function. - beforeAll(() => { - // Presets an action, which is performed only once before all test cases of the test suite start. - // This API supports only one parameter: preset action function. - }) - beforeEach(() => { - // Presets an action, which is performed before each unit test case starts. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: preset action function. - }) - afterEach(() => { - // Presets a clear action, which is performed after each unit test case ends. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: clear action function. - }) - afterAll(() => { - // Presets a clear action, which is performed after all test cases of the test suite end. - // This API supports only one parameter: clear action function. - }) - it('assertContain', 0, () => { - // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. - hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); - let a = 'abc'; - let b = 'b'; - // Defines a variety of assertion methods, which are used to declare expected boolean conditions. - expect(a).assertContain(b); - expect(a).assertEqual(a); - }) - }) -} \ No newline at end of file diff --git a/FileUploadAndDownloadSlow/entry/src/ohosTest/ets/test/List.test.ets b/FileUploadAndDownloadSlow/entry/src/ohosTest/ets/test/List.test.ets deleted file mode 100644 index 794c7dc4ed66bd98fa3865e07922906e2fcef545..0000000000000000000000000000000000000000 --- a/FileUploadAndDownloadSlow/entry/src/ohosTest/ets/test/List.test.ets +++ /dev/null @@ -1,5 +0,0 @@ -import abilityTest from './Ability.test'; - -export default function testsuite() { - abilityTest(); -} \ No newline at end of file diff --git a/FileUploadAndDownloadSlow/entry/src/ohosTest/module.json5 b/FileUploadAndDownloadSlow/entry/src/ohosTest/module.json5 deleted file mode 100644 index 55725a929993a8a18b3808d41ef037759440488b..0000000000000000000000000000000000000000 --- a/FileUploadAndDownloadSlow/entry/src/ohosTest/module.json5 +++ /dev/null @@ -1,13 +0,0 @@ -{ - "module": { - "name": "entry_test", - "type": "feature", - "deviceTypes": [ - "phone", - "tablet", - "2in1" - ], - "deliveryWithInstall": true, - "installationFree": false - } -} diff --git a/FileUploadAndDownloadSlow/entry/src/test/List.test.ets b/FileUploadAndDownloadSlow/entry/src/test/List.test.ets deleted file mode 100644 index bb5b5c3731e283dd507c847560ee59bde477bbc7..0000000000000000000000000000000000000000 --- a/FileUploadAndDownloadSlow/entry/src/test/List.test.ets +++ /dev/null @@ -1,5 +0,0 @@ -import localUnitTest from './LocalUnit.test'; - -export default function testsuite() { - localUnitTest(); -} \ No newline at end of file diff --git a/FileUploadAndDownloadSlow/entry/src/test/LocalUnit.test.ets b/FileUploadAndDownloadSlow/entry/src/test/LocalUnit.test.ets deleted file mode 100644 index 165fc1615ee8618b4cb6a622f144a9a707eee99f..0000000000000000000000000000000000000000 --- a/FileUploadAndDownloadSlow/entry/src/test/LocalUnit.test.ets +++ /dev/null @@ -1,33 +0,0 @@ -import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; - -export default function localUnitTest() { - describe('localUnitTest', () => { - // Defines a test suite. Two parameters are supported: test suite name and test suite function. - beforeAll(() => { - // Presets an action, which is performed only once before all test cases of the test suite start. - // This API supports only one parameter: preset action function. - }); - beforeEach(() => { - // Presets an action, which is performed before each unit test case starts. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: preset action function. - }); - afterEach(() => { - // Presets a clear action, which is performed after each unit test case ends. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: clear action function. - }); - afterAll(() => { - // Presets a clear action, which is performed after all test cases of the test suite end. - // This API supports only one parameter: clear action function. - }); - it('assertContain', 0, () => { - // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. - let a = 'abc'; - let b = 'b'; - // Defines a variety of assertion methods, which are used to declare expected boolean conditions. - expect(a).assertContain(b); - expect(a).assertEqual(a); - }); - }); -} \ No newline at end of file diff --git a/FileUploadAndDownloadSlow/oh-package-lock.json5 b/FileUploadAndDownloadSlow/oh-package-lock.json5 deleted file mode 100644 index 7fcf818273347b97063c0c0a151bb14770ca1c79..0000000000000000000000000000000000000000 --- a/FileUploadAndDownloadSlow/oh-package-lock.json5 +++ /dev/null @@ -1,27 +0,0 @@ -{ - "meta": { - "stableOrder": true - }, - "lockfileVersion": 3, - "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", - "specifiers": { - "@ohos/hamock@1.0.0": "@ohos/hamock@1.0.0", - "@ohos/hypium@1.0.21": "@ohos/hypium@1.0.21" - }, - "packages": { - "@ohos/hamock@1.0.0": { - "name": "@ohos/hamock", - "version": "1.0.0", - "integrity": "sha512-K6lDPYc6VkKe6ZBNQa9aoG+ZZMiwqfcR/7yAVFSUGIuOAhPvCJAo9+t1fZnpe0dBRBPxj2bxPPbKh69VuyAtDg==", - "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hamock/-/hamock-1.0.0.har", - "registryType": "ohpm" - }, - "@ohos/hypium@1.0.21": { - "name": "@ohos/hypium", - "version": "1.0.21", - "integrity": "sha512-iyKGMXxE+9PpCkqEwu0VykN/7hNpb+QOeIuHwkmZnxOpI+dFZt6yhPB7k89EgV1MiSK/ieV/hMjr5Z2mWwRfMQ==", - "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hypium/-/hypium-1.0.21.har", - "registryType": "ohpm" - } - } -} \ No newline at end of file diff --git a/FileUploadAndDownloadSlow/screenshot/index.png b/FileUploadAndDownloadSlow/screenshot/index.png new file mode 100644 index 0000000000000000000000000000000000000000..3ba485ea3b4cced28baf58887cbdced6e74a2382 Binary files /dev/null and b/FileUploadAndDownloadSlow/screenshot/index.png differ diff --git a/FitForDarkMode/AppScope/app.json5 b/FitForDarkMode/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..5a9bd1cfa579351036fdf58e7d790091ba5051ae --- /dev/null +++ b/FitForDarkMode/AppScope/app.json5 @@ -0,0 +1,10 @@ +{ + "app": { + "bundleName": "com.huawei.fitfordarkmode", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:app_layered_image", + "label": "$string:app_name" + } +} diff --git a/FitForDarkMode/AppScope/resources/base/element/string.json b/FitForDarkMode/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..3ab395312dd87a8ae171d3a16aeac2e411c8e46e --- /dev/null +++ b/FitForDarkMode/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "FitForDarkMode" + } + ] +} diff --git a/Privacy/ContactDataError/src/main/resources/base/media/background.png b/FitForDarkMode/AppScope/resources/base/media/app_background.png similarity index 100% rename from Privacy/ContactDataError/src/main/resources/base/media/background.png rename to FitForDarkMode/AppScope/resources/base/media/app_background.png diff --git a/MultiCommunityApplication/AppScope/resources/base/media/foreground.png b/FitForDarkMode/AppScope/resources/base/media/app_foreground.png similarity index 100% rename from MultiCommunityApplication/AppScope/resources/base/media/foreground.png rename to FitForDarkMode/AppScope/resources/base/media/app_foreground.png diff --git a/FitForDarkMode/AppScope/resources/base/media/app_layered_image.json b/FitForDarkMode/AppScope/resources/base/media/app_layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..b71c16122943f248ace0f5fa26da38b71dbdbdde --- /dev/null +++ b/FitForDarkMode/AppScope/resources/base/media/app_layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:app_background", + "foreground" : "$media:app_foreground" + } +} \ No newline at end of file diff --git a/FitForDarkMode/README.md b/FitForDarkMode/README.md new file mode 100644 index 0000000000000000000000000000000000000000..cdb16d82e5152bd82b1b04220c6cfa94c29f32b1 --- /dev/null +++ b/FitForDarkMode/README.md @@ -0,0 +1,30 @@ +# 实现深色模式功能 + +### 简介 + +本示例采用深色模式适配相关技术,确保应用在系统深浅色模式切换时界面效果美观自然,实现颜色资源适配、媒体资源适配、状态栏适配等。应用内还提供用户可控的深浅色模式开关,满足用户个性化需求,实现应用在不同模式下的深浅色切换。 + +### 相关权限 + +不涉及 + +### 约束与限制 + +1.本示例仅支持标准系统上运行,支持设备:华为手机。 + +2.HarmonyOS系统:HarmonyOS 5.0.5 Release及以上。 + +3.DevEco Studio版本:DevEco Studio 5.0.5 Release及以上。 + +4.HarmonyOS SDK版本:HarmonyOS 5.0.5 Release SDK及以上。 + +### 下载 + +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set FitForDarkMode +git checkout +``` \ No newline at end of file diff --git a/FitForDarkMode/build-profile.json5 b/FitForDarkMode/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..9e87e7e6f19020fe21192844709f192cec80fd44 --- /dev/null +++ b/FitForDarkMode/build-profile.json5 @@ -0,0 +1,42 @@ +{ + "app": { + "signingConfigs": [], + "products": [ + { + "name": "default", + "signingConfig": "default", + "targetSdkVersion": "5.0.5(17)", + "compatibleSdkVersion": "5.0.5(17)", + "runtimeOS": "HarmonyOS", + "buildOption": { + "strictMode": { + "caseSensitiveCheck": true, + "useNormalizedOHMUrl": true + } + } + } + ], + "buildModeSet": [ + { + "name": "debug", + }, + { + "name": "release" + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/GridComponentLoadSlow/code-linter.json5 b/FitForDarkMode/code-linter.json5 similarity index 100% rename from GridComponentLoadSlow/code-linter.json5 rename to FitForDarkMode/code-linter.json5 diff --git a/Privacy/ContactDataError/build-profile.json5 b/FitForDarkMode/entry/build-profile.json5 similarity index 100% rename from Privacy/ContactDataError/build-profile.json5 rename to FitForDarkMode/entry/build-profile.json5 diff --git a/FitForDarkMode/entry/hvigorfile.ts b/FitForDarkMode/entry/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..b0e3a1ab98a91bc918d6404b2413111a5011f14a --- /dev/null +++ b/FitForDarkMode/entry/hvigorfile.ts @@ -0,0 +1,6 @@ +import { hapTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins: [] /* Custom plugin to extend the functionality of Hvigor. */ +} \ No newline at end of file diff --git a/Privacy/ContactDataError/obfuscation-rules.txt b/FitForDarkMode/entry/obfuscation-rules.txt similarity index 100% rename from Privacy/ContactDataError/obfuscation-rules.txt rename to FitForDarkMode/entry/obfuscation-rules.txt diff --git a/FitForDarkMode/entry/oh-package.json5 b/FitForDarkMode/entry/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..248c3b7541a589682a250f86a6d3ecf7414d2d6a --- /dev/null +++ b/FitForDarkMode/entry/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "name": "entry", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "", + "author": "", + "license": "", + "dependencies": {} +} + diff --git a/FitForDarkMode/entry/src/main/ets/entryability/EntryAbility.ets b/FitForDarkMode/entry/src/main/ets/entryability/EntryAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..508880af8c33aa838016d1cd4b2c68be2f447540 --- /dev/null +++ b/FitForDarkMode/entry/src/main/ets/entryability/EntryAbility.ets @@ -0,0 +1,44 @@ +import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; + +const DOMAIN = 0x0000; + +export default class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onDestroy(): void { + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + // Main window is created, set main page for this ability + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + windowStage.loadContent('pages/Index', (err) => { + if (err.code) { + hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err)); + return; + } + hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.'); + }); + } + + onWindowStageDestroy(): void { + // Main window is destroyed, release UI related resources + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground(): void { + // Ability has brought to foreground + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground(): void { + // Ability has back to background + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground'); + } +} \ No newline at end of file diff --git a/FitForDarkMode/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets b/FitForDarkMode/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e4de99282050bad799ac892eb85ac5449364a51 --- /dev/null +++ b/FitForDarkMode/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets @@ -0,0 +1,16 @@ +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit'; + +const DOMAIN = 0x0000; + +export default class EntryBackupAbility extends BackupExtensionAbility { + async onBackup() { + hilog.info(DOMAIN, 'testTag', 'onBackup ok'); + await Promise.resolve(); + } + + async onRestore(bundleVersion: BundleVersion) { + hilog.info(DOMAIN, 'testTag', 'onRestore ok %{public}s', JSON.stringify(bundleVersion)); + await Promise.resolve(); + } +} \ No newline at end of file diff --git a/FitForDarkMode/entry/src/main/ets/pages/CustomDialogPositiveExample.ets b/FitForDarkMode/entry/src/main/ets/pages/CustomDialogPositiveExample.ets new file mode 100644 index 0000000000000000000000000000000000000000..c954beecd2f93c71f94ae13d23da3aa3e8ec7bbc --- /dev/null +++ b/FitForDarkMode/entry/src/main/ets/pages/CustomDialogPositiveExample.ets @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + +// [Start sourcecode_start] +@Entry +@Component +struct Index { + private customDialogComponentId: number = 0; + private promptAction = this.getUIContext().getPromptAction(); + + @Builder + customDialogPositiveExample() { + Column() { + Text('授权成功') + .fontColor($r('app.color.text_color')) + // [StartExclude sourcecode_start] + .fontSize(20) + .fontWeight(700) + .lineHeight(27) + // [EndExclude sourcecode_start] + Text('授权码:441132') + .fontColor($r('app.color.text_color')) + + Row({ space: 8 }) { + Button('复制', { buttonStyle: ButtonStyleMode.TEXTUAL }) + .fontColor($r('app.color.text_color')) + // [StartExclude sourcecode_start] + .width(144) + .height(40) + .borderRadius(20) + .onClick(() => { + this.promptAction.closeCustomDialog(this.customDialogComponentId); + }) + // [EndExclude sourcecode_start] + Button('确定', { buttonStyle: ButtonStyleMode.TEXTUAL }) + // [StartExclude sourcecode_start] + .fontColor($r('sys.color.ohos_id_color_text_primary_activated')) + .width(144) + .height(40) + .borderRadius(20) + .onClick(() => { + this.promptAction.closeCustomDialog(this.customDialogComponentId); + }) + // [EndExclude sourcecode_start] + } + // [StartExclude sourcecode_start] + .width('100%') + .justifyContent(FlexAlign.Center) + .alignItems(VerticalAlign.Center) + + // [EndExclude sourcecode_start] + } + // [StartExclude sourcecode_start] + .width('100%') + .padding({ top: 16, bottom: 16 }) + .justifyContent(FlexAlign.SpaceBetween) + .height(216) + .alignItems(HorizontalAlign.Center) + + // [EndExclude sourcecode_start] + } + + build() { + // [StartExclude sourcecode_start] + Row() { + Column({ space: 20 }) { + Text('组件内弹窗') + .fontSize(30) + .onClick(() => { + this.promptAction.openCustomDialog({ + builder: () => { + this.customDialogPositiveExample(); + } + }).then((dialogId: number) => { + this.customDialogComponentId = dialogId; + }) + }) + } + .width('100%') + } + .height('100%') + // [EndExclude sourcecode_start] + } +} +// [End sourcecode_start] \ No newline at end of file diff --git a/FitForDarkMode/entry/src/main/ets/pages/FitDarkIcon.ets b/FitForDarkMode/entry/src/main/ets/pages/FitDarkIcon.ets new file mode 100644 index 0000000000000000000000000000000000000000..67e0b8281d9ff3ce1518a3b82610584966f0282c --- /dev/null +++ b/FitForDarkMode/entry/src/main/ets/pages/FitDarkIcon.ets @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + +// [Start media_start] +@Component +struct Home { + // ... + + build() { + Scroll() { + Column() { + // ... + + Stack({ alignContent: Alignment.TopStart }) { + Image($r('app.media.bell')) + .width('100%') + .borderRadius(12) + .objectFit(ImageFit.Cover) + + // ... + } + // ... + } + } + // ... + } +} +// [End media_start] \ No newline at end of file diff --git a/FitForDarkMode/entry/src/main/ets/pages/Index.ets b/FitForDarkMode/entry/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..d66ea72c2cb5ef3a3dffb32f40d4ea74ac14ec84 --- /dev/null +++ b/FitForDarkMode/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ +@Entry +@Component +struct Index { + @State message: string = 'Hello World'; + + build() { + RelativeContainer() { + Text(this.message) + .id('HelloWorld') + .fontSize($r('app.float.page_text_font_size')) + .fontWeight(FontWeight.Bold) + .alignRules({ + center: { anchor: '__container__', align: VerticalAlign.Center }, + middle: { anchor: '__container__', align: HorizontalAlign.Center } + }) + .onClick(() => { + this.message = 'Welcome'; + }) + } + .height('100%') + .width('100%') + } +} \ No newline at end of file diff --git a/NativeSoIntegration/entry/src/main/module.json5 b/FitForDarkMode/entry/src/main/module.json5 similarity index 100% rename from NativeSoIntegration/entry/src/main/module.json5 rename to FitForDarkMode/entry/src/main/module.json5 diff --git a/FitForDarkMode/entry/src/main/resources/base/element/color.json b/FitForDarkMode/entry/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..8c0397dc905468763d4ab262e72267cf37ba6fad --- /dev/null +++ b/FitForDarkMode/entry/src/main/resources/base/element/color.json @@ -0,0 +1,12 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + }, + { + "name": "text_color", + "value": "#000000" + } + ] +} \ No newline at end of file diff --git a/FitForDarkMode/entry/src/main/resources/base/element/float.json b/FitForDarkMode/entry/src/main/resources/base/element/float.json new file mode 100644 index 0000000000000000000000000000000000000000..33ea22304f9b1485b5f22d811023701b5d4e35b6 --- /dev/null +++ b/FitForDarkMode/entry/src/main/resources/base/element/float.json @@ -0,0 +1,8 @@ +{ + "float": [ + { + "name": "page_text_font_size", + "value": "50fp" + } + ] +} diff --git a/FitForDarkMode/entry/src/main/resources/base/element/string.json b/FitForDarkMode/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/FitForDarkMode/entry/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/FitForDarkMode/entry/src/main/resources/base/media/background.png b/FitForDarkMode/entry/src/main/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/FitForDarkMode/entry/src/main/resources/base/media/background.png differ diff --git a/FitForDarkMode/entry/src/main/resources/base/media/bell.png b/FitForDarkMode/entry/src/main/resources/base/media/bell.png new file mode 100644 index 0000000000000000000000000000000000000000..969278ce752647d565a1c264dbcaab720d12098d Binary files /dev/null and b/FitForDarkMode/entry/src/main/resources/base/media/bell.png differ diff --git a/FitForDarkMode/entry/src/main/resources/base/media/foreground.png b/FitForDarkMode/entry/src/main/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f Binary files /dev/null and b/FitForDarkMode/entry/src/main/resources/base/media/foreground.png differ diff --git a/MultiVideoApplication/products/phone/src/main/resources/base/media/layered_image.json b/FitForDarkMode/entry/src/main/resources/base/media/layered_image.json similarity index 100% rename from MultiVideoApplication/products/phone/src/main/resources/base/media/layered_image.json rename to FitForDarkMode/entry/src/main/resources/base/media/layered_image.json diff --git a/MultiVideoApplication/products/phone/src/main/resources/base/media/startIcon.png b/FitForDarkMode/entry/src/main/resources/base/media/startIcon.png similarity index 100% rename from MultiVideoApplication/products/phone/src/main/resources/base/media/startIcon.png rename to FitForDarkMode/entry/src/main/resources/base/media/startIcon.png diff --git a/FitForDarkMode/entry/src/main/resources/base/profile/backup_config.json b/FitForDarkMode/entry/src/main/resources/base/profile/backup_config.json new file mode 100644 index 0000000000000000000000000000000000000000..78f40ae7c494d71e2482278f359ec790ca73471a --- /dev/null +++ b/FitForDarkMode/entry/src/main/resources/base/profile/backup_config.json @@ -0,0 +1,3 @@ +{ + "allowToBackupRestore": true +} \ No newline at end of file diff --git a/MultiDeviceCommunication/features/socialCircle/src/main/resources/base/profile/main_pages.json b/FitForDarkMode/entry/src/main/resources/base/profile/main_pages.json similarity index 100% rename from MultiDeviceCommunication/features/socialCircle/src/main/resources/base/profile/main_pages.json rename to FitForDarkMode/entry/src/main/resources/base/profile/main_pages.json diff --git a/FitForDarkMode/entry/src/main/resources/dark/element/color.json b/FitForDarkMode/entry/src/main/resources/dark/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3021906607b707894429b05549af9f91a9c23fe6 --- /dev/null +++ b/FitForDarkMode/entry/src/main/resources/dark/element/color.json @@ -0,0 +1,12 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#000000" + }, + { + "name": "text_color", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/FitForDarkMode/hvigor/hvigor-config.json5 b/FitForDarkMode/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..85e8d4b2175fc4747650344f025e7d145bc3d361 --- /dev/null +++ b/FitForDarkMode/hvigor/hvigor-config.json5 @@ -0,0 +1,22 @@ +{ + "modelVersion": "5.1.0", + "dependencies": { + }, + "execution": { + // "analyze": "normal", /* Define the build analyze mode. Value: [ "normal" | "advanced" | false ]. Default: "normal" */ + // "daemon": true, /* Enable daemon compilation. Value: [ true | false ]. Default: true */ + // "incremental": true, /* Enable incremental compilation. Value: [ true | false ]. Default: true */ + // "parallel": true, /* Enable parallel compilation. Value: [ true | false ]. Default: true */ + // "typeCheck": false, /* Enable typeCheck. Value: [ true | false ]. Default: false */ + }, + "logging": { + // "level": "info" /* Define the log level. Value: [ "debug" | "info" | "warn" | "error" ]. Default: "info" */ + }, + "debugging": { + // "stacktrace": false /* Disable stacktrace compilation. Value: [ true | false ]. Default: false */ + }, + "nodeOptions": { + // "maxOldSpaceSize": 8192 /* Enable nodeOptions maxOldSpaceSize compilation. Unit M. Used for the daemon process. Default: 8192*/ + // "exposeGC": true /* Enable to trigger garbage collection explicitly. Default: true*/ + } +} diff --git a/FitForDarkMode/hvigorfile.ts b/FitForDarkMode/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..47113e2e36ecefde41c136272a0bd6ff745cffe4 --- /dev/null +++ b/FitForDarkMode/hvigorfile.ts @@ -0,0 +1,6 @@ +import { appTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins: [] /* Custom plugin to extend the functionality of Hvigor. */ +} \ No newline at end of file diff --git a/FitForDarkMode/oh-package.json5 b/FitForDarkMode/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..bbe95ba9e19d532fed390c3cc9a0de085c7da773 --- /dev/null +++ b/FitForDarkMode/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "modelVersion": "5.1.0", + "description": "Please describe the basic information.", + "dependencies": { + }, + "devDependencies": { + "@ohos/hypium": "1.0.21", + "@ohos/hamock": "1.0.0" + } +} diff --git a/FoldableGuilde/README.md b/FoldableGuilde/README.md new file mode 100644 index 0000000000000000000000000000000000000000..98757b8a9c3001a571eb42b4ecf5efe929c5b6eb --- /dev/null +++ b/FoldableGuilde/README.md @@ -0,0 +1,53 @@ +# 折叠屏开发实践样例代码工程 + +### 简介 +本示例实现折叠屏上的多种常见功能,如悬停、折痕区避让、沉浸浏览等。 + +### 工程目录 +``` +├──entry/src/main/ets // 代码区 +│ ├──entryability +│ │ └──EntryAbility.ets // 本地启动ability +│ ├──modules +│ │ ├──AsideColum.ets +│ │ ├──Crease.ets +│ │ ├──Folder.ets +│ │ ├──NavigationComponent.ets +│ │ ├──PinchImage.ets +│ │ ├──PinchText.ets +│ │ ├──PopupComponent.ets +│ │ ├──Screen.ets +│ │ ├──Screen2.ets +│ │ ├──Scroll.ets +│ │ ├──ScrollParent.ets +│ │ └──Web.ets +│ ├──pages +│ │ └──Index.ets +│ └──utils +│ ├──source_add1.ets +│ ├──source_add2.ets +│ ├──source_add3.ets +│ └──WindowUtil.ets +└──entry/src/main/resources // 资源文件目录 +``` + +### 使用说明 +1. 按照个人需求在Index.ets中调用相关功能并运行。 + + +### 约束与限制 +1. 本示例仅支持标准系统上运行,支持设备:华为手机。 +2. HarmonyOS系统:HarmonyOS 5.0.5 Release及以上。 +3. DevEco Studio版本:DevEco Studio 5.0.5 Release及以上。 +4. HarmonyOS SDK版本:HarmonyOS 5.0.5 Release SDK及以上。 + +### 下载 + +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set FoldableGuilde +git checkout +``` \ No newline at end of file diff --git a/FoldableGuilde/build-profile.json5 b/FoldableGuilde/build-profile.json5 index 3887c9fe33360cfa2b94c9bf7ccb193560316c86..28db7ad2ea4faaba762bec70bd26b2a21148dc47 100644 --- a/FoldableGuilde/build-profile.json5 +++ b/FoldableGuilde/build-profile.json5 @@ -5,7 +5,8 @@ { "name": "default", "signingConfig": "default", - "compatibleSdkVersion": "4.1.0(11)", + "compatibleSdkVersion": "5.0.5(17)", + "targetSdkVersion": "5.0.5(17)", "runtimeOS": "HarmonyOS" } ], diff --git a/FoldableGuilde/entry/src/main/ets/entryability/EntryAbility.ets b/FoldableGuilde/entry/src/main/ets/entryability/EntryAbility.ets index f27981373afdc96d4b5031e87c7c19adbe4fc163..bf7df52b7b2e2fb5382adaef9257df01e0738f49 100644 --- a/FoldableGuilde/entry/src/main/ets/entryability/EntryAbility.ets +++ b/FoldableGuilde/entry/src/main/ets/entryability/EntryAbility.ets @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; import { hilog } from '@kit.PerformanceAnalysisKit'; import { window } from '@kit.ArkUI'; @@ -13,6 +28,7 @@ export default class EntryAbility extends UIAbility { onDestroy(): void { hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy'); } + onWindowStageCreate(windowStage: window.WindowStage): void { let windowUtil = WindowUtil.getInstance(); if (windowUtil !== undefined) { @@ -45,6 +61,7 @@ export default class EntryAbility extends UIAbility { hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? ''); }); } + onWindowStageDestroy(): void { // Main window is destroyed, release UI related resources hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); diff --git a/FoldableGuilde/entry/src/main/ets/modules/AsideColum.ets b/FoldableGuilde/entry/src/main/ets/modules/AsideColum.ets index 1b9587e3a3d24be72e78af0b7c2651689e048afa..ea3ff727ed9107db5b7636b7675356932b9d53dc 100644 --- a/FoldableGuilde/entry/src/main/ets/modules/AsideColum.ets +++ b/FoldableGuilde/entry/src/main/ets/modules/AsideColum.ets @@ -1,7 +1,21 @@ -@Entry +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + @Component export struct AsideColumn { - @State l_width: string = '100%' + @State l_width: string = '100%'; build() { Row() { @@ -10,16 +24,17 @@ export struct AsideColumn { } .backgroundColor(Color.Pink) .onClick(() => { - this.l_width = this.l_width === '100%' ? '50%' : '100%' + this.l_width = this.l_width === '100%' ? '50%' : '100%'; }) .height('100%') .width(this.l_width) + Column() { Text('1') - }.backgroundColor(Color.Gray) + } + .backgroundColor(Color.Gray) .width('50%') } .justifyContent(FlexAlign.SpaceBetween) - } } \ No newline at end of file diff --git a/FoldableGuilde/entry/src/main/ets/modules/Crease.ets b/FoldableGuilde/entry/src/main/ets/modules/Crease.ets index fec47eb803399d66f39cdd5f54f6188d42d2c646..f503dc271cc6a4704fa8d865d565d63ef70828fd 100644 --- a/FoldableGuilde/entry/src/main/ets/modules/Crease.ets +++ b/FoldableGuilde/entry/src/main/ets/modules/Crease.ets @@ -1,18 +1,34 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + // [Start crease] -import display from '@ohos.display'; -import { Callback } from '@ohos.base'; -@Entry +import { display } from '@kit.ArkUI'; + @Component export struct Crease { - @State status: string = "1" + @State status: string = '1'; // Register for monitoring at startup aboutToAppear() { let callback: Callback = (data: display.FoldStatus) => { console.info('Listening enabled. Data: ' + JSON.stringify(data)); // Get the folding crease area, the left and top attributes are the left and upper boundaries of the rectangular area, and the width and height attributes are the width and height of the rectangular area。 - this.status = data.toString() + " " + display.getCurrentFoldCreaseRegion().creaseRects[0].left + " " + display.getCurrentFoldCreaseRegion().creaseRects[0].top - + " " + display.getCurrentFoldCreaseRegion().creaseRects[0].width + " " + display.getCurrentFoldCreaseRegion().creaseRects[0].height; + this.status = data.toString() + ' ' + display.getCurrentFoldCreaseRegion().creaseRects[0].left + ' ' + + display.getCurrentFoldCreaseRegion().creaseRects[0].top + + ' ' + display.getCurrentFoldCreaseRegion().creaseRects[0].width + ' ' + + display.getCurrentFoldCreaseRegion().creaseRects[0].height; }; try { display.on('foldStatusChange', callback); @@ -20,15 +36,22 @@ export struct Crease { console.error('Failed to register callback. Code: ' + JSON.stringify(exception)); } } + build() { Column() { - Text(this.status).height(50).width("100%").textAlign(TextAlign.Center).fontSize(25).backgroundColor(Color.Red) + Text(this.status) + .height(50) + .width('100%') + .textAlign(TextAlign.Center) + .fontSize(25) + .backgroundColor(Color.Red) } - .height("100%") - .width("100%") + .height('100%') + .width('100%') .borderWidth(1) .backgroundColor(Color.Pink) .justifyContent(FlexAlign.Start) } } + // [End crease] \ No newline at end of file diff --git a/FoldableGuilde/entry/src/main/ets/modules/Folder.ets b/FoldableGuilde/entry/src/main/ets/modules/Folder.ets index e92c284c0d4bcdcbfc42c9b6932598b6d7531f95..a844ada272b9ec3fe364df89ff625bad718d1551 100644 --- a/FoldableGuilde/entry/src/main/ets/modules/Folder.ets +++ b/FoldableGuilde/entry/src/main/ets/modules/Folder.ets @@ -1,36 +1,65 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + // [Start Folder] -@Entry @Component export struct Folder { - @State len_wid: number = 480 - @State w: string = "40%" + @State len_wid: number = 480; + @State w: string = '40%'; + build() { Column() { // UpperItems puts the required id hovering to the upper half of the screen into upperItems, and the other components will be stacked in the lower half of the screen - FolderStack({ upperItems: ["upperitemsId"] }) { + FolderStack({ upperItems: ['upperitemsId'] }) { // This Column will automatically move up to the upper half of the screen Column() { - Text("video zone").height("100%").width("100%").textAlign(TextAlign.Center).fontSize(25) - }.backgroundColor(Color.Pink).width("100%").height("100%").id("upperitemsId") + Text('video zone') + .height('100%') + .width('100%') + .textAlign(TextAlign.Center) + .fontSize(25) + } + .backgroundColor(Color.Pink) + .width('100%') + .height('100%') + .id('upperitemsId') // The following two Column are stacked in the lower half screen area Column() { - Text("video title") - .width("100%") + Text('video title') + .width('100%') .height(50) .textAlign(TextAlign.Center) .backgroundColor(Color.Red) .fontSize(25) - }.width("100%").height("100%").justifyContent(FlexAlign.Start) + } + .width('100%') + .height('100%') + .justifyContent(FlexAlign.Start) Column() { - Text("video bar") - .width("100%") + Text('video bar') + .width('100%') .height(50) .textAlign(TextAlign.Center) .backgroundColor(Color.Red) .fontSize(25) - }.width("100%").height("100%").justifyContent(FlexAlign.End) + } + .width('100%') + .height('100%') + .justifyContent(FlexAlign.End) } .backgroundColor(Color.Yellow) // Whether to start the dynamic effect @@ -40,26 +69,26 @@ export struct Folder { // FolderStack callback callback when the folding state changes .onFolderStateChange((msg) => { if (msg.foldStatus === FoldStatus.FOLD_STATUS_EXPANDED) { - console.info("The device is currently in the expanded state") + console.info('The device is currently in the expanded state'); } else if (msg.foldStatus === FoldStatus.FOLD_STATUS_HALF_FOLDED) { - console.info("The device is currently in the half folded state") + console.info('The device is currently in the half folded state'); } else { // ............. } }) // If the folderStack does not fill the full screen of the page, it can be used as an ordinary Stack .alignContent(Alignment.Bottom) - .height("100%") - .width("100%") + .height('100%') + .width('100%') .borderWidth(1) .backgroundColor(Color.Yellow) - } - .height("100%") - .width("100%") + .height('100%') + .width('100%') .borderWidth(1) .backgroundColor(Color.Pink) .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM]) } } + // [End Folder] \ No newline at end of file diff --git a/FoldableGuilde/entry/src/main/ets/modules/NavigationComponent.ets b/FoldableGuilde/entry/src/main/ets/modules/NavigationComponent.ets index 0639dbde739858db1ad2b8eb211e5a6116554f3b..aebc234cf95cc3ef039e6ab02d0985298c1b214a 100644 --- a/FoldableGuilde/entry/src/main/ets/modules/NavigationComponent.ets +++ b/FoldableGuilde/entry/src/main/ets/modules/NavigationComponent.ets @@ -1,8 +1,22 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + // [Start NavigationComponent] -@Entry @Component export struct NavigationComponent { - @State TooTmp: ToolbarItem = {'value': "func", 'action': ()=> {}} + @State TooTmp: ToolbarItem = {'value': 'func', 'action': ()=> {}}; private arr: number[] = [1, 2, 3]; build() { @@ -10,12 +24,12 @@ export struct NavigationComponent { // Root view container for routing navigation Navigation() { List({ space: 12 }) { - ForEach(this.arr, (item:string) => { + ForEach(this.arr, (item: string) => { ListItem() { // Navigation component, which provides click response processing by default, does not require developers to customize click event logic。 Navigation() { - Text("NavRouter" + item) - .width("100%") + Text('NavRouter' + item) + .width('100%') .height(72) .backgroundColor('#FFFFFF') .borderRadius(24) @@ -24,17 +38,17 @@ export struct NavigationComponent { .textAlign(TextAlign.Center) // Non-home page display content NavDestination() { - Text("NavDestinationContent" + item) + Text('NavDestinationContent' + item) } - .title("NavDestinationTitle" + item) + .title('NavDestinationTitle' + item) } } - }, (item:string):string => item) + }, (item: string): string => item) } - .width("90%") + .width('90%') .margin({ top: 12 }) } - .title("主标题") + .title('主标题') .mode(NavigationMode.Auto) } .height('100%') @@ -42,4 +56,5 @@ export struct NavigationComponent { .backgroundColor('#F1F3F5') } } + // [End NavigationComponent] \ No newline at end of file diff --git a/FoldableGuilde/entry/src/main/ets/modules/PinchImage.ets b/FoldableGuilde/entry/src/main/ets/modules/PinchImage.ets index 1740b683aed804e4c2db30015f14c804a68f9f4d..92d64d8bb65f1b1300134e45e7a6b48751b59906 100644 --- a/FoldableGuilde/entry/src/main/ets/modules/PinchImage.ets +++ b/FoldableGuilde/entry/src/main/ets/modules/PinchImage.ets @@ -1,19 +1,33 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + // [Start PinchImage] -@Entry @Component export struct PinchImage { - list: string[] = ['image1','image2','image3','image4','image5','image6'] - @State GridColumn: string = '1fr 1fr 1fr' - @State GridRow: string = '1fr 1fr' + list: string[] = ['image1', 'image2', 'image3', 'image4', 'image5', 'image6']; + @State GridColumn: string = '1fr 1fr 1fr'; + @State GridRow: string = '1fr 1fr'; build() { - Column(){ + Column() { Grid() { ForEach(this.list, (item: string) => { GridItem() { Text(item) }.backgroundColor(Color.Grey) - }) + }, (item: string) => item) } .columnsTemplate(this.GridColumn) .rowsTemplate(this.GridRow) @@ -21,8 +35,8 @@ export struct PinchImage { .columnsGap(12) } // Change the layout of the Grid when two-finger scaling is triggered - .gesture(PinchGesture({fingers:2}).onActionUpdate((event:GestureEvent)=>{ - if (event.scale>1) { + .gesture(PinchGesture({ fingers: 2 }).onActionUpdate((event: GestureEvent) => { + if (event.scale > 1) { // Increase animation effect this.getUIContext().animateTo({ duration: 500 @@ -30,7 +44,7 @@ export struct PinchImage { // When the two-finger scaling ratio is > 1, the number of Grid columns becomes 2 this.GridColumn = '1fr 1fr'; }) - }else { + } else { this.getUIContext().animateTo({ duration: 500 }, () => { @@ -41,4 +55,5 @@ export struct PinchImage { })) } } + // [End PinchImage] \ No newline at end of file diff --git a/FoldableGuilde/entry/src/main/ets/modules/PinchText.ets b/FoldableGuilde/entry/src/main/ets/modules/PinchText.ets index 6894b274026b9deef20504ada07725452751f6fe..39e172047ecd9cd576c91184bc13f24f7aab9155 100644 --- a/FoldableGuilde/entry/src/main/ets/modules/PinchText.ets +++ b/FoldableGuilde/entry/src/main/ets/modules/PinchText.ets @@ -1,8 +1,23 @@ -@Entry +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + @Component export struct PinchText { - text: string = '亲近大海,领悟海,体会到了海的心声,海自然与你共鸣,无需可以强求,也无需费力搜寻,海,始终都会以潮声与你相亲,已其海色伴你舒适。' - @State textFontSize: number = 26 + text: string = + '亲近大海,领悟海,体会到了海的心声,海自然与你共鸣,无需可以强求,也无需费力搜寻,海,始终都会以潮声与你相亲,已其海色伴你舒适。'; + @State textFontSize: number = 26; build() { Column() { diff --git a/FoldableGuilde/entry/src/main/ets/modules/PopupComponent.ets b/FoldableGuilde/entry/src/main/ets/modules/PopupComponent.ets index cafecb89785edc4ef023baa35fe4198df0a9e736..a7973b7aaa1a58fdec35327107851bf30a560343 100644 --- a/FoldableGuilde/entry/src/main/ets/modules/PopupComponent.ets +++ b/FoldableGuilde/entry/src/main/ets/modules/PopupComponent.ets @@ -1,28 +1,43 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + // [Start PopupExample] -@Entry @Component export struct PopupExample { - @State customPopup1: boolean = false - @State customPopup2: boolean = false + @State customPopup1: boolean = false; + @State customPopup2: boolean = false; + build() { Row() { - Button("popup1") - .onClick(()=>{ - this.customPopup1 = !this.customPopup1 + Button('popup1') + .onClick(() => { + this.customPopup1 = !this.customPopup1; }) // Bind the Popup window to the component and align it near the edge .bindPopup(this.customPopup1, { - message: "this is a popup1", + message: 'this is a popup1', popupColor: Color.Pink, }) Blank() - Button("popup2") - .onClick(()=>{ - this.customPopup2 = !this.customPopup2 + Button('popup2') + .onClick(() => { + this.customPopup2 = !this.customPopup2; }) // Bind the Popup window to the component and align it near the edge .bindPopup(this.customPopup2, { - message: "this is a popup2", + message: 'this is a popup2', popupColor: Color.Pink, }) } @@ -30,4 +45,5 @@ export struct PopupExample { .height('100%') } } + // [End PopupExample] \ No newline at end of file diff --git a/FoldableGuilde/entry/src/main/ets/modules/Screen.ets b/FoldableGuilde/entry/src/main/ets/modules/Screen.ets index f773a5f3cefeb791eb8946588e493024cb9a5009..8cb430e92f8beb81586dbc4d815dec2e69585524 100644 --- a/FoldableGuilde/entry/src/main/ets/modules/Screen.ets +++ b/FoldableGuilde/entry/src/main/ets/modules/Screen.ets @@ -1,8 +1,22 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + import { display, window } from '@kit.ArkUI' import { common } from '@kit.AbilityKit'; import { BusinessError } from '@kit.BasicServicesKit'; -@Entry @Component export struct Movie { @State isFoldable: Boolean = false @@ -22,27 +36,38 @@ export struct Movie { // 如果使用Navigation路由跳转,需要在NavDestination的onShown()和onHidden()事件中注册监听 onPageShow(): void { // 获取应用主窗口 - let promise = window.getLastWindow(this.context); - promise.then((data: window.Window) => { + window.getLastWindow(this.context).then((data: window.Window) => { this.mainWindow = data; console.info('Succeeded in obtaining the top window. Data: ' + JSON.stringify(data)); - let foldStatus: display.FoldStatus = display.getFoldStatus(); - if (foldStatus === display.FoldStatus.FOLD_STATUS_FOLDED) { - // 当前折叠状态为折叠态,设置窗口横屏显示 - this.mainWindow?.setPreferredOrientation(window.Orientation.AUTO_ROTATION_LANDSCAPE); - } else if (foldStatus === display.FoldStatus.FOLD_STATUS_EXPANDED) { - // 如果折叠状态为展开态,设置窗口跟随传感器自动旋转,且受控制中心的旋转开关控制 - this.mainWindow?.setPreferredOrientation(window.Orientation.AUTO_ROTATION_RESTRICTED); + try { + let foldStatus: display.FoldStatus = display.getFoldStatus(); + if (foldStatus === display.FoldStatus.FOLD_STATUS_FOLDED) { + // 当前折叠状态为折叠态,设置窗口横屏显示 + this.mainWindow?.setPreferredOrientation(window.Orientation.AUTO_ROTATION_LANDSCAPE).catch((err: BusinessError) => { + console.error(`Failed to set AUTO_ROTATION_LANDSCAPE. Cause code: ${err.code}, message: ${err.message}`); + }); + } else if (foldStatus === display.FoldStatus.FOLD_STATUS_EXPANDED) { + // 如果折叠状态为展开态,设置窗口跟随传感器自动旋转,且受控制中心的旋转开关控制 + this.mainWindow?.setPreferredOrientation(window.Orientation.AUTO_ROTATION_RESTRICTED).catch((err: BusinessError) => { + console.error(`Failed to set AUTO_ROTATION_RESTRICTED. Cause code: ${err.code}, message: ${err.message}`); + }); + } + // 监听折叠屏折叠状态 + display.on('foldStatusChange', this.onDetailFoldStatusChange); + } catch (err) { + console.error(`Failed to obtain the fold status. Cause code: ${err.code}, message: ${err.message}`); } - // 监听折叠屏折叠状态 - display.on('foldStatusChange', this.onDetailFoldStatusChange); }).catch((err: BusinessError) => { console.error(`Failed to obtain the top window. Cause code: ${err.code}, message: ${err.message}`); }); } onPageHide(): void { - display.off('foldStatusChange'); + try { + display.off('foldStatusChange'); + } catch (err) { + console.error(`Failed to cancel monitoring the fold status. Cause code: ${err.code}, message: ${err.message}`); + } } build() { diff --git a/FoldableGuilde/entry/src/main/ets/modules/Screen2.ets b/FoldableGuilde/entry/src/main/ets/modules/Screen2.ets index 4868f48c00c5b303d78223e27ead5b04771bd178..db20de2ea65e099bab8a8122f3f9d44727c09f8d 100644 --- a/FoldableGuilde/entry/src/main/ets/modules/Screen2.ets +++ b/FoldableGuilde/entry/src/main/ets/modules/Screen2.ets @@ -1,12 +1,26 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + // FoldableScreen.ets import { display } from '@kit.ArkUI' import { WindowUtil } from '../utils/WindowUtil'; -@Entry @Component export struct FoldableScreen { - @State isFoldable: Boolean = false - @State foldStatus: display.FoldStatus = 1 + @State isFoldable: Boolean = false; + @State foldStatus: display.FoldStatus = 1; private windowUtil?: WindowUtil; aboutToAppear() { @@ -14,14 +28,18 @@ export struct FoldableScreen { this.windowUtil?.setPhoneAutoRotation(); // 实时监听设备折叠状态 - display.on('foldStatusChange', (data: display.FoldStatus) => { - console.info('实时监听设备折叠状态: ' + JSON.stringify(data)); - if (data === display.FoldStatus.FOLD_STATUS_HALF_FOLDED) { - this.windowUtil?.setPhoneLandscape() - } else if (data === display.FoldStatus.FOLD_STATUS_EXPANDED) { - this.windowUtil?.setPhoneAutoRotation(); - } - }); + try { + display.on('foldStatusChange', (data: display.FoldStatus) => { + console.info('Monitor the folding status of the device in real-time: ' + JSON.stringify(data)); + if (data === display.FoldStatus.FOLD_STATUS_HALF_FOLDED) { + this.windowUtil?.setPhoneLandscape(); + } else if (data === display.FoldStatus.FOLD_STATUS_EXPANDED) { + this.windowUtil?.setPhoneAutoRotation(); + } + }); + } catch (err) { + console.error(`Failed to monitor the folding status of the device. Cause code: ${err.code}, message: ${err.message}`); + } } build() { diff --git a/FoldableGuilde/entry/src/main/ets/modules/Scroll.ets b/FoldableGuilde/entry/src/main/ets/modules/Scroll.ets index 6a103cf1f6dca4f16bd00463ac586eed6d5aa2c4..3b8e8a765776677f831073b3bf7f5e1bac691473 100644 --- a/FoldableGuilde/entry/src/main/ets/modules/Scroll.ets +++ b/FoldableGuilde/entry/src/main/ets/modules/Scroll.ets @@ -1,23 +1,40 @@ -@Entry +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + @Component export struct ScrollComponent { - @State list: string[] = new Array(100).fill('') - @State banner_height: number = 50 - scroll_start_timeout?: number - scroll_stop_timeout?: number + @State list: string[] = new Array(100).fill(''); + @State banner_height: number = 50; + scroll_start_timeout?: number; + scroll_stop_timeout?: number; build() { Flex({ direction: FlexDirection.Column }) { Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) { - Text('top').fontSize(20) - }.height(this.banner_height) + Text('top') + .fontSize(20) + } + .height(this.banner_height) List() { ForEach(this.list, () => { ListItem() { - Text('北京').fontSize(24) + Text('北京') + .fontSize(24) } - }) + }, (item: string) => item) } .onScrollStart(() => { if (this.scroll_stop_timeout) { @@ -25,7 +42,7 @@ export struct ScrollComponent { } if (!this.scroll_start_timeout) { this.scroll_start_timeout = setTimeout(() => { - this.banner_height = 0 + this.banner_height = 0; }, 2000) } }) @@ -37,15 +54,17 @@ export struct ScrollComponent { clearTimeout(this.scroll_stop_timeout); } this.scroll_stop_timeout = setTimeout(() => { - this.banner_height = 50 - }, 2000) + this.banner_height = 50; + }, 2000); }) .backgroundColor('#FFF1F3F5') .alignListItem(ListItemAlign.Center) Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) { - Text('bottom').fontSize(20) - }.height(this.banner_height) + Text('bottom') + .fontSize(20) + } + .height(this.banner_height) } } } \ No newline at end of file diff --git a/FoldableGuilde/entry/src/main/ets/modules/ScrollParent.ets b/FoldableGuilde/entry/src/main/ets/modules/ScrollParent.ets index 636aa91429f3473a9333abe59c66d7f088f4a16c..91fd95ba260401fcd5f9d949291b1d6b4d96effb 100644 --- a/FoldableGuilde/entry/src/main/ets/modules/ScrollParent.ets +++ b/FoldableGuilde/entry/src/main/ets/modules/ScrollParent.ets @@ -1,125 +1,72 @@ -import web_webview from '@ohos.web.webview'; +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + +import { webview } from '@kit.ArkWeb'; -@Entry @Component export struct NestedScroll { private scrollerForScroll: Scroller = new Scroller() - controller: web_webview.WebviewController = new web_webview.WebviewController(); + controller: webview.WebviewController = new webview.WebviewController(); // scroll竖向的滚动 - @State ScrollDirection: ScrollDirection = ScrollDirection.Vertical - title = '2023落下帷幕,一起迎接2024年*****************************************' - review = '评论' - context = '一起迎接2024年,************************,************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************' - list = [0, 0, 0, 0] + @State ScrollDirection: ScrollDirection = ScrollDirection.Vertical; + title = '2023落下帷幕,一起迎接2024年*****************************************'; + review = '评论'; + context = '一起迎接2024年,************************,************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************'; + list = [0, 0, 0, 0]; build() { Flex() { Scroll(this.scrollerForScroll) { Column({ space: 5 }) { - Text(this.title).fontSize(40).padding(40) + Text(this.title) + .fontSize(40) + .padding(40) List() { ForEach(this.list, () => { ListItem() { Text(this.context).fontSize(16) } - }) + }, (item: string) => item) } - Web({ src: $rawfile("scroll.html"), controller: this.controller }) + Web({ src: $rawfile('scroll.html'), controller: this.controller }) .nestedScroll({ scrollForward: NestedScrollMode.SELF_FIRST, scrollBackward: NestedScrollMode.SELF_FIRST }) - .height("100%") - .width("100%") + .height('100%') + .width('100%') .layoutMode(WebLayoutMode.FIT_CONTENT) Text(this.review).fontSize(30) List() { ForEach(this.list, () => { ListItem() { - Text(this.context).fontSize(16) + Text(this.context) + .fontSize(16) } - }) + }, (item: string) => item) } - }.width("95%") + }.width('95%') } .scrollBar(BarState.Off) - .width("100%") - .height("120%") + .width('100%') + .height('120%') .scrollable(this.ScrollDirection) - }.width('100%').height('100%') + } + .width('100%') + .height('100%') } -} - -// // xxx.ets -// import web_webview from '@ohos.web.webview'; -// -// @Entry -// @Component -// export struct NestedScroll { -// private scrollerForScroll: Scroller = new Scroller() -// controller: web_webview.WebviewController = new web_webview.WebviewController(); -// controller2: web_webview.WebviewController = new web_webview.WebviewController(); -// // NestedScrollMode设置成SELF_ONLY时,Web网页滚动到页面边缘后,不与父组件联动,父组件仍无法滚动。 -// @State NestedScrollMode0: NestedScrollMode = NestedScrollMode.SELF_ONLY -// // NestedScrollMode设置成SELF_FIRST时,Web网页滚动到页面边缘后,父组件继续滚动。 -// @State NestedScrollMode1: NestedScrollMode = NestedScrollMode.SELF_FIRST -// // NestedScrollMode设置为PARENT_FIRST时,父组件先滚动,滚动至边缘后通知Web继续滚动。 -// @State NestedScrollMode2: NestedScrollMode = NestedScrollMode.PARENT_FIRST -// // NestedScrollMode设置为PARALLEL时,父组件与Web同时滚动。 -// @State NestedScrollMode3: NestedScrollMode = NestedScrollMode.PARALLEL -// @State NestedScrollModeF: NestedScrollMode = NestedScrollMode.SELF_FIRST -// @State NestedScrollModeB: NestedScrollMode = NestedScrollMode.SELF_FIRST -// // scroll竖向的滚动 -// @State ScrollDirection: ScrollDirection = ScrollDirection.Vertical -// title = '2023落下帷幕,一起迎接2024年*****************************************' -// review = '评论' -// context = '一起迎接2024年,************************,************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************' -// list = [0, 0, 0, 0] -// -// build() { -// Flex() { -// Scroll(this.scrollerForScroll) { -// -// -// Column({ space: 5 }) { -// Text(this.title).fontSize(40).padding(40) -// List() { -// ForEach(this.list, () => { -// ListItem() { -// Text(this.context).fontSize(16) -// } -// }) -// } -// -// Web({ src: $rawfile("scroll.html"), controller: this.controller }) -// .nestedScroll({ -// scrollForward: NestedScrollMode.SELF_FIRST, -// scrollBackward: NestedScrollMode.SELF_FIRST -// }) -// .height("100%") -// .width("100%") -// // .scrollBar(BarState.Off) -// -// -// Text(this.review).fontSize(30).padding(20) -// -// List() { -// ForEach(this.list, () => { -// ListItem() { -// Text(this.context).fontSize(16) -// } -// }) -// } -// -// }.width("95%").border({ width: 5 }) -// } -// .scrollBar(BarState.Off) -// .width("100%") -// .height("120%") -// .border({ width: 5 }) -// .scrollable(this.ScrollDirection) -// }.width('100%').height('100%').backgroundColor(0xDCDCDC).padding(20) -// } -// } +} \ No newline at end of file diff --git a/FoldableGuilde/entry/src/main/ets/modules/Web.ets b/FoldableGuilde/entry/src/main/ets/modules/Web.ets new file mode 100644 index 0000000000000000000000000000000000000000..d42253db109a61ac918b21726f24dbbb4f75cb03 --- /dev/null +++ b/FoldableGuilde/entry/src/main/ets/modules/Web.ets @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + +// xxx.ets +import { webview } from '@kit.ArkWeb'; + +class testClass { + constructor() { + } + + test(value: string): string { + return 'ArkTS Hello World!' + value; + } +} + +@Component +export struct Web1 { + webviewController: webview.WebviewController = new webview.WebviewController(); + // 声明需要注册的对象 + @State testObj: testClass = new testClass(); + + build() { + Column() { + // web组件加载本地index.html页面 + Web({ src: $rawfile('index.html'), controller: this.webviewController }) + // 将对象注入到web端 + .javaScriptProxy({ + object: this.testObj, + name: 'testObjName', + methodList: ['test'], + controller: this.webviewController + }) + } + } +} \ No newline at end of file diff --git a/FoldableGuilde/entry/src/main/ets/modules/web/web1.ets b/FoldableGuilde/entry/src/main/ets/modules/web/web1.ets deleted file mode 100644 index 1cab5e2870639043e5c655a7590613ffcc744717..0000000000000000000000000000000000000000 --- a/FoldableGuilde/entry/src/main/ets/modules/web/web1.ets +++ /dev/null @@ -1,32 +0,0 @@ -// xxx.ets -import web_webview from '@ohos.web.webview'; - -class testClass { - constructor() { - } - - test(value: string): string { - return 'ArkTS Hello World!' + value; - } -} - -@Entry -@Component -export struct Web1 { - webviewController: web_webview.WebviewController = new web_webview.WebviewController(); - // 声明需要注册的对象 - @State testObj: testClass = new testClass(); - - build() { - Column() { - // web组件加载本地index.html页面 - Web({ src: $rawfile('index.html'), controller: this.webviewController })// 将对象注入到web端 - .javaScriptProxy({ - object: this.testObj, - name: "testObjName", - methodList: ["test"], - controller: this.webviewController - }) - } - } -} \ No newline at end of file diff --git a/FoldableGuilde/entry/src/main/ets/modules/web/web2.ets b/FoldableGuilde/entry/src/main/ets/modules/web/web2.ets deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/FoldableGuilde/entry/src/main/ets/pages/Index.ets b/FoldableGuilde/entry/src/main/ets/pages/Index.ets index e85cfc24d15260e31e9c6a5572664a910507cd15..a5f4893a95aa07d0a203dc9beb14c494f74aa6ca 100644 --- a/FoldableGuilde/entry/src/main/ets/pages/Index.ets +++ b/FoldableGuilde/entry/src/main/ets/pages/Index.ets @@ -1,50 +1,83 @@ -import { AsideColumn } from '../modules/AsideColum' -import { Crease } from '../modules/Crease' -import { Folder } from '../modules/Folder' -import { NavigationComponent } from '../modules/NavigationComponent' -import { PinchImage } from '../modules/PinchImage' -import { PinchText } from '../modules/PinchText' -import { PopupExample } from '../modules/PopupComponent' -import { FoldableScreen } from '../modules/Screen2' -import { Movie } from '../modules/Screen' -import { ScrollTest } from '../utils/source_add1' -import { NestedScroll } from '../modules/ScrollParent' -import { Web1 } from '../modules/web/web1' -import { display } from '@kit.ArkUI' -import { deviceInfo } from '@kit.BasicServicesKit' +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + +import { AsideColumn } from '../modules/AsideColum'; +import { Crease } from '../modules/Crease'; +import { Folder } from '../modules/Folder'; +import { NavigationComponent } from '../modules/NavigationComponent'; +import { PinchImage } from '../modules/PinchImage'; +import { PinchText } from '../modules/PinchText'; +import { PopupExample } from '../modules/PopupComponent'; +import { FoldableScreen } from '../modules/Screen2'; +import { Movie } from '../modules/Screen'; +import { ScrollTest } from '../utils/source_add1'; +import { NestedScroll } from '../modules/ScrollParent'; +import { Web1 } from '../modules/Web'; +import { display } from '@kit.ArkUI'; +import { deviceInfo } from '@kit.BasicServicesKit'; @Entry @Component struct Index { // Monitor the change of folding state to obtain the current width and height of the screen onPageShow(): void { - // [Start foldDisplayModeChange] - display.on('foldDisplayModeChange', (data: display.FoldDisplayMode) => { - let displayInfo: display.Display = display.getDefaultDisplaySync(); - if (data === display.FoldDisplayMode.FOLD_DISPLAY_MODE_FULL) { - console.info('当前屏幕状态:全屏显示'); - console.info('屏幕宽度: ' + displayInfo.width); - console.info('屏幕高度: ' + displayInfo.height); - } else if (data === display.FoldDisplayMode.FOLD_DISPLAY_MODE_MAIN) { - console.info('当前屏幕状态:主屏幕显示'); - console.info('屏幕宽度: ' + displayInfo.width); - console.info('屏幕高度: ' + displayInfo.height); - } - }); - // [End foldDisplayModeChange] + try { + // [Start foldDisplayModeChange] + display.on('foldDisplayModeChange', (data: display.FoldDisplayMode) => { + let displayInfo: display.Display = display.getDefaultDisplaySync(); + if (data === display.FoldDisplayMode.FOLD_DISPLAY_MODE_FULL) { + console.info('当前屏幕状态:全屏显示'); + console.info('屏幕宽度: ' + displayInfo.width); + console.info('屏幕高度: ' + displayInfo.height); + } else if (data === display.FoldDisplayMode.FOLD_DISPLAY_MODE_MAIN) { + console.info('当前屏幕状态:主屏幕显示'); + console.info('屏幕宽度: ' + displayInfo.width); + console.info('屏幕高度: ' + displayInfo.height); + } + }); + // [End foldDisplayModeChange] + } catch (err) { + console.error(`Failed to monitor the fold display mode. Cause code: ${err.code}, message: ${err.message}`); + } } judgeDevice() { // [Start judgeDevice] // 1. The device type is phone, and it supports folding - if (deviceInfo.deviceType === 'phone' && display.isFoldable()) {} + try { + if (deviceInfo.deviceType === 'phone' && display.isFoldable()) { + } + } catch (err) { + console.error(`Failed to obtain the fold status of phone. Cause code: ${err.code}, message: ${err.message}`); + } // 2. Judging whether the current folding state is an expanded state/folded state/semi-folded state - if (display.getFoldStatus() === display.FoldStatus.FOLD_STATUS_EXPANDED) {} + try { + if (display.getFoldStatus() === display.FoldStatus.FOLD_STATUS_EXPANDED) { + } + } catch (err) { + console.error(`Failed to obtain the fold status of phone. Cause code: ${err.code}, message: ${err.message}`); + } // [End judgeDevice] } onPageHide(): void { - display.off('foldDisplayModeChange'); + try { + display.off('foldDisplayModeChange'); + } catch (err) { + console.error(`Failed to cancel monitoring the fold display mode. Cause code: ${err.code}, message: ${err.message}`); + } } build() { diff --git a/FoldableGuilde/entry/src/main/ets/utils/WindowUtil.ets b/FoldableGuilde/entry/src/main/ets/utils/WindowUtil.ets index 2d0c5c28312d13fd3fce78df3d44354534f11543..5a0a3d718ba3278a47e430f7fc92a5c6d3b85528 100644 --- a/FoldableGuilde/entry/src/main/ets/utils/WindowUtil.ets +++ b/FoldableGuilde/entry/src/main/ets/utils/WindowUtil.ets @@ -1,5 +1,21 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + // utils/WindowsUtil.ets import { window } from '@kit.ArkUI'; +import { BusinessError } from '@kit.BasicServicesKit'; @Observed export class WindowUtil { @@ -19,6 +35,9 @@ export class WindowUtil { return; } this.windowStage.getMainWindow((err, windowClass: window.Window) => { + if (err) { + console.error(`Failed to get the main window. Cause code: ${err.code}, message: ${err.message}`); + } this.mainWindowClass = windowClass; }); } @@ -28,7 +47,9 @@ export class WindowUtil { return; } // 设置传感器自动旋转模式 - this.mainWindowClass.setPreferredOrientation(window.Orientation.AUTO_ROTATION); + this.mainWindowClass.setPreferredOrientation(window.Orientation.AUTO_ROTATION).catch((err: BusinessError) => { + console.error(`Failed to set phone's screen auto rotation. Cause code: ${err.code}, message: ${err.message}`); + }); } setPhoneLandscape(): void { @@ -36,7 +57,9 @@ export class WindowUtil { return; } // 设置横屏显示模式 - this.mainWindowClass.setPreferredOrientation(window.Orientation.LANDSCAPE); + this.mainWindowClass.setPreferredOrientation(window.Orientation.LANDSCAPE).catch((err: BusinessError) => { + console.error(`Failed to set phone's screen landscape. Cause code: ${err.code}, message: ${err.message}`); + }); } setWindowStage(windowStage: window.WindowStage): void { diff --git a/FoldableGuilde/entry/src/main/ets/utils/source_add1.ets b/FoldableGuilde/entry/src/main/ets/utils/source_add1.ets index 5f0cbd9db2f18627f1e7af90394b30cca90cfda1..fcc1d5c71bf56f74d39b57cf837c20e00c13f0ed 100644 --- a/FoldableGuilde/entry/src/main/ets/utils/source_add1.ets +++ b/FoldableGuilde/entry/src/main/ets/utils/source_add1.ets @@ -1,4 +1,18 @@ -@Entry +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + @Component // [Start ScrollTest] export struct ScrollTest { @@ -14,12 +28,13 @@ export struct ScrollTest { // [StartExclude ScrollTest] ForEach(new Array(100).fill(''), () => { ListItem() { - Text('北京').fontSize(24) + Text('北京') + .fontSize(24) } - }) + }, (item: string) => item) // [EndExclude ScrollTest] } - .onScrollFrameBegin((offset: number, state: ScrollState) => { + .onScrollFrameBegin((offset: number) => { this.currentYOffset += Math.abs(offset); // Take the Y-axis offset of 100 as an example. When the offset is less than 100, the fixed area is gradually hidden if (this.currentYOffset <= 100) { diff --git a/FoldableGuilde/entry/src/main/ets/utils/source_add2.ets b/FoldableGuilde/entry/src/main/ets/utils/source_add2.ets index b8118c42b367dbcbea2eb24513182e98d09d06a2..6cde673afed2b98cc965a3aa4968502afb47c35a 100644 --- a/FoldableGuilde/entry/src/main/ets/utils/source_add2.ets +++ b/FoldableGuilde/entry/src/main/ets/utils/source_add2.ets @@ -1,4 +1,19 @@ -import { window, display } from '@kit.ArkUI' +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + +import { window, display } from '@kit.ArkUI'; import { BusinessError } from '@kit.BasicServicesKit'; export class Breakpoint { // [Start source_add2] diff --git a/FoldableGuilde/entry/src/main/ets/utils/source_add3.ets b/FoldableGuilde/entry/src/main/ets/utils/source_add3.ets index 598188a876e49c668a6b91515b482af6e55823ea..14dbb369f58c5fb72e3e2ad900d3234cd2fb9c96 100644 --- a/FoldableGuilde/entry/src/main/ets/utils/source_add3.ets +++ b/FoldableGuilde/entry/src/main/ets/utils/source_add3.ets @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + import { window } from '@kit.ArkUI'; import { BusinessError } from '@kit.BasicServicesKit'; export class BreakpointHeight { diff --git a/FoldableGuilde/entry/src/main/module.json5 b/FoldableGuilde/entry/src/main/module.json5 index 6c07d9d8839ac9716809c6e06c21805d52c138fe..8a7a1606e2be5ec1a7c4332d3293d7593c2a4f13 100644 --- a/FoldableGuilde/entry/src/main/module.json5 +++ b/FoldableGuilde/entry/src/main/module.json5 @@ -5,9 +5,7 @@ "description": "$string:module_desc", "mainElement": "EntryAbility", "deviceTypes": [ - "phone", - "tablet", - "2in1" + "phone" ], "deliveryWithInstall": true, "installationFree": false, diff --git a/FramedRendering/README.md b/FramedRendering/README.md index d89b9072b5802766d614ef5860f3044b5728586d..3190e019fdf46de41f0f40fc95d4f09372c551b0 100644 --- a/FramedRendering/README.md +++ b/FramedRendering/README.md @@ -22,7 +22,7 @@ ``` ├──entry/src/main/ets │ ├──common -│ │ ├──Constants.ets // 公共常量 +│ │ ├──CommonConstants.ets // 公共常量 │ │ └──GlobalBuilderContext.ets // 缓存全局@Builder │ ├──entryability │ │ └──EntryAbility.ets // 程序入口类 @@ -41,6 +41,7 @@ │ └──view │ ├──DateItemView.ets // 每个月的日历数据 │ ├──SlidingScene.ets // 日历页面 UI +│ ├──TestCode.ets // 代码同源举例 │ └──TransitionScene.ets // 转场场景 UI └──entry/src/main/resources // 应用资源目录 ``` @@ -57,6 +58,17 @@ ## 约束与限制 * 本示例仅支持标准系统上运行,支持设备:华为手机。 -* HarmonyOS系统:HarmonyOS 5.0.0 Release及以上。 -* DevEco Studio版本:DevEco Studio 5.0.0 Release及以上。 -* HarmonyOS SDK版本:HarmonyOS 5.0.0 Release SDK及以上。 \ No newline at end of file +* HarmonyOS系统:HarmonyOS 5.0.5 Release及以上。 +* DevEco Studio版本:DevEco Studio 5.0.5 Release及以上。 +* HarmonyOS SDK版本:HarmonyOS 5.0.5 Release SDK及以上。 + +### 下载 + +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set FramedRendering +git checkout +``` \ No newline at end of file diff --git a/FramedRendering/README_EN.md b/FramedRendering/README_EN.md index c599d2ee9faf77a063e1cf12dce077a0cf870877..ab6467262b9f0eeb5081d3cc946d77cfc22453d6 100644 --- a/FramedRendering/README_EN.md +++ b/FramedRendering/README_EN.md @@ -22,7 +22,7 @@ The involved ArkUI API is [@ohos.graphics.displaySync (Variable Frame Rate)](htt ``` ├──entry/src/main/ets │ ├──common -│ │ ├──Constants.ets // Common constants +│ │ ├──CommonConstants.ets // Common constants │ │ └──GlobalBuilderContext.ets // Caching the global @Builder │ ├──entryability │ │ └──EntryAbility.ets // Entry ability @@ -41,6 +41,7 @@ The involved ArkUI API is [@ohos.graphics.displaySync (Variable Frame Rate)](htt │ └──view │ ├──DateItemView.ets // Monthly date data │ ├──SlidingScene.ets // Calendar UI +│ ├──TestCode.ets // test data │ └──TransitionScene.ets // Transition UI └──entry/src/main/resources // Application resources ``` @@ -57,6 +58,17 @@ N/A ## Constraints * This sample is supported only on Huawei phones running the standard system. -* The HarmonyOS version must be HarmonyOS 5.0.0 Release or later. -* The DevEco Studio version must be DevEco Studio 5.0.0 Release or later. -* The HarmonyOS SDK version must be HarmonyOS 5.0.0 Release SDK or later. +* The HarmonyOS version must be HarmonyOS 5.0.5 Release or later. +* The DevEco Studio version must be DevEco Studio 5.0.5 Release or later. +* The HarmonyOS SDK version must be HarmonyOS 5.0.5 Release SDK or later. + +### Download + +To download this project separately, execute the following command: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set FramedRendering +git checkout +``` diff --git a/FramedRendering/build-profile.json5 b/FramedRendering/build-profile.json5 index 6d93d9cd5af96ec9ec78db4738722a66c9464d7e..b8ef59a125a280b3346be9be493b0705704ba1aa 100644 --- a/FramedRendering/build-profile.json5 +++ b/FramedRendering/build-profile.json5 @@ -4,7 +4,8 @@ { "name": "default", "signingConfig": "default", - "compatibleSdkVersion": "5.0.0(12)", + "compatibleSdkVersion": "5.0.5(17)", + "targetSdkVersion": "5.0.5(17)", "runtimeOS": "HarmonyOS", "buildOption": { "strictMode": { diff --git a/FramedRendering/entry/src/main/ets/common/GlobalBuilderContext.ets b/FramedRendering/entry/src/main/ets/common/GlobalBuilderContext.ets index 13569101278cd662f39e7c78668777e7dffb3589..bdd206cd77a569a1e231acc30e645575eefd1cd6 100644 --- a/FramedRendering/entry/src/main/ets/common/GlobalBuilderContext.ets +++ b/FramedRendering/entry/src/main/ets/common/GlobalBuilderContext.ets @@ -19,7 +19,7 @@ import { CommonConstants } from './CommonConstants'; export class GlobalBuilderContext { private static instance: GlobalBuilderContext; - private objects = new Map(); + private objects: Map = new Map(); public static getContext(): GlobalBuilderContext { if (!GlobalBuilderContext.instance) { diff --git a/FramedRendering/entry/src/main/ets/entryability/EntryAbility.ets b/FramedRendering/entry/src/main/ets/entryability/EntryAbility.ets index 658b37ad825e994dbaae500a620986562981d06a..9eed99659ee28bd35b517aeb8e75ce74a62167cc 100644 --- a/FramedRendering/entry/src/main/ets/entryability/EntryAbility.ets +++ b/FramedRendering/entry/src/main/ets/entryability/EntryAbility.ets @@ -51,14 +51,19 @@ export default class EntryAbility extends UIAbility { } private immersive(): void { - let type: window.AvoidAreaType = window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR; - let avoidArea: window.AvoidArea = this.windowClass?.getWindowAvoidArea(type) as window.AvoidArea; - let bottomRectHeight: number = avoidArea.bottomRect.height; - AppStorage.setOrCreate('bottomRectHeight', bottomRectHeight); - type = window.AvoidAreaType.TYPE_SYSTEM; - avoidArea = this.windowClass?.getWindowAvoidArea(type) as window.AvoidArea; - let topRectHeight: number = avoidArea.topRect.height; - AppStorage.setOrCreate('topRectHeight', topRectHeight); + try { + let type: window.AvoidAreaType = window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR; + let avoidArea: window.AvoidArea = this.windowClass?.getWindowAvoidArea(type) as window.AvoidArea; + let bottomRectHeight: number = avoidArea.bottomRect.height; + AppStorage.setOrCreate('bottomRectHeight', bottomRectHeight); + type = window.AvoidAreaType.TYPE_SYSTEM; + avoidArea = this.windowClass?.getWindowAvoidArea(type) as window.AvoidArea; + let topRectHeight: number = avoidArea.topRect.height; + AppStorage.setOrCreate('topRectHeight', topRectHeight); + } catch (error) { + let err = error as BusinessError; + hilog.error(0x0000, 'EntryAbility', `getWindowAvoidArea failed. code=${err.code}, message=${err.message}`); + } } onWindowStageDestroy(): void { diff --git a/FramedRendering/entry/src/main/ets/model/MonthDataSource.ets b/FramedRendering/entry/src/main/ets/model/MonthDataSource.ets index 0a1e33b542ccb3f2ce987a8ce3bf0013222edc7a..85dd05de55287f8e827441f6974f18c0d6c44939 100644 --- a/FramedRendering/entry/src/main/ets/model/MonthDataSource.ets +++ b/FramedRendering/entry/src/main/ets/model/MonthDataSource.ets @@ -33,14 +33,14 @@ export class MonthDataSource extends BasicDataSource { this.notifyDataAdd(this.dataArray.length - 1); } - public clearData() { + public clearData(): void { for (let i = 0; i < this.dataArray.length; i++) { this.dataArray.pop(); this.notifyDataAdd(this.dataArray.length - 1); } } - public getDateData(uiContext:UIContext) { + public getDateData(uiContext: UIContext): void { for (let i = 1; i <= 12; i++) { let monthDays: number[] = CalculationDateUtil.getMonthDate(i, this.currentYear); let lunarDays: string[] = []; diff --git a/FramedRendering/entry/src/main/ets/pages/Index.ets b/FramedRendering/entry/src/main/ets/pages/Index.ets index edc269962b480e67f5805f1b4baecbbf3e59a83d..8cb326b3d8fda7359f081a25be1ea3443f5e0f4f 100644 --- a/FramedRendering/entry/src/main/ets/pages/Index.ets +++ b/FramedRendering/entry/src/main/ets/pages/Index.ets @@ -54,7 +54,7 @@ struct Index { } @Builder - navTitle() { + navTitle(): void { Column() { Text($r('app.string.EntryAbility_label')) .fontSize(30) @@ -73,7 +73,7 @@ struct Index { } @Builder - PagesMap(id: string) { + PagesMap(id: string): void { if (GlobalBuilderContext.getContext().getObject(id)) { (GlobalBuilderContext.getContext().getObject(id) as WrappedBuilder<[string]>).builder(id); } diff --git a/FramedRendering/entry/src/main/ets/util/CalculationDateUtil.ets b/FramedRendering/entry/src/main/ets/util/CalculationDateUtil.ets index c9ab3acbc76cbf0b5c0b49e555b929a898141cfe..14d6f4433bcd1bd240adfd53e82f2979610bfa66 100644 --- a/FramedRendering/entry/src/main/ets/util/CalculationDateUtil.ets +++ b/FramedRendering/entry/src/main/ets/util/CalculationDateUtil.ets @@ -16,7 +16,7 @@ import { LunarDate, solar2lunar } from 'lunar_lite'; import hilog from '@ohos.hilog'; -const TAG = 'CalculationDateUtil'; +const TAG: string = 'CalculationDateUtil'; const SATURDAY: number = 6; export class CalculationDateUtil { diff --git a/FramedRendering/entry/src/main/ets/view/TestCode.ets b/FramedRendering/entry/src/main/ets/view/TestCode.ets index 5b4e2bf937ec464a95859095f94b4565bcea2a9c..892308ea45ac828511da021b21974972db59f60d 100644 --- a/FramedRendering/entry/src/main/ets/view/TestCode.ets +++ b/FramedRendering/entry/src/main/ets/view/TestCode.ets @@ -6,7 +6,7 @@ import { ProductDetailSource } from "../model/ProductDetailSource"; export struct TransitionScene { private productData: ProductDetailSource = new ProductDetailSource(); - aboutToAppear() { + aboutToAppear(): void { this.productData.getProductData(); } diff --git a/FramedRendering/entry/src/main/ets/view/TransitionScene.ets b/FramedRendering/entry/src/main/ets/view/TransitionScene.ets index f988839489163a7e1d1bd2d8a1f7ca710eb06403..771578859fa246144d695def5159eb1405dd0a1d 100644 --- a/FramedRendering/entry/src/main/ets/view/TransitionScene.ets +++ b/FramedRendering/entry/src/main/ets/view/TransitionScene.ets @@ -90,7 +90,7 @@ struct TransitionScene { // [End Case1] @Builder - typeSwiper() { + typeSwiper(): void { Row() { Swiper() { LazyForEach(this.swiperDataSource, (item: ProductIntroductionModel) => { @@ -118,7 +118,7 @@ struct TransitionScene { } @Builder - typeList() { + typeList(): void { Row() { List({ space: this.LIST_SPACE }) { LazyForEach(this.midListDataSource, (item: ProductIntroductionModel, index: number) => { @@ -139,7 +139,7 @@ struct TransitionScene { } @Builder - midListItem(item: ProductIntroductionModel, index: number) { + midListItem(item: ProductIntroductionModel, index: number): void { Row() { SymbolGlyph(item.icon) .fontSize(16) @@ -163,7 +163,7 @@ struct TransitionScene { } @Builder - typeWaterFlow() { + typeWaterFlow(): void { WaterFlow() { LazyForEach(this.productDetailSource, (item: ProductDetailModel, index: number) => { FlowItem() { @@ -197,7 +197,7 @@ function transitionSceneBuilder(name: string): void { } @Builder -function title() { +function title(): void { Row() { Text($r('app.string.transition')) .fontSize(20) diff --git a/FramedRendering/hvigor/hvigor-config.json5 b/FramedRendering/hvigor/hvigor-config.json5 index 06b2783670a348f95533b352c1ceda909a842bbc..5bebc9755447385d82ce4138f54d991b1f85f348 100644 --- a/FramedRendering/hvigor/hvigor-config.json5 +++ b/FramedRendering/hvigor/hvigor-config.json5 @@ -1,5 +1,5 @@ { - "modelVersion": "5.0.0", + "modelVersion": "5.0.5", "dependencies": { }, "execution": { diff --git a/FramedRendering/oh-package.json5 b/FramedRendering/oh-package.json5 index b0fd4f4fd63477187853ae0c2d3e4ebac203c20c..b4040e8431bc3cfb8a7c976128fa6243a421f8d3 100644 --- a/FramedRendering/oh-package.json5 +++ b/FramedRendering/oh-package.json5 @@ -1,5 +1,5 @@ { - "modelVersion": "5.0.0", + "modelVersion": "5.0.5", "description": "Please describe the basic information.", "dependencies": { "lunar_lite": "^1.0.0" diff --git a/FuzzySceneOptimization/README.en.md b/FuzzySceneOptimization/README.en.md index 58383ed2372780898198daf5257dcc381e1352b3..0c923b21a016f6cc10c38fbbae3cc8430f53f622 100644 --- a/FuzzySceneOptimization/README.en.md +++ b/FuzzySceneOptimization/README.en.md @@ -52,8 +52,19 @@ N/A 1. This sample is supported only on Huawei phones running the standard system. -2. The HarmonyOS version must be HarmonyOS NEXT Release or later. +2. The HarmonyOS version must be HarmonyOS 5.0.5 Release or later. -3. The DevEco Studio version must be DevEco Studio NEXT Release or later. +3. The DevEco Studio version must be DevEco Studio 5.0.5 Release or later. -4. The HarmonyOS SDK version must be HarmonyOS NEXT Release SDK or later. +4. The HarmonyOS SDK version must be HarmonyOS 5.0.5 Release SDK or later. + +### Download + +To download this project separately, execute the following command: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set FuzzySceneOptimization +git checkout +``` diff --git a/FuzzySceneOptimization/README.md b/FuzzySceneOptimization/README.md index 1a7de4bf7ff887690973092c31c15f1da8233135..841c5f9cd609bb16e4b62ee34ee84954e369dd9b 100644 --- a/FuzzySceneOptimization/README.md +++ b/FuzzySceneOptimization/README.md @@ -52,8 +52,19 @@ 1.本示例仅支持标准系统上运行,支持设备:华为手机。 -2.HarmonyOS系统:HarmonyOS NEXT Release及以上。 +2.HarmonyOS系统:HarmonyOS 5.0.5 Release及以上。 -3.DevEco Studio版本:DevEco Studio NEXT Release及以上。 +3.DevEco Studio版本:DevEco Studio 5.0.5 Release及以上。 -4.HarmonyOS SDK版本:HarmonyOS NEXT Release SDK及以上。 +4.HarmonyOS SDK版本:HarmonyOS 5.0.5 Release SDK及以上。 + +### 下载 + +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set FuzzySceneOptimization +git checkout +``` diff --git a/FuzzySceneOptimization/build-profile.json5 b/FuzzySceneOptimization/build-profile.json5 index c033ce4278fb0641d84107c3c134047ac487368e..b2ca56e35558b0dc7ca91989b68a1ea65b49a7a2 100644 --- a/FuzzySceneOptimization/build-profile.json5 +++ b/FuzzySceneOptimization/build-profile.json5 @@ -5,7 +5,8 @@ { "name": "default", "signingConfig": "default", - "compatibleSdkVersion": "5.0.0(12)", + "compatibleSdkVersion": "5.0.5(17)", + "targetSdkVersion": "5.0.5(17)", "runtimeOS": "HarmonyOS", } ], diff --git a/FuzzySceneOptimization/entry/src/main/ets/pages/MotionBlur.ets b/FuzzySceneOptimization/entry/src/main/ets/pages/MotionBlur.ets index 3fbd3f2bb680683b8bc2472ff79baa153cc0c428..16772f826e9c1bed2ba4a4c47504b6588cfbe842 100644 --- a/FuzzySceneOptimization/entry/src/main/ets/pages/MotionBlur.ets +++ b/FuzzySceneOptimization/entry/src/main/ets/pages/MotionBlur.ets @@ -15,6 +15,8 @@ // [Start dynamic_start] import { window } from '@kit.ArkUI'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { BusinessError } from '@kit.BasicServicesKit'; @Component export struct MotionBlur { @@ -22,15 +24,26 @@ export struct MotionBlur { @State isShowMotionBlur: boolean = false; @State bottomSafeHeight: number = 0; // bottom navigation bar height - aboutToAppear() { + aboutToAppear(): void { window.getLastWindow(this.getUIContext().getHostContext()!, (err, windowBar) => { if (err.code) { return; } - // get the height of the bottom navigation bar - this.bottomSafeHeight = - this.getUIContext().px2vp(windowBar.getWindowAvoidArea(window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR).bottomRect.height); - windowBar.setWindowLayoutFullScreen(true); + + try { + // get the height of the bottom navigation bar + this.bottomSafeHeight = + this.getUIContext() + .px2vp(windowBar.getWindowAvoidArea(window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR).bottomRect.height); + } catch (error) { + let err: BusinessError = error as BusinessError; + hilog.warn(0x000, 'testTag', `getWindowAvoidArea failed, code=${err.code}, message=${err.message}`); + } + windowBar.setWindowLayoutFullScreen(true) + .catch((err: BusinessError) => { + hilog.error(0x000, 'testTag', `setWindowLayoutFullScreen failed, code=${err.code}, message=${err.message}`); + }) + }); } @@ -76,4 +89,5 @@ export struct MotionBlur { .hideTitleBar(true) } } + // [End dynamic_start] \ No newline at end of file diff --git a/FuzzySceneOptimization/entry/src/main/ets/pages/StaticBlur.ets b/FuzzySceneOptimization/entry/src/main/ets/pages/StaticBlur.ets index 39a2b8e0e577b2efa68b1baa6d18c63f1f525137..de9997e075688014f4fe8fb44b39a3660c0159f9 100644 --- a/FuzzySceneOptimization/entry/src/main/ets/pages/StaticBlur.ets +++ b/FuzzySceneOptimization/entry/src/main/ets/pages/StaticBlur.ets @@ -17,6 +17,8 @@ import { image } from '@kit.ImageKit'; import { effectKit } from '@kit.ArkGraphics2D'; import { window } from '@kit.ArkUI'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { BusinessError } from '@kit.BasicServicesKit'; @Component export struct StaticBlur { @@ -26,24 +28,37 @@ export struct StaticBlur { @State imgSource: image.ImageSource | undefined = undefined; @State bottomSafeHeight: number = 0; // bottom navigation bar height - aboutToAppear() { + aboutToAppear(): void { window.getLastWindow(this.getUIContext().getHostContext()!, (err, windowBar) => { if (err.code) { return; } - // get the height of the bottom navigation bar - this.bottomSafeHeight = - this.getUIContext().px2vp(windowBar.getWindowAvoidArea(window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR).bottomRect.height); - windowBar.setWindowLayoutFullScreen(true); + try { + // get the height of the bottom navigation bar + this.bottomSafeHeight = + this.getUIContext() + .px2vp(windowBar.getWindowAvoidArea(window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR).bottomRect.height); + } catch (error) { + let err: BusinessError = error as BusinessError; + hilog.warn(0x000, 'testTag', `getWindowAvoidArea failed, code=${err.code}, message=${err.message}`); + } + windowBar.setWindowLayoutFullScreen(true) + .catch((err: BusinessError) => { + hilog.error(0x000, 'testTag', `setWindowLayoutFullScreen failed, code=${err.code}, message=${err.message}`); + }) }); } - async staticBlur() { - let context = this.getUIContext().getHostContext()!; - let resourceMgr = context.resourceManager; // retrieve the resourceManager object - const fileData = await resourceMgr.getRawFileContent('test.png'); // retrieve images from the rawfile directory - let buffer: ArrayBuffer = fileData.buffer.slice(0); // create an ArrayBuffer instance - this.imgSource = image.createImageSource(buffer); // create an image source instance + async staticBlur(): Promise { + let context: Context = this.getUIContext().getHostContext()!; + await context.resourceManager.getRawFileContent('test.png') // retrieve images from the rawfile directory + .then((fileData: Uint8Array) => { + let buffer: ArrayBuffer = fileData.buffer.slice(0); // create an ArrayBuffer instance + this.imgSource = image.createImageSource(buffer); // create an image source instance + }) + .catch((err: BusinessError) => { + hilog.error(0x000, 'testTag', `getRawFileContent failed, code=${err.code}, message=${err.message}`); + }) // create attributes for pixels let opts: image.InitializationOptions = { editable: true, // is it editable @@ -55,9 +70,9 @@ export struct StaticBlur { } }; // create PixelMap - await this.imgSource.createPixelMap(opts).then((pixelMap: image.PixelMap) => { - const blurRadius = 3; - let headFilter = effectKit.createEffect(pixelMap); // create Filter Instance + await this.imgSource!.createPixelMap(opts).then((pixelMap: image.PixelMap) => { + const blurRadius: number = 3; + let headFilter: effectKit.Filter = effectKit.createEffect(pixelMap); // create Filter Instance if (headFilter !== null) { headFilter.blur(blurRadius); // set static blur. Add the blur effect to the effect list // retrieve the image of the source image with the added linked list effect PixelMap diff --git a/GesturesConfictPractice/README.md b/GesturesConfictPractice/README.md new file mode 100644 index 0000000000000000000000000000000000000000..d4423c8f0102f73509d5893849e3989d8edcdbe1 --- /dev/null +++ b/GesturesConfictPractice/README.md @@ -0,0 +1,67 @@ +# 手势事件冲突解决方案 + +### 介绍 + +本代码示例展示了多个组件嵌套时同时绑定手势事件,或者同一个组件同时绑定多个手势等场景下,手势冲突问题的解决。 + +### 效果说明 + +* GesturesConflictScene1:Scroll组件和List组件嵌套滑动冲突解决方案,Scroll组件和List组件实现整体滑动。 +* GesturesConflictScene2:单击手势和双击手势互斥执行,优先响应单击,无法响应双击事件。 +* GesturesConflictScene2A:单击手势和双击手势并行执行,单击和双击事件同时执行。 +* GesturesConflictScene3:系统手势覆盖自定义手势,长按Image组件,Image组件放大,自定义长按手势不会触发。 +* GesturesConflictScene3A:自定义手势使用优先级手势priorityGesture,长按Image组件,Image组件无变化,自定义长按手势触发,弹出Toast提示。 +* GesturesConflictScene4:手势事件透传,在层的红色组件上左右滑动,弹出Toast提示。 +* GesturesConflictScene5:Button1使用事件独占属性.monopolizeEvents(true)后,一个手指按住Button1,另一个手指点击Button2,不会出发Button2的点击事件。 +* GesturesConflictScene6:长按红色区域不会触发拖拽效果。 +* GesturesConflictScene7:Scroll组件嵌套Scroll组件实现联合滚动。 +* WebScrollDemo:Web组件和Scroll组件嵌套,红色区域的Text组件和Web组件一起滚动。 + +#### 使用说明 + +安装运行应用,进入应用首页,点击不同的按钮跳转到不同的手势场景示例。 + +### 工程目录 + +``` +├──entry/src/main/ets +│ ├──entryability +│ │ └──EntryAbility.ets // 程序入口类 +│ ├──entrybackupability +│ │ └──EntryBackupAbility.ets // 数据备份恢复类 +│ └──pages +│ ├──GesturesConflictScene1.ets // 滚动容器嵌套滚动容器事件冲突 +│ ├──GesturesConflictScene2.ets // 使用组合手势同时绑定多个同类型手势冲突解反例 +│ ├──GesturesConflictScene2A.ets // 使用组合手势同时绑定多个同类型手势冲突解正例 +│ ├──GesturesConflictScene3.ets // 系统手势和自定义手势之间冲突反例 +│ ├──GesturesConflictScene3A.ets // 系统手势和自定义手势之间冲突正例 +│ ├──GesturesConflictScene4.ets // 手势事件透传 +│ ├──GesturesConflictScene5.ets // 多点触控场景下手势冲突 +│ ├──GesturesConflictScene6.ets // 动态控制自定义手势是否响应 +│ ├──GesturesConflictScene7.ets // 父组件如何管理子组件手势 +│ ├──Index.ets // 应用首页 +│ └──WebScrollDemo.ets // Web组件和Scroll组件嵌套示例 +└──entry/src/main/resources // 应用资源目录 +``` + +### 相关权限 + +* 允许使用Internet网络:ohos.permission.INTERNET。 + +### 约束与限制 + +* 本示例仅支持标准系统上运行,支持设备:华为手机。 +* HarmonyOS系统:HarmonyOS 5.0.5 Release及以上。 +* DevEco Studio版本:DevEco Studio 5.0.5 Release及以上。 +* HarmonyOS SDK版本:HarmonyOS 5.0.5 Release SDK及以上。 + +### 下载 + +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set GesturesConfictPractice +git checkout +``` \ No newline at end of file diff --git a/GesturesConfictPractice/build-profile.json5 b/GesturesConfictPractice/build-profile.json5 index c033ce4278fb0641d84107c3c134047ac487368e..b2ca56e35558b0dc7ca91989b68a1ea65b49a7a2 100644 --- a/GesturesConfictPractice/build-profile.json5 +++ b/GesturesConfictPractice/build-profile.json5 @@ -5,7 +5,8 @@ { "name": "default", "signingConfig": "default", - "compatibleSdkVersion": "5.0.0(12)", + "compatibleSdkVersion": "5.0.5(17)", + "targetSdkVersion": "5.0.5(17)", "runtimeOS": "HarmonyOS", } ], diff --git a/GesturesConfictPractice/entry/src/main/ets/entryability/EntryAbility.ets b/GesturesConfictPractice/entry/src/main/ets/entryability/EntryAbility.ets index 8335b7692d4cac1f8b5d78ce7bc1c45a453d563e..0f2f8b94aa24b0a50e272270e4e18b6df93ac5fd 100644 --- a/GesturesConfictPractice/entry/src/main/ets/entryability/EntryAbility.ets +++ b/GesturesConfictPractice/entry/src/main/ets/entryability/EntryAbility.ets @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; import { hilog } from '@kit.PerformanceAnalysisKit'; import { window } from '@kit.ArkUI'; diff --git a/GesturesConfictPractice/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets b/GesturesConfictPractice/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets index dc55c03d3eea7ce53d5346c732a39ce9bf5267e1..b1e212947256c5533c7b06285a597c94f840a6e3 100644 --- a/GesturesConfictPractice/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets +++ b/GesturesConfictPractice/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + import { hilog } from '@kit.PerformanceAnalysisKit'; import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit'; diff --git a/GesturesConfictPractice/entry/src/main/ets/pages/GesturesConflictScene1.ets b/GesturesConfictPractice/entry/src/main/ets/pages/GesturesConflictScene1.ets index 7bb59e01b3bed60e5281dea0b575c366ff738833..fae53af55e3cd88bb85eb3855bcaa827f753bed7 100644 --- a/GesturesConfictPractice/entry/src/main/ets/pages/GesturesConflictScene1.ets +++ b/GesturesConfictPractice/entry/src/main/ets/pages/GesturesConflictScene1.ets @@ -13,12 +13,6 @@ * limitations under the License. */ -/* - * 最佳实践:手势事件冲突解决方案 - * - * 场景一:滚动容器嵌套滚动容器事件冲突 - */ - // [Start gestures_conflictScene1] @Entry @Component diff --git a/GesturesConfictPractice/entry/src/main/ets/pages/GesturesConflictScene2.ets b/GesturesConfictPractice/entry/src/main/ets/pages/GesturesConflictScene2.ets index c33a5ae5556b8addd51bbf8d08d82fd6a80202d4..f116addb5e4b087c26afa4af1f49ae2cafa593a6 100644 --- a/GesturesConfictPractice/entry/src/main/ets/pages/GesturesConflictScene2.ets +++ b/GesturesConfictPractice/entry/src/main/ets/pages/GesturesConflictScene2.ets @@ -13,12 +13,6 @@ * limitations under the License. */ -/* - * 最佳实践:手势事件冲突解决方案 - * - * 场景二:使用组合手势同时绑定多个同类型手势冲突 - */ - // [Start gestures_conflict_scene2] @Entry @Component @@ -28,8 +22,7 @@ struct GesturesConflictScene2 { build() { Column() { - Text('Exclusive gesture\n' + 'tapGesture count is 1:' + this.count1 + '\ntapGesture count is 2:' + this.count2 + - '\n') + Text('Exclusive gesture\n' + 'Click count is:' + this.count1 + '\nDouble click count is:' + this.count2 + '\n') .fontSize(28) } .height(200) diff --git a/GesturesConfictPractice/entry/src/main/ets/pages/GesturesConflictScene2A.ets b/GesturesConfictPractice/entry/src/main/ets/pages/GesturesConflictScene2A.ets index 397e31ad321435f1fa5a2d038da262d8c2585151..c38b082cefe7c7fd96287e036208eff4383ba93e 100644 --- a/GesturesConfictPractice/entry/src/main/ets/pages/GesturesConflictScene2A.ets +++ b/GesturesConfictPractice/entry/src/main/ets/pages/GesturesConflictScene2A.ets @@ -13,13 +13,6 @@ * limitations under the License. */ -/* - * 最佳实践:手势事件冲突解决方案 - * - * 场景二:使用组合手势同时绑定多个同类型手势冲突 - * 冲突解决后代码 - */ - @Entry @Component struct GesturesConflictScene21 { @@ -28,15 +21,14 @@ struct GesturesConflictScene21 { build() { Column() { - Text('Exclusive gesture\n' + 'tapGesture count is 1:' + this.count1 + '\ntapGesture count is 2:' + this.count2 + - '\n') + Text('Exclusive gesture\n' + 'Click count is:' + this.count1 + '\nDouble click count is:' + this.count2 + '\n') .fontSize(28) } .height(200) .width('100%') // DocsCode 1 .gesture( - GestureGroup(GestureMode.Exclusive, + GestureGroup(GestureMode.Parallel, TapGesture({ count: 2 }) .onAction(() => { this.count2++; diff --git a/GesturesConfictPractice/entry/src/main/ets/pages/GesturesConflictScene3.ets b/GesturesConfictPractice/entry/src/main/ets/pages/GesturesConflictScene3.ets index 4b0a60d83459f0fade1c4d37bcca74a006784cdb..226f4c281ef1e5132543ca1c552742990dc66e53 100644 --- a/GesturesConfictPractice/entry/src/main/ets/pages/GesturesConflictScene3.ets +++ b/GesturesConfictPractice/entry/src/main/ets/pages/GesturesConflictScene3.ets @@ -13,15 +13,10 @@ * limitations under the License. */ -/* - * 最佳实践:手势事件冲突解决方案 - * - * 场景三:系统手势和自定义手势之间冲突 - */ +import { BusinessError } from '@kit.BasicServicesKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; // [Start gestures_conflict_scene3] -import { promptAction } from '@kit.ArkUI'; - @Entry @Component struct GesturesConflictScene3 { @@ -40,9 +35,15 @@ struct GesturesConflictScene3 { .gesture( LongPressGesture({ repeat: true }) .onAction((event: GestureEvent) => { - })// The long press action ends + }) + // The long press action ends .onActionEnd(() => { - this.getUIContext().getPromptAction().showToast({ message: 'Long Press' }); + try { + this.getUIContext().getPromptAction().showToast({ message: 'Long Press' }); + } catch (err) { + let error = err as BusinessError; + hilog.error(0x0000, 'testTag', `showToast err, code: ${error.code}, mesage: ${error.message}`); + } }) ) } diff --git a/GesturesConfictPractice/entry/src/main/ets/pages/GesturesConflictScene3A.ets b/GesturesConfictPractice/entry/src/main/ets/pages/GesturesConflictScene3A.ets index c75ebfdd2f9864ce98f67b0ee2cf4048adeee669..780c8286c4bd5445ac4aa19211a3e0ebce7b5924 100644 --- a/GesturesConfictPractice/entry/src/main/ets/pages/GesturesConflictScene3A.ets +++ b/GesturesConfictPractice/entry/src/main/ets/pages/GesturesConflictScene3A.ets @@ -13,14 +13,8 @@ * limitations under the License. */ -/* - * 最佳实践:手势事件冲突解决方案 - * - * 场景三:系统手势和自定义手势之间冲突 - * 冲突解决之后 - */ - -import { promptAction } from '@kit.ArkUI'; +import { BusinessError } from '@kit.BasicServicesKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; @Entry @Component @@ -37,16 +31,21 @@ struct GesturesConflictScene3A { .margin({ top: 100 }) .width(360) .height(360) - // [Start gesture_action] + // [Start gesture_action] .priorityGesture( LongPressGesture({ repeat: true }) .onAction((event: GestureEvent) => { }) .onActionEnd(() => { - this.getUIContext().getPromptAction().showToast({ message: 'Long Press' }); + try { + this.getUIContext().getPromptAction().showToast({ message: 'Long Press' }); + } catch (err) { + let error = err as BusinessError; + hilog.error(0x0000, 'testTag', `showToast err, code: ${error.code}, mesage: ${error.message}`); + } }) ) - // [End gesture_action] + // [End gesture_action] } .width('100%') } diff --git a/GesturesConfictPractice/entry/src/main/ets/pages/GesturesConflictScene4.ets b/GesturesConfictPractice/entry/src/main/ets/pages/GesturesConflictScene4.ets index fd980c012224b669c98902b8e2ad372aaaa489fa..af7d20b2315490d1cc985de20373298d5960c942 100644 --- a/GesturesConfictPractice/entry/src/main/ets/pages/GesturesConflictScene4.ets +++ b/GesturesConfictPractice/entry/src/main/ets/pages/GesturesConflictScene4.ets @@ -13,13 +13,10 @@ * limitations under the License. */ -/* - * 最佳实践:手势事件冲突解决方案 - * - * 场景四:手势事件透传 - */ - // [Start gestures_conflict_scene4] +import { BusinessError } from '@kit.BasicServicesKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; + @Entry @Component struct GesturesConflictScene4 { @@ -33,7 +30,12 @@ struct GesturesConflictScene4 { SwipeGesture({ direction: SwipeDirection.Horizontal })//水平方向滑动手势 .onAction((event) => { if (event) { - console.info('Column SwipeGesture'); + try { + this.getUIContext().getPromptAction().showToast({ message: 'SwipeGesture' }); + } catch (err) { + let error = err as BusinessError; + hilog.error(0x0000, 'testTag', `showToast err, code: ${error.code}, mesage: ${error.message}`); + } } }) ) diff --git a/GesturesConfictPractice/entry/src/main/ets/pages/GesturesConflictScene5.ets b/GesturesConfictPractice/entry/src/main/ets/pages/GesturesConflictScene5.ets index 78e31a186fa98f2011bf4a6699ae4efc14282ae9..724afc43ff8e1c82e457b616a5263eed8ed809ee 100644 --- a/GesturesConfictPractice/entry/src/main/ets/pages/GesturesConflictScene5.ets +++ b/GesturesConfictPractice/entry/src/main/ets/pages/GesturesConflictScene5.ets @@ -13,13 +13,10 @@ * limitations under the License. */ -/* - * 最佳实践:手势事件冲突解决方案 - * - * 场景五:多点触控场景下手势冲突 - */ - // [Start gestures_conflict_scene5] +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { BusinessError } from '@kit.BasicServicesKit'; + @Entry @Component struct GesturesConflictScene5 { @@ -36,7 +33,12 @@ struct GesturesConflictScene5 { .width(200) .height(50) .onClick(() => { - console.info('GesturesConflictScene5 Button2 click'); + try { + this.getUIContext().getPromptAction().showToast({ message: 'GesturesConflictScene5 Button2 click' }); + } catch (err) { + let error = err as BusinessError; + hilog.error(0x0000, 'testTag', `showToast err, code: ${error.code}, mesage: ${error.message}`); + } }) } .margin(20) @@ -45,9 +47,6 @@ struct GesturesConflictScene5 { .margin(15) } .width('100%') - .onDragStart(() => { - console.info('GesturesConflictScene5 Drag start.'); - }) .gesture( TapGesture({ count: 1 }) .onAction(() => { diff --git a/GesturesConfictPractice/entry/src/main/ets/pages/GesturesConflictScene6.ets b/GesturesConfictPractice/entry/src/main/ets/pages/GesturesConflictScene6.ets index 4a1b3350939d876fda214f47ebc8f9cd216499b5..6c84edf348462705cc93e0ed2dbb54e10abe9e65 100644 --- a/GesturesConfictPractice/entry/src/main/ets/pages/GesturesConflictScene6.ets +++ b/GesturesConfictPractice/entry/src/main/ets/pages/GesturesConflictScene6.ets @@ -13,12 +13,6 @@ * limitations under the License. */ -/* - * 最佳实践:手势事件冲突解决方案 - * - * 场景六:动态控制自定义手势是否响应 - */ - // [Start gestures_conflict_scene6] @Entry @Component diff --git a/GesturesConfictPractice/entry/src/main/ets/pages/GesturesConflictScene7.ets b/GesturesConfictPractice/entry/src/main/ets/pages/GesturesConflictScene7.ets index 7f42ce2c228eb98cbc0c5ce5426a04796f5383ea..dae26a3ddc010290f549e1a90cff7592c5d3e62c 100644 --- a/GesturesConfictPractice/entry/src/main/ets/pages/GesturesConflictScene7.ets +++ b/GesturesConfictPractice/entry/src/main/ets/pages/GesturesConflictScene7.ets @@ -13,12 +13,6 @@ * limitations under the License. */ -/* - * 最佳实践:手势事件冲突解决方案 - * - * 场景七:父组件如何管理子组件手势 - */ - // [Start gestures_conflict_scene7] @Entry @Component diff --git a/GesturesConfictPractice/entry/src/main/ets/pages/GesturesConflictScene8.ets b/GesturesConfictPractice/entry/src/main/ets/pages/GesturesConflictScene8.ets deleted file mode 100644 index 6345f0e51f6aac0b1550aa7179460e7cc9ad29ab..0000000000000000000000000000000000000000 --- a/GesturesConfictPractice/entry/src/main/ets/pages/GesturesConflictScene8.ets +++ /dev/null @@ -1,50 +0,0 @@ -/* -* Copyright (C) 2024 Huawei Device Co., Ltd. -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* 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. -*/ - -/* - * 最佳实践:手势事件冲突解决方案 - * - * 场景七:手势事件透传 - */ - -// [Start component_scene4] -@Entry -@Component -struct GesturesConflictScene4 { - build() { - Stack() { - Column()//Underlying Column - .width('100%') - .height('100%') - .backgroundColor(Color.Black) - .gesture( - SwipeGesture({ direction: SwipeDirection.Horizontal })//Horizontal swipe gesture - .onAction((event) => { - if (event) { - console.info('Column SwipeGesture'); - } - }) - ) - Column()//Upper Column - .width(300) - .height(100) - .backgroundColor(Color.Red) - .hitTestBehavior(HitTestMode.None) - } - .width(300) - .height(300) - } -} -// [End component_scene4] \ No newline at end of file diff --git a/GesturesConfictPractice/entry/src/main/ets/pages/Index.ets b/GesturesConfictPractice/entry/src/main/ets/pages/Index.ets index 9393e00f3990f2da833746e03f7fc066e15766bc..bffc149b6e8adb4130f6e18963cd44ac829873f5 100644 --- a/GesturesConfictPractice/entry/src/main/ets/pages/Index.ets +++ b/GesturesConfictPractice/entry/src/main/ets/pages/Index.ets @@ -1,20 +1,98 @@ +/* +* Copyright (C) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + +import { BusinessError } from '@kit.BasicServicesKit'; +import { Router } from '@ohos.arkui.UIContext'; + @Entry @Component struct Index { @State message: string = 'Hello World'; + private router: Router = this.getUIContext().getRouter(); + + jumperPage(url: string) { + this.router.pushUrl({ url: `pages/${url}` }).catch((error: BusinessError) => { + console.error(`reset err, code: ${error.code}, mesage: ${error.message}`); + }); + } 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 } + Column({ space: 12 }) { + Button('GesturesConflictScene1') + .width('100%') + .onClick(() => { + this.jumperPage('GesturesConflictScene1'); + }) + + Button('GesturesConflictScene2') + .width('100%') + .onClick(() => { + this.jumperPage('GesturesConflictScene2'); + }) + + Button('GesturesConflictScene2A') + .width('100%') + .onClick(() => { + this.jumperPage('GesturesConflictScene2A'); + }) + + Button('GesturesConflictScene3') + .width('100%') + .onClick(() => { + this.jumperPage('GesturesConflictScene3'); + }) + + Button('GesturesConflictScene3A') + .width('100%') + .onClick(() => { + this.jumperPage('GesturesConflictScene3A'); + }) + + Button('GesturesConflictScene4') + .width('100%') + .onClick(() => { + this.jumperPage('GesturesConflictScene4'); + }) + + Button('GesturesConflictScene5') + .width('100%') + .onClick(() => { + this.jumperPage('GesturesConflictScene5'); + }) + + Button('GesturesConflictScene6') + .width('100%') + .onClick(() => { + this.jumperPage('GesturesConflictScene6'); + }) + + Button('GesturesConflictScene7') + .width('100%') + .onClick(() => { + this.jumperPage('GesturesConflictScene7'); + }) + + Button('WebScrollDemo') + .width('100%') + .onClick(() => { + this.jumperPage('WebScrollDemo'); }) } .height('100%') .width('100%') + .padding(16) + .justifyContent(FlexAlign.End) } } \ No newline at end of file diff --git a/GesturesConfictPractice/entry/src/main/ets/pages/TestCode.ets b/GesturesConfictPractice/entry/src/main/ets/pages/TestCode.ets deleted file mode 100644 index ed677eabb5d8f14181e01a291e3bf5ec74a3558e..0000000000000000000000000000000000000000 --- a/GesturesConfictPractice/entry/src/main/ets/pages/TestCode.ets +++ /dev/null @@ -1,67 +0,0 @@ -import { webview } from '@kit.ArkWeb'; - -@Component -struct Index { - @State message: string = 'Hello World'; - - // [Start test_code_build] - build() { - StackA() { - ComponentB() { - ComponentC() - } - - ComponentD() { - ComponentE() - } - } - } - // [End test_code_build] -} - -@Component -struct StackA { - controller: webview.WebviewController = new webview.WebviewController(); - - build() { - // [Start web_nested_scroll] - Web( - // [StartExclude web_nested_scroll] - { src: 'https://developer.huawei.com/consumer/cn/', controller: this.controller } - // [EndExclude web_nested_scroll] - ) - .nestedScroll({ - scrollForward: NestedScrollMode.PARENT_FIRST, - scrollBackward: NestedScrollMode.SELF_FIRST - }) - // [End web_nested_scroll] - } -} - -@Component -struct ComponentB { - build() { - - } -} - -@Component -struct ComponentC { - build() { - - } -} - -@Component -struct ComponentD { - build() { - - } -} - -@Component -struct ComponentE { - build() { - - } -} \ No newline at end of file diff --git a/GesturesConfictPractice/entry/src/main/ets/pages/WebScrollDemo.ets b/GesturesConfictPractice/entry/src/main/ets/pages/WebScrollDemo.ets new file mode 100644 index 0000000000000000000000000000000000000000..664d8d56c906c8fdf2f5977b5b3601d24443cbfa --- /dev/null +++ b/GesturesConfictPractice/entry/src/main/ets/pages/WebScrollDemo.ets @@ -0,0 +1,46 @@ +/* +* Copyright (C) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + +import { webview } from '@kit.ArkWeb'; + +@Entry +@Component +struct WebScrollDemo { + controller: webview.WebviewController = new webview.WebviewController(); + + build() { + // [Start web_nested_scroll] + Scroll() { + Column() { + Text('Text') + .fontSize(50) + .backgroundColor(Color.Red) + .width('100%') + .height('40%') + Web( + // [StartExclude web_nested_scroll] + { src: 'https://developer.huawei.com/consumer/cn/', controller: this.controller } + // [EndExclude web_nested_scroll] + ) + .nestedScroll({ + scrollForward: NestedScrollMode.PARENT_FIRST, + scrollBackward: NestedScrollMode.SELF_FIRST + }) + + } + } + // [End web_nested_scroll] + } +} \ No newline at end of file diff --git a/GesturesConfictPractice/entry/src/main/module.json5 b/GesturesConfictPractice/entry/src/main/module.json5 index a1cea8b6a4560cee7bda7a2db52f310c035ab6c8..dd39cd499613b5fbf11765616bd1431c52fb8d82 100644 --- a/GesturesConfictPractice/entry/src/main/module.json5 +++ b/GesturesConfictPractice/entry/src/main/module.json5 @@ -5,9 +5,7 @@ "description": "$string:module_desc", "mainElement": "EntryAbility", "deviceTypes": [ - "phone", - "tablet", - "2in1" + "phone" ], "deliveryWithInstall": true, "installationFree": false, @@ -45,7 +43,12 @@ "name": "ohos.extension.backup", "resource": "$profile:backup_config" } - ], + ] + } + ], + "requestPermissions": [ + { + "name": "ohos.permission.INTERNET" } ] } diff --git a/GesturesConfictPractice/entry/src/main/resources/base/element/string.json b/GesturesConfictPractice/entry/src/main/resources/base/element/string.json index f94595515a99e0c828807e243494f57f09251930..8f729eb352ebb73503fde82b290f6ce4e4cdf555 100644 --- a/GesturesConfictPractice/entry/src/main/resources/base/element/string.json +++ b/GesturesConfictPractice/entry/src/main/resources/base/element/string.json @@ -10,7 +10,7 @@ }, { "name": "EntryAbility_label", - "value": "label" + "value": "GesturesConfictPractice" } ] } \ No newline at end of file diff --git a/GesturesConfictPractice/entry/src/main/resources/base/profile/main_pages.json b/GesturesConfictPractice/entry/src/main/resources/base/profile/main_pages.json index 1d6b935f7409cf9e7c4da7b0b7702952e2bbc012..57174054964056e515f8c0ab1873fa8e1975236c 100644 --- a/GesturesConfictPractice/entry/src/main/resources/base/profile/main_pages.json +++ b/GesturesConfictPractice/entry/src/main/resources/base/profile/main_pages.json @@ -9,6 +9,7 @@ "pages/GesturesConflictScene6", "pages/GesturesConflictScene7", "pages/GesturesConflictScene2A", - "pages/GesturesConflictScene3A" + "pages/GesturesConflictScene3A", + "pages/WebScrollDemo" ] } \ No newline at end of file diff --git a/GesturesConfictPractice/entry/src/main/resources/en_US/element/string.json b/GesturesConfictPractice/entry/src/main/resources/en_US/element/string.json index f94595515a99e0c828807e243494f57f09251930..8f729eb352ebb73503fde82b290f6ce4e4cdf555 100644 --- a/GesturesConfictPractice/entry/src/main/resources/en_US/element/string.json +++ b/GesturesConfictPractice/entry/src/main/resources/en_US/element/string.json @@ -10,7 +10,7 @@ }, { "name": "EntryAbility_label", - "value": "label" + "value": "GesturesConfictPractice" } ] } \ No newline at end of file diff --git a/GesturesConfictPractice/entry/src/main/resources/zh_CN/element/string.json b/GesturesConfictPractice/entry/src/main/resources/zh_CN/element/string.json index 597ecf95e61d7e30367c22fe2f8638008361b044..1b8ca49760e510c70f0f746f56fc26c270f890f7 100644 --- a/GesturesConfictPractice/entry/src/main/resources/zh_CN/element/string.json +++ b/GesturesConfictPractice/entry/src/main/resources/zh_CN/element/string.json @@ -10,7 +10,7 @@ }, { "name": "EntryAbility_label", - "value": "label" + "value": "GesturesConfictPractice" } ] } \ No newline at end of file diff --git a/GesturesConfictPractice/oh-package-lock.json5 b/GesturesConfictPractice/oh-package-lock.json5 deleted file mode 100644 index 98a02905872e6f7062caa795d20438bb79ed9d61..0000000000000000000000000000000000000000 --- a/GesturesConfictPractice/oh-package-lock.json5 +++ /dev/null @@ -1,27 +0,0 @@ -{ - "meta": { - "stableOrder": true - }, - "lockfileVersion": 3, - "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", - "specifiers": { - "@ohos/hamock@1.0.0": "@ohos/hamock@1.0.0", - "@ohos/hypium@1.0.18": "@ohos/hypium@1.0.18" - }, - "packages": { - "@ohos/hamock@1.0.0": { - "name": "@ohos/hamock", - "version": "1.0.0", - "integrity": "sha512-K6lDPYc6VkKe6ZBNQa9aoG+ZZMiwqfcR/7yAVFSUGIuOAhPvCJAo9+t1fZnpe0dBRBPxj2bxPPbKh69VuyAtDg==", - "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hamock/-/hamock-1.0.0.har", - "registryType": "ohpm" - }, - "@ohos/hypium@1.0.18": { - "name": "@ohos/hypium", - "version": "1.0.18", - "integrity": "sha512-RGe/iLGdeywdQilMWZsHKUoiE9OJ+9QxQsorF92R2ImLNVHVhbpSePNITGpW7TnvLgOIP/jscOqfIOhk6X7XRQ==", - "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hypium/-/hypium-1.0.18.har", - "registryType": "ohpm" - } - } -} \ No newline at end of file diff --git a/GlobalCustomComponentReuse/ComponentPrebuild/README.md b/GlobalCustomComponentReuse/ComponentPrebuild/README.md index 06c8f4c0deaeb8bd5a3e504bccd0ae1eaf4e16c1..4d33117e736816a6d53f13bc818071066fda3753 100644 --- a/GlobalCustomComponentReuse/ComponentPrebuild/README.md +++ b/GlobalCustomComponentReuse/ComponentPrebuild/README.md @@ -1,4 +1,27 @@ # Performance 最佳实践“性能”板块目录 -ComponentPrebuildByOnIdle 全局自定义组件复用实现#使用onIdle进行组件预创建#闲时预创建 \ No newline at end of file +ComponentPrebuildByOnIdle 全局自定义组件复用实现#使用onIdle进行组件预创建#闲时预创建 + +## 相关权限 +无 + +## 约束与限制 +* 本示例仅支持标准系统上运行,支持设备:华为手机。 + +* HarmonyOS系统:HarmonyOS 5.0.5 Release及以上。 + +* DevEco Studio版本:DevEco Studio 5.0.5 Release及以上。 + +* HarmonyOS SDK版本:HarmonyOS 5.0.5 Release SDK及以上。 + +## 下载 + +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set GlobalCustomComponentReuse/ComponentPrebuild +git checkout +``` \ No newline at end of file diff --git a/GlobalCustomComponentReuse/ComponentPrebuild/build-profile.json5 b/GlobalCustomComponentReuse/ComponentPrebuild/build-profile.json5 index 31ec1da047800a2143c86fcab93fe9a742b1c614..fbfa943d237d79a5046e44104427db147a633969 100644 --- a/GlobalCustomComponentReuse/ComponentPrebuild/build-profile.json5 +++ b/GlobalCustomComponentReuse/ComponentPrebuild/build-profile.json5 @@ -6,7 +6,8 @@ { "name": "default", "signingConfig": "default", - "compatibleSdkVersion": "5.0.0(12)", + "compatibleSdkVersion": "5.0.5(17)", + "targetSdkVersion": "5.0.5(17)", "runtimeOS": "HarmonyOS", "buildOption": { "strictMode": { diff --git a/GlobalCustomComponentReuse/ComponentPrebuildByOnIdle/build-profile.json5 b/GlobalCustomComponentReuse/ComponentPrebuildByOnIdle/build-profile.json5 index 18c202044f87f155e959c89a4d85ef47200dc01c..30f6f517b1b1ee0a1469b576356c16df811c0c46 100644 --- a/GlobalCustomComponentReuse/ComponentPrebuildByOnIdle/build-profile.json5 +++ b/GlobalCustomComponentReuse/ComponentPrebuildByOnIdle/build-profile.json5 @@ -6,7 +6,8 @@ { "name": "default", "signingConfig": "default", - "compatibleSdkVersion": "5.0.0(12)", + "compatibleSdkVersion": "5.0.5(17)", + "targetSdkVersion": "5.0.5(17)", "runtimeOS": "HarmonyOS", } ], diff --git a/GridComponentLoadSlow/.gitignore b/GridComponentLoadSlow/.gitignore deleted file mode 100644 index d2ff20141ceed86d87c0ea5d99481973005bab2b..0000000000000000000000000000000000000000 --- a/GridComponentLoadSlow/.gitignore +++ /dev/null @@ -1,12 +0,0 @@ -/node_modules -/oh_modules -/local.properties -/.idea -**/build -/.hvigor -.cxx -/.clangd -/.clang-format -/.clang-tidy -**/.test -/.appanalyzer \ No newline at end of file diff --git a/GridComponentLoadSlow/README.md b/GridComponentLoadSlow/README.md new file mode 100644 index 0000000000000000000000000000000000000000..ae8249317b59ba4218e272508ac221199c809c3b --- /dev/null +++ b/GridComponentLoadSlow/README.md @@ -0,0 +1,45 @@ +# Grid组件加载丢帧优化同源示例代码 + +### 介绍 + +本示例代码为最佳实践《Grid组件加载丢帧优化》配套示例代码。 + +### 使用说明 + +安装应用进入首页,点击按钮滑动列表。 + +### 工程目录 + +``` +├──entry/src/main/ets +│ ├──entryability +│ │ └──EntryAbility.ets // 程序入口类 +│ ├──entrybackupability +│ │ └──EntryBackupAbility.ets // 数据备份恢复类 +│ └──pages +│ ├──Index.ets // 使用columnStart/columnEnd设置GridItem大小示例:反例 +│ └──RightIndex.ets // 使用GridLayoutOptions设置GridItem大小:正例 +└──entry/src/main/resources // 应用资源目录 +``` + +### 相关权限 + +不涉及 + +### 约束与限制 + +* 本示例仅支持标准系统上运行,支持设备:华为手机。 +* HarmonyOS系统:HarmonyOS 5.0.5 Release及以上。 +* DevEco Studio版本:DevEco Studio 5.0.5 Release及以上。 +* HarmonyOS SDK版本:HarmonyOS 5.0.5 Release SDK及以上。 + +### 下载 + +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set GridComponentLoadSlow +git checkout +``` \ No newline at end of file diff --git a/GridComponentLoadSlow/entry/.gitignore b/GridComponentLoadSlow/entry/.gitignore deleted file mode 100644 index e2713a2779c5a3e0eb879efe6115455592caeea5..0000000000000000000000000000000000000000 --- a/GridComponentLoadSlow/entry/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -/node_modules -/oh_modules -/.preview -/build -/.cxx -/.test \ No newline at end of file diff --git a/GridComponentLoadSlow/entry/src/main/ets/entryability/EntryAbility.ets b/GridComponentLoadSlow/entry/src/main/ets/entryability/EntryAbility.ets index 508880af8c33aa838016d1cd4b2c68be2f447540..c14abf3990a158f5280b0b17f6ea6ca4d4370a5c 100644 --- a/GridComponentLoadSlow/entry/src/main/ets/entryability/EntryAbility.ets +++ b/GridComponentLoadSlow/entry/src/main/ets/entryability/EntryAbility.ets @@ -1,4 +1,20 @@ +/* +* Copyright (C) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { BusinessError } from '@kit.BasicServicesKit'; import { hilog } from '@kit.PerformanceAnalysisKit'; import { window } from '@kit.ArkUI'; @@ -6,8 +22,13 @@ const DOMAIN = 0x0000; export default class EntryAbility extends UIAbility { onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { - this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); + try { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + } catch (err) { + let error = err as BusinessError; + hilog.info(DOMAIN, 'testTag', `setColorMode err, code: ${error.code}, mesage: ${error.message}`); + } } onDestroy(): void { diff --git a/GridComponentLoadSlow/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets b/GridComponentLoadSlow/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets index 8e4de99282050bad799ac892eb85ac5449364a51..dbca64c90dd87b1e9f5a339cb0178a5495f78af3 100644 --- a/GridComponentLoadSlow/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets +++ b/GridComponentLoadSlow/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets @@ -1,3 +1,18 @@ +/* +* Copyright (C) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + import { hilog } from '@kit.PerformanceAnalysisKit'; import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit'; diff --git a/GridComponentLoadSlow/entry/src/main/ets/pages/Index.ets b/GridComponentLoadSlow/entry/src/main/ets/pages/Index.ets index 94e129f4dfc9d3e140f9264f31bbc7130b908638..686559234dfdcf6f35b85c961fe7264fa721212c 100644 --- a/GridComponentLoadSlow/entry/src/main/ets/pages/Index.ets +++ b/GridComponentLoadSlow/entry/src/main/ets/pages/Index.ets @@ -1,3 +1,18 @@ +/* +* Copyright (C) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + // [Start grid_component_load_slow] // Import performance dot modules import { hiTraceMeter } from '@kit.PerformanceAnalysisKit'; diff --git a/GridComponentLoadSlow/entry/src/main/ets/pages/RightIndex.ets b/GridComponentLoadSlow/entry/src/main/ets/pages/RightIndex.ets index fb0779d2186eb6a844a0c06a1ab7d2cfdb5aeaf7..b84d7c324813c6de9a1c1841fac2504cf28356a4 100644 --- a/GridComponentLoadSlow/entry/src/main/ets/pages/RightIndex.ets +++ b/GridComponentLoadSlow/entry/src/main/ets/pages/RightIndex.ets @@ -1,3 +1,18 @@ +/* +* Copyright (C) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + // [Start right_index] // Import performance dot modules import { hiTraceMeter } from '@kit.PerformanceAnalysisKit'; @@ -64,7 +79,10 @@ export struct GridExample2 { build() { Column({ space: 5 }) { - Text('使用GridLayoutOptions设置GridItem大小').fontColor(0xCCCCCC).fontSize(9).width('90%') + Text('使用GridLayoutOptions设置GridItem大小') + .fontColor(0xCCCCCC) + .fontSize(9) + .width('90%') Grid(this.scroller, this.layoutOptions) { LazyForEach(this.datasource, (item: string, index: number) => { GridItem() { diff --git a/GridComponentLoadSlow/entry/src/main/resources/base/element/string.json b/GridComponentLoadSlow/entry/src/main/resources/base/element/string.json index f94595515a99e0c828807e243494f57f09251930..a7d1d9860ae92b4ebceaf16ce6bf1f265455c5a1 100644 --- a/GridComponentLoadSlow/entry/src/main/resources/base/element/string.json +++ b/GridComponentLoadSlow/entry/src/main/resources/base/element/string.json @@ -10,7 +10,7 @@ }, { "name": "EntryAbility_label", - "value": "label" + "value": "GridComponentLoadSlow" } ] } \ No newline at end of file diff --git a/GridComponentLoadSlow/entry/src/mock/mock-config.json5 b/GridComponentLoadSlow/entry/src/mock/mock-config.json5 deleted file mode 100644 index 7a73a41bfdf76d6f793007240d80983a52f15f97..0000000000000000000000000000000000000000 --- a/GridComponentLoadSlow/entry/src/mock/mock-config.json5 +++ /dev/null @@ -1,2 +0,0 @@ -{ -} \ No newline at end of file diff --git a/GridComponentLoadSlow/entry/src/ohosTest/ets/test/Ability.test.ets b/GridComponentLoadSlow/entry/src/ohosTest/ets/test/Ability.test.ets deleted file mode 100644 index 85c78f67579d6e31b5f5aeea463e216b9b141048..0000000000000000000000000000000000000000 --- a/GridComponentLoadSlow/entry/src/ohosTest/ets/test/Ability.test.ets +++ /dev/null @@ -1,35 +0,0 @@ -import { hilog } from '@kit.PerformanceAnalysisKit'; -import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; - -export default function abilityTest() { - describe('ActsAbilityTest', () => { - // Defines a test suite. Two parameters are supported: test suite name and test suite function. - beforeAll(() => { - // Presets an action, which is performed only once before all test cases of the test suite start. - // This API supports only one parameter: preset action function. - }) - beforeEach(() => { - // Presets an action, which is performed before each unit test case starts. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: preset action function. - }) - afterEach(() => { - // Presets a clear action, which is performed after each unit test case ends. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: clear action function. - }) - afterAll(() => { - // Presets a clear action, which is performed after all test cases of the test suite end. - // This API supports only one parameter: clear action function. - }) - it('assertContain', 0, () => { - // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. - hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); - let a = 'abc'; - let b = 'b'; - // Defines a variety of assertion methods, which are used to declare expected boolean conditions. - expect(a).assertContain(b); - expect(a).assertEqual(a); - }) - }) -} \ No newline at end of file diff --git a/GridComponentLoadSlow/entry/src/ohosTest/ets/test/List.test.ets b/GridComponentLoadSlow/entry/src/ohosTest/ets/test/List.test.ets deleted file mode 100644 index 794c7dc4ed66bd98fa3865e07922906e2fcef545..0000000000000000000000000000000000000000 --- a/GridComponentLoadSlow/entry/src/ohosTest/ets/test/List.test.ets +++ /dev/null @@ -1,5 +0,0 @@ -import abilityTest from './Ability.test'; - -export default function testsuite() { - abilityTest(); -} \ No newline at end of file diff --git a/GridComponentLoadSlow/entry/src/ohosTest/module.json5 b/GridComponentLoadSlow/entry/src/ohosTest/module.json5 deleted file mode 100644 index 509a3a28a3e6be8d7f98cc563fa8195657d77d1d..0000000000000000000000000000000000000000 --- a/GridComponentLoadSlow/entry/src/ohosTest/module.json5 +++ /dev/null @@ -1,11 +0,0 @@ -{ - "module": { - "name": "entry_test", - "type": "feature", - "deviceTypes": [ - "phone" - ], - "deliveryWithInstall": true, - "installationFree": false - } -} diff --git a/GridComponentLoadSlow/entry/src/test/List.test.ets b/GridComponentLoadSlow/entry/src/test/List.test.ets deleted file mode 100644 index bb5b5c3731e283dd507c847560ee59bde477bbc7..0000000000000000000000000000000000000000 --- a/GridComponentLoadSlow/entry/src/test/List.test.ets +++ /dev/null @@ -1,5 +0,0 @@ -import localUnitTest from './LocalUnit.test'; - -export default function testsuite() { - localUnitTest(); -} \ No newline at end of file diff --git a/GridComponentLoadSlow/entry/src/test/LocalUnit.test.ets b/GridComponentLoadSlow/entry/src/test/LocalUnit.test.ets deleted file mode 100644 index 165fc1615ee8618b4cb6a622f144a9a707eee99f..0000000000000000000000000000000000000000 --- a/GridComponentLoadSlow/entry/src/test/LocalUnit.test.ets +++ /dev/null @@ -1,33 +0,0 @@ -import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; - -export default function localUnitTest() { - describe('localUnitTest', () => { - // Defines a test suite. Two parameters are supported: test suite name and test suite function. - beforeAll(() => { - // Presets an action, which is performed only once before all test cases of the test suite start. - // This API supports only one parameter: preset action function. - }); - beforeEach(() => { - // Presets an action, which is performed before each unit test case starts. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: preset action function. - }); - afterEach(() => { - // Presets a clear action, which is performed after each unit test case ends. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: clear action function. - }); - afterAll(() => { - // Presets a clear action, which is performed after all test cases of the test suite end. - // This API supports only one parameter: clear action function. - }); - it('assertContain', 0, () => { - // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. - let a = 'abc'; - let b = 'b'; - // Defines a variety of assertion methods, which are used to declare expected boolean conditions. - expect(a).assertContain(b); - expect(a).assertEqual(a); - }); - }); -} \ No newline at end of file diff --git a/GridComponentLoadSlow/oh-package-lock.json5 b/GridComponentLoadSlow/oh-package-lock.json5 deleted file mode 100644 index 7fcf818273347b97063c0c0a151bb14770ca1c79..0000000000000000000000000000000000000000 --- a/GridComponentLoadSlow/oh-package-lock.json5 +++ /dev/null @@ -1,27 +0,0 @@ -{ - "meta": { - "stableOrder": true - }, - "lockfileVersion": 3, - "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", - "specifiers": { - "@ohos/hamock@1.0.0": "@ohos/hamock@1.0.0", - "@ohos/hypium@1.0.21": "@ohos/hypium@1.0.21" - }, - "packages": { - "@ohos/hamock@1.0.0": { - "name": "@ohos/hamock", - "version": "1.0.0", - "integrity": "sha512-K6lDPYc6VkKe6ZBNQa9aoG+ZZMiwqfcR/7yAVFSUGIuOAhPvCJAo9+t1fZnpe0dBRBPxj2bxPPbKh69VuyAtDg==", - "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hamock/-/hamock-1.0.0.har", - "registryType": "ohpm" - }, - "@ohos/hypium@1.0.21": { - "name": "@ohos/hypium", - "version": "1.0.21", - "integrity": "sha512-iyKGMXxE+9PpCkqEwu0VykN/7hNpb+QOeIuHwkmZnxOpI+dFZt6yhPB7k89EgV1MiSK/ieV/hMjr5Z2mWwRfMQ==", - "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hypium/-/hypium-1.0.21.har", - "registryType": "ohpm" - } - } -} \ No newline at end of file diff --git a/HDRVivid/AVCodecVideo/README.en.md b/HDRVivid/AVCodecVideo/README.en.md index dd1b0cdbcda82d7595fc83e484ada93492781a74..7c757c10b784981dd640094e7e00282677a909e4 100644 --- a/HDRVivid/AVCodecVideo/README.en.md +++ b/HDRVivid/AVCodecVideo/README.en.md @@ -194,8 +194,19 @@ N/A 1. The sample app is supported only on Huawei phones running the standard system. -2. The HarmonyOS version must be HarmonyOS NEXT Beta1 or later. +2. The HarmonyOS version must be HarmonyOS 5.1.0 Release or later. -3. The DevEco Studio version must be DevEco Studio NEXT Beta1 or later. +3. The DevEco Studio version must be DevEco Studio 5.1.0 Release or later. -4. The HarmonyOS SDK version must be HarmonyOS NEXT Beta1 or later. +4. The HarmonyOS SDK version must be HarmonyOS 5.1.0 Release or later. + +### Download + +To download this project separately, execute the following command: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set HDRVivid/AVCodecVideo +git checkout +``` diff --git a/HDRVivid/AVCodecVideo/README.md b/HDRVivid/AVCodecVideo/README.md index a135efc31035ceceb69438754445fdafaf0b07cb..47754b7d253291d1af55acc707e8ae27037f0a99 100644 --- a/HDRVivid/AVCodecVideo/README.md +++ b/HDRVivid/AVCodecVideo/README.md @@ -155,10 +155,21 @@ ### 约束与限制 -1. 本示例仅支持标准系统上运行,支持设备:华为手机; +* 本示例仅支持标准系统上运行,支持设备:华为手机。 -2. HarmonyOS系统:HarmonyOS NEXT Beta1及以上; +* HarmonyOS系统:HarmonyOS 5.1.0 Release及以上。 -3. DevEco Studio版本:DevEco Studio NEXT Beta1及以上; +* DevEco Studio版本:DevEco Studio 5.1.0 Release及以上。 -4. HarmonyOS SDK版本:HarmonyOS NEXT Bata1 SDK及以上。 \ No newline at end of file +* HarmonyOS SDK版本:HarmonyOS 5.1.0 Release SDK及以上。 + +### 下载 + +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set HDRVivid/AVCodecVideo +git checkout +``` \ No newline at end of file diff --git a/HDRVivid/AVCodecVideo/build-profile.json5 b/HDRVivid/AVCodecVideo/build-profile.json5 index 01ef137f920b7763b51f7b10e0b7c752792fed62..8998f840b2855f255b02579bf5e30cba89177121 100644 --- a/HDRVivid/AVCodecVideo/build-profile.json5 +++ b/HDRVivid/AVCodecVideo/build-profile.json5 @@ -20,7 +20,8 @@ { "name": "default", "signingConfig": "default", - "compatibleSdkVersion": "5.0.0(12)", + "compatibleSdkVersion": "5.1.0(18)", + "targetSdkVersion": "5.1.0(18)", "runtimeOS": "HarmonyOS", } ] diff --git a/HDRVivid/AVCodecVideo/entry/src/main/ets/entryability/EntryAbility.ets b/HDRVivid/AVCodecVideo/entry/src/main/ets/entryability/EntryAbility.ets index b8d65e751d0c16c280efad65fc9a56ddc604a11d..760d140ba672a0a92b84f9a4dae159edc3d22407 100644 --- a/HDRVivid/AVCodecVideo/entry/src/main/ets/entryability/EntryAbility.ets +++ b/HDRVivid/AVCodecVideo/entry/src/main/ets/entryability/EntryAbility.ets @@ -43,15 +43,30 @@ export default class EntryAbility extends UIAbility { } catch (err) { Logger.error('Entry', 'requestPre() data: ' + JSON.stringify(err)); } - - windowStage.getMainWindowSync().setWindowKeepScreenOn(true); + try { + windowStage.getMainWindowSync().setWindowKeepScreenOn(true) + .then(() => { + hilog.info(0x000, 'testTag', 'setWindowKeepScreenOn success'); + }) + .catch((error: BusinessError) => { + hilog.error(0x000, 'testTag', `setWindowKeepScreenOn failed. code ${error.code}, message ${error.message}`); + }) + } catch (error) { + let err = error as BusinessError; + hilog.error(0x000, 'testTag', `getMainWindowSync failed. code=${err.code}, message=${err.message}`); + } windowStage.loadContent('pages/Index', (err) => { if (err.code) { hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); return; } - let uiContext: UIContext | undefined = windowStage.getMainWindowSync().getUIContext(); - AppStorage.setOrCreate('uiContext', uiContext); + try { + let uiContext: UIContext | undefined = windowStage.getMainWindowSync().getUIContext(); + AppStorage.setOrCreate('uiContext', uiContext); + } catch (error) { + let err = error as BusinessError; + hilog.error(0x000, 'testTag', `getMainWindowSync failed. code=${err.code}, message=${err.message}`); + } hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.'); }); } diff --git a/HDRVivid/AVCodecVideo/entry/src/main/ets/pages/Index.ets b/HDRVivid/AVCodecVideo/entry/src/main/ets/pages/Index.ets index 51d225006469ad9ff2dc6d22a48f52483e1f52b8..cf75f11f63c1927a24853fed0b385a8b9a89e59d 100644 --- a/HDRVivid/AVCodecVideo/entry/src/main/ets/pages/Index.ets +++ b/HDRVivid/AVCodecVideo/entry/src/main/ets/pages/Index.ets @@ -24,6 +24,7 @@ import DateTimeUtil from '../common/utils/DateTimeUtils'; import { CommonConstants as Const } from '../common/CommonConstants'; import { CameraDataModel } from '../model/CameraDateModel'; import { videoProfileCheck } from '../common/utils/CameraCheck'; +import { BusinessError } from '@kit.BasicServicesKit'; const TAG: string = Const.INDEX_TAG; const DATETIME: DateTimeUtil = new DateTimeUtil(); @@ -35,8 +36,18 @@ struct Player { @State isShow: boolean = false; private cameraData: CameraDataModel = new CameraDataModel(); private selectFilePath: string | null = null; - private display = display.getDefaultDisplaySync(); - private heightPx = (this.display.width * Const.DEFAULT_HEIGHT / Const.DEFAULT_WIDTH) + Const.PX; + private display: display.Display | null = null; + private heightPx = ''; + + aboutToAppear() { + try { + this.display = display.getDefaultDisplaySync(); + this.heightPx = (this.display.width * Const.DEFAULT_HEIGHT / Const.DEFAULT_WIDTH) + Const.PX; + } catch (error) { + let err = error as BusinessError; + Logger.error(`getDefaultDisplaySync failed. code=${err.code}, message=${err.message}`); + } + } selectFile() { let photoPicker = new photoAccessHelper.PhotoViewPicker(); @@ -51,50 +62,73 @@ struct Player { message: $r('app.string.alert'), duration: Const.DURATION, bottom: Const.BOTTOM - }); + }) + .catch((err: BusinessError) => { + Logger.error(`promptAction openToast failed. code=${err.code}, message=${err.message}`); + }) } else { this.play(); Logger.info(TAG, 'documentViewPicker.select to file succeed and URI is:' + this.selectFilePath); } - }); + }) + .catch((err: BusinessError) => { + Logger.error(`photoPicker select failed. code=${err.code}, message=${err.message}`); + }) } play() { - let inputFile = fileIo.openSync(this.selectFilePath, fileIo.OpenMode.READ_ONLY); - if (!inputFile) { - Logger.error(TAG, 'player inputFile is null'); - } - let inputFileState = fileIo.statSync(inputFile.fd); - if (inputFileState.size <= 0) { - Logger.error(TAG, 'player inputFile size is 0'); + try { + let inputFile = fileIo.openSync(this.selectFilePath, fileIo.OpenMode.READ_ONLY); + if (!inputFile) { + Logger.error(TAG, 'player inputFile is null'); + } + let inputFileState = fileIo.statSync(inputFile.fd); + if (inputFileState.size <= 0) { + Logger.error(TAG, 'player inputFile size is 0'); + } + this.buttonEnabled = false; + player.playNative(inputFile.fd, Const.DEFAULT_VALUE, inputFileState.size, () => { + Logger.info(TAG, 'player JSCallback'); + this.buttonEnabled = true; + fileIo.close(inputFile) + .catch((err: BusinessError) => { + Logger.error(`fileIo close failed. code=${err.code}, message=${err.message}`); + }) + }) + } catch (err) { + let error = err as BusinessError; + Logger.error(`fileIo failed. code=${error.code}, message=${error.message}`); } - this.buttonEnabled = false; - player.playNative(inputFile.fd, Const.DEFAULT_VALUE, inputFileState.size, () => { - Logger.info(TAG, 'player JSCallback'); - this.buttonEnabled = true; - fileIo.close(inputFile); - }) } async checkIsProfileSupport(): Promise { let context = this.getUIContext()?.getHostContext(); - let cameraManager: camera.CameraManager = camera.getCameraManager(context); - if (!cameraManager) { - Logger.error(TAG, 'camera.getCameraManager error!'); - } + let cameraManager: camera.CameraManager; + try { + cameraManager = camera.getCameraManager(context) + if (!cameraManager) { + Logger.error(TAG, 'camera.getCameraManager error!'); + } - let videoProfile: undefined | camera.VideoProfile = videoProfileCheck(cameraManager, this.cameraData); - if (!videoProfile) { - Logger.error(TAG, 'videoProfile is not found'); - promptAction.openToast({ - message: $r('app.string.alert_setting'), - duration: Const.DURATION, - bottom: Const.BOTTOM, - backgroundColor: Color.White, - backgroundBlurStyle: BlurStyle.NONE - }) - this.cameraData = new CameraDataModel(); - return; + let videoProfile: undefined | camera.VideoProfile = videoProfileCheck(cameraManager, this.cameraData); + if (!videoProfile) { + Logger.error(TAG, 'videoProfile is not found'); + promptAction.openToast({ + message: $r('app.string.alert_setting'), + duration: Const.DURATION, + bottom: Const.BOTTOM, + backgroundColor: Color.White, + backgroundBlurStyle: BlurStyle.NONE + }) + .catch((err: BusinessError) => { + Logger.error(`promptAction openToast failed. code=${err.code}, message=${err.message}`); + }) + this.cameraData = new CameraDataModel(); + return; + } + } catch (err) { + let error = err as BusinessError; + Logger.error(`getCameraManager failed. code=${error.code}, message=${error.message}`); } } @@ -197,27 +231,39 @@ struct Player { .onClick(async () => { let context = this.getUIContext()?.getHostContext(); let helper = photoAccessHelper.getPhotoAccessHelper(context); - let uri = await helper.createAsset(photoAccessHelper.PhotoType.VIDEO, 'mp4', { - title: `AVCodecVideo_${DATETIME.getDate()}_${DATETIME.getTime()}` - }); - let file = await fileIo.open(uri, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE); - this.cameraData.outputfd = file.fd; - if (this.cameraData.outputfd !== null) { - recorder.initNative(this.cameraData.outputfd, this.cameraData.videoCodecMime, this.cameraData.cameraWidth, - this.cameraData.cameraHeight, this.cameraData.frameRate, this.cameraData.isHDRVivid, - this.cameraData.bitRate).then((data) => { - if (data.surfaceId !== null) { - this.cameraData.surfaceId = data.surfaceId; - let uiContext = this.getUIContext(); - let router = uiContext.getRouter(); - router.pushUrl({ - url: 'pages/Recorder', - params: this.cameraData - }); - } - }) - } else { - Logger.error(TAG, 'get outputfd failed!'); + try { + let uri = await helper.createAsset(photoAccessHelper.PhotoType.VIDEO, 'mp4', { + title: `AVCodecVideo_${DATETIME.getDate()}_${DATETIME.getTime()}` + }); + let file = await fileIo.open(uri, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE); + this.cameraData.outputfd = file.fd; + if (this.cameraData.outputfd !== null) { + recorder.initNative(this.cameraData.outputfd, this.cameraData.videoCodecMime, + this.cameraData.cameraWidth, + this.cameraData.cameraHeight, this.cameraData.frameRate, this.cameraData.isHDRVivid, + this.cameraData.bitRate).then((data) => { + if (data.surfaceId !== null) { + this.cameraData.surfaceId = data.surfaceId; + let uiContext = this.getUIContext(); + let router = uiContext.getRouter(); + router.pushUrl({ + url: 'pages/Recorder', + params: this.cameraData + }) + .then(() => { + Logger.info(`router pushUrl success`); + }) + .catch((error: BusinessError) => { + Logger.error(`router pushUrl failed. code=${error.code}, message=${error.message}`); + }) + } + }) + } else { + Logger.error(TAG, 'get outputfd failed!'); + } + } catch (err) { + let error = err as BusinessError; + Logger.error(`fileIo open failed. code=${error.code}, message=${error.message}`); } }) .width('48%') @@ -230,7 +276,7 @@ struct Player { .height('52vp') } .justifyContent(FlexAlign.End) - .padding({left: '16vp', right: '16vp'}) + .padding({ left: '16vp', right: '16vp' }) .width('100%') .height('100%') } @@ -301,7 +347,7 @@ struct Player { 'bottom': { 'anchor': '__container__', 'align': VerticalAlign.Bottom }, 'left': { 'anchor': '__container__', 'align': HorizontalAlign.Start } }) - .padding({left: '16vp', right: '16vp', bottom:'16vp'}) + .padding({ left: '16vp', right: '16vp', bottom: '16vp' }) .width($r('app.string.full_width')) .height($r('app.float.index_column_height')) .justifyContent(FlexAlign.End) diff --git a/HDRVivid/AVCodecVideo/entry/src/main/ets/pages/Recorder.ets b/HDRVivid/AVCodecVideo/entry/src/main/ets/pages/Recorder.ets index 7aabb90c2fe8869c7a5f21a5c1f23e704eb82bca..362b906b26a6c067a03e0052e27cd01fc59d7ee4 100644 --- a/HDRVivid/AVCodecVideo/entry/src/main/ets/pages/Recorder.ets +++ b/HDRVivid/AVCodecVideo/entry/src/main/ets/pages/Recorder.ets @@ -47,18 +47,53 @@ async function releaseCamera(): Promise { }); } // Stop the Session. - videoSession.stop(); + videoSession.stop() + .then(() => { + Logger.info(TAG, `videoSession stop success`); + }) + .catch((error: BusinessError) => { + Logger.error(TAG, `videoSession stop. code=${error.code}, message=${error.message}`); + }) // Close file fd. - fileIo.close(params.outputfd); + fileIo.close(params.outputfd) + .then(() => { + Logger.info(TAG, `fileIo close success`); + }) + .catch((error: BusinessError) => { + Logger.error(TAG, `fileIo close. code=${error.code}, message=${error.message}`); + }) // Close camera input stream. - cameraInput.close(); + cameraInput.close() + .then(() => { + Logger.info(TAG, `cameraInput close success`); + }) + .catch((error: BusinessError) => { + Logger.error(TAG, `cameraInput close. code=${error.code}, message=${error.message}`); + }) // Release preview output stream. - XComponentPreviewOutput.release(); + XComponentPreviewOutput.release() + .then(() => { + Logger.info(TAG, `XComponentPreviewOutput release success`); + }) + .catch((error: BusinessError) => { + Logger.error(TAG, `XComponentPreviewOutput release. code=${error.code}, message=${error.message}`); + }) // Release the video output stream. - encoderVideoOutput.release(); - Logger.info(TAG, 'encoderVideoOutput release'); + encoderVideoOutput.release() + .then(() => { + Logger.info(TAG, 'encoderVideoOutput release success'); + }) + .catch((error: BusinessError) => { + Logger.error(TAG, `encoderVideoOutput release. code=${error.code}, message=${error.message}`); + }) // Release session. - videoSession.release(); + videoSession.release() + .then(() => { + Logger.info(TAG, 'videoSession release'); + }) + .catch((error: BusinessError) => { + Logger.error(TAG, `videoSession release. code=${error.code}, message=${error.message}`); + }) } // [Start set_video_color] @@ -79,11 +114,16 @@ function setVideoStabilizationMode(session: camera.VideoSession): boolean { // Check whether video anti-shake is supported let isSupported: boolean = isVideoStabilizationModeSupported(session, mode); if (isSupported) { - console.info(`setVideoStabilizationMode: ${mode}`); - // Setting video anti-shake - session.setVideoStabilizationMode(mode); - let activeVideoStabilizationMode = session.getActiveVideoStabilizationMode(); - console.info(`activeVideoStabilizationMode: ${activeVideoStabilizationMode}`); + Logger.info(TAG, `setVideoStabilizationMode: ${mode}`); + try { + // Setting video anti-shake + session.setVideoStabilizationMode(mode); + let activeVideoStabilizationMode = session.getActiveVideoStabilizationMode(); + Logger.info(TAG, `activeVideoStabilizationMode: ${activeVideoStabilizationMode}`); + } catch (err) { + let error = err as BusinessError; + Logger.error(`fileIo open failed. code=${error.code}, message=${error.message}`); + } } else { console.info(`videoStabilizationMode: ${mode} is not support`); } @@ -103,18 +143,25 @@ function getSupportedColorSpaces(session: camera.VideoSession): Array = getSupportedColorSpaces(session); let isSupportedColorSpaces = colorSpaces.indexOf(colorSpace) >= 0; if (isSupportedColorSpaces) { console.info(`setColorSpace: ${colorSpace}`); - session.setColorSpace(colorSpace); - let activeColorSpace:colorSpaceManager.ColorSpace = session.getActiveColorSpace(); - console.info(`activeColorSpace: ${activeColorSpace}`); + try { + session.setColorSpace(colorSpace); + let activeColorSpace: colorSpaceManager.ColorSpace = session.getActiveColorSpace(); + console.info(`activeColorSpace: ${activeColorSpace}`); + } catch (err) { + let error = err as BusinessError; + Logger.error(`fileIo open failed. code=${error.code}, message=${error.message}`); + } } else { console.info(`colorSpace: ${colorSpace} is not support`); } } + // [End set_video_color] @Entry @@ -129,15 +176,26 @@ struct Recorder { private cameraWidth: number = Const.DEFAULT_WIDTH; private cameraHeight: number = Const.DEFAULT_HEIGHT; private XComponentController: XComponentController = new XComponentController(); - private display = display.getDefaultDisplaySync(); - private heightPx = (this.display.width * this.cameraWidth / this.cameraHeight) + Const.PX; - private widthPx = this.display.width + Const.PX; + private display: display.Display | null = null; + private heightPx: string = ''; + private widthPx: string = ''; private timer: number = Const.DEFAULT_VALUE; private seconds: number = Const.DEFAULT_VALUE; private isReleased: boolean = false; private isBack: boolean = false; private range: number[] = []; + aboutToAppear(): void { + try { + this.display = display.getDefaultDisplaySync(); + this.heightPx = (this.display.width * this.cameraWidth / this.cameraHeight) + Const.PX; + this.widthPx = this.display.width + Const.PX; + } catch (err) { + let error = err as BusinessError; + Logger.error(`getDefaultDisplaySync failed. code=${error.code}, message=${error.message}`); + } + } + onBackPress() { this.isBack = true; } @@ -178,158 +236,164 @@ struct Recorder { releaseCamera(); // Create the CameraManager object. let context = this.getUIContext()?.getHostContext(); - let cameraManager = camera.getCameraManager(context); - if (!cameraManager) { - Logger.error(TAG, 'camera.getCameraManager error'); - return; - } + try { - // Get supported camera devices. - let cameraDevices: Array = cameraManager.getSupportedCameras(); - if (cameraDevices !== undefined && cameraDevices.length <= 0) { - Logger.error(TAG, 'cameraManager.getSupportedCameras error!'); - return; - } - // Gets supported mode types - let sceneModes: Array = cameraManager.getSupportedSceneModes(cameraDevices[0]); - let isSupportVideoMode: boolean = sceneModes.indexOf(camera.SceneMode.NORMAL_VIDEO) >= 0; - if (!isSupportVideoMode) { - Logger.error('video mode not support'); - return; - } + let cameraManager = camera.getCameraManager(context); + if (!cameraManager) { + Logger.error(TAG, 'camera.getCameraManager error'); + return; + } - // [Start create_video_output3] - let videoProfile: undefined | camera.VideoProfile = videoProfileCheck(cameraManager, params); - if (!videoProfile) { - Logger.error(TAG, 'videoProfile is not found!'); - return; - } + // Get supported camera devices. + let cameraDevices: Array = cameraManager.getSupportedCameras(); + if (cameraDevices !== undefined && cameraDevices.length <= 0) { + Logger.error(TAG, 'cameraManager.getSupportedCameras error!'); + return; + } - // [StartExclude create_video_output3] - //The preview stream of XComponent. - // [Start camera_conversation] - let XComponentPreviewProfile: camera.Profile | undefined = previewProfileCameraCheck(cameraManager, params) - if (XComponentPreviewProfile === undefined) { - Logger.error(TAG, 'XComponentPreviewProfile is not found'); - return; - } - // [StartExclude camera_conversation] - // [EndExclude create_video_output3] - - // Create a video output instance - encoderVideoOutput = cameraManager.createVideoOutput(videoProfile, params.surfaceId); - if (encoderVideoOutput === undefined) { - Logger.error(TAG, 'encoderVideoOutput is undefined'); - return; - } - Logger.info(TAG, 'encoderVideoOutput success'); - // [End create_video_output3] - - // Create a preview stream output object - XComponentPreviewOutput = cameraManager.createPreviewOutput(XComponentPreviewProfile, this.XComponentSurfaceId); - if (XComponentPreviewOutput === undefined) { - Logger.error(TAG, 'XComponentPreviewOutput is undefined'); - return; - } + // Gets supported mode types + let sceneModes: Array = cameraManager.getSupportedSceneModes(cameraDevices[0]); + let isSupportVideoMode: boolean = sceneModes.indexOf(camera.SceneMode.NORMAL_VIDEO) >= 0; + if (!isSupportVideoMode) { + Logger.error('video mode not support'); + return; + } - // Create the cameraInput object. - try { - cameraInput = cameraManager.createCameraInput(cameraDevices[0]); - } catch (error) { - let err = error as BusinessError; - Logger.error(TAG, `Failed to createCameraInput. error: ${JSON.stringify(err)}`); - } - if (cameraInput === undefined) { - Logger.error(TAG, 'cameraInput is undefined'); - return; - } + // [Start create_video_output3] + let videoProfile: undefined | camera.VideoProfile = videoProfileCheck(cameraManager, params); + if (!videoProfile) { + Logger.error(TAG, 'videoProfile is not found!'); + return; + } - // Turn on the camera. - try { - await cameraInput.open(); - } catch (error) { - let err = error as BusinessError; - Logger.error(TAG, `Failed to open cameraInput. error: ${JSON.stringify(err)}`); - } - // [EndExclude camera_conversation] + // [StartExclude create_video_output3] + //The preview stream of XComponent. + // [Start camera_conversation] + let XComponentPreviewProfile: camera.Profile | undefined = previewProfileCameraCheck(cameraManager, params) + if (XComponentPreviewProfile === undefined) { + Logger.error(TAG, 'XComponentPreviewProfile is not found'); + return; + } + // [StartExclude camera_conversation] + // [EndExclude create_video_output3] - // Create a session flow - try { - videoSession = cameraManager.createSession(camera.SceneMode.NORMAL_VIDEO) as camera.VideoSession; - } catch (error) { - let err = error as BusinessError; - Logger.error(TAG, `Failed to create the session instance. error: ${JSON.stringify(err)}`); - } - // [StartExclude camera_conversation] - if (videoSession === undefined) { - Logger.error(TAG, 'videoSession is undefined'); - return; - } - // [EndExclude camera_conversation] + // Create a video output instance + encoderVideoOutput = cameraManager.createVideoOutput(videoProfile, params.surfaceId); + if (encoderVideoOutput === undefined) { + Logger.error(TAG, 'encoderVideoOutput is undefined'); + return; + } + Logger.info(TAG, 'encoderVideoOutput success'); + // [End create_video_output3] - // Start a configuration session - try { - videoSession.beginConfig(); - } catch (error) { - // [StartExclude camera_conversation] - let err = error as BusinessError; - Logger.error(TAG, `Failed to beginConfig. error: ${JSON.stringify(err)}`); - // [EndExclude camera_conversation] - } - // [StartExclude camera_conversation] - try { - videoSession.addInput(cameraInput); - } catch (error) { - // DocsDot - let err = error as BusinessError; - Logger.error(TAG, `Failed to add cameraInput. error: ${JSON.stringify(err)}`); - // DocsDot - } - // [EndExclude camera_conversation] - // Add an XComponent preview stream to a session - try { - videoSession.addOutput(XComponentPreviewOutput); - } catch (error) { - // [StartExclude camera_conversation] - let err = error as BusinessError; - Logger.error(TAG, `Failed to add XcomponentPreviewOutput. error: ${JSON.stringify(err)}`); + // Create a preview stream output object + XComponentPreviewOutput = cameraManager.createPreviewOutput(XComponentPreviewProfile, this.XComponentSurfaceId); + if (XComponentPreviewOutput === undefined) { + Logger.error(TAG, 'XComponentPreviewOutput is undefined'); + return; + } + + // Create the cameraInput object. + try { + cameraInput = cameraManager.createCameraInput(cameraDevices[0]); + } catch (error) { + let err = error as BusinessError; + Logger.error(TAG, `Failed to createCameraInput. error: ${JSON.stringify(err)}`); + } + if (cameraInput === undefined) { + Logger.error(TAG, 'cameraInput is undefined'); + return; + } + + // Turn on the camera. + try { + await cameraInput.open(); + } catch (error) { + let err = error as BusinessError; + Logger.error(TAG, `Failed to open cameraInput. error: ${JSON.stringify(err)}`); + } // [EndExclude camera_conversation] - } - try { - videoSession.addOutput(encoderVideoOutput); - } catch (error) { + // Create a session flow + try { + videoSession = cameraManager.createSession(camera.SceneMode.NORMAL_VIDEO) as camera.VideoSession; + } catch (error) { + let err = error as BusinessError; + Logger.error(TAG, `Failed to create the session instance. error: ${JSON.stringify(err)}`); + } // [StartExclude camera_conversation] - let err = error as BusinessError; - Logger.error(TAG, `Failed to add encoderVideoOutput. error: ${JSON.stringify(err)}`); + if (videoSession === undefined) { + Logger.error(TAG, 'videoSession is undefined'); + return; + } // [EndExclude camera_conversation] - } - try { - await videoSession.commitConfig(); - } catch (error) { + // Start a configuration session + try { + videoSession.beginConfig(); + } catch (error) { + // [StartExclude camera_conversation] + let err = error as BusinessError; + Logger.error(TAG, `Failed to beginConfig. error: ${JSON.stringify(err)}`); + // [EndExclude camera_conversation] + } // [StartExclude camera_conversation] - let err = error as BusinessError; - Logger.error(TAG, `videoSession commitConfig error: ${JSON.stringify(err)}`); + try { + videoSession.addInput(cameraInput); + } catch (error) { + // DocsDot + let err = error as BusinessError; + Logger.error(TAG, `Failed to add cameraInput. error: ${JSON.stringify(err)}`); + // DocsDot + } // [EndExclude camera_conversation] - } + // Add an XComponent preview stream to a session + try { + videoSession.addOutput(XComponentPreviewOutput); + } catch (error) { + // [StartExclude camera_conversation] + let err = error as BusinessError; + Logger.error(TAG, `Failed to add XcomponentPreviewOutput. error: ${JSON.stringify(err)}`); + // [EndExclude camera_conversation] + } - // Setting video anti-shake - if (setVideoStabilizationMode(videoSession)) { - // Set the color space - setColorSpaceBeforeCommitConfig(videoSession, true); - } + try { + videoSession.addOutput(encoderVideoOutput); + } catch (error) { + // [StartExclude camera_conversation] + let err = error as BusinessError; + Logger.error(TAG, `Failed to add encoderVideoOutput. error: ${JSON.stringify(err)}`); + // [EndExclude camera_conversation] + } - try { - await videoSession.start(); - } catch (error) { - // [StartExclude camera_conversation] - let err = error as BusinessError; - Logger.error(TAG, `videoSession start error: ${JSON.stringify(err)}`); - // [EndExclude camera_conversation] - } + try { + await videoSession.commitConfig(); + } catch (error) { + // [StartExclude camera_conversation] + let err = error as BusinessError; + Logger.error(TAG, `videoSession commitConfig error: ${JSON.stringify(err)}`); + // [EndExclude camera_conversation] + } + + // Setting video anti-shake + if (setVideoStabilizationMode(videoSession)) { + // Set the color space + setColorSpaceBeforeCommitConfig(videoSession, true); + } + try { + await videoSession.start(); + } catch (error) { + // [StartExclude camera_conversation] + let err = error as BusinessError; + Logger.error(TAG, `videoSession start error: ${JSON.stringify(err)}`); + // [EndExclude camera_conversation] + } + } catch (err) { + let error = err as BusinessError; + Logger.error(`error.code=${error.code}, error.message=${error.message}`); + } // Start the video output stream encoderVideoOutput.start((err: BusinessError) => { // [StartExclude camera_conversation] @@ -371,12 +435,22 @@ struct Recorder { if (currentFov < this.range[0]) { currentFov = this.range[0]; } - videoSession.setZoomRatio(currentFov); + try { + videoSession.setZoomRatio(currentFov); + } catch (err) { + let error = err as BusinessError; + Logger.error(`setZoomRatio failed. code=${error.code}, message=${error.message}`); + } } }) .onActionEnd((event: GestureEvent) => { if (videoSession) { - this.fov = videoSession.getZoomRatio(); + try { + this.fov = videoSession.getZoomRatio(); + } catch (err) { + let error = err as BusinessError; + Logger.error(`getZoomRatio failed. code=${error.code}, message=${error.message}`); + } } }) ) diff --git a/HDRVivid/AVCodecVideo/entry/src/main/module.json5 b/HDRVivid/AVCodecVideo/entry/src/main/module.json5 index 8bd98e4a1f52a0fd9ff1566cbb38779a2112cb45..c3621aa9e628f140a7a4446d64c9cfa5141dd7af 100644 --- a/HDRVivid/AVCodecVideo/entry/src/main/module.json5 +++ b/HDRVivid/AVCodecVideo/entry/src/main/module.json5 @@ -54,6 +54,13 @@ "abilities": ["EntryAbility"], "when": "always" } + }, + { + "name": "ohos.permission.WRITE_IMAGEVIDEO", + "reason": "$string:EntryAbility_desc", + "usedScene": { + "when": "always" + } } ] } diff --git a/HDRVivid/AVPlayer/MediaService/src/main/ets/controller/AvPlayerController.ets b/HDRVivid/AVPlayer/MediaService/src/main/ets/controller/AvPlayerController.ets index ddbdb2885f89e9440d79a56ccdd308aed657afec..7c84876d6e22f67e4d2abb165e85f8694b256d02 100644 --- a/HDRVivid/AVPlayer/MediaService/src/main/ets/controller/AvPlayerController.ets +++ b/HDRVivid/AVPlayer/MediaService/src/main/ets/controller/AvPlayerController.ets @@ -18,7 +18,6 @@ import { media } from '@kit.MediaKit'; import { audio } from '@kit.AudioKit'; import { avSession } from '@kit.AVSessionKit'; import { BusinessError } from '@kit.BasicServicesKit'; -import { BackgroundTaskManager } from '../utils/BackgroundTaskManager'; import { AVPlayerState, CommonConstants } from '../common/CommonConstants'; import { secondToTime } from '../utils/CommUtils' import { VideoData } from '../model/VideoData'; @@ -58,11 +57,15 @@ export class AvPlayerController { this.avPlayer = player; // this.curSource.video is the local video path, and this.curSource.url is the network video path if (this.curSource.video) { - let fileDescriptor = this.context?.resourceManager.getRawFdSync(this.curSource.video); - if (fileDescriptor) { - let avFileDescriptor: media.AVFileDescriptor = - { fd: fileDescriptor.fd, offset: fileDescriptor.offset, length: fileDescriptor.length }; - this.avPlayer.fdSrc = avFileDescriptor; + try { + let fileDescriptor = this.context?.resourceManager.getRawFdSync(this.curSource.video); + if (fileDescriptor) { + let avFileDescriptor: media.AVFileDescriptor = + { fd: fileDescriptor.fd, offset: fileDescriptor.offset, length: fileDescriptor.length }; + this.avPlayer.fdSrc = avFileDescriptor; + } + } catch (error) { + Logger.error(`getRawFdSync failed, code is ${error.code}, message is ${error.message}`); } } else { this.avPlayer.url = this.curSource.url; @@ -108,7 +111,10 @@ export class AvPlayerController { avPlayer.on('error', (err: BusinessError) => { Logger.error(TAG, `Invoke avPlayer failed, code is ${err.code}, message is ${err.message}` + `----state:${avPlayer.state} this.curIndex:${this.curIndex}`); - avPlayer.reset(); // resets the resources and triggers the idle state + avPlayer.reset() // resets the resources and triggers the idle state + .catch((err: BusinessError) => { + Logger.error(TAG, `avPlayer reset failed, code is ${err.code}, message is ${err.message}`); + }) }) this.setInterruptCallback() this.setStateChangeCallback(avPlayer); @@ -119,13 +125,17 @@ export class AvPlayerController { if (!this.avSessionController) { return; } - this.avSessionController.getAvSession()?.on('play', () => this.sessionPlayCallback()); - this.avSessionController.getAvSession()?.on('pause', () => this.sessionPauseCallback()); - this.avSessionController.getAvSession()?.on('stop', () => this.sessionStopCallback()); - this.avSessionController.getAvSession()?.on('fastForward', - (time?: number) => this.sessionFastForwardCallback(time)); - this.avSessionController.getAvSession()?.on('rewind', (time?: number) => this.sessionRewindCallback(time)); - this.avSessionController.getAvSession()?.on('seek', (seekTime: number) => this.sessionSeekCallback(seekTime)); + try { + this.avSessionController.getAvSession()?.on('play', () => this.sessionPlayCallback()); + this.avSessionController.getAvSession()?.on('pause', () => this.sessionPauseCallback()); + this.avSessionController.getAvSession()?.on('stop', () => this.sessionStopCallback()); + this.avSessionController.getAvSession()?.on('fastForward', + (time?: number) => this.sessionFastForwardCallback(time)); + this.avSessionController.getAvSession()?.on('rewind', (time?: number) => this.sessionRewindCallback(time)); + this.avSessionController.getAvSession()?.on('seek', (seekTime: number) => this.sessionSeekCallback(seekTime)); + } catch (error) { + Logger.error(`getMediaContent failed, code is ${error.code}, message is ${error.message}`); + } } private setInterruptCallback() { @@ -207,7 +217,10 @@ export class AvPlayerController { case 'initialized': Logger.info(TAG, 'AVPlayer state initialized called.' + ` this.curIndex:${this.curIndex}`); avPlayer.surfaceId = this.surfaceID; - avPlayer.prepare(); + avPlayer.prepare() + .catch((err: BusinessError) => { + Logger.error(TAG, `avPlayer prepare failed, code is ${err.code}, message is ${err.message}`); + }) break; case 'prepared': // [StartExclude mode_volume] @@ -405,7 +418,10 @@ export class AvPlayerController { this.updateIsPlay(true); Logger.error(TAG, `stopVideo failed, code is ${err.code}, message is ${err.message}`); } else { - this.avPlayer!.release(); + this.avPlayer!.release() + .catch((err: BusinessError) => { + Logger.error(TAG, `avPlayer release failed, code is ${err.code}, message is ${err.message}`); + }) Logger.info(TAG, `stopVideo success, this.curIndex:${this.curIndex}`); } }); @@ -466,7 +482,10 @@ export class AvPlayerController { this.avPlayer.off('speedDone'); this.avPlayer.off('error'); this.avPlayer.off('stateChange'); - this.avPlayer.release(); + this.avPlayer.release() + .catch((err: BusinessError) => { + Logger.error(TAG, `avPlayer release failed, code is ${err.code}, message is ${err.message}`); + }) // [StartExclude destroy_instance] this.avSessionController?.unregisterSessionListener(); // [EndExclude destroy_instance] diff --git a/HDRVivid/AVPlayer/MediaService/src/main/ets/controller/AvSessionController.ets b/HDRVivid/AVPlayer/MediaService/src/main/ets/controller/AvSessionController.ets index d0e8b644aa4bf37ddc87af71a86436f62f56f7e8..693cea3b23da7bea85752b99f90d1ef962ffe5e8 100644 --- a/HDRVivid/AVPlayer/MediaService/src/main/ets/controller/AvSessionController.ets +++ b/HDRVivid/AVPlayer/MediaService/src/main/ets/controller/AvSessionController.ets @@ -46,13 +46,20 @@ export class AvSessionController { Logger.info(TAG, `session create failed : conext is undefined`); return; } - avSession.createAVSession(this.context, "SHORT_AUDIO_SESSION", 'video').then(async (avSession) => { - this.avSession = avSession; - Logger.info(TAG, `session create successed : sessionId : ${this.avSession.sessionId}`); - BackgroundTaskManager.startContinuousTask(this.context); - this.setLaunchAbility(); - this.avSession.activate(); - }); + avSession.createAVSession(this.context, "SHORT_AUDIO_SESSION", 'video') + .then(async (avSession) => { + this.avSession = avSession; + Logger.info(TAG, `session create successed : sessionId : ${this.avSession.sessionId}`); + BackgroundTaskManager.startContinuousTask(this.context); + this.setLaunchAbility(); + this.avSession.activate() + .catch((err: BusinessError) => { + Logger.error(TAG, `avSession activate failed Cause: ${JSON.stringify(err)}`); + }) + }) + .catch((err: BusinessError) => { + Logger.error(TAG, `createAVSession failed Cause: ${JSON.stringify(err)}`); + }) } public getAvSession() { @@ -70,19 +77,23 @@ export class AvSessionController { } const imagePixMap = await ImageUtil.getPixmapFromMedia(curSource.head, UIContext); - let metadata: avSession.AVMetadata = { - assetId: `${curSource.index}`, - title: this.context?.resourceManager.getStringSync(curSource.name), - mediaImage: imagePixMap, - duration: duration - }; - if (this.avSession) { - this.avSession.setAVMetadata(metadata).then(() => { - this.avSessionMetadata = metadata; - Logger.info(TAG, 'SetAVMetadata successfully'); - }).catch((err: BusinessError) => { - Logger.error(TAG, `SetAVMetadata BusinessError: code: ${err.code}, message: ${err.message}`); - }); + try { + let metadata: avSession.AVMetadata = { + assetId: `${curSource.index}`, + title: this.context?.resourceManager.getStringSync(curSource.name.id), + mediaImage: imagePixMap, + duration: duration + }; + if (this.avSession) { + this.avSession.setAVMetadata(metadata).then(() => { + this.avSessionMetadata = metadata; + Logger.info(TAG, 'SetAVMetadata successfully'); + }).catch((err: BusinessError) => { + Logger.error(TAG, `SetAVMetadata BusinessError: code: ${err.code}, message: ${err.message}`); + }); + } + } catch (error) { + Logger.error(`getStringSync failed Cause: ${JSON.stringify(error)}`); } } @@ -101,11 +112,17 @@ export class AvSessionController { requestCode: 0, wantAgentFlags: [wantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG] }; - wantAgent.getWantAgent(wantAgentInfo).then((agent) => { - if (this.avSession) { - this.avSession.setLaunchAbility(agent); - } - }); + wantAgent.getWantAgent(wantAgentInfo) + .then((agent) => { + if (this.avSession) { + this.avSession.setLaunchAbility(agent).catch((err: BusinessError) => { + Logger.error(TAG, `setLaunchAbility failed Cause: ${JSON.stringify(err)}`); + }) + } + }) + .catch((err: BusinessError) => { + Logger.error(TAG, `getWantAgent failed Cause: ${JSON.stringify(err)}`); + }) } public setAvSessionPlayState(playbackState: avSession.AVPlaybackState) { @@ -124,13 +141,17 @@ export class AvSessionController { if (!this.avSession) { return; } - this.avSession.off('play'); - this.avSession.off('pause'); - this.avSession.off('playNext'); - this.avSession.off('playPrevious'); - this.avSession.off('setLoopMode'); - this.avSession.off('seek'); - this.avSession.off('toggleFavorite'); - BackgroundTaskManager.stopContinuousTask(this.context); + try { + this.avSession.off('play'); + this.avSession.off('pause'); + this.avSession.off('playNext'); + this.avSession.off('playPrevious'); + this.avSession.off('setLoopMode'); + this.avSession.off('seek'); + this.avSession.off('toggleFavorite'); + BackgroundTaskManager.stopContinuousTask(this.context); + } catch (error) { + Logger.error(`avSession off failed Cause: ${JSON.stringify(error)}`); + } } } \ No newline at end of file diff --git a/HDRVivid/AVPlayer/MediaService/src/main/ets/utils/BackgroundTaskManager.ets b/HDRVivid/AVPlayer/MediaService/src/main/ets/utils/BackgroundTaskManager.ets index 0d5307896dcfdd1c8c7b885a7a29ec312e0a0efa..4fb542ccfb21cada5bf5d280d9ae4a370f482b41 100644 --- a/HDRVivid/AVPlayer/MediaService/src/main/ets/utils/BackgroundTaskManager.ets +++ b/HDRVivid/AVPlayer/MediaService/src/main/ets/utils/BackgroundTaskManager.ets @@ -47,7 +47,10 @@ export class BackgroundTaskManager { }).catch((err: BusinessError) => { Logger.error(TAG, `startBackgroundRunning failed Cause: ${JSON.stringify(err)}`); }); - }); + }) + .catch((err: BusinessError) => { + Logger.error(TAG, `getWantAgent failed Cause: ${JSON.stringify(err)}`); + }) } // cancel continuous task diff --git a/HDRVivid/AVPlayer/MediaService/src/main/ets/utils/ImageUtil.ets b/HDRVivid/AVPlayer/MediaService/src/main/ets/utils/ImageUtil.ets index 68db5f723323e418374aaa22e5bbe8503f65ee0e..73e46703890e14761363f4efa0af0023ccfdf8f5 100644 --- a/HDRVivid/AVPlayer/MediaService/src/main/ets/utils/ImageUtil.ets +++ b/HDRVivid/AVPlayer/MediaService/src/main/ets/utils/ImageUtil.ets @@ -14,16 +14,18 @@ */ import { image } from '@kit.ImageKit'; +import Logger from './Logger'; export class ImageUtil { constructor() { } public static async getPixmapFromMedia(resource: Resource, UIContext: UIContext) { - let unit8Array = await UIContext.getHostContext()?.resourceManager?.getMediaContent({ - bundleName: resource.bundleName, - moduleName: resource.moduleName, - id: resource.id - }); + let unit8Array: Uint8Array | undefined = undefined; + try { + unit8Array = await UIContext.getHostContext()?.resourceManager?.getMediaContent(resource.id); + } catch (error) { + Logger.error(`getMediaContent failed Cause: ${JSON.stringify(error)}`); + } let imageSource = image.createImageSource(unit8Array?.buffer.slice(0, unit8Array.buffer.byteLength)); let createPixelMap: image.PixelMap = await imageSource.createPixelMap({ desiredPixelFormat: image.PixelMapFormat.RGBA_8888 diff --git a/HDRVivid/AVPlayer/README.md b/HDRVivid/AVPlayer/README.md new file mode 100644 index 0000000000000000000000000000000000000000..2c66fecd63458250f785ef8a1fa71d729c1047e6 --- /dev/null +++ b/HDRVivid/AVPlayer/README.md @@ -0,0 +1,83 @@ +# 视频播放类应用 + +### 简介 + +本示例主要展示通过HarmonyOS提供的系统播放器AVPlayer和媒体会话等能力,实现视频类应用的开发。 + +### 效果预览 + +![](screenshots/AVPlay.png) + +### 使用说明 + +1. 进入页面,视频自动播放,点击视频可控制播放、暂停。 + +2. 点击进度条右侧按钮可切换竖屏或横屏模式。 + +3. 拖动进度条或全屏手势滑动可调节播放进度。 + +4. 全屏播放视频场景下,在屏幕左侧上下滑动可调节音量,在屏幕右侧上下滑动可调节亮度。 + + +### 工程目录 + +``` +├──entry/src/main/ets +│ ├──entryability +│ │ └──EntryAbility.ets // 程序入口 +│ ├──model +│ │ ├──BasicDataSource.ets // 懒加载DataSource +│ │ └──DataModel.ets // 数据类 +│ ├──pages +│ │ └──IndexPage.ets // 首页 +│ ├──utils +│ │ └──WindowUtil.ets // 窗口工具类 +│ └──view +│ ├──AVPlayer.ets // 视频组件 +│ ├──VideoList.ets // 首页视频列表 +│ ├──VideoSide.ets // 视频滑动组件 +│ └──VideoDetails.ets // 视频详情信息组件 +│──entry/src/main/resources // 应用资源目录 +│ +│──MediaService/src/main/ets +│ ├──common +│ │ └──CommonConstants.ets //常量类 +│ ├──controller +│ │ ├──AvPlayerController.ets //视频播放控制 +│ │ └──AvSessionController.ets //媒体会话控制 +│ ├──model +│ │ └──VideoData.ets //视频数据类 +│ └──utils +│ ├──BackgroundTaskManager.ets // 后台播放功能 +│ ├──CommUtils.ets // 工具类 +│ ├──ImageUtil.ets // 图片像素处理类 +│ └──Logger.ets // 日志 +└──MediaService/src/main/resources // 应用资源目录 +``` + +### 相关权限 + +1. 后台任务权限:ohos.permission.KEEP_BACKGROUND_RUNNING。 + +2. Internet网络权限:ohos.permission.INTERNET。 + +### 约束与限制 + +1. 本示例仅支持标准系统上运行,支持设备:华为手机。 + +2. HarmonyOS系统:HarmonyOS 6.0.0 Release及以上。 + +3. DevEco Studio版本:DevEco Studio 6.0.0 Release及以上。 + +4. HarmonyOS SDK版本:HarmonyOS 6.0.0 Release SDK及以上。 + +### 下载 + +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set HDRVivid/AVPlayer +git checkout +``` diff --git a/HDRVivid/AVPlayer/build-profile.json5 b/HDRVivid/AVPlayer/build-profile.json5 index 48cac0c694203e81fb01ea6d1f80b7e26cd82d1c..748ebf8f1077803a01f75a983f9fc453fb31ca09 100644 --- a/HDRVivid/AVPlayer/build-profile.json5 +++ b/HDRVivid/AVPlayer/build-profile.json5 @@ -5,7 +5,8 @@ { "name": "default", "signingConfig": "default", - "compatibleSdkVersion": "5.0.0(12)", + "compatibleSdkVersion": "6.0.0(20)", + "targetSdkVersion": "6.0.0(20)", "runtimeOS": "HarmonyOS", } ], diff --git a/HDRVivid/AVPlayer/entry/src/main/ets/entryability/EntryAbility.ets b/HDRVivid/AVPlayer/entry/src/main/ets/entryability/EntryAbility.ets index 8b2e96277cf6a779770d89f77c263996afc9f7f1..866c9f2a0fc97f0c3bc7d03c036be9125b2b9ae5 100644 --- a/HDRVivid/AVPlayer/entry/src/main/ets/entryability/EntryAbility.ets +++ b/HDRVivid/AVPlayer/entry/src/main/ets/entryability/EntryAbility.ets @@ -14,6 +14,7 @@ */ import { UIAbility } from '@kit.AbilityKit'; +import { BusinessError } from '@kit.BasicServicesKit'; import { hilog } from '@kit.PerformanceAnalysisKit'; import { UIContext, window } from '@kit.ArkUI'; import { WindowUtil } from '../utils/WindowUtil'; @@ -31,21 +32,36 @@ export default class EntryAbility extends UIAbility { onWindowStageCreate(windowStage: window.WindowStage): void { // Main window is created, set main page for this ability hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); - let windowClass: window.Window = windowStage.getMainWindowSync(); + let windowClass: window.Window | undefined = undefined; + try { + windowClass = windowStage.getMainWindowSync(); + } catch (err) { + hilog.error(0x0000, 'testTag',`getMainWindowSync failed, Code:${err.code}, message:${err.message}`); + } AppStorage.setOrCreate('windowStage', windowStage); - windowClass.setWindowLayoutFullScreen(true); + windowClass?.setWindowLayoutFullScreen(true) + .catch((err: BusinessError) => { + hilog.error(0x0000, 'testTag',`getMainWindowSync failed, Code:${err.code}, message:${err.message}`); + }) WindowUtil.getInstance().setWindowStage(windowStage); - windowClass.setWindowSystemBarProperties({ + windowClass?.setWindowSystemBarProperties({ statusBarContentColor: '#e6ffffff' - }); + }) + .catch((err: BusinessError) => { + hilog.error(0x0000, 'testTag',`getMainWindowSync failed, Code:${err.code}, message:${err.message}`); + }) windowStage.loadContent('pages/IndexPage', (err) => { if (err.code) { hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); return; } - let uiContext: UIContext | undefined = windowStage.getMainWindowSync().getUIContext(); - AppStorage.setOrCreate('uiContext', uiContext); - hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.'); + try { + let uiContext: UIContext | undefined = windowStage.getMainWindowSync().getUIContext(); + AppStorage.setOrCreate('uiContext', uiContext); + hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.'); + } catch (error) { + hilog.error(0x0000, 'testTag',`getMainWindowSync or getUIContext failed, Code:${err.code}, message:${err.message}`); + } }); } diff --git a/HDRVivid/AVPlayer/entry/src/main/ets/pages/IndexPage.ets b/HDRVivid/AVPlayer/entry/src/main/ets/pages/IndexPage.ets index 05fc2588ab7dae0ff6e7bd1e2e0f07d3bc37c82f..dffa0474aa200d93c4a455a2f3dd3c94347755e5 100644 --- a/HDRVivid/AVPlayer/entry/src/main/ets/pages/IndexPage.ets +++ b/HDRVivid/AVPlayer/entry/src/main/ets/pages/IndexPage.ets @@ -14,6 +14,7 @@ */ import { window } from '@kit.ArkUI'; +import { BusinessError } from '@kit.BasicServicesKit'; import { CommonConstants as Const, Logger, VideoData } from '@ohos/MediaService'; import { SOURCES, VideoSource } from '../model/DataModel'; import { WindowUtil } from '../utils/WindowUtil'; @@ -22,6 +23,7 @@ import { VideoList } from '../view/VideoList'; import { VideoPlayer } from '../view/AVPlayer'; import { VideoDetails } from '../view/VideoDetails'; import { common } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; const TAG = '[IndexPage]'; @@ -43,8 +45,17 @@ struct IndexPage { async aboutToAppear(): Promise { let context = this.uiContext.getHostContext() as common.UIAbilityContext; - let windowClass = await window.getLastWindow(context); - await windowClass.setWindowKeepScreenOn(true); + await window.getLastWindow(context) + .then((windowClass: window.Window) => { + windowClass.setWindowKeepScreenOn(true) + .catch((err: BusinessError) => { + hilog.error(0x0000, 'testTag',`setWindowKeepScreenOn failed, Code:${err.code}, message:${err.message}`); + }) + }) + .catch((err: BusinessError) => { + hilog.error(0x0000, 'testTag',`getLastWindow failed, Code:${err.code}, message:${err.message}`); + }) + this.windowUtil.registerOnWindowSizeChange((size) => { if (size.width > size.height) { this.isFullLandscapeScreen = true; diff --git a/HDRVivid/AVPlayer/entry/src/main/ets/utils/WindowUtil.ets b/HDRVivid/AVPlayer/entry/src/main/ets/utils/WindowUtil.ets index e41aaf59abcc390596929af6c746571393eeb555..db2a5fd9b669ecaf7cf21c7da7a65baf6fe607e9 100644 --- a/HDRVivid/AVPlayer/entry/src/main/ets/utils/WindowUtil.ets +++ b/HDRVivid/AVPlayer/entry/src/main/ets/utils/WindowUtil.ets @@ -14,7 +14,7 @@ */ import { window } from '@kit.ArkUI'; -import { CommonConstants, Logger } from '@ohos/MediaService'; +import { Logger } from '@ohos/MediaService'; import { BusinessError } from '@kit.BasicServicesKit'; const TAG: string = '[WindowUtil]'; @@ -40,15 +40,19 @@ export class WindowUtil { return; } this.mainWindowClass = windowClass; - const properties = windowClass.getWindowProperties(); - // Get status bar height. - let area: window.AvoidArea = windowClass.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM); - let naviBarArea: window.AvoidArea = - windowClass.getWindowAvoidArea(window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR); - AppStorage.setOrCreate('deviceWidth', properties.windowRect.width); - AppStorage.setOrCreate('deviceHeight', properties.windowRect.height); - AppStorage.setOrCreate('statusBarHeight', uiContext?.px2vp(area.topRect.height)); - AppStorage.setOrCreate('navBarHeight', uiContext?.px2vp(naviBarArea.bottomRect.height)); + try { + const properties = windowClass.getWindowProperties(); + // Get status bar height. + let area: window.AvoidArea = windowClass.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM); + let naviBarArea: window.AvoidArea = + windowClass.getWindowAvoidArea(window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR); + AppStorage.setOrCreate('deviceWidth', properties.windowRect.width); + AppStorage.setOrCreate('deviceHeight', properties.windowRect.height); + AppStorage.setOrCreate('statusBarHeight', uiContext?.px2vp(area.topRect.height)); + AppStorage.setOrCreate('navBarHeight', uiContext?.px2vp(naviBarArea.bottomRect.height)); + } catch (error) { + Logger.error(`getWindowProperties or getWindowAvoidArea failed, Code:${err.code}, message:${err.message}`); + } }); } @@ -71,7 +75,10 @@ export class WindowUtil { return; } // Set the status bar and navigation bar to be invisible in full-screen mode. - this.mainWindowClass.setWindowSystemBarEnable([]); + this.mainWindowClass.setWindowSystemBarEnable([]) + .catch((err: BusinessError) => { + Logger.error(TAG, `setWindowSystemBarEnable failed, Code:${err.code}, message:${err.message}`); + }) } enableWindowSystemBar(): void { @@ -79,7 +86,10 @@ export class WindowUtil { Logger.error(`MainWindowClass is undefined`); return; } - this.mainWindowClass.setWindowSystemBarEnable(['status', 'navigation']); + this.mainWindowClass.setWindowSystemBarEnable(['status', 'navigation']) + .catch((err: BusinessError) => { + Logger.error(TAG, `setWindowSystemBarEnable failed, Code:${err.code}, message:${err.message}`); + }) } setLandscapeMultiWindow(enable: boolean) { @@ -88,9 +98,15 @@ export class WindowUtil { return; } if (enable) { - this.mainWindowClass?.enableLandscapeMultiWindow(); + this.mainWindowClass?.enableLandscapeMultiWindow() + .catch((err: BusinessError) => { + Logger.error(TAG, `enableLandscapeMultiWindow failed, Code:${err.code}, message:${err.message}`); + }) } else { - this.mainWindowClass?.disableLandscapeMultiWindow(); + this.mainWindowClass?.disableLandscapeMultiWindow() + .catch((err: BusinessError) => { + Logger.error(TAG, `disableLandscapeMultiWindow failed, Code:${err.code}, message:${err.message}`); + }) } } diff --git a/HDRVivid/AVPlayer/entry/src/main/ets/view/AVPlayer.ets b/HDRVivid/AVPlayer/entry/src/main/ets/view/AVPlayer.ets index e0f634bf2d2b2c4540e53a465f81b2164e5c7c68..79d52674cd9a820d9e20e457ca2cd946a99af9dd 100644 --- a/HDRVivid/AVPlayer/entry/src/main/ets/view/AVPlayer.ets +++ b/HDRVivid/AVPlayer/entry/src/main/ets/view/AVPlayer.ets @@ -65,63 +65,56 @@ export struct VideoPlayer { private screenHeight: number = 0; private windowStage: window.WindowStage = AppStorage.get('windowStage') as window.WindowStage; // Get the main window. - private mainWin: window.Window = this.windowStage.getMainWindowSync(); + private mainWin: window.Window | null = null; uiContext = this.getUIContext() aboutToAppear(): void { + try { + this.mainWin = this.windowStage.getMainWindowSync(); + } catch (error) { + hilog.error(0x0000, 'AVPlayer', `getMainWindowSync failed. Cause code: ${error.code}, message: ${error.message}`); + } const context = this.uiContext.getHostContext() as common.UIAbilityContext; - ; settings.getValue(context, settings.display.SCREEN_BRIGHTNESS_STATUS, settings.domainName.DEVICE_SHARED) .then((value) => { hilog.info(0x0000, 'AVPlayer', `Promise:value -> ${JSON.stringify(value)}`); this.screenBrightness = Number(value) / 255; }) - try { - window.getLastWindow(context).then((data) => { - this.screenHeight = data?.getWindowProperties().windowRect.height; - }); - } catch (exception) { - hilog.error(0x0000, 'AVPlayer', - `Failed to obtain the top window. Cause code: ${exception.code}, message: ${exception.message}`); - } - + window.getLastWindow(context) + .then((data) => { + try { + this.screenHeight = data?.getWindowProperties().windowRect.height; + } catch (exception) { + hilog.error(0x0000, 'AVPlayer', `Failed to obtain the top window. Cause code: ${exception.code}, message: ${exception.message}`); + } + }) + .catch((error: BusinessError) => { + hilog.error(0x0000, 'AVPlayer', `Failed to obtain the top window. Cause code: ${error.code}, message: ${error.message}`); + }) let groupId: number = audio.DEFAULT_VOLUME_GROUP_ID; let audioManager = audio.getAudioManager(); let audioVolumeManger: audio.AudioVolumeManager = audioManager.getVolumeManager(); + try { + this.volume = audioVolumeManger.getVolumeByStream(audio.StreamUsage.STREAM_USAGE_MOVIE); + + let maxNum = audioVolumeManger.getMaxVolumeByStream(audio.StreamUsage.STREAM_USAGE_MUSIC); + hilog.info(0x0000, 'AVPlayer', `Callback invoked to indicate that the maximum volume is obtained. ${maxNum}`); + + let minNum = audioVolumeManger.getMinVolumeByStream(audio.StreamUsage.STREAM_USAGE_MUSIC); + hilog.info(0x0000, 'AVPlayer', `Callback invoked to indicate that the maximum volume is obtained. ${minNum}`); + } catch (err) { + let error = err as BusinessError; + hilog.error(0x0000, 'AVPlayer', `code=${error.code}, message=${error.message}`); + } + audioVolumeManger.getVolumeGroupManager(groupId, (err: BusinessError, value: audio.AudioVolumeGroupManager) => { if (err) { hilog.error(0x0000, 'AVPlayer', `Failed to obtain the colume group infos list. ${err}`); return; } - let audioVolumeGroupManager = value; hilog.info(0x0000, 'AVPlayer', `Callback invoked to indicate that the volume group infos list is obtained.`); - - audioVolumeGroupManager.getVolume(audio.AudioVolumeType.MEDIA, (err: BusinessError, value: number) => { - if (err) { - hilog.error(0x0000, 'AVPlayer', `Failed to obtain the volume. ${err}`); - return; - } - this.volume = value; - hilog.info(0x0000, 'AVPlayer', `Callback invoked to indicate that the volume is obtained. ${value}`); - }); - - audioVolumeGroupManager.getMaxVolume(audio.AudioVolumeType.MEDIA, (err: BusinessError, value: number) => { - if (err) { - hilog.error(0x0000, 'AVPlayer', `Failed to obtain the maximum volume. ${err}`); - return; - } - hilog.info(0x0000, 'AVPlayer', `Callback invoked to indicate that the maximum volume is obtained. ${value}`); - }); - - audioVolumeGroupManager.getMinVolume(audio.AudioVolumeType.MEDIA, (err: BusinessError, value: number) => { - if (err) { - hilog.error(0x0000, 'AVPlayer', `Failed to obtain the minimum volume. ${err}`); - return; - } - hilog.info(0x0000, 'AVPlayer', `Callback invoked to indicate that the minimum volume is obtained. ${value}`); - }); }); } @@ -192,7 +185,7 @@ export struct VideoPlayer { .width(this.isFloatWindow ? $r('app.float.size_24') : $r('app.float.icon_size_large')) .aspectRatio(1) .visibility(this.isFullScreen || this.isFullLandscapeScreen || this.isFloatWindow ? - Visibility.Visible : Visibility.Hidden) + Visibility.Visible : Visibility.Hidden) Image($r('app.media.ic_video_menu_forward')) .monopolizeEvents(true) .width(this.isFloatWindow ? $r('app.float.size_24') : $r('app.float.icon_size_large')) @@ -301,14 +294,15 @@ export struct VideoPlayer { .onActionUpdate((event: GestureEvent) => { if (event.fingerList[0].globalX > (820 / 2)) { this.visible = true; - let curBrightness = this.screenBrightness - this.uiContext.vp2px(event.offsetY) / this.uiContext.vp2px(this.screenHeight); + let curBrightness = + this.screenBrightness - this.uiContext.vp2px(event.offsetY) / this.uiContext.vp2px(this.screenHeight); curBrightness = curBrightness >= 1.0 ? 1.0 : curBrightness; curBrightness = curBrightness <= 0.0 ? 0.0 : curBrightness; this.screenBrightness = curBrightness; hilog.info(0x0000, 'AVPlayer', `this brightness is: ` + this.screenBrightness); try { - this.mainWin.setWindowBrightness(this.screenBrightness, (err) => { + this.mainWin?.setWindowBrightness(this.screenBrightness, (err) => { if (err) { hilog.error(0x0000, 'AVPlayer', `Failed to set the brightness. Cause: ${JSON.stringify(err)}`); return; @@ -452,7 +446,7 @@ export struct VideoPlayer { Column() { Row() { Image(this.avPlayerController.isPlaying ? $r('sys.media.ohos_ic_public_pause') : - $r('app.media.ic_video_menu_play')) + $r('app.media.ic_video_menu_play')) .width($r('app.float.size_24')) .height($r('app.float.size_24')) .fillColor(Color.White) @@ -481,10 +475,15 @@ export struct VideoPlayer { .selectedBorderRadius(CommonConstants.TRACK_BORDER_RADIUS) .zIndex(CommonConstants.SLIDER_INDEX) .onAreaChange(() => { - let videoSlider: componentUtils.ComponentInfo = this.getUIContext().getComponentUtils().getRectangleById('video_slider'); - this.slideWidth = this.uiContext.px2vp(videoSlider.size.width); - this.offsetY = this.uiContext.px2vp(videoSlider.localOffset.y); - this.beginX = this.uiContext.px2vp(videoSlider.localOffset.x); + try { + let videoSlider: componentUtils.ComponentInfo = + this.getUIContext().getComponentUtils().getRectangleById('video_slider'); + this.slideWidth = this.uiContext.px2vp(videoSlider.size.width); + this.offsetY = this.uiContext.px2vp(videoSlider.localOffset.y); + this.beginX = this.uiContext.px2vp(videoSlider.localOffset.x); + } catch (error) { + hilog.error(0x0000, 'testTag', `getRectangleById failed, Code:${error.code}, message:${error.message}`); + } }) .onChange((value: number, mode: SliderChangeMode) => { this.sliderOnchange(value, mode); @@ -559,8 +558,16 @@ export struct VideoPlayer { this.isTimeDisplay = 0; this.trackThicknessSize = CommonConstants.TRACK_SIZE_MIN; let context = this.uiContext.getHostContext() as common.UIAbilityContext; - let windowClass = await window.getLastWindow(context); - await windowClass.setWindowKeepScreenOn(false); + await window.getLastWindow(context) + .then((windowClass: window.Window) => { + windowClass.setWindowKeepScreenOn(false) + .catch((err: BusinessError) => { + hilog.error(0x0000, 'testTag', `setWindowKeepScreenOn failed, Code:${err.code}, message:${err.message}`); + }) + }) + .catch((err: BusinessError) => { + hilog.error(0x0000, 'testTag', `getLastWindow failed, Code:${err.code}, message:${err.message}`); + }) return; } if (this.avPlayerController.isReady === true) { @@ -580,8 +587,16 @@ export struct VideoPlayer { }, CommonConstants.TIMER_INTERVAL); } let context = this.uiContext.getHostContext() as common.UIAbilityContext; - let windowClass = await window.getLastWindow(context); - await windowClass.setWindowKeepScreenOn(true); + await window.getLastWindow(context) + .then((windowClass: window.Window) => { + windowClass.setWindowKeepScreenOn(true) + .catch((err: BusinessError) => { + hilog.error(0x0000, 'testTag', `setWindowKeepScreenOn failed, Code:${err.code}, message:${err.message}`); + }) + }) + .catch((err: BusinessError) => { + hilog.error(0x0000, 'testTag', `getLastWindow failed, Code:${err.code}, message:${err.message}`); + }) } aboutToDisappear(): void { diff --git a/HDRVivid/AVPlayer/entry/src/main/ets/view/VideoDetails.ets b/HDRVivid/AVPlayer/entry/src/main/ets/view/VideoDetails.ets index cb0a6273659c8ab32e08127ce7f4f4f0e20ef28d..3c4b0f72ef85273878bca9cb82be3057b7a6e6c9 100644 --- a/HDRVivid/AVPlayer/entry/src/main/ets/view/VideoDetails.ets +++ b/HDRVivid/AVPlayer/entry/src/main/ets/view/VideoDetails.ets @@ -13,6 +13,7 @@ * limitations under the License. */ import { CommonConstants as Const, VideoData } from '@ohos/MediaService'; +import { hilog } from '@kit.PerformanceAnalysisKit'; @Component({ freezeWhenInactive: true }) export struct VideoDetails { @@ -129,7 +130,11 @@ export struct VideoDetails { .opacity($r('app.float.opacity_4')) } .onClick(() => { - this.getPromptAction.showToast({ message: $r('app.string.comment'), duration: Const.TOAST_DURATION }); + try { + this.getPromptAction.showToast({ message: $r('app.string.comment'), duration: Const.TOAST_DURATION }) + } catch (error) { + hilog.error(0x0000, 'testTag',`getPromptAction showToast failed, Code:${error.code}, message:${error.message}`); + } }) Column() { @@ -143,7 +148,11 @@ export struct VideoDetails { .opacity($r('app.float.opacity_4')) } .onClick(() => { - this.getPromptAction.showToast({ message: $r('app.string.share'), duration: Const.TOAST_DURATION }); + try { + this.getPromptAction.showToast({ message: $r('app.string.share'), duration: Const.TOAST_DURATION }); + } catch (error) { + hilog.error(0x0000, 'testTag',`getPromptAction showToast failed, Code:${error.code}, message:${error.message}`); + } }) } .width(Const.FULL_SIZE) diff --git a/HDRVivid/AVPlayer/entry/src/main/ets/view/VideoSide.ets b/HDRVivid/AVPlayer/entry/src/main/ets/view/VideoSide.ets index 53b8adbb9df43738d2aee9c0965e06e9a8b1e7f1..9b8d24344271fc448b49d1ca709f95f5584d9470 100644 --- a/HDRVivid/AVPlayer/entry/src/main/ets/view/VideoSide.ets +++ b/HDRVivid/AVPlayer/entry/src/main/ets/view/VideoSide.ets @@ -14,6 +14,7 @@ */ import { CommonConstants as Const, VideoData } from '@ohos/MediaService'; +import { hilog } from '@kit.PerformanceAnalysisKit'; @Component export struct RightSide { @@ -91,7 +92,11 @@ export struct RightSide { .fillColor(Color.White) .margin({ bottom: $r('app.float.fabulous_margin_bottom') }) .onClick(() => { - this.getPromptAction.showToast({ message: $r('app.string.comment'), duration: Const.TOAST_DURATION }); + try { + this.getPromptAction.showToast({ message: $r('app.string.comment'), duration: Const.TOAST_DURATION }); + } catch (error) { + hilog.error(0x0000, 'testTag',`getPromptAction showToast failed, Code:${error.code}, message:${error.message}`); + } }) Text(this.item.commentCount) .fontSize($r('app.float.fabulous_font_size')) @@ -114,7 +119,11 @@ export struct RightSide { .width($r('app.float.avatar_size')) .alignItems(HorizontalAlign.Center) .onClick(() => { - this.getPromptAction.showToast({ message: $r('app.string.share'), duration: Const.TOAST_DURATION }); + try { + this.getPromptAction.showToast({ message: $r('app.string.share'), duration: Const.TOAST_DURATION }); + } catch (error) { + hilog.error(0x0000, 'testTag',`getPromptAction showToast failed, Code:${error.code}, message:${error.message}`); + } }) } .margin({ bottom: $r('app.float.video_side_margin_bottom'), right: $r('app.float.right_space') }) diff --git a/HDRVivid/AVPlayer/screenshots/AVPlay.png b/HDRVivid/AVPlayer/screenshots/AVPlay.png new file mode 100644 index 0000000000000000000000000000000000000000..f58ecef14c94e314b247f7744c2a5173e8996ef3 Binary files /dev/null and b/HDRVivid/AVPlayer/screenshots/AVPlay.png differ diff --git a/HDRVivid/AVPlayer/screenshots/videoPlayer.gif b/HDRVivid/AVPlayer/screenshots/videoPlayer.gif deleted file mode 100644 index 98cf15192ed5098fb3cb9e0b673b51d1ca594d86..0000000000000000000000000000000000000000 Binary files a/HDRVivid/AVPlayer/screenshots/videoPlayer.gif and /dev/null differ diff --git a/HDRVivid/AVPlayer/screenshots/videoPlayer_EN.gif b/HDRVivid/AVPlayer/screenshots/videoPlayer_EN.gif deleted file mode 100644 index d39150d7205ee783190807ed8ca329037d89ce2c..0000000000000000000000000000000000000000 Binary files a/HDRVivid/AVPlayer/screenshots/videoPlayer_EN.gif and /dev/null differ diff --git a/HDRVivid/AVRecorder/README.en.md b/HDRVivid/AVRecorder/README.en.md index 3c50c9779bcee9272ef29081d92c342765fb1cd1..5cf3f75ee1f0675d2fc63d56ca3cdf773bca26d0 100644 --- a/HDRVivid/AVRecorder/README.en.md +++ b/HDRVivid/AVRecorder/README.en.md @@ -17,6 +17,24 @@ This sample demonstrates the use of Camera Kit to customize a camera and use the 3. Touch the start button to start recording the video. 4. Touch the stop button to finish recording. The home page is displayed. The recorded video is displayed above the **Record video** button, and the video can be manually played. + +### Project Directory +``` +├───entry/src/main/ets +│ ├───common +│ │ └───CommonConstants.ets // Constant +│ ├───entryability +│ │ └───EntryAbility.ets // Lifecycle callback content of an ability +│ ├───pages +│ │ ├───Index.ets // Home page +│ │ └───Record.ets // Record page +│ └───utils +│ ├───FileUtil.ets // File Utility Class +│ ├───Logger.ets // Log Utility Class +│ └───RouterParams.ets // Route Parameter Class +└───entry/src/main/resources +``` + ### How to Implement 1. Use **cameraInput** to obtain the data collected by the camera and create a camera input. @@ -35,8 +53,19 @@ This sample demonstrates the use of Camera Kit to customize a camera and use the 1. The sample app is supported only on Huawei phones running the standard system. -2. The HarmonyOS version must be HarmonyOS NEXT Developer Beta1 or later. +2. The HarmonyOS version must be HarmonyOS 5.1.0 Release or later. + +3. The DevEco Studio version must be DevEco Studio 5.1.0 Release or later. + +4. The HarmonyOS SDK version must be HarmonyOS 5.1.0 Release SDK or later. -3. The DevEco Studio version must be DevEco Studio NEXT Developer Beta1 or later. +### Download -4. The HarmonyOS SDK version must be HarmonyOS NEXT Developer Beta1 or later. +To download this project separately, execute the following command: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set HDRVivid/AVRecorder +git checkout +``` diff --git a/HDRVivid/AVRecorder/README.md b/HDRVivid/AVRecorder/README.md index 6516806910b03a2fb3c828f6234c8bb9730cbe21..289b8cf7dc4ffd7affda53fc11791139aab036e5 100644 --- a/HDRVivid/AVRecorder/README.md +++ b/HDRVivid/AVRecorder/README.md @@ -10,13 +10,31 @@ |-----------------------------------|------------------------------------|-------------------------------------------|-----------------------------------| |![](screenshots/device/request.png)| ![](screenshots/device/record.png) | ![](screenshots/device/stopRecording.png) | ![](screenshots/device/index.png) | -**使用说明** +### 使用说明 1. 获取权限。 2. 点击“录制视频”按钮,判断授权权限,若权限均已授权,则跳转录制页面,否则需按提示开启所有权限后重新点击“录制视频”按钮。 3. 点击开始录制按钮,开始录制视频。 4. 点击停止录制按钮,停止录制视频,并返回首页,在“录制视频”按钮上方显示录制的视频,视频可手动播放。 +### 工程目录 + +``` +├───entry/src/main/ets +│ ├───common +│ │ └───CommonConstants.ets // 常量 +│ ├───entryability +│ │ └───EntryAbility.ets // Ability的生命周期回调内容 +│ ├───pages +│ │ ├───Index.ets // 主页 +│ │ └───Record.ets // 录制页 +│ └───utils +│ ├───FileUtil.ets // 文件工具类 +│ ├───Logger.ets // 日志工具类 +│ └───RouterParams.ets // 路由参数类 +└───entry/src/main/resources +``` + ### 实现思路 1. 通过cameraInput,获取相机采集数据,创建相机输入。 @@ -33,9 +51,20 @@ 1. 本示例仅支持标准系统上运行,支持设备:华为手机。 -2. HarmonyOS系统:HarmonyOS NEXT Developer Beta1及以上。 +2. HarmonyOS系统:HarmonyOS 5.1.0 Release及以上。 + +3. DevEco Studio版本:DevEco Studio 5.1.0 Release及以上。 + +4. HarmonyOS SDK版本:HarmonyOS 5.1.0 Release SDK及以上。 -3. DevEco Studio版本:DevEco Studio NEXT Developer Beta1及以上。 +### 下载 -4. HarmonyOS SDK版本:HarmonyOS NEXT Developer Beta1 SDK及以上。 +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set HDRVivid/AVRecorder +git checkout +``` diff --git a/HDRVivid/AVRecorder/build-profile.json5 b/HDRVivid/AVRecorder/build-profile.json5 index c033ce4278fb0641d84107c3c134047ac487368e..9f4024dd245e37b9523003ad8ba295dd0f278912 100644 --- a/HDRVivid/AVRecorder/build-profile.json5 +++ b/HDRVivid/AVRecorder/build-profile.json5 @@ -5,7 +5,8 @@ { "name": "default", "signingConfig": "default", - "compatibleSdkVersion": "5.0.0(12)", + "compatibleSdkVersion": "5.1.0(18)", + "targetSdkVersion": "5.1.0(18)", "runtimeOS": "HarmonyOS", } ], diff --git a/HDRVivid/AVRecorder/entry/src/main/ets/entryability/EntryAbility.ets b/HDRVivid/AVRecorder/entry/src/main/ets/entryability/EntryAbility.ets index ef7705b37f5272cbc2c4d6489eab222d594891af..ad1fe45c6d78b0003202d6d61d269cc6134dfd7d 100644 --- a/HDRVivid/AVRecorder/entry/src/main/ets/entryability/EntryAbility.ets +++ b/HDRVivid/AVRecorder/entry/src/main/ets/entryability/EntryAbility.ets @@ -39,19 +39,25 @@ export default class EntryAbility extends UIAbility { return; } Logger.info(TAG, 'testTag', 'Succeeded in loading the content.'); - let windowClass: window.Window = windowStage.getMainWindowSync(); - let isLayoutFullScreen = true; - let uiContext: UIContext | undefined = windowStage.getMainWindowSync().getUIContext(); - AppStorage.setOrCreate('uiContext', uiContext); - windowClass.setWindowLayoutFullScreen(isLayoutFullScreen) - .then(() => { - Logger.info(TAG, 'testTag', 'Succeeded in setting the window layout to full-screen mode. Data: %{public}s', - JSON.stringify(data) ?? ''); - }) - .catch((err: BusinessError) => { - Logger.error(TAG, 'testTag', 'Failed to set the window layout to full-screen mode. Cause: %{public}s', - JSON.stringify(err) ?? ''); - }) + + try { + let windowClass: window.Window = windowStage.getMainWindowSync(); + let isLayoutFullScreen = true; + let uiContext: UIContext | undefined = windowStage.getMainWindowSync().getUIContext(); + AppStorage.setOrCreate('uiContext', uiContext); + windowClass.setWindowLayoutFullScreen(isLayoutFullScreen) + .then(() => { + Logger.info(TAG, 'testTag', 'Succeeded in setting the window layout to full-screen mode. Data: %{public}s', + JSON.stringify(data) ?? ''); + }) + .catch((err: BusinessError) => { + Logger.error(TAG, 'testTag', 'Failed to set the window layout to full-screen mode. Cause: %{public}s', + JSON.stringify(err) ?? ''); + }) + } catch (error) { + let err = error as BusinessError; + Logger.error(TAG, `getMainWindowSync or getUIContext failed, code=${err.code}, message=${err.message}`); + } }); } diff --git a/HDRVivid/AVRecorder/entry/src/main/ets/pages/Index.ets b/HDRVivid/AVRecorder/entry/src/main/ets/pages/Index.ets index 8e530f47199d0431ad63d5e2ffd1d06234788fea..6780fd6dc37bc651712139ca2098e4bcad12153e 100644 --- a/HDRVivid/AVRecorder/entry/src/main/ets/pages/Index.ets +++ b/HDRVivid/AVRecorder/entry/src/main/ets/pages/Index.ets @@ -87,7 +87,13 @@ struct Index { message: $r('app.string.show_toast_message'), duration: CommonConstants.SHOW_TOAST_DURATION, bottom: CommonConstants.SHOW_TOAST_BOTTOM - }); + }) + .then(() => { + Logger.info(TAG, 'openToast success'); + }) + .catch((err: BusinessError) => { + Logger.error(TAG, `openToast failed, code=${err.code}, message=${err.message}`) + }) break; } } @@ -117,7 +123,13 @@ struct Index { .onClick(async () => { this.checkAccessToken(this.permissions); if (this.result) { - router?.pushUrl({ url: 'pages/Record' }); + router?.pushUrl({ url: 'pages/Record' }) + .then(() => { + Logger.info(TAG, 'pushUrl success'); + }) + .catch((err: BusinessError) => { + Logger.error(TAG, `pushUrl failed, code=${err.code}, message=${err.message}`) + }) } }) } diff --git a/HDRVivid/AVRecorder/entry/src/main/ets/pages/Record.ets b/HDRVivid/AVRecorder/entry/src/main/ets/pages/Record.ets index 94ffa836dc7fd0bbbad4049dd0015bd8fb2805d1..130d41bdcfb444713f5747567d29d1b982056262 100644 --- a/HDRVivid/AVRecorder/entry/src/main/ets/pages/Record.ets +++ b/HDRVivid/AVRecorder/entry/src/main/ets/pages/Record.ets @@ -51,7 +51,7 @@ struct Record { aboutToAppear() { this.path = context.filesDir + '/' + 'VIDEO_' + Date.parse(new Date().toString()) + '.mp4'; let file = FileUtil.createOrOpen(this.path); - this.url = 'fd://' + file.fd; + this.url = 'fd://' + file?.fd; this.videoUri = fileUri.getUriFromPath(this.path); } @@ -107,7 +107,14 @@ struct Record { } async initCamera(context: common.Context | undefined, surfaceId: string) { - this.cameraManager = camera.getCameraManager(context); + // this.cameraManager = camera.getCameraManager(context); + try { + this.cameraManager = camera.getCameraManager(context) + } catch (error) { + let err = error as BusinessError; + Logger.error(TAG, `getCameraManager failed, code=${err.code}, message=${err.message}`); + } + if (!this.cameraManager) { Logger.error(TAG, 'camera.getCameraManager error'); return; @@ -361,10 +368,16 @@ struct Record { Logger.error(`The isVideoStabilizationModeSupported call failed. error code: ${err.code}`); } if (isSupported) { - // Setting video anti-shake - this.captureSession.setVideoStabilizationMode(mode); - let activeVideoStabilizationMode = this.captureSession.getActiveVideoStabilizationMode(); - Logger.info(`activeVideoStabilizationMode: ${activeVideoStabilizationMode}`); + try { + // Setting video anti-shake + this.captureSession.setVideoStabilizationMode(mode); + let activeVideoStabilizationMode = this.captureSession.getActiveVideoStabilizationMode(); + Logger.info(`activeVideoStabilizationMode: ${activeVideoStabilizationMode}`); + } catch (error) { + let err = error as BusinessError; + Logger.warn(TAG, + `setVideoStabilizationMode or getActiveVideoStabilizationMode failed, code=${err.code}, message=${err.message}`); + } } else { Logger.error(`videoStabilizationMode: ${mode} is not support`); } @@ -388,8 +401,13 @@ struct Record { let err = error as BusinessError; Logger.error(`The setColorSpace call failed, error code: ${err.code}`); } - let activeColorSpace: colorSpaceManager.ColorSpace = this.captureSession.getActiveColorSpace(); - Logger.info(`activeColorSpace: ${activeColorSpace}`); + try { + let activeColorSpace: colorSpaceManager.ColorSpace = this.captureSession.getActiveColorSpace(); + Logger.info(`activeColorSpace: ${activeColorSpace}`); + } catch (error) { + let err = error as BusinessError; + Logger.error(`getActiveColorSpace failed, code=${err.code}, message=${err.message}`); + } } else { Logger.error(`colorSpace: ${colorSpace} is not support`); } @@ -425,6 +443,7 @@ struct Record { } } } + // [End start_record] async stopRecord() { @@ -450,28 +469,38 @@ struct Record { let err = error as BusinessError; Logger.error(TAG, `avRecorder stop error: ${JSON.stringify(err)}`); } - try { - if (this.captureSession) { - this.captureSession.stop(); - } - if (this.cameraInput) { - this.cameraInput.close(); - } - if (this.previewOutput) { - this.previewOutput.release(); - } - if (this.videoOutput) { - this.videoOutput.release(); - } - if (this.captureSession) { - this.captureSession.release(); - } - if (this.captureSession) { - this.captureSession = undefined; - } - } catch (error) { - let err = error as BusinessError; - Logger.error(TAG, `avRecorder stop error: ${JSON.stringify(err)}`); + if (this.captureSession) { + this.captureSession.stop() + .catch((err: BusinessError) => { + Logger.error(`avRecorder stop failed, code=${err.code}, message=${err.message}`) + }) + } + if (this.cameraInput) { + this.cameraInput.close() + .catch((err: BusinessError) => { + Logger.error(`avRecorder close failed, code=${err.code}, message=${err.message}`) + }) + } + if (this.previewOutput) { + this.previewOutput.release() + .catch((err: BusinessError) => { + Logger.error(`avRecorder release failed, code=${err.code}, message=${err.message}`) + }) + } + if (this.videoOutput) { + this.videoOutput.release() + .catch((err: BusinessError) => { + Logger.error(`avRecorder release failed, code=${err.code}, message=${err.message}`) + }) + } + if (this.captureSession) { + this.captureSession.release() + .catch((err: BusinessError) => { + Logger.error(`avRecorder release failed, code=${err.code}, message=${err.message}`) + }) + } + if (this.captureSession) { + this.captureSession = undefined; } } } diff --git a/HDRVivid/AVRecorder/entry/src/main/ets/utils/FileUtil.ets b/HDRVivid/AVRecorder/entry/src/main/ets/utils/FileUtil.ets index bb9612f426d8c207e6088c6790d0d36b73546310..e59fbb47ac512da8ffa575351d3ad1e69349da69 100644 --- a/HDRVivid/AVRecorder/entry/src/main/ets/utils/FileUtil.ets +++ b/HDRVivid/AVRecorder/entry/src/main/ets/utils/FileUtil.ets @@ -14,17 +14,23 @@ */ import { fileIo } from '@kit.CoreFileKit'; +import { BusinessError } from '@kit.BasicServicesKit'; import Logger from './Logger'; export class FileUtil { // Create and open a file. - static createOrOpen(path: string): fileIo.File { - let isExist = fileIo.accessSync(path); - let file: fileIo.File; - if (isExist) { - file = fileIo.openSync(path, fileIo.OpenMode.READ_WRITE); - } else { - file = fileIo.openSync(path, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE); + static createOrOpen(path: string): fileIo.File | null { + let file: fileIo.File | null = null; + try { + let isExist = fileIo.accessSync(path); + if (isExist) { + file = fileIo.openSync(path, fileIo.OpenMode.READ_WRITE); + } else { + file = fileIo.openSync(path, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE); + } + } catch (error) { + let err = error as BusinessError; + Logger.warn('testTag', `setColorMode failed, code=${err.code}, message=${err.message}`); } return file; } diff --git a/HDRVivid/AVRecorder/entry/src/main/module.json5 b/HDRVivid/AVRecorder/entry/src/main/module.json5 index 5e47c59345ea7e4f925cf0090df81791fecb34de..e01bc73d5992063f09ae169a369d1cac681c06b2 100644 --- a/HDRVivid/AVRecorder/entry/src/main/module.json5 +++ b/HDRVivid/AVRecorder/entry/src/main/module.json5 @@ -5,9 +5,7 @@ "description": "$string:module_desc", "mainElement": "EntryAbility", "deviceTypes": [ - "phone", - "tablet", - "2in1" + "phone" ], "deliveryWithInstall": true, "installationFree": false, diff --git a/HDRVivid/ProcessingInterfaceTest/README.md b/HDRVivid/ProcessingInterfaceTest/README.md new file mode 100644 index 0000000000000000000000000000000000000000..654ef69d9408731236c7ba2e1352fe190fe296ed --- /dev/null +++ b/HDRVivid/ProcessingInterfaceTest/README.md @@ -0,0 +1,32 @@ +# HDR Vivid视频转码成SDR视频 + +### 简介 + +该sample只做HDR Vivid视频转码成SDR视频的代码同源使用。 + + +### 相关权限 + +不涉及 + +### 使用说明 + +1. 打开应用,点击视频处理,进入视频处理页面,点击选择视频,进入视频选择界面,选择HDR Vivid视频后,点击选项,选择SDR视频选项,点击生成,可将视频转码为SDR视频 + +### 约束与限制 + +1. 本示例仅支持标准系统上运行,支持设备:华为手机。 +2. HarmonyOS系统:HarmonyOS 5.0.5 Release及以上。 +3. DevEco Studio版本:DevEco Studio 5.0.5 Release及以上。 +4. HarmonyOS SDK版本:HarmonyOS 5.0.5 Release SDK及以上。 + +### 下载 + +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set HDRVivid/ProcessingInterfaceTest +git checkout +``` diff --git a/HDRVivid/ProcessingInterfaceTest/build-profile.json5 b/HDRVivid/ProcessingInterfaceTest/build-profile.json5 index c033ce4278fb0641d84107c3c134047ac487368e..b2ca56e35558b0dc7ca91989b68a1ea65b49a7a2 100644 --- a/HDRVivid/ProcessingInterfaceTest/build-profile.json5 +++ b/HDRVivid/ProcessingInterfaceTest/build-profile.json5 @@ -5,7 +5,8 @@ { "name": "default", "signingConfig": "default", - "compatibleSdkVersion": "5.0.0(12)", + "compatibleSdkVersion": "5.0.5(17)", + "targetSdkVersion": "5.0.5(17)", "runtimeOS": "HarmonyOS", } ], diff --git a/HDRVivid/ProcessingInterfaceTest/entry/src/main/ets/entryability/EntryAbility.ets b/HDRVivid/ProcessingInterfaceTest/entry/src/main/ets/entryability/EntryAbility.ets index eb96be48b7ceb49cc0f99f1b1c0e4b3091dea94e..9d78462e2b3071c17a1352fbe6595c126566d068 100644 --- a/HDRVivid/ProcessingInterfaceTest/entry/src/main/ets/entryability/EntryAbility.ets +++ b/HDRVivid/ProcessingInterfaceTest/entry/src/main/ets/entryability/EntryAbility.ets @@ -22,8 +22,6 @@ import Logger from '../utils/Logger'; import { WindowUtil } from '../utils/WindowUtil'; export default class EntryAbility extends UIAbility { - private uiContext: UIContext | null = null; - onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { GlobalContext.getContext().setObject('context', this.context) hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate'); diff --git a/HDRVivid/ProcessingInterfaceTest/entry/src/main/ets/pages/Index.ets b/HDRVivid/ProcessingInterfaceTest/entry/src/main/ets/pages/Index.ets index b571c953a512a777dab94ee404e45b8c0ed1295c..b32d8f3082c7d2074589cc643530ebe7dc63e576 100644 --- a/HDRVivid/ProcessingInterfaceTest/entry/src/main/ets/pages/Index.ets +++ b/HDRVivid/ProcessingInterfaceTest/entry/src/main/ets/pages/Index.ets @@ -14,6 +14,7 @@ */ import { router } from '@kit.ArkUI'; +import { BusinessError } from '@kit.BasicServicesKit'; import Logger from '../utils/Logger'; const TAG: string = 'PickerPage'; @@ -34,9 +35,16 @@ struct Index { .borderRadius(10) .onClick(() => { Logger.info(TAG, 'Picker init VideoPage ') - this.uiContext.getRouter().pushUrl({ - url: 'pages/VideoPage', - }, router.RouterMode.Standard); + this.uiContext.getRouter() + .pushUrl({ + url: 'pages/VideoPage', + }, router.RouterMode.Standard) + .then(() => { + Logger.info(TAG, 'pushUrl success'); + }) + .catch((err: BusinessError) => { + Logger.warn(TAG, `pushUrl failed, code=${err.code}, message=${err.message}`) + }) }) .margin('30') if (this.showProgressBar) { diff --git a/HDRVivid/ProcessingInterfaceTest/entry/src/main/ets/pages/VideoPage.ets b/HDRVivid/ProcessingInterfaceTest/entry/src/main/ets/pages/VideoPage.ets index 20ac72778a1f9ba8aef1f6a064bf911590afd1da..79a754873bb57f2cf6c89f09acee0f454dee582e 100644 --- a/HDRVivid/ProcessingInterfaceTest/entry/src/main/ets/pages/VideoPage.ets +++ b/HDRVivid/ProcessingInterfaceTest/entry/src/main/ets/pages/VideoPage.ets @@ -68,22 +68,30 @@ struct VideoPage { controlDst: XComponentController = new XComponentController() preload() { - let inputFile = fileIo.openSync(this.myUris, fileIo.OpenMode.READ_ONLY); - let inputFileState = fileIo.statSync(inputFile.fd); - let msg: string = player.preload(inputFile.fd, inputFileState.size); - this.hdrMode = msg; - if (msg.includes('HDRVivid HLG')) { - this.canConvertVividPQ = true; - this.canConvertSDR = true; - } else if (msg.includes('HDRVivid PQ')) { - this.canConvertVividHLG = true; - this.canConvertSDR = true; - } else if (msg.includes('HDR')) { - this.canConvertHLG = true; - } else if (msg.includes('SDR')) { - this.canConvertSDR = true; + try { + let inputFile = fileIo.openSync(this.myUris, fileIo.OpenMode.READ_ONLY); + let inputFileState = fileIo.statSync(inputFile.fd); + let msg: string = player.preload(inputFile.fd, inputFileState.size); + this.hdrMode = msg; + if (msg.includes('HDRVivid HLG')) { + this.canConvertVividPQ = true; + this.canConvertSDR = true; + } else if (msg.includes('HDRVivid PQ')) { + this.canConvertVividHLG = true; + this.canConvertSDR = true; + } else if (msg.includes('HDR')) { + this.canConvertHLG = true; + } else if (msg.includes('SDR')) { + this.canConvertSDR = true; + } + fileIo.close(inputFile) + .catch((err: BusinessError) => { + Logger.error(`fileIo close failed, code=${err.code}, message=${err.message}`) + }) + } catch (error) { + let err = error as BusinessError; + Logger.error(`fileIo openSync or statSync failed, code=${err.code}, message=${err.message}`); } - fileIo.close(inputFile); } async callFilePickerSelectImage(): Promise { @@ -134,17 +142,27 @@ struct VideoPage { } play() { - let inputFile = fileIo.openSync(this.myUris, fileIo.OpenMode.READ_ONLY); - let inputFile2 = fileIo.openSync(this.myUris, fileIo.OpenMode.READ_ONLY); - - let inputFileState = fileIo.statSync(inputFile.fd); - let inputFileState2 = fileIo.statSync(inputFile2.fd); - player.playNative(inputFile.fd, 0, inputFileState.size, 0, this.targetVal, this.targetMetadata, () => { - fileIo.close(inputFile); - }) - player.playNative(inputFile2.fd, 0, inputFileState2.size, 1, this.targetVal, this.targetMetadata, () => { - fileIo.close(inputFile2); - }) + try { + let inputFile = fileIo.openSync(this.myUris, fileIo.OpenMode.READ_ONLY); + let inputFile2 = fileIo.openSync(this.myUris, fileIo.OpenMode.READ_ONLY); + let inputFileState = fileIo.statSync(inputFile.fd); + let inputFileState2 = fileIo.statSync(inputFile2.fd); + player.playNative(inputFile.fd, 0, inputFileState.size, 0, this.targetVal, this.targetMetadata, () => { + fileIo.close(inputFile) + .catch((err: BusinessError) => { + Logger.warn(`fileIo close failed, code=${err.code}, message=${err.message}`) + }) + }) + player.playNative(inputFile2.fd, 0, inputFileState2.size, 1, this.targetVal, this.targetMetadata, () => { + fileIo.close(inputFile2) + .catch((err: BusinessError) => { + Logger.warn(`fileIo close failed, code=${err.code}, message=${err.message}`) + }) + }) + } catch (error) { + let err = error as BusinessError; + Logger.warn(`fileIo openSync or statSync failed, code=${err.code}, message=${err.message}`); + } } @Builder @@ -199,7 +217,7 @@ struct VideoPage { }).margin('30px') Button('选项') .bindMenu(this.ColorSpaceMenu()) - Button('点击播放').onClick(() => { + Button('生成').onClick(() => { if (this.myUris != '') { this.play() } @@ -208,22 +226,6 @@ struct VideoPage { Text('视频类型:' + this.hdrMode) Text('目标格式:' + this.targetType) - Text('src video') - XComponent({ - id: 'srcPlayer', - type: XComponentType.SURFACE, - libraryname: 'player' - }).width(this.isCalcWHFinished ? this.surfaceW : '90%').height(this.isCalcWHFinished ? this.surfaceH : '30%') - .onClick(() => { - }) - Text('dst video') - XComponent({ - id: 'dstPlayer', - type: XComponentType.SURFACE, - libraryname: 'player' - }).width(this.isCalcWHFinished ? this.surfaceW : '90%').height(this.isCalcWHFinished ? this.surfaceH : '30%') - .onClick(() => { - }) } .height('100%') .width('100%') diff --git a/HDRVivid/ProcessingInterfaceTest/entry/src/main/ets/utils/AVPlayerDemo.ets b/HDRVivid/ProcessingInterfaceTest/entry/src/main/ets/utils/AVPlayerDemo.ets index 7ea4669533fdb10e8d700aed71ebfb11fcfce371..262a68852dee8a7686f91bd7a3dec8984191a188 100644 --- a/HDRVivid/ProcessingInterfaceTest/entry/src/main/ets/utils/AVPlayerDemo.ets +++ b/HDRVivid/ProcessingInterfaceTest/entry/src/main/ets/utils/AVPlayerDemo.ets @@ -19,17 +19,19 @@ import { common } from '@kit.AbilityKit'; import { BusinessError } from '@kit.BasicServicesKit'; import Logger from '../utils/Logger'; import { SizeChangeListener } from '../utils/SizeChangeInterface'; +import { resourceManager } from '@kit.LocalizationKit'; const TAG: string = 'AVPlayerDemo'; export class AVPlayerDemo { private count: number = 0; - private surfaceID: string = ''; // surfaceID用于播放画面显示,具体的值需要通过Xcomponent接口获取,相关文档链接见上面Xcomponent创建方法 + private surfaceID: string = ''; // surfaceID用于播放画面显示,具体的值需要通过XComponent接口获取,相关文档链接见上面XComponent创建方法 private isSeek: boolean = true; // 用于区分模式是否支持seek操作 private fileSize: number = -1; private fd: number = 0; private avPlayer: media.AVPlayer | undefined = undefined private UIContext: UIContext + constructor(uiContext: UIContext) { this.UIContext = uiContext } @@ -48,14 +50,20 @@ export class AVPlayerDemo { // error回调监听函数,当avPlayer在操作过程中出现错误时调用reset接口触发重置流程 avPlayer.on('error', (err: BusinessError) => { Logger.error(`Invoke avPlayer failed, code is ${err.code}, message is ${err.message}`); - avPlayer.reset(); // 调用reset重置资源,触发idle状态 + avPlayer.reset() // 调用reset重置资源,触发idle状态 + .catch((err: BusinessError) => { + Logger.error(`avPlayer reset failed, code=${err.code}, message=${err.message}`) + }) }) // 状态机变化回调函数 - avPlayer.on('stateChange', async (state: string, reason: media.StateChangeReason) => { + avPlayer.on('stateChange', async (state: string, _reason: media.StateChangeReason) => { switch (state) { case 'idle': // 成功调用reset接口后触发该状态机上报 Logger.info(TAG, 'AVPlayer state idle called.'); - avPlayer.release(); // 调用release接口销毁实例对象 + avPlayer.release() // 调用release接口销毁实例对象 + .catch((err: BusinessError) => { + Logger.error(`avPlayer release failed, code=${err.code}, message=${err.message}`) + }) break; case 'initialized': // avplayer 设置播放源后触发该状态上报 Logger.info(TAG, 'AVPlayer state initialized called.'); @@ -63,12 +71,17 @@ export class AVPlayerDemo { Logger.debug(TAG, 'surfaceID ' + this.surfaceID) avPlayer.surfaceId = this.surfaceID; - avPlayer.prepare(); - + avPlayer.prepare() + .catch((err: BusinessError) => { + Logger.error(`avPlayer prepare failed, code=${err.code}, message=${err.message}`) + }) break; case 'prepared': // prepare调用成功后上报该状态机 Logger.info(TAG, 'AVPlayer state prepared called.'); - avPlayer.play(); // 调用播放接口开始播放 + avPlayer.play() // 调用播放接口开始播放 + .catch((err: BusinessError) => { + Logger.error(`avPlayer play failed, code=${err.code}, message=${err.message}`) + }) Logger.warn(TAG, ' avPlayer surface size ' + avPlayer.width + ' ' + avPlayer.height) callback.onChange(avPlayer.width, avPlayer.height) @@ -84,21 +97,33 @@ export class AVPlayerDemo { Logger.info(TAG, 'AVPlayer wait to play end.'); } } else { - avPlayer.pause(); // 调用暂停接口暂停播放 + avPlayer.pause() // 调用暂停接口暂停播放 + .catch((err: BusinessError) => { + Logger.error(`avPlayer pause failed, code=${err.code}, message=${err.message}`) + }) } this.count++; break; case 'paused': // pause成功调用后触发该状态机上报 Logger.info(TAG, 'AVPlayer state paused called.'); - avPlayer.play(); // 再次播放接口开始播放 + avPlayer.play() // 再次播放接口开始播放 + .catch((err: BusinessError) => { + Logger.error(`avPlayer play failed, code=${err.code}, message=${err.message}`) + }) break; case 'completed': // 播放结束后触发该状态机上报 Logger.info(TAG, 'AVPlayer state completed called.'); - avPlayer.stop(); //调用播放结束接口 + avPlayer.stop() //调用播放结束接口 + .catch((err: BusinessError) => { + Logger.error(`avPlayer stop failed, code=${err.code}, message=${err.message}`) + }) break; case 'stopped': // stop接口成功调用后触发该状态机上报 Logger.info(TAG, 'AVPlayer state stopped called.'); - avPlayer.reset(); // 调用reset接口初始化avplayer状态 + avPlayer.reset() // 调用reset接口初始化avplayer状态 + .catch((err: BusinessError) => { + Logger.error(`avPlayer reset failed, code=${err.code}, message=${err.message}`) + }) break; case 'released': Logger.info(TAG, 'AVPlayer state released called.'); @@ -111,7 +136,7 @@ export class AVPlayerDemo { } private callback: SizeChangeListener = { - onChange: (width: number, height: number): void => { + onChange: (_width: number, _height: number): void => { } } @@ -125,45 +150,73 @@ export class AVPlayerDemo { Logger.debug(TAG, 'avPlayerUrlDemo ..... surface id ' + surfaceId); this.surfaceID = surfaceId; // 创建avPlayer实例对象 - this.avPlayer = await media.createAVPlayer(); - - // 创建状态机变化回调函数 - this.setAVPlayerCallback(this.avPlayer, callBack); + // this.avPlayer = await media.createAVPlayer(); + await media.createAVPlayer() + .then((data: media.AVPlayer) => { + this.avPlayer = data; + // 创建状态机变化回调函数 + this.setAVPlayerCallback(data, callBack); + }) + .catch((err: BusinessError) => { + Logger.error(`createAVPlayer failed, code=${err.code}, message=${err.message}`) + }) let fdPath = 'fd://'; // 通过UIAbilityContext获取沙箱地址filesDir,以Stage模型为例 // 打开相应的资源文件地址获取fd,并为url赋值触发initialized状态机上报 - let file = await fileIo.open(filePath, fileIo.OpenMode.READ_ONLY); - // let pathDir = context.filesDir +''+'VID_20240805_094821.mp4'; - // Logger.debug(TAG,pathDir) - fdPath = fdPath + '' + file.fd; - this.isSeek = true; // 支持seek操作 - this.avPlayer.url = fdPath; - + await fileIo.open(filePath, fileIo.OpenMode.READ_ONLY) + .then((data: fileIo.File) => { + // let pathDir = context.filesDir +''+'VID_20240805_094821.mp4'; + // Logger.debug(TAG,pathDir) + fdPath = fdPath + '' + data.fd; + this.isSeek = true; // 支持seek操作 + this.avPlayer!.url = fdPath; + }) + .catch((err: BusinessError) => { + Logger.error(`fileIo open failed, code=${err.code}, message=${err.message}`) + }) } // 以下demo为使用资源管理接口获取打包在HAP内的媒体资源文件并通过fdSrc属性进行播放示例 async avPlayerFdSrcDemo() { // 创建avPlayer实例对象 - this.avPlayer = await media.createAVPlayer(); - // 创建状态机变化回调函数 - this.setAVPlayerCallback(this.avPlayer, this.callback); + // this.avPlayer = await media.createAVPlayer(); + await media.createAVPlayer() + .then((data: media.AVPlayer) => { + this.avPlayer = data; + // 创建状态机变化回调函数 + this.setAVPlayerCallback(data, this.callback); + }) + .catch((err: BusinessError) => { + Logger.error(`createAVPlayer failed, code=${err.code}, message=${err.message}`) + }) // 通过UIAbilityContext的resourceManager成员的getRawFd接口获取媒体资源播放地址 // 返回类型为{fd,offset,length},fd为HAP包fd地址,offset为媒体资源偏移量,length为播放长度 let context = this.UIContext.getHostContext() as common.UIAbilityContext; - let fileDescriptor = await context.resourceManager.getRawFd('H264_AAC.mp4'); - let avFileDescriptor: media.AVFileDescriptor = - { fd: fileDescriptor.fd, offset: fileDescriptor.offset, length: fileDescriptor.length }; - this.isSeek = true; // 支持seek操作 - // 为fdSrc赋值触发initialized状态机上报 - this.avPlayer.fdSrc = avFileDescriptor; + await context.resourceManager.getRawFd('H264_AAC.mp4') + .then((data: resourceManager.RawFileDescriptor) => { + let avFileDescriptor: media.AVFileDescriptor = { fd: data.fd, offset: data.offset, length: data.length }; + this.isSeek = true; // 支持seek操作 + // 为fdSrc赋值触发initialized状态机上报 + this.avPlayer!.fdSrc = avFileDescriptor; + }) + .catch((err: BusinessError) => { + Logger.error(`setPreferredOrientation failed, code=${err.code}, message=${err.message}`) + }) } // 以下demo为使用fs文件系VideoPage.ets统打开沙箱地址获取媒体文件地址并通过dataSrc属性进行播放(seek模式)示例 async avPlayerDataSrcSeekDemo() { // 创建avPlayer实例对象 - let avPlayer: media.AVPlayer = await media.createAVPlayer(); - // 创建状态机变化回调函数 - this.setAVPlayerCallback(avPlayer, this.callback); + // let avPlayer: media.AVPlayer = await media.createAVPlayer(); + await media.createAVPlayer() + .then((avPlayer: media.AVPlayer) => { + this.avPlayer = avPlayer; + // 创建状态机变化回调函数 + this.setAVPlayerCallback(avPlayer, this.callback); + }) + .catch((err: BusinessError) => { + Logger.error(`createAVPlayer failed, code=${err.code}, message=${err.message}`) + }) // dataSrc播放模式的的播放源地址,当播放为Seek模式时fileSize为播放文件的具体大小,下面会对fileSize赋值 let src: media.AVDataSrcDescriptor = { fileSize: -1, @@ -172,7 +225,12 @@ export class AVPlayerDemo { if (buf == undefined || length == undefined || pos == undefined) { return -1; } - num = fileIo.readSync(this.fd, buf, { offset: pos, length: length }); + try { + num = fileIo.readSync(this.fd, buf, { offset: pos, length: length }); + } catch (error) { + let err = error as BusinessError; + Logger.error(`fileIo failed, code=${err.code}, message=${err.message}`); + } if (num > 0 && (this.fileSize >= pos)) { return num; } @@ -183,14 +241,23 @@ export class AVPlayerDemo { // 通过UIAbilityContext获取沙箱地址filesDir,以Stage模型为例 let pathDir = context.filesDir; let path = pathDir + '/H264_AAC.mp4'; - await fileIo.open(path).then((file: fileIo.File) => { - this.fd = file.fd; - }) - // 获取播放文件的大小 - this.fileSize = fileIo.statSync(path).size; + await fileIo.open(path) + .then((file: fileIo.File) => { + this.fd = file.fd; + }) + .catch((err: BusinessError) => { + Logger.error(`fileIo open failed, code=${err.code}, message=${err.message}`) + }) + try { + // 获取播放文件的大小 + this.fileSize = fileIo.statSync(path).size; + } catch (error) { + let err = error as BusinessError; + Logger.error(`setColorMode failed, code=${err.code}, message=${err.message}`); + } src.fileSize = this.fileSize; this.isSeek = true; // 支持seek操作 - avPlayer.dataSrc = src; + this.avPlayer!.dataSrc = src; } // 以下demo为使用fs文件系统打开沙箱地址获取媒体文件地址并通过dataSrc属性进行播放(No seek模式)示例 @@ -198,16 +265,27 @@ export class AVPlayerDemo { this.surfaceID = surfaceId // 创建状态机变化回调函数 - let file = await fileIo.open(filePath, fileIo.OpenMode.READ_ONLY); - if (!file) { - Logger.error(TAG, 'player inputFile is null'); - } - let inputFileState = fileIo.statSync(file.fd); - if (inputFileState.size <= 0) { - Logger.error(TAG, 'player inputFile size is 0'); - } - Logger.info(TAG, 'inputFileState size ' + inputFileState.size); - this.fd = file.fd; + // let file = await fileIo.open(filePath, fileIo.OpenMode.READ_ONLY); + await fileIo.open(filePath, fileIo.OpenMode.READ_ONLY) + .then((file: fileIo.File) => { + if (!file) { + Logger.error(TAG, 'player inputFile is null'); + } + try { + let inputFileState = fileIo.statSync(file.fd); + if (inputFileState.size <= 0) { + Logger.error(TAG, 'player inputFile size is 0'); + } + Logger.info(TAG, 'inputFileState size ' + inputFileState.size); + } catch (error) { + let err = error as BusinessError; + Logger.error(`setColorMode failed, code=${err.code}, message=${err.message}`); + } + this.fd = file.fd; + }) + .catch((err: BusinessError) => { + Logger.error(`setPreferredOrientation failed, code=${err.code}, message=${err.message}`) + }) Logger.debug(TAG, 'fd --- ' + this.fd); let src: media.AVDataSrcDescriptor = { fileSize: -1, @@ -216,48 +294,74 @@ export class AVPlayerDemo { if (buf == undefined || length == undefined || pos == undefined) { return -1; } - num = fileIo.readSync(this.fd, buf, { offset: pos, length: length }); + try { + num = fileIo.readSync(this.fd, buf, { offset: pos, length: length }); + } catch (error) { + let err = error as BusinessError; + Logger.warn(`setColorMode failed, code=${err.code}, message=${err.message}`); + } if (num > 0 && (this.fileSize >= pos)) { return num; } return -1; } } - - // 创建avPlayer实例对象 - this.avPlayer = await media.createAVPlayer(); - this.setAVPlayerCallback(this.avPlayer, this.callback); - // 获取播放文件的大小 - this.fileSize = fileIo.statSync(filePath).size; + try { + // 创建avPlayer实例对象 + this.avPlayer = await media.createAVPlayer(); + this.setAVPlayerCallback(this.avPlayer, this.callback); + } catch (error) { + let err = error as BusinessError; + Logger.warn(`createAVPlayer failed, code=${err.code}, message=${err.message}`); + } + try { + // 获取播放文件的大小 + this.fileSize = fileIo.statSync(filePath).size; + } catch (error) { + let err = error as BusinessError; + Logger.warn(`createAVPlayer failed, code=${err.code}, message=${err.message}`); + } src.fileSize = this.fileSize; this.isSeek = true; // 支持seek操作 - this.avPlayer.dataSrc = src; - + this.avPlayer!.dataSrc = src; } // 以下demo为通过url设置网络地址来实现播放直播码流的demo async avPlayerLiveDemo() { - // 创建avPlayer实例对象 - let avPlayer: media.AVPlayer = await media.createAVPlayer(); - // 创建状态机变化回调函数 - this.setAVPlayerCallback(avPlayer, this.callback); - this.isSeek = false; // 不支持seek操作 - avPlayer.url = 'http://xxx.xxx.xxx.xxx:xx/xx/index.m3u8'; // 播放hls网络直播码流 + try { + // 创建avPlayer实例对象 + let avPlayer: media.AVPlayer = await media.createAVPlayer(); + // 创建状态机变化回调函数 + this.setAVPlayerCallback(avPlayer, this.callback); + this.isSeek = false; // 不支持seek操作 + avPlayer.url = 'http://xxx.xxx.xxx.xxx:xx/xx/index.m3u8'; // 播放hls网络直播码流 + } catch (error) { + let err = error as BusinessError; + Logger.error(`createAVPlayer failed, code=${err.code}, message=${err.message}`); + } } // 以下demo为通过setMediaSource设置自定义头域及媒体播放优选参数实现初始播放参数设置 async preDownloadDemo() { - // 创建avPlayer实例对象 - let avPlayer: media.AVPlayer = await media.createAVPlayer(); - let mediaSource: media.MediaSource = - media.createMediaSourceWithUrl('http://xxx', { 'User-Agent': 'User-Agent-Value' }); - let playbackStrategy: media.PlaybackStrategy = { - preferredWidth: 1, - preferredHeight: 2, - preferredBufferDuration: 3, - preferredHdr: false - }; - // 设置媒体来源和播放策略 - avPlayer.setMediaSource(mediaSource, playbackStrategy); + try { + // 创建avPlayer实例对象 + let avPlayer: media.AVPlayer = await media.createAVPlayer(); + let mediaSource: media.MediaSource = + media.createMediaSourceWithUrl('http://xxx', { 'User-Agent': 'User-Agent-Value' }); + let playbackStrategy: media.PlaybackStrategy = { + preferredWidth: 1, + preferredHeight: 2, + preferredBufferDuration: 3, + preferredHdr: false + }; + // 设置媒体来源和播放策略 + avPlayer.setMediaSource(mediaSource, playbackStrategy) + .catch((err: BusinessError) => { + Logger.error(`setMediaSource failed, code=${err.code}, message=${err.message}`) + }) + } catch (error) { + let err = error as BusinessError; + Logger.error(`createAVPlayer or createMediaSourceWithUrl failed, code=${err.code}, message=${err.message}`); + } } } \ No newline at end of file diff --git a/HDRVivid/ProcessingInterfaceTest/entry/src/main/ets/utils/WindowUtil.ets b/HDRVivid/ProcessingInterfaceTest/entry/src/main/ets/utils/WindowUtil.ets index 62fe5a4403c1012ffd416bbdec729e001612961f..bd06b5798e2ece26ffc400888c184a8b7284a370 100644 --- a/HDRVivid/ProcessingInterfaceTest/entry/src/main/ets/utils/WindowUtil.ets +++ b/HDRVivid/ProcessingInterfaceTest/entry/src/main/ets/utils/WindowUtil.ets @@ -13,7 +13,7 @@ * limitations under the License. */ -import { deviceInfo } from '@kit.BasicServicesKit'; +import { BusinessError, deviceInfo } from '@kit.BasicServicesKit'; import { window } from '@kit.ArkUI'; import { CommonConstants } from '../utils/CommonConstants'; import Logger from './Logger'; @@ -49,9 +49,15 @@ export class WindowUtil { return; } if (deviceInfo.deviceType !== CommonConstants.DEVICE_TYPES[0] && deviceInfo.deviceType !== - CommonConstants.DEVICE_TYPES[1]) { + CommonConstants.DEVICE_TYPES[1]) { // Set portrait display. - this.mainWindowClass.setPreferredOrientation(window.Orientation.PORTRAIT); + this.mainWindowClass.setPreferredOrientation(window.Orientation.PORTRAIT) + .then(() => { + Logger.info('setPreferredOrientation success'); + }) + .catch((err: BusinessError) => { + Logger.error(`setPreferredOrientation failed, code=${err.code}, message=${err.message}`) + }) } }); } @@ -62,7 +68,13 @@ export class WindowUtil { return; } // Setting orientation. - this.mainWindowClass.setPreferredOrientation(orientation); + this.mainWindowClass.setPreferredOrientation(orientation) + .then(() => { + Logger.info('setPreferredOrientation success'); + }) + .catch((err: BusinessError) => { + Logger.error(`setPreferredOrientation failed, code=${err.code}, message=${err.message}`) + }) } disableWindowSystemBar(): void { @@ -71,7 +83,13 @@ export class WindowUtil { return; } // Set the status bar and navigation bar to be invisible in full-screen mode. - this.mainWindowClass.setWindowSystemBarEnable([]); + this.mainWindowClass.setWindowSystemBarEnable([]) + .then(() => { + Logger.info('setWindowSystemBarEnable success'); + }) + .catch((err: BusinessError) => { + Logger.error(`setWindowSystemBarEnable failed, code=${err.code}, message=${err.message}`) + }) } enableWindowSystemBar(): void { @@ -79,7 +97,13 @@ export class WindowUtil { Logger.error(`MainWindowClass is undefined`); return; } - this.mainWindowClass.setWindowSystemBarEnable(['status', 'navigation']); + this.mainWindowClass.setWindowSystemBarEnable(['status', 'navigation']) + .then(() => { + Logger.info('setWindowSystemBarEnable success'); + }) + .catch((err: BusinessError) => { + Logger.error(`setWindowSystemBarEnable failed, code=${err.code}, message=${err.message}`) + }) } setFullScreen(): void { @@ -88,7 +112,13 @@ export class WindowUtil { return; } // Set full-screen display. - this.mainWindowClass.setWindowLayoutFullScreen(true); + this.mainWindowClass.setWindowLayoutFullScreen(true) + .then(() => { + Logger.info('setWindowLayoutFullScreen success'); + }) + .catch((err: BusinessError) => { + Logger.error(`setWindowLayoutFullScreen failed, code=${err.code}, message=${err.message}`) + }) } getMainWindow(): window.Window | undefined { diff --git a/HapAndHarDependHar/.hvigor/cache/meta.json b/HapAndHarDependHar/.hvigor/cache/meta.json index 18f86af95573be1ca58a8494f7aac0c780d0dfac..1360b2dbb29f98881beead7e162fb2e185454a53 100644 --- a/HapAndHarDependHar/.hvigor/cache/meta.json +++ b/HapAndHarDependHar/.hvigor/cache/meta.json @@ -1 +1 @@ -{"compileSdkVersion":"5.0.4(16)","hvigorVersion":"5.16.2","toolChainsVersion":"5.0.4.150"} +{"compileSdkVersion":"6.0.0(20)","hvigorVersion":"6.0.5","toolChainsVersion":"6.0.0.47"} diff --git a/HapAndHarDependHar/.hvigor/dependencyMap/dependencyMap.json5 b/HapAndHarDependHar/.hvigor/dependencyMap/dependencyMap.json5 index 6191c684f34e99dec105c3e9f59200c85fe9b0a0..956b633bf3016e11b6da6833729dd1e52c1b9456 100644 --- a/HapAndHarDependHar/.hvigor/dependencyMap/dependencyMap.json5 +++ b/HapAndHarDependHar/.hvigor/dependencyMap/dependencyMap.json5 @@ -1 +1 @@ -{"basePath":"C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\.hvigor\\dependencyMap\\dependencyMap.json5","rootDependency":"./oh-package.json5","dependencyMap":{"entry":"./entry/oh-package.json5","har_library":"./har_library/oh-package.json5","har_common":"./har_common/oh-package.json5"},"modules":[{"name":"entry","srcPath":"..\\..\\..\\entry"},{"name":"har_library","srcPath":"..\\..\\..\\har_library"},{"name":"har_common","srcPath":"..\\..\\..\\har_common"}]} \ No newline at end of file +{"basePath":"D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\.hvigor\\dependencyMap\\dependencyMap.json5","rootDependency":"./oh-package.json5","dependencyMap":{"entry":"./entry/oh-package.json5","har_library":"./har_library/oh-package.json5","har_common":"./har_common/oh-package.json5"},"modules":[{"name":"entry","srcPath":"..\\..\\..\\entry"},{"name":"har_library","srcPath":"..\\..\\..\\har_library"},{"name":"har_common","srcPath":"..\\..\\..\\har_common"}]} \ No newline at end of file diff --git a/HapAndHarDependHar/.hvigor/outputs/build-logs/build.log b/HapAndHarDependHar/.hvigor/outputs/build-logs/build.log index 6ba93e9cbcc7d69490968f1654248a2a1abd504c..0169987cdc032c198311a86e9f0664cb096e1829 100644 --- a/HapAndHarDependHar/.hvigor/outputs/build-logs/build.log +++ b/HapAndHarDependHar/.hvigor/outputs/build-logs/build.log @@ -215,3 +215,238 @@ [2025-05-20T17:23:29.393] [DEBUG] debug-file - HapAndHarDependHar : init cost memory 0.00902557373046875 [2025-05-20T17:23:29.394] [DEBUG] debug-file - runTaskFromQueue task cost before running: 2 s 899 ms [2025-05-20T17:23:29.394] [INFO] debug-file - Finished ::init... after 1 ms +[2025-09-19T17:16:10.765] [DEBUG] debug-file - env: nodejsVersion=v18.20.1 +[2025-09-19T17:16:11.143] [DEBUG] debug-file - Hvigor init with startParameters:{ + hvigorfileTypeCheck: false, + parallelExecution: true, + incrementalExecution: true, + printStackTrace: false, + daemon: false, + analyze: 0, + logLevel: Level { level: 20000, levelStr: 'INFO', colour: 'green' }, + optimizationStrategy: 'memory', + hotCompile: undefined, + hotReloadBuild: undefined +} +[2025-09-19T17:16:12.600] [DEBUG] debug-file - hvigorfile, require result: { default: { system: [Function: appTasks], plugins: [] } } +[2025-09-19T17:16:12.770] [DEBUG] debug-file - Start initialize project's product build option map with build mode debug. +[2025-09-19T17:16:12.774] [DEBUG] debug-file - Obtain build option for product 'default'in this build. +[2025-09-19T17:16:12.791] [DEBUG] debug-file - Start recording SDK configuration permission data. +[2025-09-19T17:16:12.828] [DEBUG] debug-file - Project task initialization takes 5 ms +[2025-09-19T17:16:12.850] [DEBUG] debug-file - Start initialize module-target build option map, moduleName=entry, buildMode=debug +[2025-09-19T17:16:12.859] [DEBUG] debug-file - hvigorfile, resolving D:\toGit\BestPracticeSnippets\HapAndHarDependHar\har_library\hvigorfile.ts +[2025-09-19T17:16:12.920] [DEBUG] debug-file - Start to initialize dependency information. +[2025-09-19T17:16:10.766] [DEBUG] debug-file - env: hvigor-config.json5 content = { + modelVersion: '5.0.0', + dependencies: {}, + execution: {}, + logging: {}, + debugging: {}, + nodeOptions: {} +} +[2025-09-19T17:16:12.941] [DEBUG] debug-file - entry : clean cost memory 0.11110687255859375 +[2025-09-19T17:16:11.150] [DEBUG] debug-file - Since current hvigor version 6.0.5 differs from last hvigor version + 5.16.2, delete file-cache.json and task-cache.json. +[2025-09-19T17:16:12.960] [DEBUG] debug-file - Create resident worker with id: 0. +[2025-09-19T17:16:12.600] [DEBUG] debug-file - hvigorfile, binding system plugins [Function: appTasks] +[2025-09-19T17:16:12.770] [DEBUG] debug-file - Picking option from product 'default' with build mode 'debug'. +[2025-09-19T17:16:12.775] [DEBUG] debug-file - not found resModel json file in : D:\toGit\BestPracticeSnippets\HapAndHarDependHar\entry\src\ohosTest\module.json5 +[2025-09-19T17:16:12.822] [DEBUG] debug-file - Sdk init in 38 ms +[2025-09-19T17:16:12.828] [DEBUG] debug-file - hvigorfile, binding custom plugins [] +[2025-09-19T17:16:12.850] [DEBUG] debug-file - Target 'default' config initialized +[2025-09-19T17:16:12.863] [DEBUG] debug-file - hvigorfile, require result: { default: { system: [Function: harTasks], plugins: [] } } +[2025-09-19T17:16:12.927] [DEBUG] debug-file - Module entry Collected Dependency: D:\toGit\BestPracticeSnippets\HapAndHarDependHar\har_library,D:\toGit\BestPracticeSnippets\HapAndHarDependHar\har_common +[2025-09-19T17:16:10.768] [DEBUG] debug-file - env: daemon=false +[2025-09-19T17:16:11.151] [DEBUG] debug-file - Cache service initialization finished in 7 ms +[2025-09-19T17:16:12.941] [DEBUG] debug-file - runTaskFromQueue task cost before running: 1 s 804 ms +[2025-09-19T17:16:12.962] [DEBUG] debug-file - Create resident worker with id: 1. +[2025-09-19T17:16:12.770] [DEBUG] debug-file - Product 'default' build option initialized +[2025-09-19T17:16:12.781] [DEBUG] debug-file - not found resModel json file in : D:\toGit\BestPracticeSnippets\HapAndHarDependHar\har_library\src\ohosTest\module.json5 +[2025-09-19T17:16:12.828] [DEBUG] debug-file - hvigorfile, no custom plugins were found in D:\toGit\BestPracticeSnippets\HapAndHarDependHar\hvigorfile.ts +[2025-09-19T17:16:12.851] [DEBUG] debug-file - Target 'ohosTest' config initialized +[2025-09-19T17:16:12.927] [DEBUG] debug-file - Module entry's total dependency: 2 +[2025-09-19T17:16:10.768] [DEBUG] debug-file - no-daemon, use the parent process.execArgv --max-old-space-size=8192,--max-semi-space-size=16,--expose-gc +[2025-09-19T17:16:12.964] [DEBUG] debug-file - Current worker pool is stopped or closed. +[2025-09-19T17:16:12.863] [DEBUG] debug-file - hvigorfile, binding system plugins [Function: harTasks] +[2025-09-19T17:16:11.152] [DEBUG] debug-file - hvigorfile, resolving D:\toGit\BestPracticeSnippets\HapAndHarDependHar\hvigorfile.ts +[2025-09-19T17:16:12.942] [INFO] debug-file - Finished :entry:clean... after 2 ms +[2025-09-19T17:16:12.771] [DEBUG] debug-file - End initialize project's product build option map with build mode 'debug'. +[2025-09-19T17:16:12.783] [DEBUG] debug-file - not found resModel json file in : D:\toGit\BestPracticeSnippets\HapAndHarDependHar\har_common\src\ohosTest\module.json5 +[2025-09-19T17:16:12.828] [DEBUG] debug-file - hvigorfile, resolve finished D:\toGit\BestPracticeSnippets\HapAndHarDependHar\hvigorfile.ts +[2025-09-19T17:16:12.851] [DEBUG] debug-file - Module 'entry' target 'default' build option initialized +[2025-09-19T17:16:12.931] [DEBUG] debug-file - Start to initialize dependency information. +[2025-09-19T17:16:12.965] [DEBUG] debug-file - Clear worker 0. +[2025-09-19T17:16:12.864] [DEBUG] debug-file - failed to load cangjie to dynamically generate schemas: Error: Cannot find module '@ohos/cangjie-build-support/index' +Require stack: +- D:\Program Files\Huawei\DevEco Studio\tools\hvigor\hvigor-ohos-plugin\src\plugin\factory\plugin-factory.js +- D:\Program Files\Huawei\DevEco Studio\tools\hvigor\hvigor-ohos-plugin\index.js +- D:\toGit\BestPracticeSnippets\HapAndHarDependHar\hvigorfile.ts +- D:\Program Files\Huawei\DevEco Studio\tools\hvigor\hvigor\src\base\internal\lifecycle\configuration.js +- D:\Program Files\Huawei\DevEco Studio\tools\hvigor\hvigor\src\base\boot\index.js +- D:\Program Files\Huawei\DevEco Studio\tools\hvigor\hvigor\src\cli\main\cli.js +- D:\Program Files\Huawei\DevEco Studio\tools\hvigor\hvigor\bin\hvigor.js +[2025-09-19T17:16:12.942] [DEBUG] debug-file - Executing task :har_library:clean +[2025-09-19T17:16:12.784] [DEBUG] debug-file - No signingConfig found, initRemoteHspCache failed. +[2025-09-19T17:16:12.851] [DEBUG] debug-file - Module 'entry' target 'ohosTest' build option initialized +[2025-09-19T17:16:12.829] [DEBUG] debug-file - hvigorfile, resolving D:\toGit\BestPracticeSnippets\HapAndHarDependHar\entry\hvigorfile.ts +[2025-09-19T17:16:12.932] [DEBUG] debug-file - Module har_library Collected Dependency: D:\toGit\BestPracticeSnippets\HapAndHarDependHar\har_common +[2025-09-19T17:16:12.965] [DEBUG] debug-file - Worker 0 has been cleared. +[2025-09-19T17:16:12.895] [DEBUG] debug-file - Start initialize module-target build option map, moduleName=har_library, buildMode=debug +[2025-09-19T17:16:12.942] [DEBUG] debug-file - clean: Worker pool is inactive. +[2025-09-19T17:16:12.786] [DEBUG] debug-file - Local scan or download HarmonyOS sdk components toolchains,ets,js,native,previewer +[2025-09-19T17:16:12.851] [DEBUG] debug-file - End initialize module-target build option map, moduleName=entry +[2025-09-19T17:16:12.835] [DEBUG] debug-file - hvigorfile, require result: { default: { system: [Function: hapTasks], plugins: [] } } +[2025-09-19T17:16:12.932] [DEBUG] debug-file - Module har_library's total dependency: 1 +[2025-09-19T17:16:12.965] [DEBUG] debug-file - Current idle worker size: 1. +[2025-09-19T17:16:12.942] [DEBUG] debug-file - har_library : clean cost memory 0.0296478271484375 +[2025-09-19T17:16:12.895] [DEBUG] debug-file - Target 'default' config initialized +[2025-09-19T17:16:12.788] [DEBUG] debug-file - Local scan or download hmscore sdk components toolchains,ets,native +[2025-09-19T17:16:12.851] [DEBUG] debug-file - Start initialize module-target build option map, moduleName=entry, buildMode=release +[2025-09-19T17:16:12.835] [DEBUG] debug-file - hvigorfile, binding system plugins [Function: hapTasks] +[2025-09-19T17:16:12.934] [DEBUG] debug-file - Start to initialize dependency information. +[2025-09-19T17:16:12.965] [DEBUG] debug-file - Current busy worker size: 0. +[2025-09-19T17:16:12.895] [DEBUG] debug-file - Target 'ohosTest' config initialized +[2025-09-19T17:16:12.942] [DEBUG] debug-file - runTaskFromQueue task cost before running: 1 s 806 ms +[2025-09-19T17:16:12.851] [DEBUG] debug-file - Target 'default' config initialized +[2025-09-19T17:16:12.835] [DEBUG] debug-file - failed to load cangjie to dynamically generate schemas: Error: Cannot find module '@ohos/cangjie-build-support/index' +Require stack: +- D:\Program Files\Huawei\DevEco Studio\tools\hvigor\hvigor-ohos-plugin\src\plugin\factory\plugin-factory.js +- D:\Program Files\Huawei\DevEco Studio\tools\hvigor\hvigor-ohos-plugin\index.js +- D:\toGit\BestPracticeSnippets\HapAndHarDependHar\hvigorfile.ts +- D:\Program Files\Huawei\DevEco Studio\tools\hvigor\hvigor\src\base\internal\lifecycle\configuration.js +- D:\Program Files\Huawei\DevEco Studio\tools\hvigor\hvigor\src\base\boot\index.js +- D:\Program Files\Huawei\DevEco Studio\tools\hvigor\hvigor\src\cli\main\cli.js +- D:\Program Files\Huawei\DevEco Studio\tools\hvigor\hvigor\bin\hvigor.js +[2025-09-19T17:16:12.935] [DEBUG] debug-file - Module har_common Collected Dependency: +[2025-09-19T17:16:12.965] [DEBUG] debug-file - Clear worker 1. +[2025-09-19T17:16:12.896] [DEBUG] debug-file - Module 'har_library' target 'default' build option initialized +[2025-09-19T17:16:12.942] [INFO] debug-file - Finished :har_library:clean... after 1 ms +[2025-09-19T17:16:12.852] [DEBUG] debug-file - Target 'ohosTest' config initialized +[2025-09-19T17:16:12.935] [DEBUG] debug-file - Module har_common's total dependency: 0 +[2025-09-19T17:16:12.965] [DEBUG] debug-file - Worker 1 has been cleared. +[2025-09-19T17:16:12.896] [DEBUG] debug-file - Module 'har_library' target 'ohosTest' build option initialized +[2025-09-19T17:16:12.943] [DEBUG] debug-file - Executing task :har_common:clean +[2025-09-19T17:16:12.852] [DEBUG] debug-file - Module 'entry' target 'default' build option initialized +[2025-09-19T17:16:12.936] [DEBUG] debug-file - Configuration phase cost:1 s 785 ms +[2025-09-19T17:16:12.965] [DEBUG] debug-file - Current idle worker size: 0. +[2025-09-19T17:16:12.896] [DEBUG] debug-file - End initialize module-target build option map, moduleName=har_library +[2025-09-19T17:16:12.943] [DEBUG] debug-file - clean: Worker pool is inactive. +[2025-09-19T17:16:12.852] [DEBUG] debug-file - Module 'entry' target 'ohosTest' build option initialized +[2025-09-19T17:16:12.965] [DEBUG] debug-file - Current busy worker size: 0. +[2025-09-19T17:16:12.939] [DEBUG] debug-file - Configuration task cost before running: 1 s 802 ms +[2025-09-19T17:16:12.896] [DEBUG] debug-file - Start initialize module-target build option map, moduleName=har_library, buildMode=release +[2025-09-19T17:16:12.943] [DEBUG] debug-file - har_common : clean cost memory 0.0295257568359375 +[2025-09-19T17:16:12.852] [DEBUG] debug-file - End initialize module-target build option map, moduleName=entry +[2025-09-19T17:16:12.965] [DEBUG] debug-file - hvigor build process will be closed. +[2025-09-19T17:16:12.939] [DEBUG] debug-file - Executing task :entry:clean +[2025-09-19T17:16:12.896] [DEBUG] debug-file - Target 'default' config initialized +[2025-09-19T17:16:12.943] [DEBUG] debug-file - runTaskFromQueue task cost before running: 1 s 807 ms +[2025-09-19T17:16:12.852] [DEBUG] debug-file - Start initialize module-target build option map, moduleName=entry, buildMode=debug +[2025-09-19T17:16:12.969] [DEBUG] debug-file - worker[0] exits with exit code 0. +[2025-09-19T17:16:12.939] [DEBUG] debug-file - clean: Worker pool is inactive. +[2025-09-19T17:16:12.896] [DEBUG] debug-file - Target 'ohosTest' config initialized +[2025-09-19T17:16:12.943] [INFO] debug-file - Finished :har_common:clean... after 1 ms +[2025-09-19T17:16:12.852] [DEBUG] debug-file - Target 'default' config initialized +[2025-09-19T17:16:12.970] [DEBUG] debug-file - worker[1] exits with exit code 0. +[2025-09-19T17:16:12.896] [DEBUG] debug-file - Module 'har_library' target 'default' build option initialized +[2025-09-19T17:16:12.943] [DEBUG] debug-file - Executing task ::clean +[2025-09-19T17:16:12.852] [DEBUG] debug-file - Target 'ohosTest' config initialized +[2025-09-19T17:16:12.972] [DEBUG] debug-file - Current worker pool is terminated. +[2025-09-19T17:16:12.896] [DEBUG] debug-file - Module 'har_library' target 'ohosTest' build option initialized +[2025-09-19T17:16:12.943] [DEBUG] debug-file - clean: Worker pool is inactive. +[2025-09-19T17:16:12.852] [DEBUG] debug-file - Module 'entry' target 'default' build option initialized +[2025-09-19T17:16:12.896] [DEBUG] debug-file - End initialize module-target build option map, moduleName=har_library +[2025-09-19T17:16:12.943] [DEBUG] debug-file - HapAndHarDependHar : clean cost memory 0.020111083984375 +[2025-09-19T17:16:12.852] [DEBUG] debug-file - Module 'entry' target 'ohosTest' build option initialized +[2025-09-19T17:16:12.896] [DEBUG] debug-file - Start initialize module-target build option map, moduleName=har_library, buildMode=debug +[2025-09-19T17:16:12.943] [DEBUG] debug-file - runTaskFromQueue task cost before running: 1 s 807 ms +[2025-09-19T17:16:12.852] [DEBUG] debug-file - End initialize module-target build option map, moduleName=entry +[2025-09-19T17:16:12.896] [DEBUG] debug-file - Target 'default' config initialized +[2025-09-19T17:16:12.943] [INFO] debug-file - Finished ::clean... after 1 ms +[2025-09-19T17:16:12.852] [DEBUG] debug-file - Obtain build option for module 'entry' target 'default'in this build. +[2025-09-19T17:16:12.896] [DEBUG] debug-file - Target 'ohosTest' config initialized +[2025-09-19T17:16:12.943] [DEBUG] debug-file - Executing task :entry:init +[2025-09-19T17:16:12.858] [DEBUG] debug-file - Module entry task initialization takes 5 ms +[2025-09-19T17:16:12.897] [DEBUG] debug-file - Module 'har_library' target 'default' build option initialized +[2025-09-19T17:16:12.944] [DEBUG] debug-file - entry : init cost memory 0.0130157470703125 +[2025-09-19T17:16:12.858] [DEBUG] debug-file - hvigorfile, binding custom plugins [] +[2025-09-19T17:16:12.897] [DEBUG] debug-file - Module 'har_library' target 'ohosTest' build option initialized +[2025-09-19T17:16:12.944] [DEBUG] debug-file - runTaskFromQueue task cost before running: 1 s 807 ms +[2025-09-19T17:16:12.858] [DEBUG] debug-file - hvigorfile, no custom plugins were found in D:\toGit\BestPracticeSnippets\HapAndHarDependHar\entry\hvigorfile.ts +[2025-09-19T17:16:12.897] [DEBUG] debug-file - End initialize module-target build option map, moduleName=har_library +[2025-09-19T17:16:12.944] [INFO] debug-file - Finished :entry:init... after 1 ms +[2025-09-19T17:16:12.858] [DEBUG] debug-file - hvigorfile, resolve finished D:\toGit\BestPracticeSnippets\HapAndHarDependHar\entry\hvigorfile.ts +[2025-09-19T17:16:12.897] [DEBUG] debug-file - Obtain build option for module 'har_library' target 'default'in this build. +[2025-09-19T17:16:12.944] [DEBUG] debug-file - Executing task :har_library:init +[2025-09-19T17:16:12.898] [DEBUG] debug-file - Module har_library task initialization takes 2 ms +[2025-09-19T17:16:12.944] [DEBUG] debug-file - har_library : init cost memory 0.01064300537109375 +[2025-09-19T17:16:12.898] [DEBUG] debug-file - hvigorfile, binding custom plugins [] +[2025-09-19T17:16:12.944] [DEBUG] debug-file - runTaskFromQueue task cost before running: 1 s 808 ms +[2025-09-19T17:16:12.898] [DEBUG] debug-file - hvigorfile, no custom plugins were found in D:\toGit\BestPracticeSnippets\HapAndHarDependHar\har_library\hvigorfile.ts +[2025-09-19T17:16:12.944] [INFO] debug-file - Finished :har_library:init... after 1 ms +[2025-09-19T17:16:12.898] [DEBUG] debug-file - hvigorfile, resolve finished D:\toGit\BestPracticeSnippets\HapAndHarDependHar\har_library\hvigorfile.ts +[2025-09-19T17:16:12.944] [DEBUG] debug-file - Executing task :har_common:init +[2025-09-19T17:16:12.899] [DEBUG] debug-file - hvigorfile, resolving D:\toGit\BestPracticeSnippets\HapAndHarDependHar\har_common\hvigorfile.ts +[2025-09-19T17:16:12.944] [DEBUG] debug-file - har_common : init cost memory 0.01055908203125 +[2025-09-19T17:16:12.902] [DEBUG] debug-file - hvigorfile, require result: { default: { system: [Function: harTasks], plugins: [] } } +[2025-09-19T17:16:12.944] [DEBUG] debug-file - runTaskFromQueue task cost before running: 1 s 808 ms +[2025-09-19T17:16:12.902] [DEBUG] debug-file - hvigorfile, binding system plugins [Function: harTasks] +[2025-09-19T17:16:12.944] [INFO] debug-file - Finished :har_common:init... after 1 ms +[2025-09-19T17:16:12.903] [DEBUG] debug-file - failed to load cangjie to dynamically generate schemas: Error: Cannot find module '@ohos/cangjie-build-support/index' +Require stack: +- D:\Program Files\Huawei\DevEco Studio\tools\hvigor\hvigor-ohos-plugin\src\plugin\factory\plugin-factory.js +- D:\Program Files\Huawei\DevEco Studio\tools\hvigor\hvigor-ohos-plugin\index.js +- D:\toGit\BestPracticeSnippets\HapAndHarDependHar\hvigorfile.ts +- D:\Program Files\Huawei\DevEco Studio\tools\hvigor\hvigor\src\base\internal\lifecycle\configuration.js +- D:\Program Files\Huawei\DevEco Studio\tools\hvigor\hvigor\src\base\boot\index.js +- D:\Program Files\Huawei\DevEco Studio\tools\hvigor\hvigor\src\cli\main\cli.js +- D:\Program Files\Huawei\DevEco Studio\tools\hvigor\hvigor\bin\hvigor.js +[2025-09-19T17:16:12.945] [DEBUG] debug-file - Executing task ::init +[2025-09-19T17:16:12.904] [DEBUG] debug-file - Start initialize module-target build option map, moduleName=har_common, buildMode=debug +[2025-09-19T17:16:12.945] [DEBUG] debug-file - HapAndHarDependHar : init cost memory 0.0115966796875 +[2025-09-19T17:16:12.904] [DEBUG] debug-file - Target 'default' config initialized +[2025-09-19T17:16:12.945] [DEBUG] debug-file - runTaskFromQueue task cost before running: 1 s 808 ms +[2025-09-19T17:16:12.904] [DEBUG] debug-file - Target 'ohosTest' config initialized +[2025-09-19T17:16:12.945] [INFO] debug-file - Finished ::init... after 1 ms +[2025-09-19T17:16:12.904] [DEBUG] debug-file - Module 'har_common' target 'default' build option initialized +[2025-09-19T17:16:12.951] [DEBUG] debug-file - Obtain build option for module 'entry' target 'default'in this build. +[2025-09-19T17:16:12.904] [DEBUG] debug-file - Module 'har_common' target 'ohosTest' build option initialized +[2025-09-19T17:16:12.951] [DEBUG] debug-file - Obtain build option for module 'entry' target 'ohosTest'in this build. +[2025-09-19T17:16:12.904] [DEBUG] debug-file - End initialize module-target build option map, moduleName=har_common +[2025-09-19T17:16:12.952] [DEBUG] debug-file - Obtain build option for module 'har_library' target 'default'in this build. +[2025-09-19T17:16:12.904] [DEBUG] debug-file - Start initialize module-target build option map, moduleName=har_common, buildMode=release +[2025-09-19T17:16:12.952] [DEBUG] debug-file - Obtain build option for module 'har_library' target 'ohosTest'in this build. +[2025-09-19T17:16:12.904] [DEBUG] debug-file - Target 'default' config initialized +[2025-09-19T17:16:12.952] [DEBUG] debug-file - Obtain build option for module 'har_common' target 'default'in this build. +[2025-09-19T17:16:12.907] [DEBUG] debug-file - Target 'ohosTest' config initialized +[2025-09-19T17:16:12.953] [DEBUG] debug-file - Obtain build option for module 'har_common' target 'ohosTest'in this build. +[2025-09-19T17:16:12.907] [DEBUG] debug-file - Module 'har_common' target 'default' build option initialized +[2025-09-19T17:16:12.958] [DEBUG] debug-file - Since there is no instance or instance is terminated, create a new worker pool. +[2025-09-19T17:16:12.907] [DEBUG] debug-file - Module 'har_common' target 'ohosTest' build option initialized +[2025-09-19T17:16:12.958] [DEBUG] debug-file - Worker pool is initialized with config: { + minPoolNum: 2, + maxPoolNum: undefined, + maxCoreSize: undefined, + cacheCapacity: undefined, + cacheTtl: undefined +} +[2025-09-19T17:16:12.907] [DEBUG] debug-file - End initialize module-target build option map, moduleName=har_common +[2025-09-19T17:16:12.907] [DEBUG] debug-file - Start initialize module-target build option map, moduleName=har_common, buildMode=debug +[2025-09-19T17:16:12.907] [DEBUG] debug-file - Target 'default' config initialized +[2025-09-19T17:16:12.907] [DEBUG] debug-file - Target 'ohosTest' config initialized +[2025-09-19T17:16:12.907] [DEBUG] debug-file - Module 'har_common' target 'default' build option initialized +[2025-09-19T17:16:12.907] [DEBUG] debug-file - Module 'har_common' target 'ohosTest' build option initialized +[2025-09-19T17:16:12.907] [DEBUG] debug-file - End initialize module-target build option map, moduleName=har_common +[2025-09-19T17:16:12.907] [DEBUG] debug-file - Obtain build option for module 'har_common' target 'default'in this build. +[2025-09-19T17:16:12.908] [DEBUG] debug-file - Module har_common task initialization takes 1 ms +[2025-09-19T17:16:12.908] [DEBUG] debug-file - hvigorfile, binding custom plugins [] +[2025-09-19T17:16:12.908] [DEBUG] debug-file - hvigorfile, no custom plugins were found in D:\toGit\BestPracticeSnippets\HapAndHarDependHar\har_common\hvigorfile.ts +[2025-09-19T17:16:12.908] [DEBUG] debug-file - hvigorfile, resolve finished D:\toGit\BestPracticeSnippets\HapAndHarDependHar\har_common\hvigorfile.ts +[2025-09-19T17:16:12.908] [DEBUG] debug-file - project has submodules:entry,har_library,har_common +[2025-09-19T17:16:12.909] [DEBUG] debug-file - module:har_library no need to execute packageHap +[2025-09-19T17:16:12.909] [DEBUG] debug-file - module:har_common no need to execute packageHap +[2025-09-19T17:16:12.911] [DEBUG] debug-file - start to load updatedOhPackageInfo to the disk +[2025-09-19T17:16:12.916] [DEBUG] debug-file - load to the disk finished +[2025-09-19T17:16:12.917] [DEBUG] debug-file - Start to initialize dependency information. +[2025-09-19T17:16:12.919] [DEBUG] debug-file - Module HapAndHarDependHar Collected Dependency: +[2025-09-19T17:16:12.919] [DEBUG] debug-file - Module HapAndHarDependHar's total dependency: 0 diff --git a/HapAndHarDependHar/.hvigor/outputs/sync/fileCache.json b/HapAndHarDependHar/.hvigor/outputs/sync/fileCache.json index 7aa6aea27f2be5f199cca65e4e239e7422a006b0..d5e7b9107b214bd7867080cf30d1b2970a41dccc 100644 --- a/HapAndHarDependHar/.hvigor/outputs/sync/fileCache.json +++ b/HapAndHarDependHar/.hvigor/outputs/sync/fileCache.json @@ -1 +1 @@ -{"CACHE_SYNC_FILE_HASH":{"C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\hvigor\\hvigor-config.json5":"ed91e76a91d79e84e5afa0a9322b4444e6abc4f611f0fdc631fd67623d5fed5b","C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\build-profile.json5":"372689807663d9e04b79f03454906bd609dfcd4119507685c552409fbd7154b2","C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\hvigorfile.ts":"d06f45b46a59b102bb51ff3dbad67dcc84594f138b6a79a43d3dfb7361dd39c6","C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\oh-package.json5":"68432f9732847072805d5baaf7d17e4e3eb164aad77e2ad8a0cc1a4c70b25e92","C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build-profile.json5":"8839d039323b1a286ef9339a475c3362fcc151108d462da055c32457737ac8e5","C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\hvigorfile.ts":"3c08830fe1bda9281ad9c08fb61d308dc0a91d1448d56dc66ee4c0b36d27a2ca","C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\oh-package.json5":"9ce8f0ed8487ea9f414870435dd3f24a76da82d121608e91c1f337972fdc11d2","C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build-profile.json5":"cd010d19626ca1a3a7fa23ef90ce21588bb46cc8287dd086657ff180727d77f7","C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\hvigorfile.ts":"c8d466428a00198ce37a756c18e0af6533ab7036cd4c9db261ac548cc643e962","C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\oh-package.json5":"eeac7b3418329012fd607378a786cba5945c686f9e8d9adca4e1559d5cedb1ca","C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build-profile.json5":"3c5909484808caf6a3717798b79dea26aaa3cdab9948844887ad385ac6b015fa","C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\hvigorfile.ts":"4ec65cd4aa5540b79f253fc81aa973ef0c4fac67f367b032e9a213fbdea89117","C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\oh-package.json5":"6cbb7adda60279e21707d59ea034ca532f6f0fc391327346504c13f23a9ff336","C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\.hvigor\\outputs\\sync\\output.json":"337b6c7db8aac45a1c62204249ce204b20e1cbe44e7c259c79eeeecab404f2f0","SDK_LOCATION":"C:/Program Files/Huawei/DevEco Studio/sdk"},"OHPM_INSTALL_FILE_HASH":{"C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\oh-package.json5":"68432f9732847072805d5baaf7d17e4e3eb164aad77e2ad8a0cc1a4c70b25e92","C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\oh_modules\\.ohpm\\lock.json5":"269eab4430f3d8d96102adc3a074a3b6d4bfe7f30ee31fbbab46c22acab80175","C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\oh-package.json5":"9ce8f0ed8487ea9f414870435dd3f24a76da82d121608e91c1f337972fdc11d2","C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\oh-package.json5":"eeac7b3418329012fd607378a786cba5945c686f9e8d9adca4e1559d5cedb1ca","C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\oh-package.json5":"6cbb7adda60279e21707d59ea034ca532f6f0fc391327346504c13f23a9ff336","C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\oh_modules":true,"C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\oh_modules":true,"C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\oh_modules":true,"C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\oh_modules":false}} \ No newline at end of file +{"CACHE_SYNC_FILE_HASH":{"D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\hvigor\\hvigor-config.json5":"cb41725891a3a63cc59cc50eeb0871ac75d86c892206d344ddcc7f6aa5b3dd28","D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\build-profile.json5":"ae0ba228ee643e3fd520e51cec4ee2cb129e1860eb0706c022dc69bde30406cb","D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\hvigorfile.ts":"5fa16f0825e5ac7fbf9ceba45332e1274bcc811db863eb5f365afaa9d8c14ad4","D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\oh-package.json5":"e2f85d54ded1649c2bbc9b4a5ad85b6d97d22898576474fe275f3b6f6240f93c","D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build-profile.json5":"be8f264d9841a0e122a58b02077bccff57d9155c5f35a70af9f58106b0cee61e","D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\hvigorfile.ts":"193d54dc45ddda429a8484031fa5770091c83ef3da76a34fc6b6ca9baf9b6af7","D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\oh-package.json5":"38ef6519a84a9d25b3c03ef3cefaa71cdc049423776c9be6e4af36dde9489399","D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build-profile.json5":"7c55cfeed8b764aefc0be24ee1712ff8ac59b817da7df727f2702ce41cbc021b","D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\hvigorfile.ts":"81214c875f6f4987c2e79300122d41022c650217e714d4f38767c6f36f6c07e3","D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\oh-package.json5":"0af97868a297d93bed294534dfb98a105e1b6e86b035b2f3b543d588bdd14244","D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build-profile.json5":"7c55cfeed8b764aefc0be24ee1712ff8ac59b817da7df727f2702ce41cbc021b","D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\hvigorfile.ts":"81214c875f6f4987c2e79300122d41022c650217e714d4f38767c6f36f6c07e3","D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\oh-package.json5":"58481d13adcf1db3ebf11798973927507f95f1ea11559bf4a43b97b2a9c72b07","D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\.hvigor\\outputs\\sync\\output.json":"021bf6e88d92be5fa109bf97b23de757778b8b6a5e70bb42a3140a153f3d4ef5","SDK_LOCATION":"D:/Program Files/Huawei/DevEco Studio/sdk"},"OHPM_INSTALL_FILE_HASH":{"D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\oh-package.json5":"e2f85d54ded1649c2bbc9b4a5ad85b6d97d22898576474fe275f3b6f6240f93c","D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\oh_modules\\.ohpm\\lock.json5":"29c08cde47ec18974ef805cf252ac4d2dd7b94c4d7b990dfeffa558d72a27aa4","D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\oh-package.json5":"38ef6519a84a9d25b3c03ef3cefaa71cdc049423776c9be6e4af36dde9489399","D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\oh-package.json5":"0af97868a297d93bed294534dfb98a105e1b6e86b035b2f3b543d588bdd14244","D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\oh-package.json5":"58481d13adcf1db3ebf11798973927507f95f1ea11559bf4a43b97b2a9c72b07","D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\oh_modules":true,"D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\oh_modules":true,"D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\oh_modules":true,"D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\oh_modules":false}} \ No newline at end of file diff --git a/HapAndHarDependHar/.hvigor/outputs/sync/output.json b/HapAndHarDependHar/.hvigor/outputs/sync/output.json index 52db4d7677bcf85f0b3de9ac538f6bdb0910ba90..4e41aafddafa82ea9049d01d119ffde5ea35a7e2 100644 --- a/HapAndHarDependHar/.hvigor/outputs/sync/output.json +++ b/HapAndHarDependHar/.hvigor/outputs/sync/output.json @@ -1,53 +1,49 @@ { "ohos-module-entry": { "SELECT_TARGET": "default", - "MODULE_BUILD_DIR": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build", - "DEPENDENCY_INFO": { - "har_library": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_library", - "har_common": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_common" - }, + "MODULE_BUILD_DIR": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build", "TARGETS": { "default": { - "SOURCE_ROOT": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\src\\main", + "SOURCE_ROOT": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\src\\main", "RESOURCES_PATH": [ - "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\src\\main\\resources" + "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\src\\main\\resources" ], "BUILD_PATH": { - "OUTPUT_PATH": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\outputs\\default", - "INTERMEDIA_PATH": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates", - "JS_ASSETS_PATH": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates\\loader_out\\default", - "JS_LITE_ASSETS_PATH": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates\\loader_out_lite\\default", - "RES_PATH": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates\\res\\default", - "RES_PROFILE_PATH": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates\\res\\default\\resources\\base\\profile", - "ETS_SUPER_VISUAL_PATH": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\cache\\default\\default@CompileArkTS\\esmodule", - "JS_SUPER_VISUAL_PATH": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\cache\\default\\default@CompileJS\\jsbundle", - "WORKER_LOADER": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates\\loader\\default\\loader.json", - "MANIFEST_JSON": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates\\manifest\\default", - "OUTPUT_METADATA_JSON": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates\\hap_metadata\\default\\output_metadata.json", - "SOURCE_MAP_DIR": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates\\source_map\\default" + "OUTPUT_PATH": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\outputs\\default", + "INTERMEDIA_PATH": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates", + "JS_ASSETS_PATH": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates\\loader_out\\default", + "JS_LITE_ASSETS_PATH": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates\\loader_out_lite\\default", + "RES_PATH": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates\\res\\default", + "RES_PROFILE_PATH": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates\\res\\default\\resources\\base\\profile", + "ETS_SUPER_VISUAL_PATH": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\cache\\default\\default@CompileArkTS\\esmodule", + "JS_SUPER_VISUAL_PATH": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\cache\\default\\default@CompileJS\\jsbundle", + "WORKER_LOADER": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates\\loader\\default\\loader.json", + "MANIFEST_JSON": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates\\manifest\\default", + "OUTPUT_METADATA_JSON": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates\\hap_metadata\\default\\output_metadata.json", + "SOURCE_MAP_DIR": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates\\source_map\\default" }, "BUILD_OPTION": { "debuggable": true } }, "ohosTest": { - "SOURCE_ROOT": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\src\\ohosTest", + "SOURCE_ROOT": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\src\\ohosTest", "RESOURCES_PATH": [ - "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\src\\ohosTest\\resources" + "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\src\\ohosTest\\resources" ], "BUILD_PATH": { - "OUTPUT_PATH": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\outputs\\ohosTest", - "INTERMEDIA_PATH": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates", - "JS_ASSETS_PATH": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates\\loader_out\\ohosTest", - "JS_LITE_ASSETS_PATH": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates\\loader_out_lite\\ohosTest", - "RES_PATH": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates\\res\\ohosTest", - "RES_PROFILE_PATH": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates\\res\\ohosTest\\resources\\base\\profile", - "ETS_SUPER_VISUAL_PATH": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\cache\\ohosTest\\ohosTest@OhosTestCompileArkTS\\esmodule", - "JS_SUPER_VISUAL_PATH": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\cache\\ohosTest\\ohosTest@OhosTestCompileJS\\jsbundle", - "WORKER_LOADER": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates\\loader\\ohosTest\\loader.json", - "MANIFEST_JSON": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates\\manifest\\ohosTest", - "OUTPUT_METADATA_JSON": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates\\hap_metadata\\ohosTest\\output_metadata.json", - "SOURCE_MAP_DIR": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates\\source_map\\ohosTest" + "OUTPUT_PATH": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\outputs\\ohosTest", + "INTERMEDIA_PATH": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates", + "JS_ASSETS_PATH": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates\\loader_out\\ohosTest", + "JS_LITE_ASSETS_PATH": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates\\loader_out_lite\\ohosTest", + "RES_PATH": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates\\res\\ohosTest", + "RES_PROFILE_PATH": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates\\res\\ohosTest\\resources\\base\\profile", + "ETS_SUPER_VISUAL_PATH": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\cache\\ohosTest\\ohosTest@OhosTestCompileArkTS\\esmodule", + "JS_SUPER_VISUAL_PATH": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\cache\\ohosTest\\ohosTest@OhosTestCompileJS\\jsbundle", + "WORKER_LOADER": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates\\loader\\ohosTest\\loader.json", + "MANIFEST_JSON": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates\\manifest\\ohosTest", + "OUTPUT_METADATA_JSON": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates\\hap_metadata\\ohosTest\\output_metadata.json", + "SOURCE_MAP_DIR": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates\\source_map\\ohosTest" }, "BUILD_OPTION": { "debuggable": true @@ -98,29 +94,49 @@ }, "ohos-module-har_library": { "SELECT_TARGET": "default", - "MODULE_BUILD_DIR": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build", - "DEPENDENCY_INFO": { - "har_common": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_common" - }, + "MODULE_BUILD_DIR": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build", "TARGETS": { "default": { - "SOURCE_ROOT": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\src\\main", + "SOURCE_ROOT": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\src\\main", + "RESOURCES_PATH": [ + "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\src\\main\\resources" + ], + "BUILD_PATH": { + "OUTPUT_PATH": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\outputs\\default", + "INTERMEDIA_PATH": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\intermediates", + "JS_ASSETS_PATH": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\intermediates\\loader_out\\default", + "JS_LITE_ASSETS_PATH": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\intermediates\\loader_out_lite\\default", + "RES_PATH": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\intermediates\\res\\default", + "RES_PROFILE_PATH": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\intermediates\\res\\default\\resources\\base\\profile", + "ETS_SUPER_VISUAL_PATH": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\cache\\default\\default@HarCompileArkTS\\esmodule", + "JS_SUPER_VISUAL_PATH": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\cache\\default\\default@HarCompileJS\\jsbundle", + "WORKER_LOADER": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\intermediates\\loader\\default\\loader.json", + "MANIFEST_JSON": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\intermediates\\manifest\\default", + "OUTPUT_METADATA_JSON": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\intermediates\\hap_metadata\\default\\output_metadata.json", + "SOURCE_MAP_DIR": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\intermediates\\source_map\\default" + }, + "BUILD_OPTION": { + "debuggable": true + } + }, + "ohosTest": { + "SOURCE_ROOT": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\src\\ohosTest", "RESOURCES_PATH": [ - "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\src\\main\\resources" + "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\src\\ohosTest\\resources" ], "BUILD_PATH": { - "OUTPUT_PATH": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\outputs\\default", - "INTERMEDIA_PATH": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\intermediates", - "JS_ASSETS_PATH": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\intermediates\\loader_out\\default", - "JS_LITE_ASSETS_PATH": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\intermediates\\loader_out_lite\\default", - "RES_PATH": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\intermediates\\res\\default", - "RES_PROFILE_PATH": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\intermediates\\res\\default\\resources\\base\\profile", - "ETS_SUPER_VISUAL_PATH": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\cache\\default\\default@HarCompileArkTS\\esmodule", - "JS_SUPER_VISUAL_PATH": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\cache\\default\\default@HarCompileJS\\jsbundle", - "WORKER_LOADER": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\intermediates\\loader\\default\\loader.json", - "MANIFEST_JSON": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\intermediates\\manifest\\default", - "OUTPUT_METADATA_JSON": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\intermediates\\hap_metadata\\default\\output_metadata.json", - "SOURCE_MAP_DIR": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\intermediates\\source_map\\default" + "OUTPUT_PATH": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\outputs\\ohosTest", + "INTERMEDIA_PATH": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\intermediates", + "JS_ASSETS_PATH": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\intermediates\\loader_out\\ohosTest", + "JS_LITE_ASSETS_PATH": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\intermediates\\loader_out_lite\\ohosTest", + "RES_PATH": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\intermediates\\res\\ohosTest", + "RES_PROFILE_PATH": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\intermediates\\res\\ohosTest\\resources\\base\\profile", + "ETS_SUPER_VISUAL_PATH": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\cache\\ohosTest\\ohosTest@OhosTestCompileArkTS\\esmodule", + "JS_SUPER_VISUAL_PATH": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\cache\\ohosTest\\ohosTest@OhosTestCompileJS\\jsbundle", + "WORKER_LOADER": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\intermediates\\loader\\ohosTest\\loader.json", + "MANIFEST_JSON": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\intermediates\\manifest\\ohosTest", + "OUTPUT_METADATA_JSON": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\intermediates\\hap_metadata\\ohosTest\\output_metadata.json", + "SOURCE_MAP_DIR": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\intermediates\\source_map\\ohosTest" }, "BUILD_OPTION": { "debuggable": true @@ -174,27 +190,49 @@ }, "ohos-module-har_common": { "SELECT_TARGET": "default", - "MODULE_BUILD_DIR": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build", - "DEPENDENCY_INFO": {}, + "MODULE_BUILD_DIR": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build", "TARGETS": { "default": { - "SOURCE_ROOT": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\src\\main", + "SOURCE_ROOT": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\src\\main", + "RESOURCES_PATH": [ + "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\src\\main\\resources" + ], + "BUILD_PATH": { + "OUTPUT_PATH": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\outputs\\default", + "INTERMEDIA_PATH": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\intermediates", + "JS_ASSETS_PATH": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\intermediates\\loader_out\\default", + "JS_LITE_ASSETS_PATH": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\intermediates\\loader_out_lite\\default", + "RES_PATH": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\intermediates\\res\\default", + "RES_PROFILE_PATH": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\intermediates\\res\\default\\resources\\base\\profile", + "ETS_SUPER_VISUAL_PATH": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\cache\\default\\default@HarCompileArkTS\\esmodule", + "JS_SUPER_VISUAL_PATH": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\cache\\default\\default@HarCompileJS\\jsbundle", + "WORKER_LOADER": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\intermediates\\loader\\default\\loader.json", + "MANIFEST_JSON": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\intermediates\\manifest\\default", + "OUTPUT_METADATA_JSON": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\intermediates\\hap_metadata\\default\\output_metadata.json", + "SOURCE_MAP_DIR": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\intermediates\\source_map\\default" + }, + "BUILD_OPTION": { + "debuggable": true + } + }, + "ohosTest": { + "SOURCE_ROOT": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\src\\ohosTest", "RESOURCES_PATH": [ - "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\src\\main\\resources" + "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\src\\ohosTest\\resources" ], "BUILD_PATH": { - "OUTPUT_PATH": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\outputs\\default", - "INTERMEDIA_PATH": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\intermediates", - "JS_ASSETS_PATH": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\intermediates\\loader_out\\default", - "JS_LITE_ASSETS_PATH": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\intermediates\\loader_out_lite\\default", - "RES_PATH": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\intermediates\\res\\default", - "RES_PROFILE_PATH": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\intermediates\\res\\default\\resources\\base\\profile", - "ETS_SUPER_VISUAL_PATH": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\cache\\default\\default@HarCompileArkTS\\esmodule", - "JS_SUPER_VISUAL_PATH": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\cache\\default\\default@HarCompileJS\\jsbundle", - "WORKER_LOADER": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\intermediates\\loader\\default\\loader.json", - "MANIFEST_JSON": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\intermediates\\manifest\\default", - "OUTPUT_METADATA_JSON": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\intermediates\\hap_metadata\\default\\output_metadata.json", - "SOURCE_MAP_DIR": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\intermediates\\source_map\\default" + "OUTPUT_PATH": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\outputs\\ohosTest", + "INTERMEDIA_PATH": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\intermediates", + "JS_ASSETS_PATH": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\intermediates\\loader_out\\ohosTest", + "JS_LITE_ASSETS_PATH": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\intermediates\\loader_out_lite\\ohosTest", + "RES_PATH": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\intermediates\\res\\ohosTest", + "RES_PROFILE_PATH": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\intermediates\\res\\ohosTest\\resources\\base\\profile", + "ETS_SUPER_VISUAL_PATH": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\cache\\ohosTest\\ohosTest@OhosTestCompileArkTS\\esmodule", + "JS_SUPER_VISUAL_PATH": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\cache\\ohosTest\\ohosTest@OhosTestCompileJS\\jsbundle", + "WORKER_LOADER": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\intermediates\\loader\\ohosTest\\loader.json", + "MANIFEST_JSON": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\intermediates\\manifest\\ohosTest", + "OUTPUT_METADATA_JSON": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\intermediates\\hap_metadata\\ohosTest\\output_metadata.json", + "SOURCE_MAP_DIR": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\intermediates\\source_map\\ohosTest" }, "BUILD_OPTION": { "debuggable": true @@ -248,15 +286,15 @@ }, "ohos-project": { "SELECT_PRODUCT_NAME": "default", - "MODULE_BUILD_DIR": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\build", + "MODULE_BUILD_DIR": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\build", "BUNDLE_NAME": "com.example.coldstart", "BUILD_PATH": { - "OUTPUT_PATH": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\build\\outputs\\default" + "OUTPUT_PATH": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\build\\outputs\\default" }, "MODULES": [ { "name": "entry", - "srcPath": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\entry", + "srcPath": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\entry", "targets": [ { "name": "default", @@ -265,17 +303,17 @@ ] } ], - "belongProjectPath": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar" + "belongProjectPath": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar" }, { "name": "har_library", - "srcPath": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_library", - "belongProjectPath": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar" + "srcPath": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_library", + "belongProjectPath": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar" }, { "name": "har_common", - "srcPath": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_common", - "belongProjectPath": "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar" + "srcPath": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_common", + "belongProjectPath": "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar" } ], "PROFILE_OPT": { @@ -285,7 +323,8 @@ { "name": "default", "signingConfig": "default", - "compatibleSdkVersion": "5.0.0(12)", + "compatibleSdkVersion": "5.0.5(17)", + "targetSdkVersion": "5.0.5(17)", "runtimeOS": "HarmonyOS" } ], @@ -327,7 +366,7 @@ "hvigor.keepDependency": true }, "OVERALL_PROJECT_PATHS": [ - "C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar" + "D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar" ], "BUILD_CACHE_DIR": "" }, diff --git a/HapAndHarDependHar/.idea/.deveco/module/entry.cache.json b/HapAndHarDependHar/.idea/.deveco/module/entry.cache.json index e06b420c8e4b4e99a1e37347e58afbd6ef2f8c22..56a5221800b803a8bfc70b0e4c91999c9bd3b99f 100644 --- a/HapAndHarDependHar/.idea/.deveco/module/entry.cache.json +++ b/HapAndHarDependHar/.idea/.deveco/module/entry.cache.json @@ -5,18 +5,18 @@ "BuildOptions":{ "SELECT_BUILD_TARGET":"default", "BUILD_PATH":{ - "OUTPUT_METADATA_JSON":"C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates\\hap_metadata\\default\\output_metadata.json", - "OUTPUT_PATH":"C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\outputs\\default", - "RES_PATH":"C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates\\res\\default", - "ETS_SUPER_VISUAL_PATH":"C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\cache\\default\\default@CompileArkTS\\esmodule", - "JS_ASSETS_PATH":"C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates\\loader_out\\default", - "SOURCE_MAP_DIR":"C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates\\source_map\\default", - "INTERMEDIA_PATH":"C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates", - "RES_PROFILE_PATH":"C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates\\res\\default\\resources\\base\\profile", - "WORKER_LOADER":"C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates\\loader\\default\\loader.json", - "MANIFEST_JSON":"C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates\\manifest\\default", - "JS_LITE_ASSETS_PATH":"C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates\\loader_out_lite\\default", - "JS_SUPER_VISUAL_PATH":"C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\cache\\default\\default@CompileJS\\jsbundle" + "OUTPUT_METADATA_JSON":"D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates\\hap_metadata\\default\\output_metadata.json", + "OUTPUT_PATH":"D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\outputs\\default", + "RES_PATH":"D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates\\res\\default", + "ETS_SUPER_VISUAL_PATH":"D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\cache\\default\\default@CompileArkTS\\esmodule", + "JS_ASSETS_PATH":"D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates\\loader_out\\default", + "SOURCE_MAP_DIR":"D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates\\source_map\\default", + "INTERMEDIA_PATH":"D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates", + "RES_PROFILE_PATH":"D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates\\res\\default\\resources\\base\\profile", + "WORKER_LOADER":"D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates\\loader\\default\\loader.json", + "MANIFEST_JSON":"D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates\\manifest\\default", + "JS_LITE_ASSETS_PATH":"D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\intermediates\\loader_out_lite\\default", + "JS_SUPER_VISUAL_PATH":"D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\entry\\build\\default\\cache\\default\\default@CompileJS\\jsbundle" } } } \ No newline at end of file diff --git a/HapAndHarDependHar/.idea/.deveco/module/har_common.cache.json b/HapAndHarDependHar/.idea/.deveco/module/har_common.cache.json index ccdfe1db15fa8a254a528c917e6af1b6ed6a5d17..a01cb10792f67b78d994d99747a2f1f8e90327b6 100644 --- a/HapAndHarDependHar/.idea/.deveco/module/har_common.cache.json +++ b/HapAndHarDependHar/.idea/.deveco/module/har_common.cache.json @@ -5,18 +5,18 @@ "BuildOptions":{ "SELECT_BUILD_TARGET":"default", "BUILD_PATH":{ - "OUTPUT_METADATA_JSON":"C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\intermediates\\hap_metadata\\default\\output_metadata.json", - "OUTPUT_PATH":"C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\outputs\\default", - "RES_PATH":"C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\intermediates\\res\\default", - "ETS_SUPER_VISUAL_PATH":"C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\cache\\default\\default@HarCompileArkTS\\esmodule", - "JS_ASSETS_PATH":"C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\intermediates\\loader_out\\default", - "SOURCE_MAP_DIR":"C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\intermediates\\source_map\\default", - "INTERMEDIA_PATH":"C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\intermediates", - "RES_PROFILE_PATH":"C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\intermediates\\res\\default\\resources\\base\\profile", - "WORKER_LOADER":"C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\intermediates\\loader\\default\\loader.json", - "MANIFEST_JSON":"C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\intermediates\\manifest\\default", - "JS_LITE_ASSETS_PATH":"C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\intermediates\\loader_out_lite\\default", - "JS_SUPER_VISUAL_PATH":"C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\cache\\default\\default@HarCompileJS\\jsbundle" + "OUTPUT_METADATA_JSON":"D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\intermediates\\hap_metadata\\default\\output_metadata.json", + "OUTPUT_PATH":"D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\outputs\\default", + "RES_PATH":"D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\intermediates\\res\\default", + "ETS_SUPER_VISUAL_PATH":"D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\cache\\default\\default@HarCompileArkTS\\esmodule", + "JS_ASSETS_PATH":"D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\intermediates\\loader_out\\default", + "SOURCE_MAP_DIR":"D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\intermediates\\source_map\\default", + "INTERMEDIA_PATH":"D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\intermediates", + "RES_PROFILE_PATH":"D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\intermediates\\res\\default\\resources\\base\\profile", + "WORKER_LOADER":"D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\intermediates\\loader\\default\\loader.json", + "MANIFEST_JSON":"D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\intermediates\\manifest\\default", + "JS_LITE_ASSETS_PATH":"D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\intermediates\\loader_out_lite\\default", + "JS_SUPER_VISUAL_PATH":"D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_common\\build\\default\\cache\\default\\default@HarCompileJS\\jsbundle" } } } \ No newline at end of file diff --git a/HapAndHarDependHar/.idea/.deveco/module/har_library.cache.json b/HapAndHarDependHar/.idea/.deveco/module/har_library.cache.json index 7c4d405a1de25d38223f990d1f4cfbfe0f15da56..0285ca8338230a7f611b321947464ac97c36f22a 100644 --- a/HapAndHarDependHar/.idea/.deveco/module/har_library.cache.json +++ b/HapAndHarDependHar/.idea/.deveco/module/har_library.cache.json @@ -5,18 +5,18 @@ "BuildOptions":{ "SELECT_BUILD_TARGET":"default", "BUILD_PATH":{ - "OUTPUT_METADATA_JSON":"C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\intermediates\\hap_metadata\\default\\output_metadata.json", - "OUTPUT_PATH":"C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\outputs\\default", - "RES_PATH":"C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\intermediates\\res\\default", - "ETS_SUPER_VISUAL_PATH":"C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\cache\\default\\default@HarCompileArkTS\\esmodule", - "JS_ASSETS_PATH":"C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\intermediates\\loader_out\\default", - "SOURCE_MAP_DIR":"C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\intermediates\\source_map\\default", - "INTERMEDIA_PATH":"C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\intermediates", - "RES_PROFILE_PATH":"C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\intermediates\\res\\default\\resources\\base\\profile", - "WORKER_LOADER":"C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\intermediates\\loader\\default\\loader.json", - "MANIFEST_JSON":"C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\intermediates\\manifest\\default", - "JS_LITE_ASSETS_PATH":"C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\intermediates\\loader_out_lite\\default", - "JS_SUPER_VISUAL_PATH":"C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\cache\\default\\default@HarCompileJS\\jsbundle" + "OUTPUT_METADATA_JSON":"D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\intermediates\\hap_metadata\\default\\output_metadata.json", + "OUTPUT_PATH":"D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\outputs\\default", + "RES_PATH":"D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\intermediates\\res\\default", + "ETS_SUPER_VISUAL_PATH":"D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\cache\\default\\default@HarCompileArkTS\\esmodule", + "JS_ASSETS_PATH":"D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\intermediates\\loader_out\\default", + "SOURCE_MAP_DIR":"D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\intermediates\\source_map\\default", + "INTERMEDIA_PATH":"D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\intermediates", + "RES_PROFILE_PATH":"D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\intermediates\\res\\default\\resources\\base\\profile", + "WORKER_LOADER":"D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\intermediates\\loader\\default\\loader.json", + "MANIFEST_JSON":"D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\intermediates\\manifest\\default", + "JS_LITE_ASSETS_PATH":"D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\intermediates\\loader_out_lite\\default", + "JS_SUPER_VISUAL_PATH":"D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\har_library\\build\\default\\cache\\default\\default@HarCompileJS\\jsbundle" } } } \ No newline at end of file diff --git a/HapAndHarDependHar/.idea/.deveco/project.cache.json b/HapAndHarDependHar/.idea/.deveco/project.cache.json index 3df030e90966f8ce3724f591a626772d3ac652ca..9581e1e1883102c2f9f9aace8d5766ced028ea42 100644 --- a/HapAndHarDependHar/.idea/.deveco/project.cache.json +++ b/HapAndHarDependHar/.idea/.deveco/project.cache.json @@ -1,6 +1,6 @@ { "CommonInfo":{ - "project.ide.version":"5.0.11.100", + "project.ide.version":"6.0.0.848", "current.select.product":"default", "current.select.buildMode":"", "crossplatform.projectType":"" @@ -9,7 +9,7 @@ "SELECT_BUILD_PRODUCT":"default", "BUNDLE_NAME":"com.example.coldstart", "BUILD_PATH":{ - "OUTPUT_PATH":"C:\\Users\\fy\\Desktop\\newproject\\5.15new10\\BestPracticeSnippets\\HapAndHarDependHar\\build\\outputs\\default" + "OUTPUT_PATH":"D:\\toGit\\BestPracticeSnippets\\HapAndHarDependHar\\build\\outputs\\default" }, "SELECT_BUILD_MODE":"" } diff --git a/HapAndHarDependHar/.idea/modules.xml b/HapAndHarDependHar/.idea/modules.xml index faccfc5b6d5f95cbb14c1a740483d2a501325f8c..174ab3910b73fc7bd36cced182b268fad6859bb6 100644 --- a/HapAndHarDependHar/.idea/modules.xml +++ b/HapAndHarDependHar/.idea/modules.xml @@ -3,9 +3,9 @@ - - - + + + \ No newline at end of file diff --git a/HapAndHarDependHar/.idea/modules/HapAndHarDependHar.iml b/HapAndHarDependHar/.idea/modules/HapAndHarDependHar.iml index c2374d61aac50ab4ac8824f19011f78f118ce553..999bca034a4103a65c8e3ca56dab4602d016ed6b 100644 --- a/HapAndHarDependHar/.idea/modules/HapAndHarDependHar.iml +++ b/HapAndHarDependHar/.idea/modules/HapAndHarDependHar.iml @@ -32,24 +32,24 @@ - + - - + + + + - + - - - - + + diff --git a/HapAndHarDependHar/README.md b/HapAndHarDependHar/README.md new file mode 100644 index 0000000000000000000000000000000000000000..0b47e662f9a98b5932661eb64528a68416881965 --- /dev/null +++ b/HapAndHarDependHar/README.md @@ -0,0 +1,56 @@ +# 模块化设计 + +### 介绍 + +本示例是《模块化设计》最佳实践中的代码示例片段。 + +### 使用说明 + +进入首面,加载示例逻辑。 + +### 工程目录 +``` +├──entry/src/main/ets +│ ├──entryability +│ │ └──EntryAbility.ets // Ability入口类 +│ └──pages +│ └──Index.ets // 首页 +├──har_common/src/main/ets +│ ├──components +│ │ └──MainPage.ets // common模块中MainPage +│ └──utils +│ └──Utils.ets // 工具类 +└──har_library/src/main/ets + └──components/mainpage + └──MainPage.ets // library模块中MainPage +``` + + +### 具体实现 + +1. 分别包括三个模块:主业务模块entry,公共模块har_common,库模块har_library + +### 相关权限 + +不涉及。 + +### 约束与限制 + +1. 本示例仅支持标准系统上运行,支持设备:华为手机。 + +2. HarmonyOS系统:HarmonyOS 5.0.5 Release及以上。 + +3. DevEco Studio版本:DevEco Studio 5.0.5 Release及以上。 + +4. HarmonyOS SDK版本:HarmonyOS 5.0.5 Release SDK及以上。 + +### 下载 + +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set HapAndHarDependHar +git checkout +``` \ No newline at end of file diff --git a/HapAndHarDependHar/build-profile.json5 b/HapAndHarDependHar/build-profile.json5 index 63a55a4fb11c40a724aa0da825014155330b9124..b455e223003379ff05ce7b74364b568aee0c2120 100644 --- a/HapAndHarDependHar/build-profile.json5 +++ b/HapAndHarDependHar/build-profile.json5 @@ -5,7 +5,8 @@ { "name": "default", "signingConfig": "default", - "compatibleSdkVersion": "5.0.0(12)", + "compatibleSdkVersion": "5.0.5(17)", + "targetSdkVersion": "5.0.5(17)", "runtimeOS": "HarmonyOS", } ], diff --git a/HapAndHarDependHar/entry/obfuscation-rules.txt b/HapAndHarDependHar/entry/obfuscation-rules.txt index 985b2aeb7658286b17bd26eab8f217c3fe75ea8b..a1dfa0bd175984dc49e641436aa67b1de1b8abeb 100644 --- a/HapAndHarDependHar/entry/obfuscation-rules.txt +++ b/HapAndHarDependHar/entry/obfuscation-rules.txt @@ -15,4 +15,8 @@ # Keep options: # -keep-property-name: specifies property names that you want to keep -# -keep-global-name: specifies names that you want to keep in the global scope \ No newline at end of file +# -keep-global-name: specifies names that you want to keep in the global scope +-enable-property-obfuscation +-enable-toplevel-obfuscation +-enable-filename-obfuscation +-enable-export-obfuscation \ No newline at end of file diff --git a/HapAndHarDependHar/entry/oh-package-lock.json5 b/HapAndHarDependHar/entry/oh-package-lock.json5 index 231608a0756149b5af6a398afea23f308409a2e5..693078bc860d94884310724a94c40fa355da1c9e 100644 --- a/HapAndHarDependHar/entry/oh-package-lock.json5 +++ b/HapAndHarDependHar/entry/oh-package-lock.json5 @@ -1,6 +1,7 @@ { "meta": { - "stableOrder": true + "stableOrder": true, + "enableUnifiedLockfile": false }, "lockfileVersion": 3, "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", @@ -12,13 +13,13 @@ "har_common@../har_common": { "name": "har_common", "version": "1.0.0", - "resolved": "../har_common", + "resolved": "", "registryType": "local" }, "har_library@../har_library": { "name": "har_library", "version": "1.0.0", - "resolved": "../har_library", + "resolved": "", "registryType": "local", "dependencies": { "har_common": "file:../har_common" diff --git a/HapAndHarDependHar/entry/oh_modules/har_common/obfuscation-rules.txt b/HapAndHarDependHar/entry/oh_modules/har_common/obfuscation-rules.txt index 985b2aeb7658286b17bd26eab8f217c3fe75ea8b..a1dfa0bd175984dc49e641436aa67b1de1b8abeb 100644 --- a/HapAndHarDependHar/entry/oh_modules/har_common/obfuscation-rules.txt +++ b/HapAndHarDependHar/entry/oh_modules/har_common/obfuscation-rules.txt @@ -15,4 +15,8 @@ # Keep options: # -keep-property-name: specifies property names that you want to keep -# -keep-global-name: specifies names that you want to keep in the global scope \ No newline at end of file +# -keep-global-name: specifies names that you want to keep in the global scope +-enable-property-obfuscation +-enable-toplevel-obfuscation +-enable-filename-obfuscation +-enable-export-obfuscation \ No newline at end of file diff --git a/HapAndHarDependHar/entry/oh_modules/har_common/src/main/ets/utils/Utils.ets b/HapAndHarDependHar/entry/oh_modules/har_common/src/main/ets/utils/Utils.ets index 4742ef515534d31b3afec2ebe7d4d8e9d0c5cc30..df7da42fbb590a57b1872f8d823fd66672baea05 100644 --- a/HapAndHarDependHar/entry/oh_modules/har_common/src/main/ets/utils/Utils.ets +++ b/HapAndHarDependHar/entry/oh_modules/har_common/src/main/ets/utils/Utils.ets @@ -18,6 +18,7 @@ */ // [Start large_number] +// har_common/src/main/ets/utils/Utils.ets const LARGE_NUMBER = 100000000; function func(): number { diff --git a/HapAndHarDependHar/entry/oh_modules/har_library/obfuscation-rules.txt b/HapAndHarDependHar/entry/oh_modules/har_library/obfuscation-rules.txt index 985b2aeb7658286b17bd26eab8f217c3fe75ea8b..a1dfa0bd175984dc49e641436aa67b1de1b8abeb 100644 --- a/HapAndHarDependHar/entry/oh_modules/har_library/obfuscation-rules.txt +++ b/HapAndHarDependHar/entry/oh_modules/har_library/obfuscation-rules.txt @@ -15,4 +15,8 @@ # Keep options: # -keep-property-name: specifies property names that you want to keep -# -keep-global-name: specifies names that you want to keep in the global scope \ No newline at end of file +# -keep-global-name: specifies names that you want to keep in the global scope +-enable-property-obfuscation +-enable-toplevel-obfuscation +-enable-filename-obfuscation +-enable-export-obfuscation \ No newline at end of file diff --git a/HapAndHarDependHar/entry/oh_modules/har_library/oh-package-lock.json5 b/HapAndHarDependHar/entry/oh_modules/har_library/oh-package-lock.json5 index 587ad773b07c8bbd8891d9da47d8eccef105c449..80997756525f69154f109e8866a4fd1af88b2702 100644 --- a/HapAndHarDependHar/entry/oh_modules/har_library/oh-package-lock.json5 +++ b/HapAndHarDependHar/entry/oh_modules/har_library/oh-package-lock.json5 @@ -1,6 +1,7 @@ { "meta": { - "stableOrder": true + "stableOrder": true, + "enableUnifiedLockfile": false }, "lockfileVersion": 3, "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", @@ -11,7 +12,7 @@ "har_common@../har_common": { "name": "har_common", "version": "1.0.0", - "resolved": "../har_common", + "resolved": "", "registryType": "local" } } diff --git a/HapAndHarDependHar/entry/oh_modules/har_library/oh_modules/har_common/obfuscation-rules.txt b/HapAndHarDependHar/entry/oh_modules/har_library/oh_modules/har_common/obfuscation-rules.txt index 985b2aeb7658286b17bd26eab8f217c3fe75ea8b..a1dfa0bd175984dc49e641436aa67b1de1b8abeb 100644 --- a/HapAndHarDependHar/entry/oh_modules/har_library/oh_modules/har_common/obfuscation-rules.txt +++ b/HapAndHarDependHar/entry/oh_modules/har_library/oh_modules/har_common/obfuscation-rules.txt @@ -15,4 +15,8 @@ # Keep options: # -keep-property-name: specifies property names that you want to keep -# -keep-global-name: specifies names that you want to keep in the global scope \ No newline at end of file +# -keep-global-name: specifies names that you want to keep in the global scope +-enable-property-obfuscation +-enable-toplevel-obfuscation +-enable-filename-obfuscation +-enable-export-obfuscation \ No newline at end of file diff --git a/HapAndHarDependHar/entry/oh_modules/har_library/oh_modules/har_common/src/main/ets/utils/Utils.ets b/HapAndHarDependHar/entry/oh_modules/har_library/oh_modules/har_common/src/main/ets/utils/Utils.ets index 4742ef515534d31b3afec2ebe7d4d8e9d0c5cc30..df7da42fbb590a57b1872f8d823fd66672baea05 100644 --- a/HapAndHarDependHar/entry/oh_modules/har_library/oh_modules/har_common/src/main/ets/utils/Utils.ets +++ b/HapAndHarDependHar/entry/oh_modules/har_library/oh_modules/har_common/src/main/ets/utils/Utils.ets @@ -18,6 +18,7 @@ */ // [Start large_number] +// har_common/src/main/ets/utils/Utils.ets const LARGE_NUMBER = 100000000; function func(): number { diff --git a/HapAndHarDependHar/entry/src/main/resources/base/element/string.json b/HapAndHarDependHar/entry/src/main/resources/base/element/string.json index f94595515a99e0c828807e243494f57f09251930..47d750c25c23e102a481e5ab3727ee748db572cf 100644 --- a/HapAndHarDependHar/entry/src/main/resources/base/element/string.json +++ b/HapAndHarDependHar/entry/src/main/resources/base/element/string.json @@ -10,7 +10,7 @@ }, { "name": "EntryAbility_label", - "value": "label" + "value": "HapAndHarDependHar" } ] } \ No newline at end of file diff --git a/HapAndHarDependHar/har_common/obfuscation-rules.txt b/HapAndHarDependHar/har_common/obfuscation-rules.txt index 985b2aeb7658286b17bd26eab8f217c3fe75ea8b..a1dfa0bd175984dc49e641436aa67b1de1b8abeb 100644 --- a/HapAndHarDependHar/har_common/obfuscation-rules.txt +++ b/HapAndHarDependHar/har_common/obfuscation-rules.txt @@ -15,4 +15,8 @@ # Keep options: # -keep-property-name: specifies property names that you want to keep -# -keep-global-name: specifies names that you want to keep in the global scope \ No newline at end of file +# -keep-global-name: specifies names that you want to keep in the global scope +-enable-property-obfuscation +-enable-toplevel-obfuscation +-enable-filename-obfuscation +-enable-export-obfuscation \ No newline at end of file diff --git a/HapAndHarDependHar/har_library/obfuscation-rules.txt b/HapAndHarDependHar/har_library/obfuscation-rules.txt index 985b2aeb7658286b17bd26eab8f217c3fe75ea8b..a1dfa0bd175984dc49e641436aa67b1de1b8abeb 100644 --- a/HapAndHarDependHar/har_library/obfuscation-rules.txt +++ b/HapAndHarDependHar/har_library/obfuscation-rules.txt @@ -15,4 +15,8 @@ # Keep options: # -keep-property-name: specifies property names that you want to keep -# -keep-global-name: specifies names that you want to keep in the global scope \ No newline at end of file +# -keep-global-name: specifies names that you want to keep in the global scope +-enable-property-obfuscation +-enable-toplevel-obfuscation +-enable-filename-obfuscation +-enable-export-obfuscation \ No newline at end of file diff --git a/HapAndHarDependHar/har_library/oh-package-lock.json5 b/HapAndHarDependHar/har_library/oh-package-lock.json5 index 587ad773b07c8bbd8891d9da47d8eccef105c449..80997756525f69154f109e8866a4fd1af88b2702 100644 --- a/HapAndHarDependHar/har_library/oh-package-lock.json5 +++ b/HapAndHarDependHar/har_library/oh-package-lock.json5 @@ -1,6 +1,7 @@ { "meta": { - "stableOrder": true + "stableOrder": true, + "enableUnifiedLockfile": false }, "lockfileVersion": 3, "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", @@ -11,7 +12,7 @@ "har_common@../har_common": { "name": "har_common", "version": "1.0.0", - "resolved": "../har_common", + "resolved": "", "registryType": "local" } } diff --git a/HapAndHarDependHar/har_library/oh_modules/har_common/obfuscation-rules.txt b/HapAndHarDependHar/har_library/oh_modules/har_common/obfuscation-rules.txt index 985b2aeb7658286b17bd26eab8f217c3fe75ea8b..a1dfa0bd175984dc49e641436aa67b1de1b8abeb 100644 --- a/HapAndHarDependHar/har_library/oh_modules/har_common/obfuscation-rules.txt +++ b/HapAndHarDependHar/har_library/oh_modules/har_common/obfuscation-rules.txt @@ -15,4 +15,8 @@ # Keep options: # -keep-property-name: specifies property names that you want to keep -# -keep-global-name: specifies names that you want to keep in the global scope \ No newline at end of file +# -keep-global-name: specifies names that you want to keep in the global scope +-enable-property-obfuscation +-enable-toplevel-obfuscation +-enable-filename-obfuscation +-enable-export-obfuscation \ No newline at end of file diff --git a/HapAndHarDependHar/har_library/oh_modules/har_common/src/main/ets/utils/Utils.ets b/HapAndHarDependHar/har_library/oh_modules/har_common/src/main/ets/utils/Utils.ets index 4742ef515534d31b3afec2ebe7d4d8e9d0c5cc30..df7da42fbb590a57b1872f8d823fd66672baea05 100644 --- a/HapAndHarDependHar/har_library/oh_modules/har_common/src/main/ets/utils/Utils.ets +++ b/HapAndHarDependHar/har_library/oh_modules/har_common/src/main/ets/utils/Utils.ets @@ -18,6 +18,7 @@ */ // [Start large_number] +// har_common/src/main/ets/utils/Utils.ets const LARGE_NUMBER = 100000000; function func(): number { diff --git a/HapAndHarDependHar/oh_modules/.ohpm/lock.json5 b/HapAndHarDependHar/oh_modules/.ohpm/lock.json5 index ad44038f8d695b06caeac6a0ab32d1b5ca0f3f68..ddfb1a8569ff40fa5e8e083caad13784407cf989 100644 --- a/HapAndHarDependHar/oh_modules/.ohpm/lock.json5 +++ b/HapAndHarDependHar/oh_modules/.ohpm/lock.json5 @@ -52,19 +52,19 @@ } }, "packages": { - "har_library@file:har_library": { - "storePath": "har_library", - "dependencies": { - "har_common": "har_common" - }, + "har_common@file:har_common": { + "storePath": "har_common", + "dependencies": {}, "dynamicDependencies": {}, "dev": false, "dynamic": false, "maskedByOverrideDependencyMap": false }, - "har_common@file:har_common": { - "storePath": "har_common", - "dependencies": {}, + "har_library@file:har_library": { + "storePath": "har_library", + "dependencies": { + "har_common": "har_common" + }, "dynamicDependencies": {}, "dev": false, "dynamic": false, diff --git a/HpDemo/AppScope/app.json5 b/HpDemo/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..82b55ac4c9c2b13944600aef4e6d0c7d4b1487b7 --- /dev/null +++ b/HpDemo/AppScope/app.json5 @@ -0,0 +1,10 @@ +{ + "app": { + "bundleName": "com.example.hpdemo", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:layered_image", + "label": "$string:app_name" + } +} diff --git a/HpDemo/AppScope/resources/base/element/string.json b/HpDemo/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..16fb31e3d2a2afec77534d8e66606c76b5ca697c --- /dev/null +++ b/HpDemo/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "HpDemo" + } + ] +} diff --git a/HpDemo/AppScope/resources/base/media/background.png b/HpDemo/AppScope/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/HpDemo/AppScope/resources/base/media/background.png differ diff --git a/HpDemo/AppScope/resources/base/media/foreground.png b/HpDemo/AppScope/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..eb9427585b36d14b12477435b6419d1f07b3e0bb Binary files /dev/null and b/HpDemo/AppScope/resources/base/media/foreground.png differ diff --git a/NativeSoIntegration/Multiply/src/main/resources/base/media/layered_image.json b/HpDemo/AppScope/resources/base/media/layered_image.json similarity index 100% rename from NativeSoIntegration/Multiply/src/main/resources/base/media/layered_image.json rename to HpDemo/AppScope/resources/base/media/layered_image.json diff --git a/HpDemo/build-profile.json5 b/HpDemo/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..d3fe3beb28b59a5e0318d7d915aa9864359099e0 --- /dev/null +++ b/HpDemo/build-profile.json5 @@ -0,0 +1,42 @@ +{ + "app": { + "signingConfigs": [], + "products": [ + { + "name": "default", + "signingConfig": "default", + "targetSdkVersion": "5.1.1(19)", + "compatibleSdkVersion": "5.1.1(19)", + "runtimeOS": "HarmonyOS", + "buildOption": { + "strictMode": { + "caseSensitiveCheck": true, + "useNormalizedOHMUrl": true + } + } + } + ], + "buildModeSet": [ + { + "name": "debug", + }, + { + "name": "release" + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/HpDemo/entry/build-profile.json5 b/HpDemo/entry/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..4d611879c7913fb0610c686e2399258ab3a6dad1 --- /dev/null +++ b/HpDemo/entry/build-profile.json5 @@ -0,0 +1,28 @@ +{ + "apiType": "stageMode", + "buildOption": { + }, + "buildOptionSet": [ + { + "name": "release", + "arkOptions": { + "obfuscation": { + "ruleOptions": { + "enable": false, + "files": [ + "./obfuscation-rules.txt" + ] + } + } + } + }, + ], + "targets": [ + { + "name": "default" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/HpDemo/entry/hvigorfile.ts b/HpDemo/entry/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..b0e3a1ab98a91bc918d6404b2413111a5011f14a --- /dev/null +++ b/HpDemo/entry/hvigorfile.ts @@ -0,0 +1,6 @@ +import { hapTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins: [] /* Custom plugin to extend the functionality of Hvigor. */ +} \ No newline at end of file diff --git a/HpDemo/entry/obfuscation-rules.txt b/HpDemo/entry/obfuscation-rules.txt new file mode 100644 index 0000000000000000000000000000000000000000..272efb6ca3f240859091bbbfc7c5802d52793b0b --- /dev/null +++ b/HpDemo/entry/obfuscation-rules.txt @@ -0,0 +1,23 @@ +# Define project specific obfuscation rules here. +# You can include the obfuscation configuration files in the current module's build-profile.json5. +# +# For more details, see +# https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5 + +# Obfuscation options: +# -disable-obfuscation: disable all obfuscations +# -enable-property-obfuscation: obfuscate the property names +# -enable-toplevel-obfuscation: obfuscate the names in the global scope +# -compact: remove unnecessary blank spaces and all line feeds +# -remove-log: remove all console.* statements +# -print-namecache: print the name cache that contains the mapping from the old names to new names +# -apply-namecache: reuse the given cache file + +# Keep options: +# -keep-property-name: specifies property names that you want to keep +# -keep-global-name: specifies names that you want to keep in the global scope + +-enable-property-obfuscation +-enable-toplevel-obfuscation +-enable-filename-obfuscation +-enable-export-obfuscation \ No newline at end of file diff --git a/HpDemo/entry/oh-package.json5 b/HpDemo/entry/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..248c3b7541a589682a250f86a6d3ecf7414d2d6a --- /dev/null +++ b/HpDemo/entry/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "name": "entry", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "", + "author": "", + "license": "", + "dependencies": {} +} + diff --git a/HpDemo/entry/src/main/ets/entryability/EntryAbility.ets b/HpDemo/entry/src/main/ets/entryability/EntryAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..29169f015d52b3f2d722582e5c881577e8788070 --- /dev/null +++ b/HpDemo/entry/src/main/ets/entryability/EntryAbility.ets @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + +import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; +import { BusinessError } from '@kit.BasicServicesKit'; + +const DOMAIN = 0x0000; + +export default class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + try { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + } catch (err) { + let error = err as BusinessError; + hilog.error(DOMAIN, 'testTag', `Failed to set colorMode. code=${error.code}, message=${error.message}`); + } + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onDestroy(): void { + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + // Main window is created, set main page for this ability + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + windowStage.loadContent('pages/Index', (err) => { + if (err.code) { + hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err)); + return; + } + hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.'); + }); + } + + onWindowStageDestroy(): void { + // Main window is destroyed, release UI related resources + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground(): void { + // Ability has brought to foreground + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground(): void { + // Ability has back to background + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground'); + } +} \ No newline at end of file diff --git a/HpDemo/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets b/HpDemo/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..0a97e21bd7a15599af76a806695860ff1eb0ebfe --- /dev/null +++ b/HpDemo/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit'; + +const DOMAIN = 0x0000; + +export default class EntryBackupAbility extends BackupExtensionAbility { + async onBackup() { + hilog.info(DOMAIN, 'testTag', 'onBackup ok'); + await Promise.resolve(); + } + + async onRestore(bundleVersion: BundleVersion) { + hilog.info(DOMAIN, 'testTag', 'onRestore ok %{public}s', JSON.stringify(bundleVersion)); + await Promise.resolve(); + } +} \ No newline at end of file diff --git a/HpDemo/entry/src/main/ets/pages/Index.ets b/HpDemo/entry/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..5fff919f6f85fb15bc09d88ec703248e63e9c00f --- /dev/null +++ b/HpDemo/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + +import { display, window } from '@kit.ArkUI'; +import { common } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { BusinessError } from '@kit.BasicServicesKit'; + +@Entry +@Component +struct Index { + @State availableHeightVal1: string = ''; + @State availableHeightVal2: string = ''; + + aboutToAppear(): void { + try { + this.availableHeightVal1 = display.getDisplayByIdSync(0).availableHeight.toString(); + this.availableHeightVal2 = display.getDisplayByIdSync(999).availableHeight.toString(); + } catch (err) { + let error = err as BusinessError; + hilog.error(0x000, 'testTag', `get availableHeight failed. code=${error.code}, message=${error.message}`); + } + } + + build() { + Column() { + Text(this.availableHeightVal1) + Text(this.availableHeightVal2) + Button('remove') + .onClick(async () => { + try { + // [Start moveWindow] + let mainWindow = + (this.getUIContext().getHostContext() as common.UIAbilityContext).windowStage.getMainWindowSync(); + let moveConfiguration: window.MoveConfiguration = { + displayId: 0 + }; + await mainWindow.moveWindowToGlobal(0, 0, moveConfiguration); + // [End moveWindow] + // [Start resizeWindow] + let rectWidth = Number(display.getDisplayByIdSync(0).availableWidth); + let foldCreaseRegion = display.getCurrentFoldCreaseRegion().creaseRects[0].height; + let rectHeight = Number(display.getDisplayByIdSync(0).availableHeight) + + Number(display.getDisplayByIdSync(999).availableHeight) + Number(foldCreaseRegion); + mainWindow.resizeAsync(rectWidth, rectHeight) + .then(() => { + hilog.info(0x000, 'testTag', `resizeAsync succeed.`); + }) + .catch((error: BusinessError) => { + hilog.error(0x000, 'testTag', `resizeAsync falied. code=${error.code}, message=${error.message}`); + }) + // [End resizeWindow] + } catch (exception) { + hilog.error(0x0000, 'test', + `Failed to move the window. Cause code: ${exception.code}, message: ${exception.message}`); + } + }) + } + .height('100%') + .width('100%') + } +} \ No newline at end of file diff --git a/HpDemo/entry/src/main/module.json5 b/HpDemo/entry/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..b55220245fbd2bb3100a1cb02f4b9e60f2d72a49 --- /dev/null +++ b/HpDemo/entry/src/main/module.json5 @@ -0,0 +1,52 @@ +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ets", + "description": "$string:EntryAbility_desc", + "icon": "$media:layered_image", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:startIcon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "ohos.want.action.home" + ] + } + ] + } + ], + "extensionAbilities": [ + { + "name": "EntryBackupAbility", + "srcEntry": "./ets/entrybackupability/EntryBackupAbility.ets", + "type": "backup", + "exported": false, + "metadata": [ + { + "name": "ohos.extension.backup", + "resource": "$profile:backup_config" + } + ], + } + ] + } +} \ No newline at end of file diff --git a/MultiPictureBeautification/product/phone/src/main/resources/base/element/color.json b/HpDemo/entry/src/main/resources/base/element/color.json similarity index 100% rename from MultiPictureBeautification/product/phone/src/main/resources/base/element/color.json rename to HpDemo/entry/src/main/resources/base/element/color.json diff --git a/HpDemo/entry/src/main/resources/base/element/float.json b/HpDemo/entry/src/main/resources/base/element/float.json new file mode 100644 index 0000000000000000000000000000000000000000..33ea22304f9b1485b5f22d811023701b5d4e35b6 --- /dev/null +++ b/HpDemo/entry/src/main/resources/base/element/float.json @@ -0,0 +1,8 @@ +{ + "float": [ + { + "name": "page_text_font_size", + "value": "50fp" + } + ] +} diff --git a/HpDemo/entry/src/main/resources/base/element/string.json b/HpDemo/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/HpDemo/entry/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/HpDemo/entry/src/main/resources/base/media/background.png b/HpDemo/entry/src/main/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/HpDemo/entry/src/main/resources/base/media/background.png differ diff --git a/HpDemo/entry/src/main/resources/base/media/foreground.png b/HpDemo/entry/src/main/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f Binary files /dev/null and b/HpDemo/entry/src/main/resources/base/media/foreground.png differ diff --git a/NativeSoIntegration/Ndk/src/main/resources/base/media/layered_image.json b/HpDemo/entry/src/main/resources/base/media/layered_image.json similarity index 100% rename from NativeSoIntegration/Ndk/src/main/resources/base/media/layered_image.json rename to HpDemo/entry/src/main/resources/base/media/layered_image.json diff --git a/NativeSoIntegration/Multiply/src/main/resources/base/media/startIcon.png b/HpDemo/entry/src/main/resources/base/media/startIcon.png similarity index 100% rename from NativeSoIntegration/Multiply/src/main/resources/base/media/startIcon.png rename to HpDemo/entry/src/main/resources/base/media/startIcon.png diff --git a/HpDemo/entry/src/main/resources/base/profile/backup_config.json b/HpDemo/entry/src/main/resources/base/profile/backup_config.json new file mode 100644 index 0000000000000000000000000000000000000000..78f40ae7c494d71e2482278f359ec790ca73471a --- /dev/null +++ b/HpDemo/entry/src/main/resources/base/profile/backup_config.json @@ -0,0 +1,3 @@ +{ + "allowToBackupRestore": true +} \ No newline at end of file diff --git a/MultiDeviceCommunication/products/phone/src/main/resources/base/profile/main_pages.json b/HpDemo/entry/src/main/resources/base/profile/main_pages.json similarity index 100% rename from MultiDeviceCommunication/products/phone/src/main/resources/base/profile/main_pages.json rename to HpDemo/entry/src/main/resources/base/profile/main_pages.json diff --git a/HpDemo/entry/src/main/resources/dark/element/color.json b/HpDemo/entry/src/main/resources/dark/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..79b11c2747aec33e710fd3a7b2b3c94dd9965499 --- /dev/null +++ b/HpDemo/entry/src/main/resources/dark/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#000000" + } + ] +} \ No newline at end of file diff --git a/HpDemo/hvigor/hvigor-config.json5 b/HpDemo/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..6f008c99c91ca502036e67232e4c089e0421aefc --- /dev/null +++ b/HpDemo/hvigor/hvigor-config.json5 @@ -0,0 +1,22 @@ +{ + "modelVersion": "5.1.1", + "dependencies": { + }, + "execution": { + // "analyze": "normal", /* Define the build analyze mode. Value: [ "normal" | "advanced" | false ]. Default: "normal" */ + // "daemon": true, /* Enable daemon compilation. Value: [ true | false ]. Default: true */ + // "incremental": true, /* Enable incremental compilation. Value: [ true | false ]. Default: true */ + // "parallel": true, /* Enable parallel compilation. Value: [ true | false ]. Default: true */ + // "typeCheck": false, /* Enable typeCheck. Value: [ true | false ]. Default: false */ + }, + "logging": { + // "level": "info" /* Define the log level. Value: [ "debug" | "info" | "warn" | "error" ]. Default: "info" */ + }, + "debugging": { + // "stacktrace": false /* Disable stacktrace compilation. Value: [ true | false ]. Default: false */ + }, + "nodeOptions": { + // "maxOldSpaceSize": 8192 /* Enable nodeOptions maxOldSpaceSize compilation. Unit M. Used for the daemon process. Default: 8192*/ + // "exposeGC": true /* Enable to trigger garbage collection explicitly. Default: true*/ + } +} diff --git a/HpDemo/hvigorfile.ts b/HpDemo/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..47113e2e36ecefde41c136272a0bd6ff745cffe4 --- /dev/null +++ b/HpDemo/hvigorfile.ts @@ -0,0 +1,6 @@ +import { appTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins: [] /* Custom plugin to extend the functionality of Hvigor. */ +} \ No newline at end of file diff --git a/AdaptiveCapabilities/local.properties b/HpDemo/local.properties similarity index 94% rename from AdaptiveCapabilities/local.properties rename to HpDemo/local.properties index 7199108af44dc22a99a367d3e63af71854dfe3f7..20f608699522ce5b5f170457336fbfbf96165c62 100644 --- a/AdaptiveCapabilities/local.properties +++ b/HpDemo/local.properties @@ -5,4 +5,5 @@ # as it contains information specific to your local configuration. # # For customization when using a Version Control System, please read the header note. -sdk.dir=D:/sdk_home \ No newline at end of file + + diff --git a/HpDemo/oh-package.json5 b/HpDemo/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..052cc24d6e7b3f754ab5557652fd9db52c4c2549 --- /dev/null +++ b/HpDemo/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "modelVersion": "5.1.1", + "description": "Please describe the basic information.", + "dependencies": { + }, + "devDependencies": { + "@ohos/hypium": "1.0.21", + "@ohos/hamock": "1.0.0" + } +} diff --git a/ImageEditTaskPool/README.md b/ImageEditTaskPool/README.md index ca7368520c0298a2564a62954abc108ddd1eb04b..3f082ba09555d3341ee6fde54ced1c30d71f49d7 100644 --- a/ImageEditTaskPool/README.md +++ b/ImageEditTaskPool/README.md @@ -25,7 +25,9 @@ │ ├──view │ │ ├──AdjustContentView.ets // 色域调整视图 │ │ ├──CommBackgroundIcon.ets // 公共带背景色icon -│ │ └──TitleBar.ets // 顶部工具栏 +│ │ ├──newBuffer1.ets +│ │ ├──TitleBar.ets // 顶部工具栏 +│ │ └──WorkerPort.ets │ └──viewmodel │ ├──IconListViewModel.ets // icon数据 │ ├──MessageItem.ets // 多线程封装消息 @@ -51,6 +53,17 @@ ### 约束与限制 1. 本示例仅支持标准系统上运行,支持设备:华为手机。 -2. HarmonyOS系统:HarmonyOS NEXT Release及以上。 -3. DevEco Studio版本:DevEco Studio NEXT Release及以上。 -4. HarmonyOS SDK版本:HarmonyOS NEXT Release SDK及以上。 \ No newline at end of file +2. HarmonyOS系统:HarmonyOS 5.0.5 Release及以上。 +3. DevEco Studio版本:DevEco Studio 5.0.5 Release及以上。 +4. HarmonyOS SDK版本:HarmonyOS 5.0.5 Release SDK及以上。 + +### 下载 + +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set ImageEditTaskPool +git checkout +``` \ No newline at end of file diff --git a/ImageEditTaskPool/build-profile.json5 b/ImageEditTaskPool/build-profile.json5 index 1d12140d202702d7c73d64f1b291fe5c45a660ce..69cf13d77e884ca9452a4542f84e6475705b0474 100644 --- a/ImageEditTaskPool/build-profile.json5 +++ b/ImageEditTaskPool/build-profile.json5 @@ -5,7 +5,8 @@ { "name": "default", "signingConfig": "default", - "compatibleSdkVersion": "5.0.0(12)", + "compatibleSdkVersion": "5.0.5(17)", + "targetSdkVersion": "5.0.5(17)", "runtimeOS": "HarmonyOS" } ] diff --git a/ImageEditTaskPool/entry/src/main/ets/common/constant/CommonConstants.ets b/ImageEditTaskPool/entry/src/main/ets/common/constant/CommonConstants.ets index 765cde5c37efadc88488fbeb466131afb9e1715a..0f551cda2c60bca359e6cad1bc3704a85534e370 100644 --- a/ImageEditTaskPool/entry/src/main/ets/common/constant/CommonConstants.ets +++ b/ImageEditTaskPool/entry/src/main/ets/common/constant/CommonConstants.ets @@ -18,5 +18,10 @@ export class CommonConstants { * Adjust slider value. */ static readonly ADJUST_SLIDER_VALUE: number[] = [100, 100, 100]; - static readonly PIXEL_STEP:number + static readonly PIXEL_STEP: number; + + /** + * Slider step. + */ + static readonly SLIDER_MAX: number = 100; } \ No newline at end of file diff --git a/ImageEditTaskPool/entry/src/main/ets/entryability/EntryAbility.ets b/ImageEditTaskPool/entry/src/main/ets/entryability/EntryAbility.ets index a910cbde1b62e24cac154651d7e996c5a8152ef0..969ae52a030e9b743525ec7950b803ef4758479c 100644 --- a/ImageEditTaskPool/entry/src/main/ets/entryability/EntryAbility.ets +++ b/ImageEditTaskPool/entry/src/main/ets/entryability/EntryAbility.ets @@ -48,36 +48,45 @@ export default class EntryAbility extends UIAbility { } }); - let windowClass: window.Window = windowStage.getMainWindowSync(); - windowClass.setWindowLayoutFullScreen(true); - - let SystemBarProperties: window.SystemBarProperties = { - statusBarContentColor: '#FFFFFF' - }; - let promise = windowClass.setWindowSystemBarProperties(SystemBarProperties); - promise.then(() => { - hilog.info(0x0000, TAG, 'Succeeded in setting the system bar properties.'); - }).catch((err: BusinessError) => { - hilog.error(0x0000, TAG, - `Failed to set the system bar properties. Cause code: ${err.code}, message: ${err.message}`); - }); - + let windowClass: window.Window; + try { + windowClass = windowStage.getMainWindowSync(); + windowClass.setWindowLayoutFullScreen(true).catch((err: BusinessError) => { + hilog.error(0x0000, TAG, 'Failed to set window layout full screen. Cause: %{public}s', + JSON.stringify(err) ?? ''); + }); + let SystemBarProperties: window.SystemBarProperties = { + statusBarContentColor: '#FFFFFF' + }; + windowClass.setWindowSystemBarProperties(SystemBarProperties).then(() => { + hilog.info(0x0000, TAG, 'Succeeded in setting the system bar properties.'); + }).catch((err: BusinessError) => { + hilog.error(0x0000, TAG, + `Failed to set the system bar properties. Cause code: ${err.code}, message: ${err.message}`); + }); + } catch (err) { + hilog.error(0x0000, TAG, 'Failed to get main window. Cause: %{public}s', + JSON.stringify(err) ?? ''); + } - windowStage.loadContent('pages/HomePage', (err, data) => { + windowStage.loadContent('pages/HomePage', (err) => { if (err.code) { hilog.error(0x0000, TAG, 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); return; } - const uiContext = windowClass.getUIContext(); - AppStorage.setOrCreate('uiContext', uiContext); - let navigationBarArea: window.AvoidArea = - windowClass.getWindowAvoidArea(window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR); - let area: window.AvoidArea = windowClass.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM); - AppStorage.setOrCreate('naviIndicatorHeight', uiContext.px2vp(navigationBarArea.bottomRect.height)); - AppStorage.setOrCreate('statusBarHeight', uiContext.px2vp(area.topRect.height)); - hilog.info(0x0000, TAG, 'Succeeded in loading the content. Data: %{public}s', - JSON.stringify(data) ?? ''); + try { + const uiContext = windowClass.getUIContext(); + AppStorage.setOrCreate('uiContext', uiContext); + let navigationBarArea: window.AvoidArea = + windowClass.getWindowAvoidArea(window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR); + let area: window.AvoidArea = windowClass.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM); + AppStorage.setOrCreate('naviIndicatorHeight', uiContext.px2vp(navigationBarArea.bottomRect.height)); + AppStorage.setOrCreate('statusBarHeight', uiContext.px2vp(area.topRect.height)); + } catch (err) { + hilog.error(0x0000, TAG, 'Failed to load the content. Cause: %{public}s', + JSON.stringify(err) ?? ''); + } }); } diff --git a/ImageEditTaskPool/entry/src/main/ets/utils/AdjustUtil.ts b/ImageEditTaskPool/entry/src/main/ets/utils/AdjustUtil.ts index b952c3593834ddd41ce206e0cd2e8f1c338fb129..94df19528aad9ccbcee812624d37901612aad24c 100644 --- a/ImageEditTaskPool/entry/src/main/ets/utils/AdjustUtil.ts +++ b/ImageEditTaskPool/entry/src/main/ets/utils/AdjustUtil.ts @@ -13,29 +13,7 @@ * limitations under the License. */ -import { RGBIndex, HSVIndex, AngelRange } from '../viewModel/OptionViewModel'; - -/** - * Saturation adjust. - * - * @param pixelMap. - * @param value saturation's value. - * @return arrayBuffer. - */ -export function adjustSaturation(bufferArray: ArrayBuffer, last: number, cur: number): ArrayBuffer | undefined { - return execColorInfo(bufferArray, last, cur, HSVIndex.SATURATION); -} - -/** - * Image brightness adjust. - * - * @param pixelMap. - * @param value image's brigtness. - * @return arrayBuffer. - */ -export function adjustImageValue(bufferArray: ArrayBuffer, last: number, cur: number): ArrayBuffer | undefined { - return execColorInfo(bufferArray, last, cur, HSVIndex.VALUE); -} +import { AdjustId } from '../viewModel/OptionViewModel'; /** * Exec color transform. @@ -46,141 +24,63 @@ export function adjustImageValue(bufferArray: ArrayBuffer, last: number, cur: nu * @param hsvIndex. * @return arrayBuffer. */ -export function execColorInfo(bufferArray: ArrayBuffer, last: number, cur: number, - hsvIndex: number): ArrayBuffer | undefined { - if (!bufferArray) { - return; +export function execColorInfo(bufferArray: ArrayBuffer, last: number, cur: number, hsvIndex: number) { + if (!bufferArray || bufferArray.byteLength === 0) { + return null; } - const newBufferArr = bufferArray; - let colorInfo = new Uint8Array(newBufferArr); - for (let i = 0; i < colorInfo?.length; i += 4) { - const hsv = rgb2hsv(colorInfo[i + RGBIndex.RED], colorInfo[i + RGBIndex.GREEN], colorInfo[i + RGBIndex.BLUE]); - let rate = cur / last; - hsv[hsvIndex] *= rate; - const rgb = hsv2rgb(hsv[HSVIndex.HUE], hsv[HSVIndex.SATURATION], hsv[HSVIndex.VALUE]); - colorInfo[i + RGBIndex.RED] = rgb[RGBIndex.RED]; - colorInfo[i + RGBIndex.GREEN] = rgb[RGBIndex.GREEN]; - colorInfo[i + RGBIndex.BLUE] = rgb[RGBIndex.BLUE]; + + if (last <= 0 || cur < 0) { + return null; } - return newBufferArr; -} -/** - * Color transform. - * - * @param rgbValue 0 - 255. - * @return 0 - 1. - */ -function colorTransform(rgbValue: number): number { - return Number((rgbValue / 255).toFixed(2)); -} + try { + const pixelData = new Uint8ClampedArray(bufferArray); + const adjustedData = new Uint8ClampedArray(pixelData.length); + const bytesPerPixel = 4; + const factor = cur / 100; // Regulatory factor + for (let i = 0; i < pixelData.length; i += bytesPerPixel) { + // Reserve the alpha channel + adjustedData[i + 3] = pixelData[i + 3]; -/** - * RGB transform to HSV. - * - * @param red 0- 255. - * @param green 0- 255. - * @param blue 0- 255. - * @return h (0 - 360) s(0 - 100) v (0 - 100). - */ -function rgb2hsv(red: number, green: number, blue: number): number[] { - let hsvH: number = 0, hsvS: number = 0, hsvV: number = 0; - const rgbR: number = colorTransform(red); - const rgbG: number = colorTransform(green); - const rgbB: number = colorTransform(blue); - const maxValue = Math.max(rgbR, Math.max(rgbG, rgbB)); - const minValue = Math.min(rgbR, Math.min(rgbG, rgbB)); - hsvV = maxValue * 100; - if (maxValue === 0) { - hsvS = 0; - } else { - hsvS = Number((1 - minValue / maxValue).toFixed(2)) * 100; - } - if (maxValue === minValue) { - hsvH = 0; - } - if (maxValue === rgbR && rgbG >= rgbB) { - hsvH = Math.floor(60 * ((rgbG - rgbB) / (maxValue - minValue))); - } - if (maxValue === rgbR && rgbG < rgbB) { - hsvH = Math.floor(60 * ((rgbG - rgbB) / (maxValue - minValue)) + 360); - } - if (maxValue === rgbG) { - hsvH = Math.floor(60 * ((rgbB - rgbR) / (maxValue - minValue)) + 120); - } - if (maxValue === rgbB) { - hsvH = Math.floor(60 * ((rgbR - rgbG) / (maxValue - minValue)) + 240); - } - return [hsvH, hsvS, hsvV]; -} + // Skip the pixels that are completely transparent + if (pixelData[i + 3] < 1) { + continue; + } -/** - * HSV to RGB conversion formula: - * When 0 <= H <= 360, 0 <= S <= 1 and 0 <= V <= 1: - * C = V * S - * X = C * (1 - Math.abs((H / 60) mod 2 - 1)) - * m = V - C - * | (C, X ,0), 0 <= H < 60 - * | (X, C, 0), 60 <= H < 120 - * | (0, C, X), 120 <= H < 180 - * (R', G', B') = | (0, X, C), 180 <= H < 240 - * | (X, 0, C), 240 <= H < 300 - * | (C, 0, X), 300 <= H < 360 - * - * (R, G, B) = ((R' + m) * 255, (G' + m) * 255, (B' + m) * 255) - * - * @param h hue 0 ~ 360. - * @param s saturation 0 ~ 100. - * @param v value 0 ~ 100. - * @return rgb value. - */ -function hsv2rgb(hue: number, saturation: number, value: number) { - let rgbR: number = 0, rgbG: number = 0, rgbB: number = 0; - if (saturation === 0) { - rgbR = rgbG = rgbB = Math.round((value * 255) / 100); - return { rgbR, rgbG, rgbB }; - } - const cxmC = (value * saturation) / (100 * 100); - const cxmX = cxmC * (1 - Math.abs((hue / 60) % 2 - 1)); - const cxmM = (value - cxmC * 100) / 100; - const hsvHRange = Math.floor(hue / 60); - switch (hsvHRange) { - case AngelRange.ANGEL_0_60: - rgbR = (cxmC + cxmM) * 255; - rgbG = (cxmX + cxmM) * 255; - rgbB = (0 + cxmM) * 255; - break; - case AngelRange.ANGEL_60_120: - rgbR = (cxmX + cxmM) * 255; - rgbG = (cxmC + cxmM) * 255; - rgbB = (0 + cxmM) * 255; - break; - case AngelRange.ANGEL_120_180: - rgbR = (0 + cxmM) * 255; - rgbG = (cxmC + cxmM) * 255; - rgbB = (cxmX + cxmM) * 255; - break; - case AngelRange.ANGEL_180_240: - rgbR = (0 + cxmM) * 255; - rgbG = (cxmX + cxmM) * 255; - rgbB = (cxmC + cxmM) * 255; - break; - case AngelRange.ANGEL_240_300: - rgbR = (cxmX + cxmM) * 255; - rgbG = (0 + cxmM) * 255; - rgbB = (cxmC + cxmM) * 255; - break; - case AngelRange.ANGEL_300_360: - rgbR = (cxmC + cxmM) * 255; - rgbG = (0 + cxmM) * 255; - rgbB = (cxmX + cxmM) * 255; - break; - default: - break; + if (hsvIndex === AdjustId.BRIGHTNESS) { + // Calculate adjusted RGB values (keep relative proportions) + let r = pixelData[i] * factor; + let g = pixelData[i + 1] * factor; + let b = pixelData[i + 2] * factor; + + // Ensure the value is in the valid range (0-255) + adjustedData[i] = Math.max(0, Math.min(255, Math.round(r))); + adjustedData[i + 1] = Math.max(0, Math.min(255, Math.round(g))); + adjustedData[i + 2] = Math.max(0, Math.min(255, Math.round(b))); + } + if (hsvIndex === AdjustId.SATURATION) { + // Extract the RGB value and normalize it + const r = pixelData[i] / 255; + const g = pixelData[i + 1] / 255; + const b = pixelData[i + 2] / 255; + + // Calculate the grayscale value + const luminance = 0.2126 * r + 0.7152 * g + 0.0722 * b; + + // Adjust saturation: move closer or further away from the grayscale value + const adjustedR = luminance + (r - luminance) * factor; + const adjustedG = luminance + (g - luminance) * factor; + const adjustedB = luminance + (b - luminance) * factor; + + // Convert back to the 0-255 range and write to the buffer + adjustedData[i] = Math.max(0, Math.min(255, Math.round(adjustedR * 255))); + adjustedData[i + 1] = Math.max(0, Math.min(255, Math.round(adjustedG * 255))); + adjustedData[i + 2] = Math.max(0, Math.min(255, Math.round(adjustedB * 255))); + } + } + return adjustedData.buffer; + } catch (error) { + console.log(`Failed to set adjustedData: ${JSON.stringify(error.message)}`); + return null; } - return [ - Math.round(rgbR), - Math.round(rgbG), - Math.round(rgbB) - ]; } \ No newline at end of file diff --git a/ImageEditTaskPool/entry/src/main/ets/utils/DecodeUtil.ets b/ImageEditTaskPool/entry/src/main/ets/utils/DecodeUtil.ets index ee53b915c6aa8be725d933ab2f11608f715aa84d..db652b8357ce2fe1935ef8d38f934388dcaf3998 100644 --- a/ImageEditTaskPool/entry/src/main/ets/utils/DecodeUtil.ets +++ b/ImageEditTaskPool/entry/src/main/ets/utils/DecodeUtil.ets @@ -27,11 +27,17 @@ const TAG: string = '[DecodeUtil]'; async function getResourceFd(component: UIContext): Promise { const context = component.getHostContext()!; const resourceMgr = context.resourceManager; - let imageBuffer = await resourceMgr.getMediaContent($r('app.media.ic_low')); - let filePath = context.cacheDir + '/low.jpg'; - let file = fileIo.openSync(filePath, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE); - fileIo.writeSync(file.fd, imageBuffer.buffer); - return file.fd; + let res = -1; + try { + let imageBuffer = await resourceMgr.getMediaContent($r('app.media.ic_low').id); + let filePath = context.cacheDir + '/low.jpg'; + let file = fileIo.openSync(filePath, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE); + fileIo.writeSync(file.fd, imageBuffer.buffer); + res = file.fd; + } catch (err) { + hilog.error(0x0000, 'DecodeUtil', 'Failed to get resource fd: ', JSON.stringify(err) ?? ''); + } + return res; } /** diff --git a/ImageEditTaskPool/entry/src/main/ets/utils/EncodeUtil.ets b/ImageEditTaskPool/entry/src/main/ets/utils/EncodeUtil.ets index bfd292066f2478c03b3001cbd8db205f566dfd15..1c6c330c2517ca3764828a0bb2c9e50eeaacaeed 100644 --- a/ImageEditTaskPool/entry/src/main/ets/utils/EncodeUtil.ets +++ b/ImageEditTaskPool/entry/src/main/ets/utils/EncodeUtil.ets @@ -15,9 +15,9 @@ import { photoAccessHelper } from '@kit.MediaLibraryKit'; import { hilog } from '@kit.PerformanceAnalysisKit'; -import { promptAction } from '@kit.ArkUI'; import { fileIo } from '@kit.CoreFileKit'; import { image } from '@kit.ImageKit'; +import { BusinessError } from '@kit.BasicServicesKit'; const TAG: string = '[EncodeUtil]'; const context = AppStorage.get('uiContext') as UIContext; @@ -37,20 +37,26 @@ export async function encode(component: Object, pixelMap: PixelMap) { format: 'image/jpeg', quality: 100 } - const imageData = await imagePackerApi.packToData(newPixelMap, packOptions); - hilog.info(0x0000, TAG, '%{public}s', `imageData's length is ${imageData.byteLength}`); - // Create image asset. - let photoType: photoAccessHelper.PhotoType = photoAccessHelper.PhotoType.IMAGE; - let extension: string = 'jpg'; - phAccessHelper.createAsset(photoType, extension, (err, uri) => { - if (err) { - hilog.error(0x0000, TAG, 'createAsset ', JSON.stringify(err) ?? ''); - } - if (uri != undefined) { - let file = fileIo.openSync(uri, fileIo.OpenMode.READ_WRITE); - fileIo.writeSync(file.fd, imageData); - fileIo.close(file.fd); - context.getPromptAction().showToast({ message: $r('app.string.image_save') }); - } - }); + try { + const imageData = await imagePackerApi.packToData(newPixelMap, packOptions); + hilog.info(0x0000, TAG, '%{public}s', `imageData's length is ${imageData.byteLength}`); + // Create image asset. + let photoType: photoAccessHelper.PhotoType = photoAccessHelper.PhotoType.IMAGE; + let extension: string = 'jpg'; + phAccessHelper.createAsset(photoType, extension, (err, uri) => { + if (err) { + hilog.error(0x0000, TAG, 'createAsset ', JSON.stringify(err) ?? ''); + } + if (uri !== undefined) { + let file = fileIo.openSync(uri, fileIo.OpenMode.READ_WRITE); + fileIo.writeSync(file.fd, imageData); + fileIo.close(file.fd).catch((err: BusinessError) => { + hilog.error(0x0000, TAG, 'Failed to close: ', JSON.stringify(err) ?? ''); + }); + context.getPromptAction().showToast({ message: $r('app.string.image_save') }); + } + }); + } catch (err) { + hilog.error(0x0000, TAG, 'Failed to packToData: ', JSON.stringify(err) ?? ''); + } } \ No newline at end of file diff --git a/ImageEditTaskPool/entry/src/main/ets/view/AdjustContentView.ets b/ImageEditTaskPool/entry/src/main/ets/view/AdjustContentView.ets index 6a22217ac5ed91b5c9a250871ba39815b32b0d98..5486617678ffd079c22e870236d9b7203fd5ef3a 100644 --- a/ImageEditTaskPool/entry/src/main/ets/view/AdjustContentView.ets +++ b/ImageEditTaskPool/entry/src/main/ets/view/AdjustContentView.ets @@ -12,16 +12,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { MessageEvents, worker } from '@kit.ArkTS'; +import { worker } from '@kit.ArkTS'; import { taskpool } from '@kit.ArkTS'; import { image } from '@kit.ImageKit'; import { adjustIconList, IconStatus } from '../viewModel/IconListViewModel'; -import { adjustImageValue, adjustSaturation } from '../utils/AdjustUtil'; -import { AdjustId, HSVIndex, RGBIndex } from '../viewModel/OptionViewModel'; -import { adjustOpacity } from '../utils/OpacityUtil'; +import { execColorInfo } from '../utils/AdjustUtil'; +import { AdjustId } from '../viewModel/OptionViewModel'; import { MessageItem } from '../viewModel/MessageItem'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { BusinessError } from '@kit.BasicServicesKit'; import { CommonConstants } from '../common/constant/CommonConstants'; +const TAG = `AdjustContentView`; + @Component export default struct AdjustContentView { @State currentAdjustIndex: number = 0; @@ -121,6 +124,7 @@ struct SliderCustom { @Prop max: number; @Consume('pixelMap') pixelMap?: image.PixelMap; @Consume('isPixelMapChange') isPixelMapChange: boolean; + private startEditPixelMap?: PixelMap; private postState: boolean = true; saturationLastSlider: number = 100; brightnessLastSlider: number = 100; @@ -131,6 +135,10 @@ struct SliderCustom { customStyle: true }); + aboutToAppear(): void { + this.startEditPixelMap = this.pixelMap; + } + build() { Column() { Text(`${this.currentAdjustData[this.currentIndex]}`) @@ -163,32 +171,72 @@ struct SliderCustom { } } - sliderChange(value: number, mode: SliderChangeMode): void { + // [Start handleImage] + // ImageEditTaskPool/entry/src/main/ets/view/AdjustContentView.ets + async sliderChange(value: number, mode: SliderChangeMode) { + // [StartExclude handleImage] if ((mode === SliderChangeMode.End) && (value !== this.currentAdjustData[this.currentIndex])) { + if (this.postState) { + this.deviceListDialogController.open(); + } + this.postState = false; + this.currentAdjustData[this.currentIndex] = Math.round(value); - switch (this.currentIndex) { - case AdjustId.BRIGHTNESS: - this.postProcess(AdjustId.BRIGHTNESS, value); - break; - case AdjustId.TRANSPARENCY: - if (this.pixelMap) { - adjustOpacity(this.pixelMap, Math.round(value)) - .then((pixelMap?: image.PixelMap) => { - if (pixelMap) { - this.pixelMap = pixelMap; - this.isPixelMapChange = !this.isPixelMapChange; - } - }); + const px = this.getStartEditPixelMap(); + let buffer = new ArrayBuffer(px.getPixelBytesNumber()); + px.readPixelsToBufferSync(buffer); + + // [EndExclude handleImage] + const needBrightness = this.currentAdjustData[AdjustId.BRIGHTNESS] !== CommonConstants.SLIDER_MAX; + const needSaturation = this.currentAdjustData[AdjustId.SATURATION] !== CommonConstants.SLIDER_MAX; + if (needBrightness || needSaturation) { + try { + if (needBrightness) { + buffer = await this.execImageProcessing(buffer, AdjustId.BRIGHTNESS, this.currentAdjustData[AdjustId.BRIGHTNESS]); } - break; - case AdjustId.SATURATION: - this.postProcess(AdjustId.SATURATION, value); - break; - default: - break; + if (needSaturation) { + buffer = await this.execImageProcessing(buffer, AdjustId.SATURATION, this.currentAdjustData[AdjustId.SATURATION]); + } + px.writeBufferToPixelsSync(buffer); + } catch (err) { + let error = err as BusinessError; + hilog.error(0x0000, TAG, `${error.code}, ${error.message}`); + } } + + if (this.currentAdjustData[AdjustId.TRANSPARENCY] !== CommonConstants.SLIDER_MAX) { + const opacity = this.currentAdjustData[AdjustId.TRANSPARENCY] / CommonConstants.SLIDER_MAX; + try { + px.opacitySync(opacity); + } catch (err) { + let error = err as BusinessError; + hilog.error(0x0000, TAG, `${error.code}, ${error.message}`); + } + } + // [StartExclude handleImage] + + this.pixelMap = px; + this.isPixelMapChange = !this.isPixelMapChange; + this.deviceListDialogController.close(); + this.postState = true; + // [EndExclude handleImage] } } + // [End handleImage] + + // [Start execImageProcessing] + private async execImageProcessing(buffer: ArrayBuffer, type: AdjustId, value: number): Promise { + const buffers = splitArrayBuffer(buffer, 240); + const group = splitTask(buffers, type, value); + try { + return mergeArrayBuffers(await taskpool.execute(group, taskpool.Priority.HIGH) as ArrayBuffer[]); + } catch (err) { + let error = err as BusinessError; + hilog.error(0x0000, TAG, `${error.code}, ${error.message}`); + return buffer; + } + } + // [End execImageProcessing] // [Start postProcess_start] // ImageEditTaskPool/entry/src/main/ets/view/AdjustContentView.ets @@ -203,12 +251,14 @@ struct SliderCustom { this.pixelMap.readPixelsToBuffer(bufferArray) .then(() => { const buffers: ArrayBuffer[] = splitArrayBuffer(bufferArray, 240); - const group = splitTask(buffers, type, sliderValue, value); + const group = splitTask(buffers, type, value); // [StartExclude postProcess_start] // [Start execute_start] - taskpool.execute(group, taskpool.Priority.HIGH).then((ret) => { + taskpool.execute(group, taskpool.Priority.HIGH).catch((err: BusinessError) => { + hilog.error(0x0000, 'AdjustContentView', 'Failed to execute taskpool: ', JSON.stringify(err) ?? ''); + }).then((ret) => { // Combine the results of each task execution - const entireArrayBuffer = mergeArrayBuffers(ret); + const entireArrayBuffer = mergeArrayBuffers(ret as Object[]); // Update the UI based on the calculation results this.updatePixelMap(entireArrayBuffer); }); @@ -225,6 +275,7 @@ struct SliderCustom { // [EndExclude postProcess_start] }) } + // [StartExclude postProcess_start] updatePixelMap(ret: ArrayBuffer) { const newPixel = this.pixelMap as image.PixelMap; @@ -234,8 +285,31 @@ struct SliderCustom { this.deviceListDialogController.close(); this.postState = true; } + // [EndExclude postProcess_start] // [End postProcess_start] + + getStartEditPixelMap() { + return this.clonePixelMap(this.startEditPixelMap as image.PixelMap); + } + + clonePixelMap(pixelMap: PixelMap, desiredPixelFormat?: image.PixelMapFormat): PixelMap { + try { + const imageInfo = pixelMap.getImageInfoSync(); + const buffer = new ArrayBuffer(pixelMap.getPixelBytesNumber()); + pixelMap.readPixelsToBufferSync(buffer); + const options: image.InitializationOptions = { + srcPixelFormat: imageInfo.pixelFormat, + pixelFormat: desiredPixelFormat ?? imageInfo.pixelFormat, + size: imageInfo.size + }; + return image.createPixelMapSync(buffer, options); + } catch (err) { + let error = err as BusinessError; + hilog.error(0x0000, 'testTag', `${error.code}, ${error.message}`); + return pixelMap; + } + } } @CustomDialog @@ -253,69 +327,65 @@ export struct Dialog { } // [Start postProcess_start] +// [Start execImageProcessing] /** * Each task processes a portion of the pixel data and adds the task to the task group. * */ -function splitTask(buffers: ArrayBuffer[], type: AdjustId, sliderValue: number, value: number): taskpool.TaskGroup { +function splitTask(buffers: ArrayBuffer[], type: AdjustId, value: number): taskpool.TaskGroup { // Creating a Task Group let group: taskpool.TaskGroup = new taskpool.TaskGroup(); for (const buffer of buffers) { - group.addTask(imageProcessing, { - // Add a task to a task group - type, - bufferArray: buffer, - sliderValue, - value - }); + try { + group.addTask(imageProcessing, { + // Add a task to a task group + value: value, + buffer: buffer, + type: type + }); + } catch (err) { + hilog.error(0x0000, 'AdjustContentView', 'Failed to add the task: ', JSON.stringify(err) ?? ''); + } } return group; } +// [End execImageProcessing] // [End postProcess_start] @Concurrent async function imageProcessing(args: ImageProcessing) { - const type: AdjustId = args.type; - const bufferArray: ArrayBuffer = args.bufferArray; - const value: number = args.value; - const sliderValue: number = args.sliderValue; - if (type === AdjustId.BRIGHTNESS) { - return adjustImageValue(bufferArray, sliderValue, value); - } else if (type === AdjustId.SATURATION) { - return adjustSaturation(bufferArray, sliderValue, value); - } else { - return undefined; - } + const buf = execColorInfo(args.buffer, CommonConstants.SLIDER_MAX, args.value, args.type) as ArrayBuffer; + return buf; } interface ImageProcessing { type: AdjustId; - bufferArray: ArrayBuffer; - sliderValue: number; + buffer: ArrayBuffer; value: number; } // [Start split_buffer1] //Split the picture pixel data ArrayBuffer according to the number of tasks N. -function splitArrayBuffer(buffer: ArrayBuffer, n: number): ArrayBuffer[] { - let num = Math.floor(buffer.byteLength / n); - while (num % 4 !== 0) { - num += 1; - } +function splitArrayBuffer(buffer: ArrayBuffer, taskCount: number): ArrayBuffer[] { + const BYTES_PER_PIXEL = 4; // RGBA + const bytesPerTask = Math.floor(buffer.byteLength / taskCount / BYTES_PER_PIXEL) * BYTES_PER_PIXEL; + let result: ArrayBuffer[] = []; - for (let index = 0; index < n; index++) { - if (index === n - 1) { - result[index] = buffer.slice(index * num); + for (let i = 0; i < taskCount; i++) { + if (i === taskCount - 1) { + // The final block contains all the remaining data + result[i] = buffer.slice(i * bytesPerTask); } else { - result[index] = buffer.slice(index * num, (index + 1) * num); + result[i] = buffer.slice(i * bytesPerTask, (i + 1) * bytesPerTask); } } return result; } + // [StartExclude split_buffer1] -function buffer(bufferArray:ESObject, taskNum: number, sliderValue: number, value: number){ - let Workers:ESObject -// [EndExclude split_buffer1] +function buffer(bufferArray: ESObject, taskNum: number, sliderValue: number, value: number) { + let Workers: ESObject + // [EndExclude split_buffer1] // Assign the split pixels to the Worker instance. const buffers: ArrayBuffer[] = splitArrayBuffer(bufferArray, taskNum); let messages: MessageItem[] = []; @@ -354,7 +424,7 @@ function mergeArrayBuffers(buffers: Object[]) { return mergedBuffer; } -function taskNum(WorkerName:string){ +function taskNum(WorkerName: string) { // [Start task1] let taskNum: number = 14; // The number of concurrent tasks is controlled, which can be adjusted according to the demand. let curTaskNum: number = taskNum <= 64 ? taskNum : 64; // Control allows up to 64 Worker instances to run at the same time. diff --git a/ImageEditTaskPool/entry/src/main/ets/view/CommBackgroundIcon.ets b/ImageEditTaskPool/entry/src/main/ets/view/CommBackgroundIcon.ets index 3df69270e540b7740b005e943c1ecb8345f80c85..d7db3d9803175473ae3099350bfdb1e22eacb852 100644 --- a/ImageEditTaskPool/entry/src/main/ets/view/CommBackgroundIcon.ets +++ b/ImageEditTaskPool/entry/src/main/ets/view/CommBackgroundIcon.ets @@ -16,7 +16,7 @@ @Component export struct CommBackgroundIcon { @Prop icon: Resource; - private onClickImage: () => void = () => { + onClickImage: () => void = () => { }; build() { diff --git a/ImageEditTaskPool/entry/src/main/ets/view/TitleBar.ets b/ImageEditTaskPool/entry/src/main/ets/view/TitleBar.ets index 5777aec071cd02fcef9c9658292bd912c2c6d3d9..7f41ce76970e595b9938d0afa0c17e2c274fd1ce 100644 --- a/ImageEditTaskPool/entry/src/main/ets/view/TitleBar.ets +++ b/ImageEditTaskPool/entry/src/main/ets/view/TitleBar.ets @@ -17,11 +17,11 @@ import { CommBackgroundIcon } from './CommBackgroundIcon'; @Component export default struct TitleBar { - private onBack: () => void = () => { + onBack: () => void = () => { }; - private onReset: () => void = () => { + onReset: () => void = () => { }; - private onSave: () => void = () => { + onSave: () => void = () => { }; build() { diff --git a/ImageEditTaskPool/entry/src/main/ets/view/WorkerPort.ets b/ImageEditTaskPool/entry/src/main/ets/view/WorkerPort.ets index 2d75640019346d119911e8ba8c4b577a8680c311..f8956eee6419a0a2b1bfc3aa5de2604bc293f571 100644 --- a/ImageEditTaskPool/entry/src/main/ets/view/WorkerPort.ets +++ b/ImageEditTaskPool/entry/src/main/ets/view/WorkerPort.ets @@ -1,24 +1,26 @@ -import { buffer, MessageEvents } from '@kit.ArkTS'; +import { MessageEvents } from '@kit.ArkTS'; import { CommonConstants } from '../common/constant/CommonConstants'; import { AngelRange, HSVIndex, RGBIndex } from '../viewModel/OptionViewModel'; -let WorkerPort:ESObject; -let WorkerBuffer:ESObject; + +let WorkerPort: ESObject; +let WorkerBuffer: ESObject; // [Start WorkerPort] // The child thread receives the task and calculates it. WorkerPort.onmessage = (event: MessageEvents) => { - let bufferArray:ArrayBuffer = event.data.buf; - let last:number = event.data.last; - let cur :number= event.data.cur; - let index:number = event.data.index; + let bufferArray: ArrayBuffer = event.data.buf; + let last: number = event.data.last; + let cur: number = event.data.cur; + let index: number = event.data.index; let buffer = adjustImageValue(bufferArray, last, cur); // Pixel calculation execution - let output :ESObject= new WorkerBuffer(buffer, index); + let output: ESObject = new WorkerBuffer(buffer, index); WorkerPort.postMessage(output); // Send the calculation result to the main thread. } -function adjustImageValue(bufferArray: ArrayBuffer, last: number, cur: number, hsvIndex?: number):ArrayBuffer{ +function adjustImageValue(bufferArray: ArrayBuffer, last: number, cur: number, hsvIndex?: number): ArrayBuffer { return execColorInfo(bufferArray, last, cur, HSVIndex.VALUE); } + // Picture pixel calculation function execColorInfo(bufferArray: ArrayBuffer, last: number, cur: number, hsvIndex: number) { // ... @@ -35,10 +37,12 @@ function execColorInfo(bufferArray: ArrayBuffer, last: number, cur: number, hsvI } return newBufferArr; } + // [End WorkerPort] function colorTransform(rgbValue: number): number { return Number((rgbValue / 255).toFixed(2)); } + function rgb2hsv(red: number, green: number, blue: number): number[] { let hsvH: number = 0, hsvS: number = 0, hsvV: number = 0; const rgbR: number = colorTransform(red); @@ -69,7 +73,8 @@ function rgb2hsv(red: number, green: number, blue: number): number[] { } return [hsvH, hsvS, hsvV]; } -function hsv2rgb(hue: number, saturation: number, value: number):ESObject { + +function hsv2rgb(hue: number, saturation: number, value: number): ESObject { let rgbR: number = 0, rgbG: number = 0, rgbB: number = 0; if (saturation === 0) { rgbR = rgbG = rgbB = Math.round((value * 255) / 100); diff --git a/ImageEditTaskPool/entry/src/main/ets/view/newBuffer1.ets b/ImageEditTaskPool/entry/src/main/ets/view/newBuffer1.ets index 98bf574cc5e4f2037221d612a956ecf9fd9abb3c..57ddca78c4228721d7060c2ff39174d560c71e47 100644 --- a/ImageEditTaskPool/entry/src/main/ets/view/newBuffer1.ets +++ b/ImageEditTaskPool/entry/src/main/ets/view/newBuffer1.ets @@ -1,26 +1,27 @@ let Workers: ESObject; -let taskNum:number=1; -let allocation:number=1 -let index:number=0 -let messages:number[]; -let n=0; -let curTaskNum=2 -let that=this -function test(){ -// [Start buffer_test] +let taskNum: number = 1; +let allocation: number = 1 +let index: number = 0 +let messages: number[]; +let n = 0; +let curTaskNum = 2 +let that = this + +function test() { + // [Start buffer_test] let num = 0; // Number of tasks processed let newBuffers: ArrayBuffer[] = []; for (let i = 0; i < taskNum; i++) { newBuffers[i] = new ArrayBuffer(0); // Initialize calculation result data of each task } - Workers[index].onmessage = (e:ESObject) => { + Workers[index].onmessage = (e: ESObject) => { newBuffers[e.data.index] = e.data.buffer; // The main thread receives the calculation result. num = num + 1; // Number of tasks completed +1 - if (allocation != 0) { // If the total task has not been processed, reuse the sub-thread to continue processing the remaining tasks. + if (allocation !== 0) { // If the total task has not been processed, reuse the sub-thread to continue processing the remaining tasks. Workers[index].postMessage(messages[n]); n += 1; allocation = allocation - 1; - } else if (num == taskNum) { + } else if (num === taskNum) { for (let i = 0; i < curTaskNum; i++) { Workers[i].terminate(); // When all tasks are processed, the child thread is destroyed. } @@ -28,11 +29,12 @@ function test(){ that.updatePixelMap(entireArrayBuffer); // Refresh the UI according to the calculation result. } } -// [End buffer_test] + // [End buffer_test] } + // [Start buffer_test] // Merge the calculation results of all tasks. -function mergeArrayBuffers(buffers:ArrayBuffer[]) { +function mergeArrayBuffers(buffers: ArrayBuffer[]) { // Calculate the combined total length. let totalLength = buffers.reduce((length, buffer) => { length += buffer.byteLength; @@ -51,4 +53,5 @@ function mergeArrayBuffers(buffers:ArrayBuffer[]) { } return mergedBuffer; } + // [End buffer_test] diff --git a/ImageEditTaskPool/entry/src/main/module.json5 b/ImageEditTaskPool/entry/src/main/module.json5 index 0381c7f68e0691d7ac52e929074c612d5a3c9798..d0b88962da3c4b29bfdbd812998833d735a002f1 100644 --- a/ImageEditTaskPool/entry/src/main/module.json5 +++ b/ImageEditTaskPool/entry/src/main/module.json5 @@ -5,7 +5,7 @@ "description": "$string:module_desc", "mainElement": "EntryAbility", "deviceTypes": [ - "default" + "phone" ], "deliveryWithInstall": true, "installationFree": false, diff --git a/ImageWhiteLumpSolution/PreHttpRequestUseFiles/README.md b/ImageWhiteLumpSolution/PreHttpRequestUseFiles/README.md index 5c0843794007036fea155b1ed54b49e52f532bd6..6e7bb4ddd1bed5770a185068f5b7adab41e2e578 100644 --- a/ImageWhiteLumpSolution/PreHttpRequestUseFiles/README.md +++ b/ImageWhiteLumpSolution/PreHttpRequestUseFiles/README.md @@ -1,2 +1,27 @@ -最佳实践"Image白块解决指导"目录 -ImageWhiteLumpSolution-PreHttpRequestUseFiles 使用预下载解决Image长时间白块 正例 \ No newline at end of file +# Image白块解决指导 + +## 简介 +最佳实践"Image白块解决指导"目录,ImageWhiteLumpSolution-PreHttpRequestUseFiles,使用预下载解决Image长时间白块正例代码示例。 + +## 相关权限 +无 + +## 约束与限制 +* 本示例仅支持标准系统上运行,支持设备:华为手机。 + +* HarmonyOS系统:HarmonyOS 5.0.5 Release及以上。 + +* DevEco Studio版本:DevEco Studio 5.0.5 Release及以上。 + +* HarmonyOS SDK版本:HarmonyOS 5.0.5 Release SDK及以上。 + +## 下载 + +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set ImageWhiteLumpSolution/PreHttpRequestUseFiles +git checkout +``` \ No newline at end of file diff --git a/ImageWhiteLumpSolution/PreHttpRequestUseFiles/build-profile.json5 b/ImageWhiteLumpSolution/PreHttpRequestUseFiles/build-profile.json5 index c033ce4278fb0641d84107c3c134047ac487368e..b2ca56e35558b0dc7ca91989b68a1ea65b49a7a2 100644 --- a/ImageWhiteLumpSolution/PreHttpRequestUseFiles/build-profile.json5 +++ b/ImageWhiteLumpSolution/PreHttpRequestUseFiles/build-profile.json5 @@ -5,7 +5,8 @@ { "name": "default", "signingConfig": "default", - "compatibleSdkVersion": "5.0.0(12)", + "compatibleSdkVersion": "5.0.5(17)", + "targetSdkVersion": "5.0.5(17)", "runtimeOS": "HarmonyOS", } ], diff --git a/ImageWhiteLumpSolution/UseImageHttpRequest/README.md b/ImageWhiteLumpSolution/UseImageHttpRequest/README.md index 35857a0abb6769408338dd33676c5c657d554680..f6afc06fcbfb2d06cdb0ca2982b7faa0e171d8de 100644 --- a/ImageWhiteLumpSolution/UseImageHttpRequest/README.md +++ b/ImageWhiteLumpSolution/UseImageHttpRequest/README.md @@ -1,2 +1,27 @@ -最佳实践"Image白块解决指导"目录 -ImageWhiteLumpSolution-UseImageHttpRequest 直接使用Image原生组件加载网络图片白块时长较长 反例 \ No newline at end of file +# Image白块解决指导 + +## 简介 +最佳实践"Image白块解决指导"目录,ImageWhiteLumpSolution-UseImageHttpRequest,直接使用Image原生组件加载网络图片白块时长较长反例。 + +## 相关权限 +无 + +## 约束与限制 +* 本示例仅支持标准系统上运行,支持设备:华为手机。 + +* HarmonyOS系统:HarmonyOS 5.0.5 Release及以上。 + +* DevEco Studio版本:DevEco Studio 5.0.5 Release及以上。 + +* HarmonyOS SDK版本:HarmonyOS 5.0.5 Release SDK及以上。 + +## 下载 + +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set ImageWhiteLumpSolution/UseImageHttpRequest +git checkout +``` \ No newline at end of file diff --git a/ImageWhiteLumpSolution/UseImageHttpRequest/build-profile.json5 b/ImageWhiteLumpSolution/UseImageHttpRequest/build-profile.json5 index c033ce4278fb0641d84107c3c134047ac487368e..b2ca56e35558b0dc7ca91989b68a1ea65b49a7a2 100644 --- a/ImageWhiteLumpSolution/UseImageHttpRequest/build-profile.json5 +++ b/ImageWhiteLumpSolution/UseImageHttpRequest/build-profile.json5 @@ -5,7 +5,8 @@ { "name": "default", "signingConfig": "default", - "compatibleSdkVersion": "5.0.0(12)", + "compatibleSdkVersion": "5.0.5(17)", + "targetSdkVersion": "5.0.5(17)", "runtimeOS": "HarmonyOS", } ], diff --git a/JSCrash/README.md b/JSCrash/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e8b94af777f7df357dddc532326a93ebca6af282 --- /dev/null +++ b/JSCrash/README.md @@ -0,0 +1,62 @@ +# 应用崩溃(JS Crash)样例代码工程 + +### 介绍 + +本示例为应用崩溃(JS Crash)样例代码工程,包含最佳实践文档中涉及的分析方法、优化建议、问题案例等内容的局部样例代码。工程本身不具备实际功能,开发者请直接阅读具体源码结合文档来理解应用崩溃(JS Crash)类问题的产生原因,规避方法等。 + + +### 效果预览 + +不涉及。 + +### 工程目录 +``` +├──entry/src/main/ets +│ ├──entryability +│ │ └──EntryAbility.ets // 程序入口类 +│ ├──entrybackupability +│ │ └──EntryBackupAbility.ets // 数据恢复类 +│ └──pages +│ ├──Index.ets // 首页 +│ ├── JSCrashCaseAnalyse1.ets // ArkTS样例代码 +│ ├── JSCrashCaseAnalyse2.ets // ArkTS样例代码 +│ ├── JSCrashCaseAnalyse3.ets // ArkTS样例代码 +│ ├── JSCrashCaseAnalyse4.ets // ArkTS样例代码 +│ ├── JSCrashCaseAnalyse5.ets // ArkTS样例代码 +│ ├── JSCrashQuestionCheck.ets // ArkTS样例代码 +│ └── utils.ets // 工具类 +└──entry/src/main/resources // 应用资源目录 +``` + +### 具体实现 + +不涉及。 + +### 相关权限 + +不涉及。 + +### 依赖 + +不涉及。 + +### 约束与限制 + +1. 本示例仅支持标准系统上运行,支持设备:华为手机。 + +2. HarmonyOS系统:HarmonyOS NEXT 5.0.5 Release及以上。 + +3. DevEco Studio版本:DevEco Studio NEXT 5.0.5 Release及以上。 + +4. HarmonyOS SDK版本:HarmonyOS NEXT 5.0.5 Release SDK及以上。 + +### 下载 + +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set JSCrash +git checkout +``` \ No newline at end of file diff --git a/JSCrash/build-profile.json5 b/JSCrash/build-profile.json5 index adff6a0e3095f2c79f2fede08f299e7658c3dbca..9e87e7e6f19020fe21192844709f192cec80fd44 100644 --- a/JSCrash/build-profile.json5 +++ b/JSCrash/build-profile.json5 @@ -6,7 +6,7 @@ "name": "default", "signingConfig": "default", "targetSdkVersion": "5.0.5(17)", - "compatibleSdkVersion": "5.0.0(12)", + "compatibleSdkVersion": "5.0.5(17)", "runtimeOS": "HarmonyOS", "buildOption": { "strictMode": { diff --git a/JSCrash/entry/src/main/ets/entryability/EntryAbility.ets b/JSCrash/entry/src/main/ets/entryability/EntryAbility.ets index 508880af8c33aa838016d1cd4b2c68be2f447540..26beeb5e11a8372c6144d6ebd23ed1f6abcd4c6e 100644 --- a/JSCrash/entry/src/main/ets/entryability/EntryAbility.ets +++ b/JSCrash/entry/src/main/ets/entryability/EntryAbility.ets @@ -1,12 +1,18 @@ import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; import { hilog } from '@kit.PerformanceAnalysisKit'; import { window } from '@kit.ArkUI'; +import { BusinessError } from '@kit.BasicServicesKit'; const DOMAIN = 0x0000; export default class EntryAbility extends UIAbility { onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { - this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + try { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + } catch (e) { + let err = e as BusinessError; + hilog.error(DOMAIN, 'testTag', `failed code=${err.code}, message=${err.message}`); + } hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); } diff --git a/JSCrash/entry/src/main/ets/pages/Index.ets b/JSCrash/entry/src/main/ets/pages/Index.ets index 841fa4da997d915d282019f72b90246e2b07b50f..35886cdece20cb73bb5a77e0298468a9d52c75bc 100644 --- a/JSCrash/entry/src/main/ets/pages/Index.ets +++ b/JSCrash/entry/src/main/ets/pages/Index.ets @@ -18,10 +18,6 @@ struct Index { middle: { anchor: '__container__', align: HorizontalAlign.Center } }) .onClick(() => { - // [Start xiaoming] - let test:string = "{name:'xiaoming' age:10}"; - let result:object = JSON.parse(test); - // [End xiaoming] this.message = 'Welcome'; }) } diff --git a/JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse1.ets b/JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse1.ets index efb1ae76721ac90681ac6a6ab90ffbfb26ac464b..54843f35d16ac66424a2bf2c3d8187cd36576438 100644 --- a/JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse1.ets +++ b/JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse1.ets @@ -25,7 +25,8 @@ struct Index { // [Start updateGestureValue1] // Update the attributes related to manual effects - public updateGestureValue(screenWidth: number, recentScale: number, sceneContainerSessionList: SCBSceneContainerSession[]) { + public updateGestureValue(screenWidth: number, recentScale: number, + sceneContainerSessionList: SCBSceneContainerSession[]): void { // Calculation of the distance moved by the hand this.translationUpY = (this.multiCardsNum >= 1) ? sceneContainerSessionList[this.multiCardsNum - 1].needRenderTranslate.translateY : 0; // Report an incorrect line number this.translationDownY = (this.multiCardsNum >= 2) ? sceneContainerSessionList[this.multiCardsNum - 2].needRenderTranslate.translateY : 0; diff --git a/JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse2.ets b/JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse2.ets index 268bb2ff4c8af9019c6daff56ec48f74188166d0..a38af1724142de766e2ebfc5cb2ab1a9a7216076 100644 --- a/JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse2.ets +++ b/JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse2.ets @@ -25,7 +25,8 @@ struct Index { // [Start updateGestureValue2] // Update the attributes related to manual effects - public updateGestureValue(screenWidth: number, recentScale: number, sceneContainerSessionList: SCBSceneContainerSession[]) { + public updateGestureValue(screenWidth: number, recentScale: number, + sceneContainerSessionList: SCBSceneContainerSession[]): void { // Calculation of the distance moved by the hand this.translationUpY = (this.multiCardsNum >= 1) ? sceneContainerSessionList[this.multiCardsNum - 1]?.needRenderTranslate.translateY : 0; diff --git a/JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse6.ets b/JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse6.ets deleted file mode 100644 index 047f1c2721ee7f2c47162a02b43f45f1e90e13d2..0000000000000000000000000000000000000000 --- a/JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse6.ets +++ /dev/null @@ -1,150 +0,0 @@ -/** - * 最佳实践:JSCrash类问题案例 - */ - -// [Start JSCrashCaseAnalyse6] -function b(a) { - a.trim(); // 报错 undefined is not callable -} - -export function c() { - let a = 123; - b(a); -} - -let a = 123; -a(); // 123 is not callable -// [End JSCrashCaseAnalyse6] - - -// [Start JSCrashCaseAnalyse7] -// A.ets -import { Animal } from './B' -export let a = "this is A"; -export function A() { - return new Animal; -} - -// ------------ -// B.ets -import { a } from './A' -export class Animal { - static { - console.log("this is in class"); - let str = a; // 报错信息:a is not initialized - } -} -// [End JSCrashCaseAnalyse7] - -// [Start JSCrashCaseAnalyse8] -// B.ets -import { a } from './A' -export class Animal { - static { - console.log("this is in class"); - } - str = a; // 修改点 -} -// [End JSCrashCaseAnalyse8] - -// [Start JSCrashCaseAnalyse9] -// module1.ets -import { a, b} from './module2' - -export let i = 1; -export let m = a; -export const j = 2; -export const n = b; - -// ------------- -import { i, j } from './module1' - -export let a = i; // 报错信息:Error Message: i is not initialized -export const b = j; // 报错信息:Error Message: j is not initialized -// [End JSCrashCaseAnalyse9] - -// [Start JSCrashCaseAnalyse10] -// class1.ets -import { b } from './class2' - -export class A { - static a = b; -} - -// ------------- -// class2.ets -export let b = 1; - -const i = A.a; // 报错信息:Error message: A is not initialized -const j = new A(); // 报错信息:Error message: A is not initialized -// [End JSCrashCaseAnalyse10] - -// [Start JSCrashCaseAnalyse11] -// utils.ets -@Concurrent -export function printArgs(args: number): number { - return args -} - -// Index.ets -@Concurrent -function creatTask(a:number, b:number) { - let sum = a + b; - let task:taskpool.Task = new taskpool.Task(printArgs, sum); - return task; -} -function resultError() { - let task: taskpool.Task = new taskpool.Task(creatTask, 1, 2); - taskpool.execute(task).then((res) => { - }).catch((e:BusinessError)=>{ - console.error("resultError task catch message:" + e.message) - }) -} -// [End JSCrashCaseAnalyse11] - -// [Start JSCrashCaseAnalyse12] -// utils.ets -@Concurrent -export function printArgs(args: number): number { - return args -} - -// Index.ets -@Concurrent -function creatTask(a:number, b:number) { - let sum = a + b; - return sum; -} -function resultError() { - let task: taskpool.Task = new taskpool.Task(creatTask, 1, 2); - taskpool.execute(task).then((res) => { - let task2:taskpool.Task = new taskpool.Task(printArgs, res); - console.info("resultError task success"); - }).catch((e:BusinessError)=>{ - console.error("resultError task catch message:" + e.message) - }) -} -// [End JSCrashCaseAnalyse12] - -// [Start JSCrashCaseAnalyse13] -import { PersistenceV2 } from '@kit.ArkUI' -@ObservedV2 -export class IntegrationUserInfo { - userId: string = ''; - deviceId: string = ''; - static setUserInfo(userInfo: IntegrationUserInfo) { - const us = PersistenceV2.connect(IntegrationUserInfo, 'IntegrationUserInfo' () => userInfo)!; - us.userId = userInfo.userId; - us.deviceId = userInfo.deviceId; - PersistenceV2.save('IntegrationUserInfo'); - } -} -// [End JSCrashCaseAnalyse13] - -// [Start JSCrashCaseAnalyse14] -@ObservedV2 -export class IntegrationUserInfo { - @Trace userId: string = '000'; - deviceId: string = '000'; -} -// [End JSCrashCaseAnalyse14] diff --git a/JSCrash/entry/src/main/ets/pages/utils.ets b/JSCrash/entry/src/main/ets/pages/utils.ets index 624c38b007bf4a3b92688590bb1195e592430e13..98e8e5760051c7cb929d01b940f5df81947e3079 100644 --- a/JSCrash/entry/src/main/ets/pages/utils.ets +++ b/JSCrash/entry/src/main/ets/pages/utils.ets @@ -1,9 +1,9 @@ import hilog from '@ohos.hilog'; -const TAG = 'ZCM_Default'; +const TAG: string = 'ZCM_Default'; -const DOMAIN = 0x0011; -const SYMBOL = " --> "; +const DOMAIN: number = 0x0011; +const SYMBOL: string = " --> "; export class Log { /** @@ -14,7 +14,7 @@ export class Log { * @param args Indicates the log parameters. * @since 7 */ - static showInfo(tag: string) { + static showInfo(tag: string): void { if (Log.isLoggable(tag, hilog.LogLevel.INFO)) { hilog.info(DOMAIN, TAG, tag + SYMBOL); } @@ -28,7 +28,7 @@ export class Log { * @param args Indicates the log parameters. * @since 7 */ - static showDebug(tag: string, format: string, ...args: string[]) { + static showDebug(tag: string, format: string, ...args: string[]): void { if (Log.isLoggable(tag, hilog.LogLevel.DEBUG)) { hilog.debug(DOMAIN, TAG, tag + SYMBOL + format, args); } @@ -42,7 +42,7 @@ export class Log { * @param args Indicates the log parameters. * @since 7 */ - static showWarn(tag: string, format: string, ...args: string[]) { + static showWarn(tag: string, format: string, ...args: string[]): void { if (Log.isLoggable(tag, hilog.LogLevel.WARN)) { hilog.warn(DOMAIN, TAG, tag + SYMBOL + format, args); } @@ -56,7 +56,7 @@ export class Log { * @param args Indicates the log parameters. * @since 7 */ - static showError(tag: string) { + static showError(tag: string): void { if (Log.isLoggable(tag, hilog.LogLevel.ERROR)) { hilog.error(DOMAIN, TAG, tag + SYMBOL); } @@ -70,7 +70,7 @@ export class Log { * @param args Indicates the log parameters. * @since 7 */ - static showFatal(tag: string, format: string, ...args: string[]) { + static showFatal(tag: string, format: string, ...args: string[]): void { if (Log.isLoggable(tag, hilog.LogLevel.FATAL)) { hilog.fatal(DOMAIN, TAG, tag + SYMBOL + format, args); } @@ -83,7 +83,7 @@ export class Log { * @param level log level * @since 7 */ - private static isLoggable(tag:string, level: hilog.LogLevel): boolean { + private static isLoggable(tag: string, level: hilog.LogLevel): boolean { return hilog.isLoggable(DOMAIN, tag, level); } } \ No newline at end of file diff --git a/JSCrash/entry/src/main/module.json5 b/JSCrash/entry/src/main/module.json5 index a1cea8b6a4560cee7bda7a2db52f310c035ab6c8..ad219d733f6afa5ea07f85f580208b08cc3b9041 100644 --- a/JSCrash/entry/src/main/module.json5 +++ b/JSCrash/entry/src/main/module.json5 @@ -5,9 +5,7 @@ "description": "$string:module_desc", "mainElement": "EntryAbility", "deviceTypes": [ - "phone", - "tablet", - "2in1" + "phone" ], "deliveryWithInstall": true, "installationFree": false, diff --git a/JSCrash/entry/src/main/resources/base/element/string.json b/JSCrash/entry/src/main/resources/base/element/string.json index f94595515a99e0c828807e243494f57f09251930..fe7f30a579005c28973798a23aafb25485fd0ad5 100644 --- a/JSCrash/entry/src/main/resources/base/element/string.json +++ b/JSCrash/entry/src/main/resources/base/element/string.json @@ -10,7 +10,7 @@ }, { "name": "EntryAbility_label", - "value": "label" + "value": "JSCrash" } ] } \ No newline at end of file diff --git a/JSCrash/entry/src/mock/mock-config.json5 b/JSCrash/entry/src/mock/mock-config.json5 deleted file mode 100644 index 7a73a41bfdf76d6f793007240d80983a52f15f97..0000000000000000000000000000000000000000 --- a/JSCrash/entry/src/mock/mock-config.json5 +++ /dev/null @@ -1,2 +0,0 @@ -{ -} \ No newline at end of file diff --git a/JSCrash/entry/src/ohosTest/ets/test/Ability.test.ets b/JSCrash/entry/src/ohosTest/ets/test/Ability.test.ets deleted file mode 100644 index 85c78f67579d6e31b5f5aeea463e216b9b141048..0000000000000000000000000000000000000000 --- a/JSCrash/entry/src/ohosTest/ets/test/Ability.test.ets +++ /dev/null @@ -1,35 +0,0 @@ -import { hilog } from '@kit.PerformanceAnalysisKit'; -import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; - -export default function abilityTest() { - describe('ActsAbilityTest', () => { - // Defines a test suite. Two parameters are supported: test suite name and test suite function. - beforeAll(() => { - // Presets an action, which is performed only once before all test cases of the test suite start. - // This API supports only one parameter: preset action function. - }) - beforeEach(() => { - // Presets an action, which is performed before each unit test case starts. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: preset action function. - }) - afterEach(() => { - // Presets a clear action, which is performed after each unit test case ends. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: clear action function. - }) - afterAll(() => { - // Presets a clear action, which is performed after all test cases of the test suite end. - // This API supports only one parameter: clear action function. - }) - it('assertContain', 0, () => { - // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. - hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); - let a = 'abc'; - let b = 'b'; - // Defines a variety of assertion methods, which are used to declare expected boolean conditions. - expect(a).assertContain(b); - expect(a).assertEqual(a); - }) - }) -} \ No newline at end of file diff --git a/JSCrash/entry/src/ohosTest/ets/test/List.test.ets b/JSCrash/entry/src/ohosTest/ets/test/List.test.ets deleted file mode 100644 index 794c7dc4ed66bd98fa3865e07922906e2fcef545..0000000000000000000000000000000000000000 --- a/JSCrash/entry/src/ohosTest/ets/test/List.test.ets +++ /dev/null @@ -1,5 +0,0 @@ -import abilityTest from './Ability.test'; - -export default function testsuite() { - abilityTest(); -} \ No newline at end of file diff --git a/JSCrash/entry/src/ohosTest/module.json5 b/JSCrash/entry/src/ohosTest/module.json5 deleted file mode 100644 index 55725a929993a8a18b3808d41ef037759440488b..0000000000000000000000000000000000000000 --- a/JSCrash/entry/src/ohosTest/module.json5 +++ /dev/null @@ -1,13 +0,0 @@ -{ - "module": { - "name": "entry_test", - "type": "feature", - "deviceTypes": [ - "phone", - "tablet", - "2in1" - ], - "deliveryWithInstall": true, - "installationFree": false - } -} diff --git a/JSCrash/entry/src/test/List.test.ets b/JSCrash/entry/src/test/List.test.ets deleted file mode 100644 index bb5b5c3731e283dd507c847560ee59bde477bbc7..0000000000000000000000000000000000000000 --- a/JSCrash/entry/src/test/List.test.ets +++ /dev/null @@ -1,5 +0,0 @@ -import localUnitTest from './LocalUnit.test'; - -export default function testsuite() { - localUnitTest(); -} \ No newline at end of file diff --git a/JSCrash/entry/src/test/LocalUnit.test.ets b/JSCrash/entry/src/test/LocalUnit.test.ets deleted file mode 100644 index 165fc1615ee8618b4cb6a622f144a9a707eee99f..0000000000000000000000000000000000000000 --- a/JSCrash/entry/src/test/LocalUnit.test.ets +++ /dev/null @@ -1,33 +0,0 @@ -import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; - -export default function localUnitTest() { - describe('localUnitTest', () => { - // Defines a test suite. Two parameters are supported: test suite name and test suite function. - beforeAll(() => { - // Presets an action, which is performed only once before all test cases of the test suite start. - // This API supports only one parameter: preset action function. - }); - beforeEach(() => { - // Presets an action, which is performed before each unit test case starts. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: preset action function. - }); - afterEach(() => { - // Presets a clear action, which is performed after each unit test case ends. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: clear action function. - }); - afterAll(() => { - // Presets a clear action, which is performed after all test cases of the test suite end. - // This API supports only one parameter: clear action function. - }); - it('assertContain', 0, () => { - // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. - let a = 'abc'; - let b = 'b'; - // Defines a variety of assertion methods, which are used to declare expected boolean conditions. - expect(a).assertContain(b); - expect(a).assertEqual(a); - }); - }); -} \ No newline at end of file diff --git a/LIstOptimizationBak/build-profile.json5 b/LIstOptimizationBak/build-profile.json5 index b2cc02977d74631a63703f33a1ae6c1f94d81219..bfab034db9430fe842b10916d584f8927b558277 100644 --- a/LIstOptimizationBak/build-profile.json5 +++ b/LIstOptimizationBak/build-profile.json5 @@ -6,7 +6,8 @@ { "name": "default", "signingConfig": "default", - "compatibleSdkVersion": "5.0.0(12)", + "targetSdkVersion": "5.0.5(17)", + "compatibleSdkVersion": "5.0.5(17)", "runtimeOS": "HarmonyOS", } ], diff --git a/LibuvDevelopment/README.md b/LibuvDevelopment/README.md new file mode 100644 index 0000000000000000000000000000000000000000..defce59fc1d6308532b099e25e10887a74014933 --- /dev/null +++ b/LibuvDevelopment/README.md @@ -0,0 +1,52 @@ +# libuv使用规范及案例 + +### 介绍 + +本示例是《libuv使用规范及案例》最佳实践中的代码示例片段。 + +### 使用说明 + +进入首面,加载示例逻辑。 + + +### 工程目录 + +``` +├──entry/src/main/ets +│ ├──entryability +│ │ └──EntryAbility.ets // 入口类 +│ ├──entrybackupability +│ │ └──EntryBackupAbility.ets // 数据备份类 +│ └──pages +│ └──Index.ets // 示例页面 +└──entry/src/main/resources // 应用资源目录 +``` + +### 具体实现 + +1. 主要介绍libuv使用规范及案例,提供代码示例。 + +### 相关权限 + +不涉及。 + +### 约束与限制 + +1. 本示例仅支持标准系统上运行,支持设备:华为手机。 + +2. HarmonyOS系统:HarmonyOS 5.0.5 Release及以上。 + +3. DevEco Studio版本:DevEco Studio 5.0.5 Release及以上。 + +4. HarmonyOS SDK版本:HarmonyOS 5.0.5 Release SDK及以上。 + +### 下载 + +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set LibuvDevelopment +git checkout +``` \ No newline at end of file diff --git a/LibuvDevelopment/build-profile.json5 b/LibuvDevelopment/build-profile.json5 index 03ac3a3ae9dd397844173066e5d5ee21b49455a1..9e87e7e6f19020fe21192844709f192cec80fd44 100644 --- a/LibuvDevelopment/build-profile.json5 +++ b/LibuvDevelopment/build-profile.json5 @@ -5,7 +5,8 @@ { "name": "default", "signingConfig": "default", - "compatibleSdkVersion": "5.0.4(16)", + "targetSdkVersion": "5.0.5(17)", + "compatibleSdkVersion": "5.0.5(17)", "runtimeOS": "HarmonyOS", "buildOption": { "strictMode": { diff --git a/LibuvDevelopment/entry/src/main/cpp/NapiTaskRunner.h b/LibuvDevelopment/entry/src/main/cpp/NapiTaskRunner.h index 047f63e0c5d4bf3576a220f71b4bc911ad62ffcb..246fdc3b319e22785c427f863372be9fe0d79f7c 100644 --- a/LibuvDevelopment/entry/src/main/cpp/NapiTaskRunner.h +++ b/LibuvDevelopment/entry/src/main/cpp/NapiTaskRunner.h @@ -1,8 +1,18 @@ -// -// Created on 2025/5/28. -// -// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found, -// please include "napi/native_api.h". +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + /** * libuv使用规范及案例 */ diff --git a/LibuvDevelopment/entry/src/main/cpp/libuvHandleNormal.h b/LibuvDevelopment/entry/src/main/cpp/libuvHandleNormal.h index 5954ce54991b4d50388ddf023afa1de5fa8170bb..8a493480b45a447d9ec683765fb3e74b97c7b95c 100644 --- a/LibuvDevelopment/entry/src/main/cpp/libuvHandleNormal.h +++ b/LibuvDevelopment/entry/src/main/cpp/libuvHandleNormal.h @@ -1,8 +1,18 @@ -// -// Created on 2025/5/28. -// -// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found, -// please include "napi/native_api.h". +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + /** * libuv使用规范及案例 */ diff --git a/LibuvDevelopment/entry/src/main/cpp/libuvHandles.h b/LibuvDevelopment/entry/src/main/cpp/libuvHandles.h index 906f049dc9178a41e2b10c0facb3f9c9adb03024..105fc36092569f8fe3972d044565a4a7d9ccfe72 100644 --- a/LibuvDevelopment/entry/src/main/cpp/libuvHandles.h +++ b/LibuvDevelopment/entry/src/main/cpp/libuvHandles.h @@ -1,8 +1,18 @@ -// -// Created on 2025/5/28. -// -// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found, -// please include "napi/native_api.h". +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + // libuv使用规范及案例 #ifndef LIBUVDEVELOPMENT_LIBUVHANDLES_H #define LIBUVDEVELOPMENT_LIBUVHANDLES_H diff --git a/LibuvDevelopment/entry/src/main/cpp/libuvRequest.h b/LibuvDevelopment/entry/src/main/cpp/libuvRequest.h index b20c3fcaf637590903c88ad9f59e3970b10cd89b..cbfbd943b34c0396ef2641da6980cc5e2eace85c 100644 --- a/LibuvDevelopment/entry/src/main/cpp/libuvRequest.h +++ b/LibuvDevelopment/entry/src/main/cpp/libuvRequest.h @@ -1,8 +1,18 @@ -// -// Created on 2025/5/28. -// -// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found, -// please include "napi/native_api.h". +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + /** * libuv使用规范及案例 */ diff --git a/LibuvDevelopment/entry/src/main/cpp/libuvRequestAsyn.h b/LibuvDevelopment/entry/src/main/cpp/libuvRequestAsyn.h index bf9548f6d3286f7b737a9735207c1365ff267120..2160b298b9e40ce35078b44b8260b8770f1ed884 100644 --- a/LibuvDevelopment/entry/src/main/cpp/libuvRequestAsyn.h +++ b/LibuvDevelopment/entry/src/main/cpp/libuvRequestAsyn.h @@ -1,8 +1,18 @@ -// -// Created on 2025/5/28. -// -// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found, -// please include "napi/native_api.h". +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + /** * libuv使用规范及案例 */ diff --git a/LibuvDevelopment/entry/src/main/cpp/napi_init.cpp b/LibuvDevelopment/entry/src/main/cpp/napi_init.cpp index 19e280e6dacd7a1f9dae8f4b918bdf36a97eca38..1ed682f26dada1c0021a8f3274ce39771c15f194 100644 --- a/LibuvDevelopment/entry/src/main/cpp/napi_init.cpp +++ b/LibuvDevelopment/entry/src/main/cpp/napi_init.cpp @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + #include "napi/native_api.h" #include diff --git a/LibuvDevelopment/entry/src/main/ets/entryability/EntryAbility.ets b/LibuvDevelopment/entry/src/main/ets/entryability/EntryAbility.ets index 508880af8c33aa838016d1cd4b2c68be2f447540..d6c8a8e454f830409bd59e18826cd56e0412125c 100644 --- a/LibuvDevelopment/entry/src/main/ets/entryability/EntryAbility.ets +++ b/LibuvDevelopment/entry/src/main/ets/entryability/EntryAbility.ets @@ -1,12 +1,33 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; import { hilog } from '@kit.PerformanceAnalysisKit'; import { window } from '@kit.ArkUI'; +import { BusinessError } from '@kit.BasicServicesKit'; const DOMAIN = 0x0000; export default class EntryAbility extends UIAbility { onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { - this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + try { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + } catch (e) { + let err = e as BusinessError; + hilog.error(DOMAIN, 'testTag', `failed code=${err.code}, message=${err.message}`); + } hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); } diff --git a/LibuvDevelopment/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets b/LibuvDevelopment/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets index 8e4de99282050bad799ac892eb85ac5449364a51..0a97e21bd7a15599af76a806695860ff1eb0ebfe 100644 --- a/LibuvDevelopment/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets +++ b/LibuvDevelopment/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + import { hilog } from '@kit.PerformanceAnalysisKit'; import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit'; diff --git a/LibuvDevelopment/entry/src/main/ets/pages/Index.ets b/LibuvDevelopment/entry/src/main/ets/pages/Index.ets index 0738f87946f68a3e67f70b0397ea1c8a4ab75500..71b23174229cd3cf4b127d77e25069eb7a1f3c4a 100644 --- a/LibuvDevelopment/entry/src/main/ets/pages/Index.ets +++ b/LibuvDevelopment/entry/src/main/ets/pages/Index.ets @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + import { hilog } from '@kit.PerformanceAnalysisKit'; import testNapi from 'libentry.so'; diff --git a/LibuvDevelopment/entry/src/main/module.json5 b/LibuvDevelopment/entry/src/main/module.json5 index a1cea8b6a4560cee7bda7a2db52f310c035ab6c8..ad219d733f6afa5ea07f85f580208b08cc3b9041 100644 --- a/LibuvDevelopment/entry/src/main/module.json5 +++ b/LibuvDevelopment/entry/src/main/module.json5 @@ -5,9 +5,7 @@ "description": "$string:module_desc", "mainElement": "EntryAbility", "deviceTypes": [ - "phone", - "tablet", - "2in1" + "phone" ], "deliveryWithInstall": true, "installationFree": false, diff --git a/LibuvDevelopment/entry/src/main/resources/base/element/string.json b/LibuvDevelopment/entry/src/main/resources/base/element/string.json index f94595515a99e0c828807e243494f57f09251930..5d298c928386f90ceeb0573710a0a9d92cf956a2 100644 --- a/LibuvDevelopment/entry/src/main/resources/base/element/string.json +++ b/LibuvDevelopment/entry/src/main/resources/base/element/string.json @@ -10,7 +10,7 @@ }, { "name": "EntryAbility_label", - "value": "label" + "value": "LibuvDevelopment" } ] } \ No newline at end of file diff --git a/LibuvDevelopment/log.txt b/LibuvDevelopment/log.txt index d88706a07d5348c611f8bacf013fb38e04f9b916..35dd54f99e43afa3cdd15ac6f0edbbbe3e4d05f7 100644 --- a/LibuvDevelopment/log.txt +++ b/LibuvDevelopment/log.txt @@ -2220,3 +2220,44 @@ 15:06:56:890 log before pop task size: 1 15:06:56:890 log after task size: 0 15:06:57:400 log timer task size: 1 +09:01:15:841 log timer task size: 1 +09:01:29:142 log task queue not empty +09:01:29:142 log task size: 1 +09:01:29:142 log before pop task size: 1 +09:01:29:142 log after task size: 0 +09:01:29:647 log timer task size: 1 +09:01:32:420 log task queue not empty +09:01:32:420 log task size: 1 +09:01:32:421 log before pop task size: 1 +09:01:32:421 log after task size: 0 +09:01:32:923 log timer task size: 1 +09:01:35:378 log task queue not empty +09:01:35:378 log task size: 1 +09:01:35:378 log before pop task size: 1 +09:01:35:378 log after task size: 0 +09:01:35:879 log timer task size: 1 +09:01:40:764 log task queue not empty +09:01:40:765 log task size: 1 +09:01:40:765 log before pop task size: 1 +09:01:40:765 log after task size: 0 +09:01:41:267 log timer task size: 1 +09:01:45:387 log task queue not empty +09:01:45:388 log task size: 1 +09:01:45:388 log before pop task size: 1 +09:01:45:388 log after task size: 0 +09:01:45:890 log timer task size: 1 +09:01:48:808 log task queue not empty +09:01:48:808 log task size: 1 +09:01:48:808 log before pop task size: 1 +09:01:48:808 log after task size: 0 +09:01:49:313 log timer task size: 1 +09:01:51:979 log task queue not empty +09:01:51:979 log task size: 1 +09:01:51:980 log before pop task size: 1 +09:01:51:980 log after task size: 0 +09:01:52:480 log timer task size: 1 +09:02:00:492 log task queue not empty +09:02:00:492 log task size: 1 +09:02:00:493 log before pop task size: 1 +09:02:00:493 log after task size: 0 +09:02:00:994 log timer task size: 1 diff --git a/LiteWearable/LICENSE b/LiteWearable/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..18795a48d6b12fcdc1aa7bac9a9cb99f83815267 --- /dev/null +++ b/LiteWearable/LICENSE @@ -0,0 +1,78 @@ + Copyright (c) 2025 Huawei Device Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + 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. + +Apache License, Version 2.0 +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. + +"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. + +2. Grant of Copyright License. + +Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. + +Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. + +You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: +1.You must give any other recipients of the Work or Derivative Works a copy of this License; and +2.You must cause any modified files to carry prominent notices stating that You changed the files; and +3.You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and +4.If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. + +You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. + +5. Submission of Contributions. + +Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. + +6. Trademarks. + +This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. + +Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. + +In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. + +While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/LiteWearable/README.md b/LiteWearable/README.md new file mode 100644 index 0000000000000000000000000000000000000000..b99ce78c631de6c366e39671f3c8da45aebcbc4a --- /dev/null +++ b/LiteWearable/README.md @@ -0,0 +1,101 @@ +# 轻量级智能穿戴应用开发 + +## 介绍 +本示例为轻量级智能穿戴应用开发同源代码块。 + +## 预览效果 +![LiteWearable.png](screenshots/device/LiteWearable.png) + +## 工程目录 + +``` +├──entry/src/main/js +│ └──MainAbility +│ ├──cryptoFramework +│ │ ├──cryptoFramework.css // @ohos.security.cryptoFramework (加解密算法库框架)页面样式 +│ │ ├──cryptoFramework.hml // @ohos.security.cryptoFramework (加解密算法库框架)页面 +│ │ └──cryptoFramework.js // @ohos.security.cryptoFramework (加解密算法库框架)页面交互功能 +│ ├──detail +│ │ ├──detail.css // 页面路由页面样式 +│ │ ├──detail.hml // 页面路由页面 +│ │ └──detail.js // 页面路由页面交互功能 +│ ├──details +│ │ ├──details.css // 页面路由页面样式 +│ │ ├──details.hml // 页面路由页面 +│ │ └──details.js // 页面路由页面交互功能 +│ ├──event +│ │ ├──event.css // 交互事件页面样式 +│ │ ├──event.hml // 交互事件页面 +│ │ └──event.js // 交互事件页面交互功能 +│ ├──exit +│ │ ├──exit.css // 应用退出页面样式 +│ │ ├──exit.hml // 应用退出页面 +│ │ └──exit.js // 应用退出页面交互功能 +│ ├──i18n +│ │ ├──en-US.json // 英文文件 +│ │ └──zh-CN.json // 中文文件 +│ ├──initpage +│ │ ├──initpage.css // 工程目录介绍页面样式 +│ │ ├──initpage.hml // 工程目录介绍页面 +│ │ └──initpage.js // 工程目录介绍页面交互功能 +│ ├──pages/index +│ │ ├──index.css // 百分比使用页面样式 +│ │ ├──index.hml // 百分比使用页面 +│ │ └──index.js // 百分比使用页面交互功能 +│ ├──screenLock +│ │ ├──screenLock.css // @ohos.screenLock (锁屏管理)页面样式 +│ │ ├──screenLock.hml // @ohos.screenLock (锁屏管理)页面 +│ │ └──screenLock.js // @ohos.screenLock (锁屏管理)页面交互功能 +│ ├──security +│ │ ├──DES.js // DES-CBC算法密钥 +│ │ ├──DesCBC64.js // 查询密钥是否存在和删除密钥 +│ │ ├──HMAC.js // 生成HMAC密钥/密文 +│ │ ├──KeyAlias.js // 导入密钥和导出密钥 +│ │ ├──RSA.js // 生成RSA算法密钥和使用RSA算法进行加密/解密 +│ │ ├──security.css // 安全接口的使用页面样式 +│ │ ├──security.hml // 安全接口的使用页面 +│ │ └──security.js // 安全接口的使用页面交互功能 +│ ├──style1 +│ │ ├──style1.css // 实现应用页面样式 +│ │ ├──style1.hml // 实现应用页面 +│ │ └──style1.js // 实现应用页面交互功能 +│ ├──style2 +│ │ ├──style2.css // 行内样式页面样式 +│ │ ├──style2.hml // 行内样式页面 +│ │ └──style2.js // 行内样式页面交互功能 +│ ├──style3 +│ │ ├──style3.css // 选择器样式页面样式 +│ │ ├──style3.hml // 选择器样式页面 +│ │ └──style3.js // 选择器样式页面交互功能 +│ ├──style4 +│ │ ├──style4.css // 动态绑定样式 +│ │ ├──style4.hml // 动态绑定页面 +│ │ └──style4.js // 动态绑定样式页面的交互功能 +│ └──app.js // 应用与页面的生命周期 +└──entry/src/main/resources // 应用资源目录 +``` + +## 相关权限 +不涉及。 + +## 依赖 + +不涉及。 + +## 约束与限制 + +1. 本示例仅支持标准系统上运行,支持设备:华为手表。 +2. HarmonyOS系统:HarmonyOS 5.0.5 Release及以上。 +3. DevEco Studio版本:DevEco Studio 5.0.5 Release及以上。 +4. HarmonyOS SDK版本:HarmonyOS 5.0.5 Release SDK及以上。 + +## 下载 + +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set LiteWearable +git checkout +``` \ No newline at end of file diff --git a/LiteWearable/build-profile.json5 b/LiteWearable/build-profile.json5 index 9952ea80b6c8fe477b3f226597fbf48a22525fad..0a975a680dfd1360890e10a665c2d19bc8b3ef83 100644 --- a/LiteWearable/build-profile.json5 +++ b/LiteWearable/build-profile.json5 @@ -5,7 +5,8 @@ { "name": "default", "signingConfig": "default", - "compatibleSdkVersion": "4.0.0(10)", + "targetSdkVersion": "5.0.5(17)", + "compatibleSdkVersion": "5.0.5(17)", "runtimeOS": "HarmonyOS", "buildOption": { "strictMode": { diff --git a/LiteWearable/entry/src/main/js/MainAbility/cryptoFramework/cryptoFramework.js b/LiteWearable/entry/src/main/js/MainAbility/cryptoFramework/cryptoFramework.js index a15bc8599dcf52fc8e6fa527d9e1455e2df25335..335bb5f101208a074d75b58f2b43d7f48571ba94 100644 --- a/LiteWearable/entry/src/main/js/MainAbility/cryptoFramework/cryptoFramework.js +++ b/LiteWearable/entry/src/main/js/MainAbility/cryptoFramework/cryptoFramework.js @@ -6,7 +6,7 @@ export default { title: "" }, onInit() { - this.title = "Hello World"; + this.title = 'Hello World'; } }; // [EndExclude do_md] @@ -20,31 +20,32 @@ function stringToUint8Array(str) { } function doMd() { - let mdAlgName = 'SHA256'; // 摘要算法名 - let message = 'mdTestMessage'; // 待摘要的数据 + let mdAlgName = 'SHA256'; // Abstract algorithm name. + let message = 'mdTestMessage'; // The data to be summarized. let handle; let mdResult; let mdLen; - //指定摘要算法SHA256,生成摘要操作实例 + // Specify the digest algorithm SHA256 and generate an instance of the digest operation. try { handle = cryptoFramework.createMd(mdAlgName); } catch (error) { console.error(`createMd error, code: ${error.code}, msg: ${error.message}`); } try { - // 数据量较少时,可以只做一次update,将数据全部传入,接口未对入参长度做限制 + // When the data volume is small, only one update operation can be performed, and all the data can be sent in. + // The interface does not impose any restrictions on the length of the input parameters. handle?.updateSync({ data: stringToUint8Array(message) }); } catch (error) { console.error(`updateSync error, code:+${error.code}, msg: ${error.message}`); } - // 获取摘要计算结果。 + // Obtain the summary calculation results. try { mdResult = handle?.digest(); } catch (error) { console.error(`digest error, code: ${error.code}, msg: ${error.message}`); } console.info('Md result:' + mdResult?.data); - // 获取摘要计算长度,单位为字节 + // Obtain the length of the summary calculation, with the unit being bytes. try { mdLen = handle?.getMdLength(); } catch (error) { @@ -58,7 +59,7 @@ function doRand() { let rand; let ret = true; let randData - // 生成随机数操作实例 + // Example of generating random numbers operation. try { rand = cryptoFramework.createRandom(); } catch (error) { @@ -66,7 +67,7 @@ function doRand() { console.error(`createRandom error, code:+${error.code}, msg: ${error.message}`); } let len = 24; // Generate a 24-byte random number. - // (可选)调用Random.setSeed,为随机数生成池设置种子 + // (Optional) Call Random.setSeed to set the seed for the random number generation pool. let seed = new Uint8Array([1, 2, 3]); try { rand?.setSeed({ data: seed }); @@ -76,7 +77,7 @@ function doRand() { } try { - //生成安全随机数 + // Generate secure random numbers. randData = rand?.generateRandomSync(len); } catch (error) { ret = false; diff --git a/LiteWearable/entry/src/main/js/MainAbility/exit/exit.hml b/LiteWearable/entry/src/main/js/MainAbility/exit/exit.hml index 9b0a820d11f8cb72f2dfa22b34e69027fc8fab19..db1fc10f0f24b1c4d1f929a48c1fa711a6cb684d 100644 --- a/LiteWearable/entry/src/main/js/MainAbility/exit/exit.hml +++ b/LiteWearable/entry/src/main/js/MainAbility/exit/exit.hml @@ -1,5 +1,5 @@ +
Hello {{ title }} diff --git a/LiteWearable/entry/src/main/js/MainAbility/exit/exit.js b/LiteWearable/entry/src/main/js/MainAbility/exit/exit.js index 8d9cfc726c9f630933ec07178db4b93965aff8de..5af73721be3dd29a26dca6d26bc6eefdba38faa3 100644 --- a/LiteWearable/entry/src/main/js/MainAbility/exit/exit.js +++ b/LiteWearable/entry/src/main/js/MainAbility/exit/exit.js @@ -1,7 +1,7 @@ // [Start exit_js] // index.js import router from '@ohos.router'; -// 导入app模块 +// Import the app module. import app from '@system.app'; export default { @@ -13,8 +13,8 @@ export default { uri: 'pages/details/details' }); }, - touchMove(e) { // swipe处理事件 - if (e.direction == 'right') { // 右滑退出 + touchMove(e) { // Handle swipe events. + if (e.direction == 'right') { // Swipe right to exit. app.terminate(); } } diff --git a/LiteWearable/entry/src/main/js/MainAbility/initpage/initpage.hml b/LiteWearable/entry/src/main/js/MainAbility/initpage/initpage.hml index 0acac82f39ee3acca68239dc977f69f0b0215435..6ac9727451eca5d6832e487f84bb3506787503a1 100644 --- a/LiteWearable/entry/src/main/js/MainAbility/initpage/initpage.hml +++ b/LiteWearable/entry/src/main/js/MainAbility/initpage/initpage.hml @@ -1,5 +1,5 @@ +
Hello {{ title }} diff --git a/LiteWearable/entry/src/main/js/MainAbility/pages/index/index.css b/LiteWearable/entry/src/main/js/MainAbility/pages/index/index.css index a75028a4780f2f5652297afac125500b61e51370..6388b193331250028e80862664846517dad4e053 100644 --- a/LiteWearable/entry/src/main/js/MainAbility/pages/index/index.css +++ b/LiteWearable/entry/src/main/js/MainAbility/pages/index/index.css @@ -1,10 +1,10 @@ .container { - width: 100%;/* 容器宽度设置为 100% */ - height: 100%;/* 容器高度设置为 100% */ + width: 100%;/* The width of the container is set to 100%. */ + height: 100%;/* The height of the container is set to 100%. */ justify-content: center; align-items: center; flex-direction: column; - background-color: aquamarine;/* 设置背景色为碧绿色 */ + background-color: aquamarine;/* Set the background color to light green. */ } .stackContainer { @@ -14,8 +14,8 @@ } .button { - top: 10%;/* 设置y轴上距离父组件为父组件高度的10%位置 */ - left: 10%;/* 设置x轴上距离父组件为父组件宽度的10%位置 */ + top: 10%;/* Set the position on the y-axis to be 10% of the height of the parent component from the top. */ + left: 10%;/* Set the position on the x-axis to be 10% of the width of the parent component from the parent component itself. */ width: 50%; height: 30%; font-size: 30px; @@ -27,5 +27,5 @@ height: 20%; font-size: 30px; background-color: black; - margin-top: 2%;/* 父组件高度的2% */ + margin-top: 2%;/* 2% of the height of the parent component. */ } \ No newline at end of file diff --git a/LiteWearable/entry/src/main/js/MainAbility/security/DES.js b/LiteWearable/entry/src/main/js/MainAbility/security/DES.js index efa05f9af4c6be0efd0340185ee73b9d40f38da8..a9cbba6cd9d3ae3ae968e90905912073541209d5 100644 --- a/LiteWearable/entry/src/main/js/MainAbility/security/DES.js +++ b/LiteWearable/entry/src/main/js/MainAbility/security/DES.js @@ -3,35 +3,35 @@ import huks from '@ohos.security.huks'; // [Start des_encrypt] // [Start des_decrypt] -// 别名,用于区分生成的KEY +// Alias, used to distinguish the generated KEY. const DES_CBC_64_KEY_ALIAS = 'DesCBC64KeyAlias'; // [StartExclude des_generate] -// 三段式句柄,用于连接三段式上下文 +// Three-part handle, used for connecting three-part context. let handle; let IV = '12345678'; -// 明文,加密前数据 +// Plain text, data before encryption. let plainText = 'DESAAAdffssghCBC5612345612345L64'; -// 密文,存放加密后数据 +// Ciphertext, storing the encrypted data. let cipherText = ''; // [EndExclude des_generate] // [StartExclude des_encrypt] // [StartExclude des_decrypt] -// 配置生成密钥所需的Tag +// Configure the Tag required for generating the key. function getDesGenProperties() { let properties = new Array(); let index = 0; - // DES算法 + // DES algorithm. properties[index++] = { tag: huks.HuksTag.HUKS_TAG_ALGORITHM, value: huks.HuksKeyAlg.HUKS_ALG_DES }; - // 密钥长度64 + // Key length: 64. properties[index++] = { tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, value: huks.HuksKeySize.HUKS_DES_KEY_SIZE_64 }; - // 密钥用途,加密和解密 + // Key usage, encryption and decryption. properties[index++] = { tag: huks.HuksTag.HUKS_TAG_PURPOSE, value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT | huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT @@ -40,7 +40,7 @@ function getDesGenProperties() { return properties; } -// 生成密钥 +// Generate a key. function generateDESKey() { let huksInfo; let options = { properties: getDesGenProperties() } @@ -58,37 +58,37 @@ function generateDESKey() { function getDesCBCEncryptProperties() { let properties = new Array(); let index = 0; - // 算法 + // algorithm. properties[index++] = { tag: huks.HuksTag.HUKS_TAG_ALGORITHM, value: huks.HuksKeyAlg.HUKS_ALG_DES }; - // 密钥长度 + // key length. properties[index++] = { tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, value: huks.HuksKeySize.HUKS_DES_KEY_SIZE_64 }; - // 密钥用途 + // Key usage. properties[index++] = { tag: huks.HuksTag.HUKS_TAG_PURPOSE, value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT }; - // 填充方式 + // Filling method. properties[index++] = { tag: huks.HuksTag.HUKS_TAG_PADDING, value: huks.HuksKeyPadding.HUKS_PADDING_NONE }; - // 分组方式 + // packet mode. properties[index++] = { tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE, value: huks.HuksCipherMode.HUKS_MODE_CBC }; - // 分组加密偏移向量,更安全 + // Group encryption offset vector, more secure. properties[index++] = { tag: huks.HuksTag.HUKS_TAG_IV, value: stringToUint8Array(IV) @@ -143,7 +143,7 @@ function encryptDES() { } }); } else { - // 密文接收 + // Encrypted message reception cipherText = uint8ArrayToString(updateData.outData); huksInfo = cipherText } @@ -163,7 +163,7 @@ function encryptDES() { } }); } else { - // 密文接收 + // Encrypted message reception cipherText = cipherText + uint8ArrayToString(finishData.outData); huksInfo = cipherText } @@ -194,32 +194,32 @@ function uint8ArrayToString(fileData) { function GetDesCBCDecryptProperties() { let properties = new Array(); let index = 0; - // 算法 + // algorithm properties[index++] = { tag: huks.HuksTag.HUKS_TAG_ALGORITHM, value: huks.HuksKeyAlg.HUKS_ALG_DES }; - // 密钥长度 + // key length properties[index++] = { tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, value: huks.HuksKeySize.HUKS_DES_KEY_SIZE_64 }; - // 密钥用途 + // Key usage properties[index++] = { tag: huks.HuksTag.HUKS_TAG_PURPOSE, value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT }; - // 填充方式 + // Filling method properties[index++] = { tag: huks.HuksTag.HUKS_TAG_PADDING, value: huks.HuksKeyPadding.HUKS_PADDING_NONE }; - // 分组方式 + // packet mode properties[index++] = { tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE, value: huks.HuksCipherMode.HUKS_MODE_CBC }; - // 分组加密偏移向量,更安全 + // Group encryption offset vector, more secure properties[index++] = { tag: huks.HuksTag.HUKS_TAG_IV, value: stringToUint8Array(IV) @@ -274,7 +274,7 @@ function decryptDES() { } }); } else { - // 明文接收 + // Clear text reception outPlainText = uint8ArrayToString(updateData.outData); huksInfo = outPlainText; } @@ -294,7 +294,7 @@ function decryptDES() { } }); } else { - // 明文接收 + // Clear text reception outPlainText = outPlainText + uint8ArrayToString(finishData.outData); huksInfo = outPlainText; } diff --git a/LiteWearable/entry/src/main/js/MainAbility/security/HMAC.js b/LiteWearable/entry/src/main/js/MainAbility/security/HMAC.js index c3048f3cf141a0733ac714f956ba137d2ed27a00..97784c83dc3cb4e4135985f1decb8ff259cb3194 100644 --- a/LiteWearable/entry/src/main/js/MainAbility/security/HMAC.js +++ b/LiteWearable/entry/src/main/js/MainAbility/security/HMAC.js @@ -2,31 +2,31 @@ // [Start hmac_process] import huks from '@ohos.security.huks'; -// HMACKeyAlias 别名,用于区分生成的KEY +// HMACKeyAlias - Alias used to distinguish the generated KEY. const HMAC_KEY_ALIAS = 'HMACKeyAlias'; // [StartExclude hmac_generate] -// 明文,加密前数据 +// Plain text, data before encryption. let plainText = 'HMACSAdffssghABC5612345612345192'; -// 密文,存放加密后数据 +// Ciphertext, storing the encrypted data. let cipherText = ''; -// 操作句柄 +// Operation handle. let handle; // [EndExclude hmac_generate] // [StartExclude hmac_process] function getHMACGenProperties() { let properties = new Array(); let index = 0; - // 算法 + // algorithm properties[index++] = { tag: huks.HuksTag.HUKS_TAG_ALGORITHM, value: huks.HuksKeyAlg.HUKS_ALG_AES }; - // 密钥长度 + // key length. properties[index++] = { tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_256 }; - // 密钥用途 + // Key usage. properties[index++] = { tag: huks.HuksTag.HUKS_TAG_PURPOSE, value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_MAC @@ -69,22 +69,22 @@ function stringToUnit8Array(str) { function getHMACProperties() { let properties = new Array(); let index = 0; - // 算法 + // algorithm. properties[index++] = { tag: huks.HuksTag.HUKS_TAG_ALGORITHM, value: huks.HuksKeyAlg.HUKS_ALG_HMAC }; - // 密钥长度 + // key length. properties[index++] = { tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_256 }; - // 密钥用途 + // Key usage. properties[index++] = { tag: huks.HuksTag.HUKS_TAG_PURPOSE, value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_MAC }; - // 摘要算法 + // digest algorithm. properties[index++] = { tag: huks.HuksTag.HUKS_TAG_DIGEST, value: huks.HuksKeyPurpose.HUKS_DIGEST_SHA256 @@ -152,7 +152,7 @@ function HMACProcess() { } }); } else { - // HMAC密文接收 + // HMAC ciphertext reception. cipherText = uint8ArrayToString(finishData.outData); } }); diff --git a/LiteWearable/entry/src/main/js/MainAbility/security/KeyAlias.js b/LiteWearable/entry/src/main/js/MainAbility/security/KeyAlias.js index 2bf669097719b0037752f788cfc25662954772b7..af84aa3556a8c250d5f4590f82a081f6bed208f8 100644 --- a/LiteWearable/entry/src/main/js/MainAbility/security/KeyAlias.js +++ b/LiteWearable/entry/src/main/js/MainAbility/security/KeyAlias.js @@ -3,30 +3,31 @@ import huks from '@ohos.security.huks'; // [StartExclude export_key] -// 密钥材料 +// Key material. let plainTextKey = new Uint8Array([ 0x1d, 0x2c, 0x3a, 0x4b, 0x5e, 0x6f, 0x7d, 0x8a, 0x9c, 0xab, 0xbc, 0xcd, 0xde, 0xef, 0xf1, 0x23 ]); // [EndExclude export_key] -// 确定密钥别名 +// Confirm the key alias. const KEY_ALIAS = 'keyAlias'; // [StartExclude export_key] -// 封装密钥属性集和密钥材料 +// Package the set of key attributes and key materials. function getImportKeyProperties() { let properties = new Array(); let index = 0; - // 算法 + // algorithm. properties[index++] = { tag: huks.HuksTag.HUKS_TAG_ALGORITHM, value: huks.HuksKeyAlg.HUKS_ALG_AES }; - // 秘钥长度 (128/192/256) + // Key length (128/192/256). properties[index++] = { tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_128 }; - // 秘钥用途,生成秘钥时使用可以限制秘钥的使用权限 (AES一般用于加密、解密) + // Key usage: When generating the key, + // using it can limit the usage rights of the key (AES is generally used for encryption and decryption). properties[index++] = { tag: huks.HuksTag.HUKS_TAG_PURPOSE, value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT | huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT @@ -34,7 +35,7 @@ function getImportKeyProperties() { return properties } -// 明文导入密钥 +// Explicitly imported key. function importKey() { let huksInfo; let ret = true; diff --git a/LiteWearable/entry/src/main/js/MainAbility/security/RSA.js b/LiteWearable/entry/src/main/js/MainAbility/security/RSA.js index 73469f3132bcde33a2a243a376f22607370589ec..c3b77afedb9c552737cfa71d15236e8ce211acdb 100644 --- a/LiteWearable/entry/src/main/js/MainAbility/security/RSA.js +++ b/LiteWearable/entry/src/main/js/MainAbility/security/RSA.js @@ -3,18 +3,18 @@ import huks from '@ohos.security.huks'; // [Start rsa_encrypt] -// 别名,用于区分生成的KEY +// Alias, used to distinguish the generated KEY. const RSA_KEY_ALIAS = 'RSAKeyAlias'; -// 自定义密钥长度必须在1024 -2048之间,且是8的倍数 +// The custom key length must be between 1024 and 2048, and it must be a multiple of 8. const HUKS_RSA_KEY_SIZE_1024 = 1024; // [StartExclude rsa_generate] -// 明文,加密前数据 +// Plain text, data before encryption. let plainText = 'RSASSAdffssghCBC5612345612345192'; -// 明文,加密前数据的长度 +// Plain text, the length of the data before encryption. let plainTextLen = 32; -// 密文,存放加密后数据 +// Ciphertext, storing the encrypted data. let cipherText = ''; -// 操作句柄 +// Operation handle. let handle; // [EndExclude rsa_generate] @@ -23,17 +23,17 @@ let handle; function getRSAGenProperties() { let properties = new Array(); let index = 0; - // 算法 + // algorithm. properties[index++] = { tag: huks.HuksTag.HUKS_TAG_ALGORITHM, value: huks.HuksKeyAlg.HUKS_ALG_RSA }; - // 密钥长度 + // key length. properties[index++] = { tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, value: HUKS_RSA_KEY_SIZE_1024 }; - // 密钥用途 + // Key usage. properties[index++] = { tag: huks.HuksTag.HUKS_TAG_PURPOSE, value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT | huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT @@ -59,23 +59,23 @@ function generateRSAKey() { function getRSAEncryptProperties() { let properties = new Array(); let index = 0; - // 算法 + // algorithm. properties[index++] = { tag: huks.HuksTag.HUKS_TAG_ALGORITHM, value: huks.HuksKeyAlg.HUKS_ALG_RSA }; - // 密钥长度 + // key length. properties[index++] = { tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, value: HUKS_RSA_KEY_SIZE_1024 }; - // 密钥用途 + // Key usage. properties[index++] = { tag: huks.HuksTag.HUKS_TAG_PURPOSE, value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT }; - // 密钥 PADDING方式 + // Key PADDING method. properties[index++] = { tag: huks.HuksTag.HUKS_TAG_PADDING, value: huks.HuksKeyPadding.HUKS_PADDING_PKCS1_V1_5 @@ -148,7 +148,7 @@ function encryptProcess() { } }); } else { - // 密文接收 + // Encrypted message reception. cipherText = uint8ArrayToString(finishData.outData); huksInfo = cipherText; } @@ -177,30 +177,30 @@ function stringToUint8Array(str) { function getRSADecryptProperties() { let properties = new Array(); let index = 0; - // 算法 + // algorithm. properties[index++] = { tag: huks.HuksTag.HUKS_TAG_ALGORITHM, value: huks.HuksKeyAlg.HUKS_ALG_RSA }; - // 密钥长度 + // key length. properties[index++] = { tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, value: HUKS_RSA_KEY_SIZE_1024 }; - // 密钥用途 + // Key usage. properties[index++] = { tag: huks.HuksTag.HUKS_TAG_PURPOSE, value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT }; - // 密钥 PADDING方式 + // Key PADDING method. properties[index++] = { tag: huks.HuksTag.HUKS_TAG_PADDING, value: huks.HuksKeyPadding.HUKS_PADDING_PKCS1_V1_5 }; - // 摘要算法 + // digest algorithm. properties[index++] = { tag: huks.HuksTag.HUKS_TAG_DIGEST, value: huks.HuksKeyDigest.HUKS_DIGEST_SHA256 @@ -210,7 +210,7 @@ function getRSADecryptProperties() { } function decryptProcess() { - // 加密密文长度 + // Length of encrypted ciphertext. let len = HUKS_RSA_KEY_SIZE_1024 / 8; let ret = true; let outPlainText; @@ -271,7 +271,7 @@ function decryptProcess() { } }); } else { - // 明文接收 + // Clear text reception. outPlainText = uint8ArrayToString(finishData.outData); } }); diff --git a/LiteWearable/entry/src/main/js/MainAbility/style1/style1.hml b/LiteWearable/entry/src/main/js/MainAbility/style1/style1.hml index bc53d37ea47559a2b108ca0f9aee9faa8a588a6e..86089f34602fd88a279a4d1f28eb1106d2db25f7 100644 --- a/LiteWearable/entry/src/main/js/MainAbility/style1/style1.hml +++ b/LiteWearable/entry/src/main/js/MainAbility/style1/style1.hml @@ -1,8 +1,9 @@ + +
- + Hello World
diff --git a/LiteWearable/entry/src/main/js/MainAbility/style2/style2.hml b/LiteWearable/entry/src/main/js/MainAbility/style2/style2.hml index 161b7efb6b36ea3d1cef91f15b3381cba5cddd5a..7f5f73b188475b893014f7bf00fa734a7f62142d 100644 --- a/LiteWearable/entry/src/main/js/MainAbility/style2/style2.hml +++ b/LiteWearable/entry/src/main/js/MainAbility/style2/style2.hml @@ -1,7 +1,9 @@ + +
- + + Hello World diff --git a/LiteWearable/entry/src/main/js/MainAbility/style3/style3.css b/LiteWearable/entry/src/main/js/MainAbility/style3/style3.css index e90d8da48e528984be67910b8cd52dd03b12ab16..2dde480f1ec0e25a69acf242539e0639f4de6229 100644 --- a/LiteWearable/entry/src/main/js/MainAbility/style3/style3.css +++ b/LiteWearable/entry/src/main/js/MainAbility/style3/style3.css @@ -1,4 +1,4 @@ -/* .为类选择器,所有组件中class="container" 的组件都会使用该样式 */ +/* . For the class selector, all components with the class attribute set to "container" will apply this style. */ .container { display: flex; justify-content: center; @@ -6,7 +6,7 @@ width: 466px; height: 466px; } -/* #为ID选择器,id为title的组件会使用该样式 */ +/* # For the ID selector, the component with the ID "title" will apply this style. */ #title { font-size: 30px; text-align: center; diff --git a/LiteWearable/entry/src/main/js/MainAbility/style3/style3.hml b/LiteWearable/entry/src/main/js/MainAbility/style3/style3.hml index e23b9118819bafc36c863ac7d32df3de4d3ced7c..e63cb8f9256001e062d7ae3752d5fe94c70a099b 100644 --- a/LiteWearable/entry/src/main/js/MainAbility/style3/style3.hml +++ b/LiteWearable/entry/src/main/js/MainAbility/style3/style3.hml @@ -1,8 +1,8 @@ - +
- + Hello World diff --git a/LiteWearable/hvigor/hvigor-config.json5 b/LiteWearable/hvigor/hvigor-config.json5 index fe83c3e838abfb3629eed84f6c7092f306d818f9..5bebc9755447385d82ce4138f54d991b1f85f348 100644 --- a/LiteWearable/hvigor/hvigor-config.json5 +++ b/LiteWearable/hvigor/hvigor-config.json5 @@ -1,5 +1,5 @@ { - "modelVersion": "5.0.2", + "modelVersion": "5.0.5", "dependencies": { }, "execution": { diff --git a/LiteWearable/oh-package.json5 b/LiteWearable/oh-package.json5 index b185185d31c2454034ed6fbd80bcc73beea65fc6..2d9c74ff34f1383ec920815a40399dd0fe46a6c5 100644 --- a/LiteWearable/oh-package.json5 +++ b/LiteWearable/oh-package.json5 @@ -1,5 +1,5 @@ { - "modelVersion": "5.0.2", + "modelVersion": "5.0.5", "description": "Please describe the basic information.", "dependencies": { }, diff --git a/LiteWearable/screenshots/device/LiteWearable.png b/LiteWearable/screenshots/device/LiteWearable.png new file mode 100644 index 0000000000000000000000000000000000000000..b8f2b82beb654e2c4f7511a481b849b5d33e8105 Binary files /dev/null and b/LiteWearable/screenshots/device/LiteWearable.png differ diff --git a/LiveViewLockScreen/README.md b/LiveViewLockScreen/README.md deleted file mode 100644 index e45666cba70ef95f2125cd2633316ec2f8c0a16f..0000000000000000000000000000000000000000 --- a/LiveViewLockScreen/README.md +++ /dev/null @@ -1,25 +0,0 @@ -# BestPracticeSnippets - -## 目录 - -* [DealStrideSolution: 处理stride解决相机预览花屏问题](DealStrideSolution) -* [AppDataSecurity: 应用数据安全](AppDataSecurity) -* [AppPrivacyProtection:应用隐私保护](AppPrivacyProtection) -* [AvoidTimeComsume:主线程耗时操作优化指导](AvoidTimeComsume) -* [ComponentReuse:组件复用开发实践](ComponentReuse) -* [CustomDialogPractice:应用自定义弹窗开发实践](CustomDialogPractice) -* [FramedRendering:高负载分帧渲染开发实践](FramedRendering) -* [FuzzySceneOptimization:图像模糊动效优化](FuzzySceneOptimization) -* [NdkQoS:基于QoS设置线程优先级](NdkQoS) -* [NetworkManagement:网络管理与状态监听](NetworkManagement) -* [PreHttpRequestUseFiles:Image白块解决指导](PreHttpRequestUseFiles) -* [ImageEditTaskPool:基于TaskPool实现图片编辑功能](ImageEditTaskPool) -* [SegmentedPhotograph:实现相机分段式拍照功能](SegmentedPhotograph) -* [ScreenFlickerSolution:解决应用动效闪屏的方案](ScreenFlickerSolution) -* [VisibleComponent:不可见组件低功耗建议](VisibleComponent) - -## 使用说明 - -1. 将独立的应用示例工程导入DevEco Studio进行编译构建及运行调试。 -2. 安装运行后,即可在设备上查看应用示例运行效果,以及进行相关调试。 - diff --git a/LoadPerformanceInWeb/.gitignore b/LoadPerformanceInWeb/.gitignore deleted file mode 100644 index d2ff20141ceed86d87c0ea5d99481973005bab2b..0000000000000000000000000000000000000000 --- a/LoadPerformanceInWeb/.gitignore +++ /dev/null @@ -1,12 +0,0 @@ -/node_modules -/oh_modules -/local.properties -/.idea -**/build -/.hvigor -.cxx -/.clangd -/.clang-format -/.clang-tidy -**/.test -/.appanalyzer \ No newline at end of file diff --git a/LoadPerformanceInWeb/README.md b/LoadPerformanceInWeb/README.md new file mode 100644 index 0000000000000000000000000000000000000000..721cca08cf1fb7a5a2f1e6f807901d35ca37975e --- /dev/null +++ b/LoadPerformanceInWeb/README.md @@ -0,0 +1,94 @@ +# Web加载性能优化 + +## 项目简介 + +本示例展示了Web加载性能优化相关案例。 + +## 效果预览 +不涉及 + +## 使用说明 +不涉及 + +## 工程目录 +``` +├──entry/src/main/cpp // C++代码区 +│ ├──types/libentry +│ │ ├──Index.d.ts // 暴露给UI层的接口 +│ │ └──oh-package.json5 +│ ├──CMakeLists.txt // 编译入口 +│ ├──DefineJSBridge.cpp // 定义JSBridge +│ ├──hello.cpp // 代码注册 +│ ├──napi_init.cpp // 代码注册 +│ └──nnapi_init.cpp // 读取Rawfile +├──entry/src/main/ets // 代码区 +│ ├──entryability +│ │ └──EntryAbility.ets // 程序入口类 +│ ├──entrybackupability +│ │ └──EntryBackupAbility.ets +│ ├──pages +│ │ ├──ByteCodeCache.ets // 字节码缓存 +│ │ ├──CaseFour.ets // prefetchPage预链接 +│ │ ├──CaseOne.ets // prepareForPageLoad +│ │ ├──CaseThree.ets // prepareForPageLoad预加载 +│ │ ├──CaseTwo.ets // prepareForPageLoad预加载 +│ │ ├──ClearResourceCache.ets // clearPrefetch +│ │ ├──common.ets // 预渲染 +│ │ ├──CreateCarrier.ets // 预创建Web +│ │ ├──CreateNodeController.ets // 预渲染Web +│ │ ├──Index.ets // 首页 +│ │ ├──JsBridgeOfArkTS.ets // ArkTS的JsBridge +│ │ ├──JsBridgeOfNDK.ets // NDK的JsBridge +│ │ ├──LoadWebComponentError.ets // loadUrl +│ │ ├──LoadWebComponentRight.ets // loadUrl +│ │ ├──LoadWebPage.ets // startTrace +│ │ ├──PageRequestInterception.ets // Web拦截 +│ │ ├──PracticalCaseOne.ets // 未预编译 +│ │ ├──PracticalCaseTwo.ets // 预编译 +│ │ ├──PrefetchResource.ets // 预加载资源 +│ │ ├──RegisterJavaScriptProxy.ets // 注册JavaScript +│ │ ├──RegisterSyncFunction.ets // 注册异步方法 +│ │ ├──Second.ets // 预渲染 +│ │ ├──SetResposeData.ets // 拦截 +│ │ ├──SetSchemeHandler.et // 设置Scheme +│ │ ├──UseArrayBufferInterceptReplace.ets // 拦截后使用ArrayBuffer +│ │ ├──UseNodeController.ets // controller +│ │ ├──UseStringInterceptReplace.ets // 拦截后使用字符串 +│ │ ├──WebComponent.ets // Web组件 +│ │ └──WebComponentLoad.ets // Web组件加载 +│ ├──utils +│ │ ├──CreateResourceConfig.ets // ForEach页面 +│ │ └──HttpRequestPost.js // LazyForEach页面 +│ └──view +│ └──Second.ets // Web页面 +└──entry/src/main/resources // 应用资源目录 +``` + +## 具体实现 + +不涉及。 + +## 相关权限 + +不涉及。 + +## 约束与限制 + +1. 本示例仅支持标准系统上运行,支持设备:华为手机。 + +2. HarmonyOS系统:HarmonyOS 5.0.5 Release及以上。 + +3. DevEco Studio版本:DevEco Studio 5.0.5 Release及以上。 + +4. HarmonyOS SDK版本:HarmonyOS 5.0.5 Release SDK及以上。 + +## 下载 + +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set LoadPerformanceInWeb +git checkout +``` \ No newline at end of file diff --git a/LoadPerformanceInWeb/entry/.gitignore b/LoadPerformanceInWeb/entry/.gitignore deleted file mode 100644 index e2713a2779c5a3e0eb879efe6115455592caeea5..0000000000000000000000000000000000000000 --- a/LoadPerformanceInWeb/entry/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -/node_modules -/oh_modules -/.preview -/build -/.cxx -/.test \ No newline at end of file diff --git a/LoadPerformanceInWeb/entry/build-profile.json5 b/LoadPerformanceInWeb/entry/build-profile.json5 index 4d611879c7913fb0610c686e2399258ab3a6dad1..0311b505dbf43f0d22662c8d783c5f4464d15b15 100644 --- a/LoadPerformanceInWeb/entry/build-profile.json5 +++ b/LoadPerformanceInWeb/entry/build-profile.json5 @@ -20,9 +20,6 @@ "targets": [ { "name": "default" - }, - { - "name": "ohosTest", } ] } \ No newline at end of file diff --git a/LoadPerformanceInWeb/entry/oh-package.json5 b/LoadPerformanceInWeb/entry/oh-package.json5 index 248c3b7541a589682a250f86a6d3ecf7414d2d6a..49272b92c5bf80d3b57b46e03664b86eae213cb5 100644 --- a/LoadPerformanceInWeb/entry/oh-package.json5 +++ b/LoadPerformanceInWeb/entry/oh-package.json5 @@ -5,6 +5,8 @@ "main": "", "author": "", "license": "", - "dependencies": {} + "dependencies": { + "libentry.so": "file:./src/main/cpp/types/libentry" + } } diff --git a/LoadPerformanceInWeb/entry/src/main/cpp/CMakeLists.txt b/LoadPerformanceInWeb/entry/src/main/cpp/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..e53f17275e5609f6543456acb87bd97336f3fe8d --- /dev/null +++ b/LoadPerformanceInWeb/entry/src/main/cpp/CMakeLists.txt @@ -0,0 +1,16 @@ +# the minimum version of CMake. +cmake_minimum_required(VERSION 3.5.0) +project(AVScreenCaptureScreenRecord) + +set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}) + +if(DEFINED PACKAGE_FIND_FILE) + include(${PACKAGE_FIND_FILE}) +endif() + +include_directories(${NATIVERENDER_ROOT_PATH} + ${NATIVERENDER_ROOT_PATH}/include) + +add_library(entry SHARED napi_init.cpp) + +target_link_libraries(entry PUBLIC libace_napi.z.so) \ No newline at end of file diff --git a/LoadPerformanceInWeb/entry/src/main/ets/cpps/DefineJSBridge.cpp b/LoadPerformanceInWeb/entry/src/main/cpp/DefineJSBridge.cpp similarity index 100% rename from LoadPerformanceInWeb/entry/src/main/ets/cpps/DefineJSBridge.cpp rename to LoadPerformanceInWeb/entry/src/main/cpp/DefineJSBridge.cpp diff --git a/LoadPerformanceInWeb/entry/src/main/ets/cpps/hello.cpp b/LoadPerformanceInWeb/entry/src/main/cpp/hello.cpp similarity index 100% rename from LoadPerformanceInWeb/entry/src/main/ets/cpps/hello.cpp rename to LoadPerformanceInWeb/entry/src/main/cpp/hello.cpp diff --git a/LoadPerformanceInWeb/entry/src/main/cpp/napi_init.cpp b/LoadPerformanceInWeb/entry/src/main/cpp/napi_init.cpp new file mode 100644 index 0000000000000000000000000000000000000000..da0f7b8b9bd5df93b23c8da6cd9f37b6998b329f --- /dev/null +++ b/LoadPerformanceInWeb/entry/src/main/cpp/napi_init.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + +#include "napi/native_api.h" + +static napi_value registerCustomSchemes(napi_env env, napi_callback_info info) { + size_t argc = 3; + napi_value args[3] = {nullptr}; + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + + int32_t outputFd, videoWidth, videoHeight; + napi_get_value_int32(env, args[0], &outputFd); + napi_get_value_int32(env, args[1], &videoWidth); + napi_get_value_int32(env, args[2], &videoHeight); + CAVScreenCaptureToStream::GetInstance().StartScreenCapture(outputFd, videoWidth, videoHeight); + + return nullptr; +} + +static napi_value StopScreenCaptureToStream(napi_env env, napi_callback_info info) { + CAVScreenCaptureToStream::GetInstance().StopScreenCapture(); + return nullptr; +} + +EXTERN_C_START +static napi_value Init(napi_env env, napi_value exports) { + napi_property_descriptor desc[] = { + {"startScreenCaptureToFile", nullptr, registerCustomSchemes, nullptr, nullptr, + nullptr, napi_default, nullptr}, + {"stopScreenCaptureToFile", nullptr, CAVScreenCaptureToFile::StopScreenCaptureToFile, nullptr, nullptr, nullptr, + napi_default, nullptr}, + {"setStopCallbackToFile", nullptr, CAVScreenCaptureToFile::SetStopCallbackToFile, nullptr, nullptr, nullptr, + napi_default, nullptr}, + {"startScreenCaptureToStream", nullptr, StartScreenCaptureToStream, nullptr, nullptr, nullptr, napi_default, + nullptr}, + {"stopScreenCaptureToStream", nullptr, StopScreenCaptureToStream, nullptr, nullptr, nullptr, napi_default, + nullptr}, + {"setStopCallbackToStream", nullptr, CAVScreenCaptureToStream::GetInstance().SetStopCallbackToStream, nullptr, + nullptr, nullptr, napi_default, nullptr}, + }; + napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); + return exports; +} +EXTERN_C_END + +static napi_module demoModule = { + .nm_version = 1, + .nm_flags = 0, + .nm_filename = nullptr, + .nm_register_func = Init, + .nm_modname = "entry", + .nm_priv = ((void *)0), + .reserved = {0}, +}; + +extern "C" __attribute__((constructor)) void RegisterEntryModule(void) { napi_module_register(&demoModule); } diff --git a/LoadPerformanceInWeb/entry/src/main/ets/cpps/nnapi_init.cpp b/LoadPerformanceInWeb/entry/src/main/cpp/nnapi_init.cpp similarity index 90% rename from LoadPerformanceInWeb/entry/src/main/ets/cpps/nnapi_init.cpp rename to LoadPerformanceInWeb/entry/src/main/cpp/nnapi_init.cpp index 74d717907e512b4d745f59da435ebf2a9e2c1003..6bd574b7f40d8d8a8d5d59989b9ddc2bd91684ca 100644 --- a/LoadPerformanceInWeb/entry/src/main/ets/cpps/nnapi_init.cpp +++ b/LoadPerformanceInWeb/entry/src/main/cpp/nnapi_init.cpp @@ -1,5 +1,5 @@ // [Start register_custom_schemes] -// 注册三方协议的配置,需要在Web内核初始化之前调用,否则会注册失败。 +// register Custom Schemes before web initialized static napi_value RegisterCustomSchemes(napi_env env, napi_callback_info info) { OH_LOG_INFO(LOG_APP, "register custom schemes"); OH_ArkWeb_RegisterCustomSchemes("custom", ARKWEB_SCHEME_OPTION_STANDARD | ARKWEB_SCHEME_OPTION_CORS_ENABLED | ARKWEB_SCHEME_OPTION_CODE_CACHE_ENABLED); @@ -8,7 +8,7 @@ static napi_value RegisterCustomSchemes(napi_env env, napi_callback_info info) { // [End register_custom_schemes] // [Start rawfile_request] -// 在worker线程中读取rawfile,并通过ResourceHandler返回给Web内核。 +// Read Rawfile Data On Worker Thread void RawfileRequest::ReadRawfileDataOnWorkerThread() { OH_LOG_INFO(LOG_APP, "read rawfile in worker thread."); const struct UrlInfo { diff --git a/LoadPerformanceInWeb/entry/src/main/cpp/types/libentry/Index.d.ts b/LoadPerformanceInWeb/entry/src/main/cpp/types/libentry/Index.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..5c22bd6e63a911de3d2fb8e5ba67c6a83935fc64 --- /dev/null +++ b/LoadPerformanceInWeb/entry/src/main/cpp/types/libentry/Index.d.ts @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ +export const registerCustomSchemes: () => void; + +export const setSchemeHandler: () => void; + +export const nativeWebInit: (webTag: string) => void; + +export const runJavaScript: (webTag: string, js: string) => void; diff --git a/NativeSoIntegration/Ndk/src/main/cpp/types/libentry/oh-package.json5 b/LoadPerformanceInWeb/entry/src/main/cpp/types/libentry/oh-package.json5 similarity index 100% rename from NativeSoIntegration/Ndk/src/main/cpp/types/libentry/oh-package.json5 rename to LoadPerformanceInWeb/entry/src/main/cpp/types/libentry/oh-package.json5 diff --git a/LoadPerformanceInWeb/entry/src/main/ets/entryability/EntryAbility.ets b/LoadPerformanceInWeb/entry/src/main/ets/entryability/EntryAbility.ets index 924b521c190df1ca53f54f4fede8a67c5d5cb4e0..498212e055f7fd83a01109796af3e578ccfe9f72 100644 --- a/LoadPerformanceInWeb/entry/src/main/ets/entryability/EntryAbility.ets +++ b/LoadPerformanceInWeb/entry/src/main/ets/entryability/EntryAbility.ets @@ -8,7 +8,7 @@ export default class EntryAbility extends UIAbility { onWindowStageCreate(windowStage: window.WindowStage): void { windowStage.loadContent('pages/Index', (err) => { // Create an empty ArkWeb dynamic component in advance (need to pass in UIContext) and start the rendering process. - createNWeb('about://blank', windowStage.getMainWindowSync().getUIContext()); + createNWeb('about:blank', windowStage.getMainWindowSync().getUIContext()); }); } } diff --git a/LoadPerformanceInWeb/entry/src/main/ets/entryability/CaseFour.ets b/LoadPerformanceInWeb/entry/src/main/ets/pages/CaseFour.ets similarity index 100% rename from LoadPerformanceInWeb/entry/src/main/ets/entryability/CaseFour.ets rename to LoadPerformanceInWeb/entry/src/main/ets/pages/CaseFour.ets diff --git a/LoadPerformanceInWeb/entry/src/main/ets/pages/CaseOne.ets b/LoadPerformanceInWeb/entry/src/main/ets/pages/CaseOne.ets index ef0cd636615496fe700ddbaf23886eb02f3d6f32..d48fff01cf07ea2997f148e65a94a3fa19e0878f 100644 --- a/LoadPerformanceInWeb/entry/src/main/ets/pages/CaseOne.ets +++ b/LoadPerformanceInWeb/entry/src/main/ets/pages/CaseOne.ets @@ -1,7 +1,5 @@ // [Start case_one] import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; -import { hilog } from '@kit.PerformanceAnalysisKit'; -import { window } from '@kit.ArkUI'; import { webview } from '@kit.ArkWeb'; export default class EntryAbility extends UIAbility { @@ -10,6 +8,7 @@ export default class EntryAbility extends UIAbility { webview.WebviewController.initializeWebEngine(); // When pre-connecting, you need to replace' https://www.example.com' with the actual website address to visit // Specify that the second parameter is true, which means to pre-connect. If it is false, the interface will only pre-resolve the URL. + // The third parameter, numSockets, has a value range of 1-6. If it exceeds 6, the parameter will be treated as 6. webview.WebviewController.prepareForPageLoad('https://www.example.com/', true, 2); AppStorage.setOrCreate('abilityWant', want); console.log('EntryAbility onCreate done'); diff --git a/LoadPerformanceInWeb/entry/src/main/ets/pages/CaseThree.ets b/LoadPerformanceInWeb/entry/src/main/ets/pages/CaseThree.ets index 460f3bb7c3af4a0773d20f88d253a2e541ac24cf..df431fd6b9436f0ad430574140fddf36995e760d 100644 --- a/LoadPerformanceInWeb/entry/src/main/ets/pages/CaseThree.ets +++ b/LoadPerformanceInWeb/entry/src/main/ets/pages/CaseThree.ets @@ -10,7 +10,8 @@ struct WebComponent { Web({ src: 'https://www.example.com/', controller: this.webviewController}) .onPageEnd(() => { // Pre-connected https://www.example1.com/ - webview.WebviewController.prepareForPageLoad('https://www.example.com/', true, 120); + // The third parameter, numSockets, has a value range of 1-6. If it exceeds 6, the parameter will be treated as 6. + webview.WebviewController.prepareForPageLoad('https://www.example.com/', true, 2); }) } } diff --git a/LoadPerformanceInWeb/entry/src/main/ets/entryability/CreateCarrier.ets b/LoadPerformanceInWeb/entry/src/main/ets/pages/CreateCarrier.ets similarity index 93% rename from LoadPerformanceInWeb/entry/src/main/ets/entryability/CreateCarrier.ets rename to LoadPerformanceInWeb/entry/src/main/ets/pages/CreateCarrier.ets index 9429d5c252c11bef5a10eebc9c20232e8652d2ea..b47a025efc88ff78fcc25dcff786ac55acb02170 100644 --- a/LoadPerformanceInWeb/entry/src/main/ets/entryability/CreateCarrier.ets +++ b/LoadPerformanceInWeb/entry/src/main/ets/pages/CreateCarrier.ets @@ -3,7 +3,7 @@ import { UIAbility } from '@kit.AbilityKit'; import { window } from '@kit.ArkUI'; // Carrier Ability // EntryAbility.ets -import {createNWeb} from '../pages/common'; +import {createNWeb} from './common'; export default class EntryAbility extends UIAbility { onWindowStageCreate(windowStage: window.WindowStage): void { windowStage.loadContent('pages/Index', (err, data) => { diff --git a/LoadPerformanceInWeb/entry/src/main/ets/pages/CreateNodeController.ets b/LoadPerformanceInWeb/entry/src/main/ets/pages/CreateNodeController.ets index 7c33ce6fc4514ea9a94e524a5d13491c098839b4..a10d5cb75d1a3d49860a1667f72ec65d14baeac6 100644 --- a/LoadPerformanceInWeb/entry/src/main/ets/pages/CreateNodeController.ets +++ b/LoadPerformanceInWeb/entry/src/main/ets/pages/CreateNodeController.ets @@ -5,13 +5,14 @@ import { UIContext } from '@kit.ArkUI'; import { webview } from '@kit.ArkWeb'; import { NodeController, BuilderNode, Size, FrameNode } from '@kit.ArkUI'; -// Specific component contents of dynamic components in @Builder,@Builder中为动态组件的具体组件内容 +// Specific component contents of dynamic components in @Builder // Data is a parameter encapsulation class. class Data{ url: string = 'https://www.example.com'; controller: WebviewController = new webview.WebviewController(); } +let shouldInactive: boolean = true; @Builder function WebBuilder(data:Data) { Column() { @@ -25,13 +26,23 @@ function WebBuilder(data:Data) { .onPageBegin(() => { data.controller.onActive(); }) + .onPageEnd(() => { + console.info(`load page end time: ${Date.now()}`); + }) + .onFirstMeaningfulPaint(() =>{ + if (!shouldInactive) { + return; + } + // stop render + data.controller.onInactive(); + shouldInactive = false; + }) } } -let wrap = wrapBuilder(WebBuilder); // Used to control and feedback the behavior of nodes on the corresponding NodeContainer, which needs to be used together with NodeContainer -export class myNodeController extends NodeController { +export class MyNodeController extends NodeController { private rootNode: BuilderNode | null = null; private root: FrameNode | null = null; @@ -40,7 +51,7 @@ export class myNodeController extends NodeController { makeNode(uiContext: UIContext): FrameNode | null { console.log(' uicontext is undefined : '+ (uiContext === undefined)); if (this.rootNode != null) { - const parent = this.rootNode.getFrameNode()?.getParent(); + const parent: FrameNode = this.rootNode.getFrameNode()?.getParent() as FrameNode; if (parent) { console.info(JSON.stringify(parent.getInspectorInfo())); parent.removeChild(this.rootNode.getFrameNode()); @@ -55,23 +66,23 @@ export class myNodeController extends NodeController { return null; } // Callback when layout size changes. - aboutToResize(size: Size) { + aboutToResize(size: Size): void { console.log('aboutToResize width : ' + size.width + ' height : ' + size.height ) } // Call back when the NodeContainer corresponding to the controller is in Appear. - aboutToAppear() { + aboutToAppear(): void { console.log('aboutToAppear') } // Call back when the NodeContainer corresponding to the controller is Disappear. - aboutToDisappear() { + aboutToDisappear(): void { console.log('aboutToDisappear') } // This function is a user-defined function and can be used as an initialization function. // Initialize builderNode through UIContext, and then initialize the contents in @Builder through the Build interface in BuilderNode. - initWeb(url:string, uiContext:UIContext, control:WebviewController) { + initWeb(url:string, uiContext:UIContext, control:WebviewController): void { if(this.rootNode != null) { return; @@ -79,20 +90,20 @@ export class myNodeController extends NodeController { // Creating a node requires uiContext. this.rootNode = new BuilderNode(uiContext) // Create dynamic Web components - this.rootNode.build(wrap, { url:url, controller:control }) + this.rootNode.build(wrapBuilder(WebBuilder), { url:url, controller:control }) } } // Create the NodeController needed for Map saving. -let NodeMap:Map = new Map(); +let NodeMap:Map = new Map(); // Create WebViewController needed for Map saving. let controllerMap:Map = new Map(); // Initialization requires UIContext to be obtained in Ability. export const createNWeb = (url: string, uiContext: UIContext) => { // Create NodeController - let baseNode = new myNodeController(); - let controller = new webview.WebviewController() ; + let baseNode: MyNodeController = new MyNodeController(); + let controller: WebviewController = new webview.WebviewController() ; // Initialize a custom web component baseNode.initWeb(url, uiContext, controller); controllerMap.set(url, controller) @@ -100,7 +111,7 @@ export const createNWeb = (url: string, uiContext: UIContext) => { } // Customize to get the NodeController interface. -export const getNWeb = (url : string) : myNodeController | undefined => { +export const getNWeb = (url : string) : MyNodeController | undefined => { return NodeMap.get(url); } // [End create_node_controller] \ No newline at end of file diff --git a/LoadPerformanceInWeb/entry/src/main/ets/pages/JsBridgeOfArkTS.ets b/LoadPerformanceInWeb/entry/src/main/ets/pages/JsBridgeOfArkTS.ets index 1c4c47fde571c3db25ea5188b61aa858b39e8a30..65ee464a51d2d7b9c2a380039f9b813b0a33e494 100644 --- a/LoadPerformanceInWeb/entry/src/main/ets/pages/JsBridgeOfArkTS.ets +++ b/LoadPerformanceInWeb/entry/src/main/ets/pages/JsBridgeOfArkTS.ets @@ -6,7 +6,7 @@ import { webview } from '@kit.ArkWeb'; struct WebComponent { webviewController: webview.WebviewController = new webview.WebviewController(); - aboutToAppear() { + aboutToAppear(): void { // Configure the Web to open the debugging mode webview.WebviewController.setWebDebuggingAccess(true); } diff --git a/LoadPerformanceInWeb/entry/src/main/ets/pages/JsBridgeOfNdk.ets b/LoadPerformanceInWeb/entry/src/main/ets/pages/JsBridgeOfNdk.ets index 3c1e086905e6f89aa604eac62b921eef37ba0632..25b841c09a8774a0695064b35bf3acf0fed7418c 100644 --- a/LoadPerformanceInWeb/entry/src/main/ets/pages/JsBridgeOfNdk.ets +++ b/LoadPerformanceInWeb/entry/src/main/ets/pages/JsBridgeOfNdk.ets @@ -23,7 +23,7 @@ struct Index { controller: webview.WebviewController = new webview.WebviewController(this.webTag); @State testObjtest: testObj = new testObj(); - aboutToAppear() { + aboutToAppear(): void { console.info("aboutToAppear"); // init web ndk testNapi.nativeWebInit(this.webTag); diff --git a/LoadPerformanceInWeb/entry/src/main/ets/pages/LoadWebComponentError.ets b/LoadPerformanceInWeb/entry/src/main/ets/pages/LoadWebComponentError.ets index f85eb69ad86b5e88c0f02b4a846ee57953e2802f..f8277777d6f1c7561bd7221381114181ffbeca30 100644 --- a/LoadPerformanceInWeb/entry/src/main/ets/pages/LoadWebComponentError.ets +++ b/LoadPerformanceInWeb/entry/src/main/ets/pages/LoadWebComponentError.ets @@ -11,7 +11,7 @@ struct WebComponent { // Load the business Web component at an appropriate time. This example takes the Button click trigger as an example. Button('加载页面') .onClick(() => { - // Please replace url with real address. + // Please replace the URL with the real address. this.webviewController.loadUrl('https://www.example1.com/'); }) Web({ src: 'https://www.example.com/', controller: this.webviewController }) diff --git a/LoadPerformanceInWeb/entry/src/main/ets/pages/LoadWebComponentRight.ets b/LoadPerformanceInWeb/entry/src/main/ets/pages/LoadWebComponentRight.ets index 7f8de490e184a84495e4c6f5fa10adb14513b7a0..d4e442000bd22518c934de721556f8e7cd80aff6 100644 --- a/LoadPerformanceInWeb/entry/src/main/ets/pages/LoadWebComponentRight.ets +++ b/LoadPerformanceInWeb/entry/src/main/ets/pages/LoadWebComponentRight.ets @@ -15,7 +15,7 @@ struct WebComponent { .onClick(() => { // Performance dot hiTraceMeter.startTrace('getMessageData', 1); - // Please replace url with real address. + // Please replace the URL with the real address. this.controller.loadUrl('https://www.example1.com/'); }) Web({ src: 'https://www.example.com/', controller: this.webviewController }) diff --git a/LoadPerformanceInWeb/entry/src/main/ets/pages/PracticalCaseOne.ets b/LoadPerformanceInWeb/entry/src/main/ets/pages/PracticalCaseOne.ets index c4b679836c96d2e641c7a4a440940660f87ea644..b76f289e47261983c5475ea571d34d5baba0f48c 100644 --- a/LoadPerformanceInWeb/entry/src/main/ets/pages/PracticalCaseOne.ets +++ b/LoadPerformanceInWeb/entry/src/main/ets/pages/PracticalCaseOne.ets @@ -9,13 +9,13 @@ struct Index { build() { Column() { - // Load the business Web component at an appropriate time. This example takes the Button click trigger as an example.在适当的时机加载业务用Web组件,本例以Button点击触发为例 + // Load the business Web component at an appropriate time. This example takes the Button click trigger as an example. Button('加载页面') .onClick(() => { // Performance dot hiTraceMeter.startTrace('unPrecompileJavaScript', 1); - // Please replace url with real address. - this.controller.loadUrl('https://www.example.com/b.html'); + // Please replace the URL with the real address. + this.controller?.loadUrl('https://www.example.com/b.html'); }) Web({ src: 'https://www.example.com/a.html', controller: this.controller }) .fileAccess(true) diff --git a/LoadPerformanceInWeb/entry/src/main/ets/pages/PracticalCaseTwo.ets b/LoadPerformanceInWeb/entry/src/main/ets/pages/PracticalCaseTwo.ets index dcd58d26acb08447c737c3d0cc0d1080e909c4a0..71d01b39f5af91a636e1db27379867f2b12ecd87 100644 --- a/LoadPerformanceInWeb/entry/src/main/ets/pages/PracticalCaseTwo.ets +++ b/LoadPerformanceInWeb/entry/src/main/ets/pages/PracticalCaseTwo.ets @@ -1,10 +1,9 @@ // [Start practical_case_two] import { webview } from '@kit.ArkWeb'; -import { hiTraceMeter } from '@kit.PerformanceAnalysisKit'; interface Config { url: string, - localPath: string, // 本地资源路径 + localPath: string, // local resource path options: webview.CacheOptions } @@ -34,18 +33,18 @@ struct Index { .onControllerAttached(async () => { // Read the configuration and precompile. for (const config of this.configs) { - let content = await this.getUIContext().getHostContext().resourceManager.getRawFileContentSync(config.localPath); - - try { - this.controller.precompileJavaScript(config.url, content, config.options) - .then((errCode: number) => { - console.log('precompile successfully!' ); - }).catch((errCode: number) => { - console.error('precompile failed.' + errCode); - }) - } catch (err) { - console.error('precompile failed!.' + err.code + err.message); - } + this.getUIContext() + .getHostContext()?.resourceManager.getRawFileContent(config.localPath) + .then((content: Uint8Array) => { + this.controller.precompileJavaScript(config.url, content, config.options) + .then(() => { + console.log('precompile successfully!'); + }).catch((errCode: number) => { + console.error('precompile failed.' + errCode); + }) + }).catch(() => { + console.error('precompile failed!.'); + }) } }) // [End web_attach_controller] diff --git a/LoadPerformanceInWeb/entry/src/main/ets/entryability/PrefetchResource.ets b/LoadPerformanceInWeb/entry/src/main/ets/pages/PrefetchResource.ets similarity index 90% rename from LoadPerformanceInWeb/entry/src/main/ets/entryability/PrefetchResource.ets rename to LoadPerformanceInWeb/entry/src/main/ets/pages/PrefetchResource.ets index 2cac2ea40b0ed98a7c048259f66841ca0bb48cb4..c2dcbc2cf5425abd308ab071116f51f589f3ade6 100644 --- a/LoadPerformanceInWeb/entry/src/main/ets/entryability/PrefetchResource.ets +++ b/LoadPerformanceInWeb/entry/src/main/ets/pages/PrefetchResource.ets @@ -1,7 +1,5 @@ // [Start prefetch_resource] import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; -import { hilog } from '@kit.PerformanceAnalysisKit'; -import { window } from '@kit.ArkUI'; import { webview } from '@kit.ArkWeb'; export default class EntryAbility extends UIAbility { diff --git a/LoadPerformanceInWeb/entry/src/main/ets/pages/RegisterJavaScriptProxy.ets b/LoadPerformanceInWeb/entry/src/main/ets/pages/RegisterJavaScriptProxy.ets index 94e1c2cba781ac06c697651c31d31a77c0938081..3d2d0267495a76338793e03f79231cdedfcdbc0e 100644 --- a/LoadPerformanceInWeb/entry/src/main/ets/pages/RegisterJavaScriptProxy.ets +++ b/LoadPerformanceInWeb/entry/src/main/ets/pages/RegisterJavaScriptProxy.ets @@ -3,21 +3,21 @@ import { BusinessError } from '@kit.BasicServicesKit'; // Define ETS side objects and functions class TestObj { constructor() {} - test(testStr:string): string { - let start = Date.now(); + test(): string { + let start: number = Date.now(); // Simulate time-consuming operations for(let i = 0; i < 500000; i++) {} - let end = Date.now(); + let end: number = Date.now(); console.log('objName.test start: ' + start); return 'objName.test Sync function took ' + (end - start) + 'ms'; } - asyncTestBool(testBol:boolean): Promise { + asyncTestBool(): Promise { return new Promise((resolve, reject) => { - let start = Date.now(); + let start: number = Date.now(); // Simulate time-consuming operation (asynchronous) setTimeout(() => { for(let i = 0; i < 500000; i++) {} - let end = Date.now(); + let end: number = Date.now(); console.log('objAsyncName.asyncTestBool start: ' + start); resolve('objName.asyncTestBool Async function took ' + (end - start) + 'ms'); }, 0); // Use 0 ms delay to simulate an asynchronous operation that starts immediately @@ -28,18 +28,18 @@ class TestObj { class WebObj { constructor() {} webTest(): string { - let start = Date.now(); + let start: number = Date.now(); // Simulate time-consuming operations for(let i = 0; i < 500000; i++) {} - let end = Date.now(); + let end: number = Date.now(); console.log('objTestName.webTest start: ' + start); return 'objTestName.webTest Sync function took ' + (end - start) + 'ms'; } webString(): string { - let start = Date.now(); + let start: number = Date.now(); // Simulate time-consuming operations for(let i = 0; i < 500000; i++) {} - let end = Date.now(); + let end: number = Date.now(); console.log('objTestName.webString start: ' + start); return 'objTestName.webString Sync function took ' + (end - start) + 'ms'; } @@ -51,26 +51,26 @@ class AsyncObj { asyncTest(): Promise { return new Promise((resolve, reject) => { - let start = Date.now(); + let start: number = Date.now(); // Simulate time-consuming operation (asynchronous) setTimeout(() => { for (let i = 0; i < 500000; i++) { } - let end = Date.now(); + let end: number = Date.now(); console.log('objAsyncName.asyncTest start: ' + start); resolve('objAsyncName.asyncTest Async function took ' + (end - start) + 'ms'); }, 0); // Use 0 ms delay to simulate an asynchronous operation that starts immediately }); } - asyncString(testStr:string): Promise { + asyncString(): Promise { return new Promise((resolve, reject) => { - let start = Date.now(); + let start: number = Date.now(); // Simulate time-consuming operation (asynchronous) setTimeout(() => { for (let i = 0; i < 500000; i++) { } - let end = Date.now(); + let end: number = Date.now(); console.log('objAsyncName.asyncString start: ' + start); resolve('objAsyncName.asyncString Async function took ' + (end - start) + 'ms'); }, 0); // Use 0 millisecond delay to simulate immediate asynchronous operation diff --git a/LoadPerformanceInWeb/entry/src/main/ets/pages/RegisterSyncFunction.ets b/LoadPerformanceInWeb/entry/src/main/ets/pages/RegisterSyncFunction.ets index fbebce72f61c69b557cb94dafac5e921397ca82a..d7021274b5027fc9304eea1572bdead264e6a1b6 100644 --- a/LoadPerformanceInWeb/entry/src/main/ets/pages/RegisterSyncFunction.ets +++ b/LoadPerformanceInWeb/entry/src/main/ets/pages/RegisterSyncFunction.ets @@ -5,20 +5,20 @@ import { BusinessError } from '@kit.BasicServicesKit'; class TestObj { constructor() {} test(testStr:string): string { - let start = Date.now(); + let start: number = Date.now(); // Simulate time-consuming operations for(let i = 0; i < 500000; i++) {} - let end = Date.now(); + let end: number = Date.now(); console.log('objName.test start: ' + start); return 'objName.test Sync function took ' + (end - start) + 'ms'; } asyncTestBool(testBol:boolean): Promise { return new Promise((resolve, reject) => { - let start = Date.now(); + let start: number = Date.now(); // Simulate time-consuming operation (asynchronous) setTimeout(() => { for(let i = 0; i < 500000; i++) {} - let end = Date.now(); + let end: number = Date.now(); console.log('objAsyncName.asyncTestBool start: ' + start); resolve('objName.asyncTestBool Async function took ' + (end - start) + 'ms'); }, 0); // Use 0 ms delay to simulate an asynchronous operation that starts immediately @@ -29,18 +29,18 @@ class TestObj { class WebObj { constructor() {} webTest(): string { - let start = Date.now(); + let start: number = Date.now(); // Simulate time-consuming operations for(let i = 0; i < 500000; i++) {} - let end = Date.now(); + let end: number = Date.now(); console.log('objTestName.webTest start: ' + start); return 'objTestName.webTest Sync function took ' + (end - start) + 'ms'; } webString(): string { - let start = Date.now(); + let start: number = Date.now(); // Simulate time-consuming operations for(let i = 0; i < 500000; i++) {} - let end = Date.now(); + let end: number = Date.now(); console.log('objTestName.webString start: ' + start); return 'objTestName.webString Sync function took ' + (end - start) + 'ms'; } @@ -52,12 +52,12 @@ class AsyncObj { asyncTest(): Promise { return new Promise((resolve, reject) => { - let start = Date.now(); + let start: number = Date.now(); // Simulate time-consuming operation (asynchronous) setTimeout(() => { for (let i = 0; i < 500000; i++) { } - let end = Date.now(); + let end: number = Date.now(); console.log('objAsyncName.asyncTest start: ' + start); resolve('objAsyncName.asyncTest Async function took ' + (end - start) + 'ms'); }, 0); // Use 0 ms delay to simulate an asynchronous operation that starts immediately @@ -66,12 +66,12 @@ class AsyncObj { asyncString(testStr:string): Promise { return new Promise((resolve, reject) => { - let start = Date.now(); + let start: number = Date.now(); // Simulate time-consuming operation (asynchronous) setTimeout(() => { for (let i = 0; i < 500000; i++) { } - let end = Date.now(); + let end: number = Date.now(); console.log('objAsyncName.asyncString start: ' + start); resolve('objAsyncName.asyncString Async function took ' + (end - start) + 'ms'); }, 0); // Use 0 millisecond delay to simulate immediate asynchronous operation diff --git a/LoadPerformanceInWeb/entry/src/main/ets/pages/Second.ets b/LoadPerformanceInWeb/entry/src/main/ets/pages/Second.ets index f6086e22976bffb95b14a3bb468bfcc726cf1fe9..15a44d80840f02699baa9819f9dc486382529088 100644 --- a/LoadPerformanceInWeb/entry/src/main/ets/pages/Second.ets +++ b/LoadPerformanceInWeb/entry/src/main/ets/pages/Second.ets @@ -19,7 +19,7 @@ export struct Second { NavDestination() { Row() { Column() { - // Please replace url with real address. + // Please replace the URL with the real address. NodeContainer(getNWeb('https://www.example.com')) .height('100%') .width('100%') diff --git a/LoadPerformanceInWeb/entry/src/main/ets/entryability/SetSchemeHandler.ets b/LoadPerformanceInWeb/entry/src/main/ets/pages/SetSchemeHandler.ets similarity index 79% rename from LoadPerformanceInWeb/entry/src/main/ets/entryability/SetSchemeHandler.ets rename to LoadPerformanceInWeb/entry/src/main/ets/pages/SetSchemeHandler.ets index 7af1f021d4188f5badde7fd8d54993bfa238caa4..a8d66c821a276cb180d8cbe2cff3291fd8425017 100644 --- a/LoadPerformanceInWeb/entry/src/main/ets/entryability/SetSchemeHandler.ets +++ b/LoadPerformanceInWeb/entry/src/main/ets/pages/SetSchemeHandler.ets @@ -1,5 +1,4 @@ import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; -import { hilog } from '@kit.PerformanceAnalysisKit'; import { window } from '@kit.ArkUI'; import testNapi from 'libentry.so'; import webview from '@ohos.web.webview'; @@ -8,11 +7,11 @@ export default class EntryAbility extends UIAbility { // [Start set_scheme_handler] // EntryAbility.ets onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { - // 注册三方协议的配置。 + // register CustomSchemes testNapi.registerCustomSchemes(); - // 初始化Web组件内核,该操作会初始化Browser进程以及创建BrowserContext。 + // initializeWebEngine webview.WebviewController.initializeWebEngine(); - // 设置SchemeHandler。 + // set SchemeHandler。 testNapi.setSchemeHandler(); } // [End set_scheme_handler] diff --git a/LoadPerformanceInWeb/entry/src/main/ets/pages/UseArrayBufferInterceptReplace.ets b/LoadPerformanceInWeb/entry/src/main/ets/pages/UseArrayBufferInterceptReplace.ets index bafdc93b9ce5a41a07757692e44a56a524b02567..da5952a26deb56fb3514df86e7cfcc27e5ddfa89 100644 --- a/LoadPerformanceInWeb/entry/src/main/ets/pages/UseArrayBufferInterceptReplace.ets +++ b/LoadPerformanceInWeb/entry/src/main/ets/pages/UseArrayBufferInterceptReplace.ets @@ -61,6 +61,7 @@ struct WebComponent { console.info("init data length: " + this.data.length); } + // size - 1:10k, 2:1M, 3:10M initArrayBufferData(size:Number): void { this.initStringData(size); console.error("target string: " + this.data); diff --git a/LoadPerformanceInWeb/entry/src/main/ets/pages/UseNodeController.ets b/LoadPerformanceInWeb/entry/src/main/ets/pages/UseNodeController.ets index fff0679327990bef1f973ee20abf7a9c637febe1..657ec95d1c03182570d713b0903d285de52bf796 100644 --- a/LoadPerformanceInWeb/entry/src/main/ets/pages/UseNodeController.ets +++ b/LoadPerformanceInWeb/entry/src/main/ets/pages/UseNodeController.ets @@ -1,7 +1,7 @@ // [Start use_node_controller] // Use the Page page of NodeController. // Index.ets -import {createNWeb, getNWeb} from './common'; +import {getNWeb} from './common'; @Entry @Component diff --git a/LoadPerformanceInWeb/entry/src/main/ets/pages/WebComponentLoad.ets b/LoadPerformanceInWeb/entry/src/main/ets/pages/WebComponentLoad.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e8699a31d4690dc1d44c16247335f10b6693647 --- /dev/null +++ b/LoadPerformanceInWeb/entry/src/main/ets/pages/WebComponentLoad.ets @@ -0,0 +1,19 @@ +// [Start web_component_load] +import { webview } from '@kit.ArkWeb'; + +@Entry +@Component +struct WebComponent { + webviewController: webview.WebviewController = new webview.WebviewController(); + + build() { + Column() { + Button('加载页面') + .onClick(() => { + this.webviewController.loadUrl('https://www.example1.com/'); + }) + Web({ src: 'https://www.example.com/', controller: this.webviewController }) + } + } +} +// [End web_component_load] \ No newline at end of file diff --git a/LoadPerformanceInWeb/entry/src/main/ets/pages/common.ets b/LoadPerformanceInWeb/entry/src/main/ets/pages/common.ets index b293cfb9b83571437b3303b4b6141fdc2ceacc86..b4ee606e9139c5da75074a7c1e17afa975f4390c 100644 --- a/LoadPerformanceInWeb/entry/src/main/ets/pages/common.ets +++ b/LoadPerformanceInWeb/entry/src/main/ets/pages/common.ets @@ -4,8 +4,9 @@ import { UIContext } from '@kit.ArkUI'; import { webview } from '@kit.ArkWeb'; import { NodeController, BuilderNode, Size, FrameNode } from '@kit.ArkUI'; +import { hilog } from '@kit.PerformanceAnalysisKit'; -// Specific component contents of dynamic components in @Builder@Builder中为动态组件的具体组件内容 +// Specific component contents of dynamic components in @Builder // Data is a parameter encapsulation class. class Data { url: string = 'https://www.example.com'; @@ -29,8 +30,6 @@ function webBuilder(data: Data) { } } -let wrap = wrapBuilder(webBuilder); - // Used to control and feedback the behavior of nodes on the corresponding NodeContainer, which needs to be used together with NodeContainer export class MyNodeController extends NodeController { private rootNode: BuilderNode | null = null; @@ -41,40 +40,44 @@ export class MyNodeController extends NodeController { // //Called when the corresponding NodeContainer is created, or refreshed by calling the rebuild method. makeNode(uiContext: UIContext): FrameNode | null { console.info(' uicontext is undefined : ' + (uiContext === undefined)); - if (this.rootNode != null) { - const parent = this.rootNode.getFrameNode()?.getParent(); - if (parent) { - console.info(JSON.stringify(parent.getInspectorInfo())); - parent.removeChild(this.rootNode.getFrameNode()); - this.root = null; + try { + if (this.rootNode != null) { + const parent: FrameNode = this.rootNode.getFrameNode()?.getParent() as FrameNode; + if (parent) { + console.info(JSON.stringify(parent.getInspectorInfo())); + parent.removeChild(this.rootNode.getFrameNode()); + this.root = null; + } + this.root = new FrameNode(uiContext); + this.root.appendChild(this.rootNode.getFrameNode()); + // Returns the FrameNode node + return this.root; } - this.root = new FrameNode(uiContext); - this.root.appendChild(this.rootNode.getFrameNode()); - // Returns the FrameNode node - return this.root; + // Returns a null node that controls the dynamic component to be unbound. + return null; + } catch (error) { + return null; } - // Returns a null node that controls the dynamic component to be unbound. - return null; } // Callback when layout size changes. - aboutToResize(size: Size) { + aboutToResize(size: Size): void { console.info('aboutToResize width : ' + size.width + ' height : ' + size.height); } // Call back when the NodeContainer corresponding to the controller is in Appear. - aboutToAppear() { + aboutToAppear(): void { console.info('aboutToAppear'); } // Call back when the NodeContainer corresponding to the controller is Disappear. - aboutToDisappear() { + aboutToDisappear(): void { console.info('aboutToDisappear'); } // This function is a user-defined function and can be used as an initialization function. // Initialize builderNode through UIContext, and then initialize the contents in @Builder through the Build interface in BuilderNode. - initWeb(url: string, uiContext: UIContext, control: WebviewController) { + initWeb(url: string, uiContext: UIContext, control: WebviewController): void { if (this.rootNode != null) { return; } @@ -83,14 +86,18 @@ export class MyNodeController extends NodeController { // Creating a node requires uiContext. this.rootNode = new BuilderNode(uiContext); // Create dynamic Web components - this.rootNode.build(wrap, { url: url, controller: control }); + this.rootNode.build(wrapBuilder(webBuilder), { url: url, controller: control }); } // This function is a user-defined function and can be used as an initialization function. - loadUrl(url: string) { + loadUrl(url: string): void { if (this.rootWebviewController !== null) { - // Reuse the pre-created components and reload the url. - this.rootWebviewController.loadUrl(url); + try { + // Reuse the pre-created components and reload the url. + this.rootWebviewController.loadUrl(url); + } catch (error) { + hilog.info(0x0000, 'testTag', '%{public}s', 'loadUrl fail'); + } } } } @@ -103,8 +110,8 @@ let controllerMap: Map = new Map(); // Initialization requires UIContext to be obtained in Ability. export const createNWeb = (url: string, uiContext: UIContext) => { // Create NodeController - let baseNode = new MyNodeController(); - let controller = new webview.WebviewController(); + let baseNode: MyNodeController = new MyNodeController(); + let controller: WebviewController = new webview.WebviewController(); // Initialize a custom web component baseNode.initWeb(url, uiContext, controller); controllerMap.set(url, controller); @@ -116,7 +123,7 @@ export const getNWeb = (url: string): MyNodeController | undefined => { // When loading a new Url, it is recommended to reuse pre-created Web components. if (!NodeMap.get(url) && NodeMap.get('about://blank')) { // Get pre-created Web components - let webNode = NodeMap.get('about://blank') as MyNodeController; + let webNode: MyNodeController = NodeMap.get('about://blank') as MyNodeController; // Reload url webNode.loadUrl(url); return webNode; diff --git a/LoadPerformanceInWeb/entry/src/main/ets/utils/CreateResourceConfig.ets b/LoadPerformanceInWeb/entry/src/main/ets/utils/CreateResourceConfig.ets index fca61c2bd6a6cc2da7bd295b3099618fc94a179f..36bbd0052e0981077b5b3fbf33e68ea9d292afb9 100644 --- a/LoadPerformanceInWeb/entry/src/main/ets/utils/CreateResourceConfig.ets +++ b/LoadPerformanceInWeb/entry/src/main/ets/utils/CreateResourceConfig.ets @@ -19,8 +19,8 @@ export interface ExceptionResource { } -export const baseURL = 'http://localhost:8083/resource/'; -export const baseURL1 = 'http://localhost:8083/resource/'; +export const baseURL: string = 'http://localhost:8083/resource/'; +export const baseURL1: string = 'http://localhost:8083/resource/'; export const basicResources: Array = [ @@ -89,7 +89,7 @@ export const basicResources: Array = [ // [Start inject_offline_resource] // Call the offline resource injection cache interface -export async function injectOfflineResource(controller: WebviewController, resourceMapArr: Array) { +export async function injectOfflineResource(controller: WebviewController, resourceMapArr: Array): Promise { try { controller.injectOfflineResources(resourceMapArr); } catch (err) { diff --git a/LoadPerformanceInWeb/entry/src/main/ets/view/Second.ets b/LoadPerformanceInWeb/entry/src/main/ets/view/Second.ets index 7b6517c65fe8fbcc207d56aa101caab8839199af..c6966f753a8a27a8ed3c29d21c882a7e04e3eb05 100644 --- a/LoadPerformanceInWeb/entry/src/main/ets/view/Second.ets +++ b/LoadPerformanceInWeb/entry/src/main/ets/view/Second.ets @@ -20,7 +20,7 @@ export struct Second { NavDestination() { Row() { Column() { - // Please replace url with real address. + // Please replace the URL with the real address. Web({ src: 'https://www.example.com', controller: this.webviewController }) .height('100%') .width('100%') diff --git a/LoadPerformanceInWeb/entry/src/main/resources/base/element/string.json b/LoadPerformanceInWeb/entry/src/main/resources/base/element/string.json index f94595515a99e0c828807e243494f57f09251930..eddc0a5a9d389a69319b0e50816ac434e46ff42c 100644 --- a/LoadPerformanceInWeb/entry/src/main/resources/base/element/string.json +++ b/LoadPerformanceInWeb/entry/src/main/resources/base/element/string.json @@ -10,7 +10,7 @@ }, { "name": "EntryAbility_label", - "value": "label" + "value": "LoadPerformance" } ] } \ No newline at end of file diff --git a/LoadPerformanceInWeb/entry/src/main/resources/rawfile/test.html b/LoadPerformanceInWeb/entry/src/main/resources/rawfile/test.html index cd3371b2426fadf27df4b102802de4ae872eb529..118262bec92bb26d0216ff1614f82b2c60a6b53d 100644 --- a/LoadPerformanceInWeb/entry/src/main/resources/rawfile/test.html +++ b/LoadPerformanceInWeb/entry/src/main/resources/rawfile/test.html @@ -5,19 +5,16 @@

这是一个测试信息,默认字体为黑色,调用runJavaScript方法后字体为绿色,调用runJavaScriptCodePassed方法后字体为红色

diff --git a/WebApplicationJump/entry/src/main/resources/rawfile/index1_en.html b/WebApplicationJump/entry/src/main/resources/rawfile/index1_en.html new file mode 100644 index 0000000000000000000000000000000000000000..211cdee9d6cd59726f134dd8235f2ae162b5d44e --- /dev/null +++ b/WebApplicationJump/entry/src/main/resources/rawfile/index1_en.html @@ -0,0 +1,29 @@ + + + + + + Document + + + +
+
+
+ +
+ + Web Page +
+
Hello Web
+ Navigate back to the Web page +
+ + + diff --git a/WebApplicationJump/entry/src/main/resources/rawfile/index_cn.html b/WebApplicationJump/entry/src/main/resources/rawfile/index_cn.html new file mode 100644 index 0000000000000000000000000000000000000000..f72d09ccef82ea00ccebbfd66ef1d435fe7ca4bc --- /dev/null +++ b/WebApplicationJump/entry/src/main/resources/rawfile/index_cn.html @@ -0,0 +1,36 @@ + + + + + + Document + + + + + + + + diff --git a/WebApplicationJump/entry/src/main/resources/rawfile/index_en.html b/WebApplicationJump/entry/src/main/resources/rawfile/index_en.html new file mode 100644 index 0000000000000000000000000000000000000000..cd0bccff2b53e2eae681f6df91c4907c52463f1c --- /dev/null +++ b/WebApplicationJump/entry/src/main/resources/rawfile/index_en.html @@ -0,0 +1,38 @@ + + + + + + Document + + + + +
+
web and application jump and pull up
+ +
+ + + diff --git a/WebApplicationJump/entry/src/main/resources/rawfile/statics/ic_back.png b/WebApplicationJump/entry/src/main/resources/rawfile/statics/ic_back.png new file mode 100644 index 0000000000000000000000000000000000000000..4cfaff3395298b86ce6faa8121ff53f9f1dc35fa Binary files /dev/null and b/WebApplicationJump/entry/src/main/resources/rawfile/statics/ic_back.png differ diff --git a/WebApplicationJump/entry/src/main/resources/zh_CN/element/string.json b/WebApplicationJump/entry/src/main/resources/zh_CN/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..592138a78d93df8bcf0be9f64de718c0eb90143f --- /dev/null +++ b/WebApplicationJump/entry/src/main/resources/zh_CN/element/string.json @@ -0,0 +1,32 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "模块描述" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "Web应用拉起" + }, + { + "name": "back_to_web_page", + "value": "跳转回Web页面" + }, + { + "name": "distributed_permission", + "value": "用于拉起其他设备上的应用" + }, + { + "name": "original_page", + "value": "原生页面" + }, + { + "name": "not_found_toast", + "value": "未发现周边设备,请检查后重试!" + } + ] +} \ No newline at end of file diff --git a/CrossPlatformCompatibility/hvigor/hvigor-config.json5 b/WebApplicationJump/hvigor/hvigor-config.json5 similarity index 100% rename from CrossPlatformCompatibility/hvigor/hvigor-config.json5 rename to WebApplicationJump/hvigor/hvigor-config.json5 diff --git a/MultiFinancialManagement/hvigorfile.ts b/WebApplicationJump/hvigorfile.ts similarity index 100% rename from MultiFinancialManagement/hvigorfile.ts rename to WebApplicationJump/hvigorfile.ts diff --git a/CrossPlatformCompatibility/oh-package.json5 b/WebApplicationJump/oh-package.json5 similarity index 100% rename from CrossPlatformCompatibility/oh-package.json5 rename to WebApplicationJump/oh-package.json5 diff --git a/WebApplicationJump/screenshots/device/phone.png b/WebApplicationJump/screenshots/device/phone.png new file mode 100644 index 0000000000000000000000000000000000000000..ccc84f936bcf78437fa0be7f064007c6f8239bbf Binary files /dev/null and b/WebApplicationJump/screenshots/device/phone.png differ diff --git a/WebApplicationJump/screenshots/device/phone_EN.png b/WebApplicationJump/screenshots/device/phone_EN.png new file mode 100644 index 0000000000000000000000000000000000000000..c96185e96ba3f4795e6f6d0af8d7b97b865fb03b Binary files /dev/null and b/WebApplicationJump/screenshots/device/phone_EN.png differ diff --git a/WebDevelopOptimizationRender/README.md b/WebDevelopOptimizationRender/README.md index 0afa916d4c470eada855b189a9600a36979dcd34..b2ecdab90ef8d70a03641ba57cc766e0d816abb2 100644 --- a/WebDevelopOptimizationRender/README.md +++ b/WebDevelopOptimizationRender/README.md @@ -1,4 +1,27 @@ -#Performance +# 性能示例代码工程 -最佳实践“性能”板块目录 -WebDevelopOptimization Web场景性能优化指导#预启动Web Render \ No newline at end of file +## 介绍 +最佳实践“性能”板块目录,WebDevelopOptimization,Web场景性能优化指导,预启动Web Render。 + +## 相关权限 +无 + +## 约束与限制 +* 本示例仅支持标准系统上运行,支持设备:华为手机。 + +* HarmonyOS系统:HarmonyOS 5.0.5 Release及以上。 + +* DevEco Studio版本:DevEco Studio 5.0.5 Release及以上。 + +* HarmonyOS SDK版本:HarmonyOS 5.0.5 Release SDK及以上。 + +### 下载 + +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set WebDevelopOptimizationRender +git checkout +``` \ No newline at end of file diff --git a/WebDevelopOptimizationRender/build-profile.json5 b/WebDevelopOptimizationRender/build-profile.json5 index 9112e921430528e84202ab51adc032d815bf9ddc..d472dfdeec7fc6138dbf194897db44733b96a97f 100644 --- a/WebDevelopOptimizationRender/build-profile.json5 +++ b/WebDevelopOptimizationRender/build-profile.json5 @@ -4,7 +4,8 @@ { "name": "default", "signingConfig": "default", - "compatibleSdkVersion": "5.0.0(12)", + "compatibleSdkVersion": "5.0.5(17)", + "targetSdkVersion": "5.0.5(17)", "runtimeOS": "HarmonyOS", } ], diff --git a/XiaoyiAgentDemo/README.md b/XiaoyiAgentDemo/README.md new file mode 100644 index 0000000000000000000000000000000000000000..f9baef0d095f8c5a896311013584ad420f60d3ba --- /dev/null +++ b/XiaoyiAgentDemo/README.md @@ -0,0 +1,76 @@ +# 实现简易音频播放功能 + +### 介绍 + +本示例主要作为可外部调用操作的本地运行模块,实现了音频播放、信息获取、页面跳转的功能。 + +### 效果预览 + +| 首页 | 第二页页 | +|------------------------------------|------------------------------------| +| ![](screenshots/devices/page1.png) | ![](screenshots/devices/page2.png) | + +### 使用说明 + +1. 进入首页,点击“跳转到第二页”按钮,进入第二页; +2. 点击“播放音乐”,播放设置的音频; +3. 点击“获取信息”,展示APP信息区域显示音乐名称; +4. 点击“返回”,返回上一页。 + +### 工程目录 + +``` +├──entry/src/main/ets // 代码区 +│ ├──entryability +│ │ │──intentHandlers // 意图实现类 +│ │ │ ├──AudioPlayHandler.ets // 音频播放实现类 +│ │ │ ├──PageNavigateHandler.ets // 页面跳转实现类 +│ │ │ └──TextGetHandler.ets // 获取文本实现类 +│ │ ├──EntryAbility.ets // 程序入口 +│ │ └──InsightIntentExecutorImpl.ets // 业务逻辑处理 +│ ├──entrybackupability +│ │ └──EntryBackupAbility.ets +│ ├──models +│ │ │──MusicData.ets // 音频播放枚举类 +│ │ └──SongItem.ets // 音乐信息类 +│ ├──pages +│ │ ├──MainPage.ets // 首页 +│ │ └──SecondPage.ets // 第二页 +│ └──utils +│ │──audioplayer // 音频播放工具类 +│ │ ├──BackgroundUtil.ets +│ │ ├──MediaService.ets +│ │ ├──MediaTools.ets +│ │ └──SongItemBuilder.ets +│ └──Logger.ets // 日志 +└──entry/src/main/resources // 应用资源目录 +``` + +### 相关权限 + +不涉及。 + +### 依赖 + +不涉及。 + +### 约束与限制 + +1. 本示例仅支持标准系统上运行,支持设备:华为手机。 + +2. HarmonyOS系统:HarmonyOS 5.1.0 Release及以上。 + +3. DevEco Studio版本:DevEco Studio 5.1.0 Release及以上。 + +4. HarmonyOS SDK版本:HarmonyOS 5.1.0 Release SDK及以上。 + +### 下载 + +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set XiaoyiAgentDemo +git checkout +``` \ No newline at end of file diff --git a/XiaoyiAgentDemo/build-profile.json5 b/XiaoyiAgentDemo/build-profile.json5 index a311b56a3d299b50378ca886bc8ada80a8ac022d..1799d8ead585d71dc3265c2ef5c5ef812869678f 100644 --- a/XiaoyiAgentDemo/build-profile.json5 +++ b/XiaoyiAgentDemo/build-profile.json5 @@ -6,6 +6,7 @@ "name": "default", "signingConfig": "default", "compatibleSdkVersion": "5.1.0(18)", + "targetSdkVersion": "5.1.0(18)", "runtimeOS": "HarmonyOS", "buildOption": { "strictMode": { diff --git a/XiaoyiAgentDemo/entry/src/main/ets/entryability/EntryAbility.ets b/XiaoyiAgentDemo/entry/src/main/ets/entryability/EntryAbility.ets index a93263cec41aaabd4127eea6410073cdf1c2bb1d..bd7ee0377a50b34012fe16d41bfe56c97ec99f07 100644 --- a/XiaoyiAgentDemo/entry/src/main/ets/entryability/EntryAbility.ets +++ b/XiaoyiAgentDemo/entry/src/main/ets/entryability/EntryAbility.ets @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; import { hilog } from '@kit.PerformanceAnalysisKit'; import { window } from '@kit.ArkUI'; @@ -8,7 +23,6 @@ const DOMAIN = 0x0000; let uiContext: UIContext | null = null; export default class EntryAbility extends UIAbility { - onCreate(): void { AppStorage.setOrCreate('context', this.context); hilog.info(DOMAIN, 'testTag', '[EntryAbility] onCreate completed'); @@ -28,9 +42,14 @@ export default class EntryAbility extends UIAbility { return; } windowStage.getMainWindow((err: BusinessError, data) => { - let windowClass = data; - uiContext = windowClass.getUIContext(); - AppStorage.set('uiContext', uiContext); + try { + let windowClass = data; + uiContext = windowClass.getUIContext(); + AppStorage.set('uiContext', uiContext); + } catch (error) { + let err = error as BusinessError; + hilog.error(0x000, 'testTag', `getUIContext failed. code=${err.code}, message=${err.message}`); + } }) hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.'); @@ -56,10 +75,19 @@ export default class EntryAbility extends UIAbility { onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): void { hilog.info(DOMAIN, 'testTag', 'Received URI:', want.uri); const uri = want.uri; + let pathname = ''; if (uri) { - const urlObj = url.URL.parseURL(uri); - let pathname = urlObj.pathname; - uiContext?.getRouter().pushUrl({ url: 'pages' + pathname }); + try { + const urlObj = url.URL.parseURL(uri); + pathname = urlObj.pathname; + } catch (error) { + let err = error as BusinessError; + hilog.error(0x000, 'testTag', `getUIContext failed. code=${err.code}, message=${err.message}`); + } + uiContext?.getRouter().pushUrl({ url: 'pages' + pathname }) + .catch((error: BusinessError) => { + hilog.error(0x000, 'testTag', `pushUrl failed. code=${error.code}, message=${error.message}`); + }) } } // [End onNewWant] diff --git a/XiaoyiAgentDemo/entry/src/main/ets/entryability/InsightIntentExecutorImpl.ets b/XiaoyiAgentDemo/entry/src/main/ets/entryability/InsightIntentExecutorImpl.ets index c8d4856b5d49af95e7110c62e5d9784cfcbb6550..6f7a63045a74657b06ce3d76b78701e0f80ed8df 100644 --- a/XiaoyiAgentDemo/entry/src/main/ets/entryability/InsightIntentExecutorImpl.ets +++ b/XiaoyiAgentDemo/entry/src/main/ets/entryability/InsightIntentExecutorImpl.ets @@ -1,10 +1,26 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + // [Start executorImpl] import { insightIntent, InsightIntentExecutor } from '@kit.AbilityKit'; import { BusinessError } from '@kit.BasicServicesKit'; +import { window } from '@kit.ArkUI'; import AudioPlayHandler from './intentHandlers/AudioPlayHandler'; import TextGetHandler from './intentHandlers/TextGetHandler'; import PageNavigateHandler from './intentHandlers/PageNavigateHandler'; -import { window } from '@kit.ArkUI'; +import { hilog } from '@kit.PerformanceAnalysisKit'; export default class InsightIntentExecutorImpl extends InsightIntentExecutor { // Instruction implementation class. @@ -66,7 +82,10 @@ export default class InsightIntentExecutorImpl extends InsightIntentExecutor { case 'OpenSecondPage': return this.pageHandler.execute(); default: - pageLoader.loadContent('pages/MainPage'); + pageLoader.loadContent('pages/MainPage') + .catch((error: BusinessError) => { + hilog.error(0x000, 'testTag', `loadContent failed. code=${error.code}, message=${error.message}`); + }) break; } return Promise.resolve({ @@ -77,4 +96,5 @@ export default class InsightIntentExecutorImpl extends InsightIntentExecutor { } as insightIntent.ExecuteResult) } } + // [End executorImpl] \ No newline at end of file diff --git a/XiaoyiAgentDemo/entry/src/main/ets/entryability/intentHandlers/AudioPlayHandler.ets b/XiaoyiAgentDemo/entry/src/main/ets/entryability/intentHandlers/AudioPlayHandler.ets index 2d9db0f743dbb311387794aabff1201c3fa9afe3..b996db70eb88280e7acc10d2238118f3628a094a 100644 --- a/XiaoyiAgentDemo/entry/src/main/ets/entryability/intentHandlers/AudioPlayHandler.ets +++ b/XiaoyiAgentDemo/entry/src/main/ets/entryability/intentHandlers/AudioPlayHandler.ets @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + // [Start play] import { insightIntent } from '@kit.AbilityKit'; import { BusinessError } from '@kit.BasicServicesKit'; diff --git a/XiaoyiAgentDemo/entry/src/main/ets/entryability/intentHandlers/PageNavigateHandler.ets b/XiaoyiAgentDemo/entry/src/main/ets/entryability/intentHandlers/PageNavigateHandler.ets index 6221b6c7a026cd876cf6a7f1a7c0af63d1ac9c19..7d329eb00d7c8226f02ec1b04b03142e29c73ab4 100644 --- a/XiaoyiAgentDemo/entry/src/main/ets/entryability/intentHandlers/PageNavigateHandler.ets +++ b/XiaoyiAgentDemo/entry/src/main/ets/entryability/intentHandlers/PageNavigateHandler.ets @@ -1,6 +1,22 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + // [Start router] import { insightIntent } from '@kit.AbilityKit'; import { BusinessError } from '@kit.BasicServicesKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; export default class PageNavigateHandler { async execute(): Promise { @@ -8,7 +24,10 @@ export default class PageNavigateHandler { // Execute page redirection. let uiContext: UIContext | null | undefined = null; uiContext = AppStorage.get('uiContext'); - uiContext?.getRouter().pushUrl({ url: 'pages/SecondPage' }); + uiContext?.getRouter().pushUrl({ url: 'pages/SecondPage' }) + .catch((err: BusinessError) => { + hilog.error(0x0000, 'testTag',`pushUrl failed, Code:${err.code}, message:${err.message}`); + }) return { code: 0, diff --git a/XiaoyiAgentDemo/entry/src/main/ets/entryability/intentHandlers/TextGetHandler.ets b/XiaoyiAgentDemo/entry/src/main/ets/entryability/intentHandlers/TextGetHandler.ets index 9c98f86d87eb2c2369552dd5baa680881a7edf8e..d321c1a56209c3ea1828272319fbed7982a355d5 100644 --- a/XiaoyiAgentDemo/entry/src/main/ets/entryability/intentHandlers/TextGetHandler.ets +++ b/XiaoyiAgentDemo/entry/src/main/ets/entryability/intentHandlers/TextGetHandler.ets @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + // [Start name] import { insightIntent } from '@kit.AbilityKit'; import { BusinessError } from '@kit.BasicServicesKit'; diff --git a/XiaoyiAgentDemo/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets b/XiaoyiAgentDemo/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets index 8e4de99282050bad799ac892eb85ac5449364a51..0a97e21bd7a15599af76a806695860ff1eb0ebfe 100644 --- a/XiaoyiAgentDemo/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets +++ b/XiaoyiAgentDemo/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + import { hilog } from '@kit.PerformanceAnalysisKit'; import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit'; diff --git a/XiaoyiAgentDemo/entry/src/main/ets/models/MusicData.ets b/XiaoyiAgentDemo/entry/src/main/ets/models/MusicData.ets index 9992060760046fceacb2138903cc3107e3eadf2e..58a1e0ecc8d329583a88412f701bf80982a910fc 100644 --- a/XiaoyiAgentDemo/entry/src/main/ets/models/MusicData.ets +++ b/XiaoyiAgentDemo/entry/src/main/ets/models/MusicData.ets @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/XiaoyiAgentDemo/entry/src/main/ets/models/SongItem.ets b/XiaoyiAgentDemo/entry/src/main/ets/models/SongItem.ets index 97087e1df856d47c71d301942fef72288abf63e7..385be3bd9101d4bcbdea8ad4adace7904420cd42 100644 --- a/XiaoyiAgentDemo/entry/src/main/ets/models/SongItem.ets +++ b/XiaoyiAgentDemo/entry/src/main/ets/models/SongItem.ets @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/XiaoyiAgentDemo/entry/src/main/ets/pages/MainPage.ets b/XiaoyiAgentDemo/entry/src/main/ets/pages/MainPage.ets index 4fc2aa7d371a551cf0e77deb72aa3299c2e8b716..c50b9c1d7cadbf5fc9a70674bbbaea43ac5f233c 100644 --- a/XiaoyiAgentDemo/entry/src/main/ets/pages/MainPage.ets +++ b/XiaoyiAgentDemo/entry/src/main/ets/pages/MainPage.ets @@ -1,5 +1,19 @@ -// HelloWorldPage.ets -import router from '@ohos.router'; +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ +import { BusinessError } from '@kit.BasicServicesKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; @Entry @Component @@ -8,7 +22,13 @@ struct HelloWorldPage { // Jump to the second page private navigateToSecond() { - this.getUIContext().getRouter().pushUrl({ url: 'pages/SecondPage' }); + this.getUIContext().getRouter().pushUrl({ url: 'pages/SecondPage' }) + .then(() => { + hilog.info(0x000, 'testTag', `pushUrl success`); + }) + .catch((error: BusinessError) => { + hilog.error(0x000, 'testTag', `pushUrl failed. code=${error.code}, message=${error.message}`); + }) } build() { diff --git a/XiaoyiAgentDemo/entry/src/main/ets/pages/SecondPage.ets b/XiaoyiAgentDemo/entry/src/main/ets/pages/SecondPage.ets index 301c6a58781c67fe158512421dcafe5654a278e1..c532438b14616156b8b8d5f30a7d8d555ba9dc5e 100644 --- a/XiaoyiAgentDemo/entry/src/main/ets/pages/SecondPage.ets +++ b/XiaoyiAgentDemo/entry/src/main/ets/pages/SecondPage.ets @@ -1,8 +1,22 @@ -import { router } from '@kit.ArkUI'; +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + +import { insightIntent } from '@kit.AbilityKit'; +import { BusinessError } from '@kit.BasicServicesKit'; import AudioPlayHandler from '../entryability/intentHandlers/AudioPlayHandler'; import TextGetHandler from '../entryability/intentHandlers/TextGetHandler'; -import { insightIntent } from '@kit.AbilityKit'; -import { BusinessError } from '@ohos.base'; @Entry @Component diff --git a/XiaoyiAgentDemo/entry/src/main/ets/utils/Logger.ets b/XiaoyiAgentDemo/entry/src/main/ets/utils/Logger.ets index 87e9a7df7747e309efe26282ac5330df7ce67f2f..fd935c999d248189838c911314c106bf4b1aa36a 100644 --- a/XiaoyiAgentDemo/entry/src/main/ets/utils/Logger.ets +++ b/XiaoyiAgentDemo/entry/src/main/ets/utils/Logger.ets @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use Logger file except in compliance with the License. * You may obtain a copy of the License at diff --git a/XiaoyiAgentDemo/entry/src/main/ets/utils/audioplayer/BackgroundUtil.ets b/XiaoyiAgentDemo/entry/src/main/ets/utils/audioplayer/BackgroundUtil.ets index eb65b805238d331378ee6abe89526eba2382bfac..dee283da9b607e3d00239da3deddf7c1e9a71095 100644 --- a/XiaoyiAgentDemo/entry/src/main/ets/utils/audioplayer/BackgroundUtil.ets +++ b/XiaoyiAgentDemo/entry/src/main/ets/utils/audioplayer/BackgroundUtil.ets @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -41,19 +41,23 @@ export class BackgroundUtil { wantAgentFlags: [wantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG] }; - wantAgent.getWantAgent(wantAgentInfo).then((wantAgentObj: Object) => { - try { - backgroundTaskManager.startBackgroundRunning(context, - backgroundTaskManager.BackgroundMode.AUDIO_PLAYBACK, wantAgentObj).then(() => { - Logger.info('this avPlayer: ', 'startBackgroundRunning succeeded'); - }).catch((error: BusinessError) => { - Logger.error('this avPlayer: ', `startBackgroundRunning failed Cause: code ${error.code}`); - }); - } catch (error) { - Logger.error('this avPlayer: ', `startBackgroundRunning failed. code ${(error as BusinessError).code} + wantAgent.getWantAgent(wantAgentInfo) + .then((wantAgentObj: Object) => { + try { + backgroundTaskManager.startBackgroundRunning(context, + backgroundTaskManager.BackgroundMode.AUDIO_PLAYBACK, wantAgentObj).then(() => { + Logger.info('this avPlayer: ', 'startBackgroundRunning succeeded'); + }).catch((error: BusinessError) => { + Logger.error('this avPlayer: ', `startBackgroundRunning failed Cause: code ${error.code}`); + }); + } catch (error) { + Logger.error('this avPlayer: ', `startBackgroundRunning failed. code ${(error as BusinessError).code} message ${(error as BusinessError).message}`); - } - }); + } + }) + .catch((error: BusinessError) => { + Logger.error('this avPlayer: ', `getWantAgent failed. code=${error.code}, message=${error.message}`); + }) } /** @@ -72,5 +76,5 @@ export class BackgroundUtil { Logger.error('this avPlayer: ', `stopBackgroundRunning failed. code ${(error as BusinessError).code} message ${(error as BusinessError).message}`); } - } + }; } \ No newline at end of file diff --git a/XiaoyiAgentDemo/entry/src/main/ets/utils/audioplayer/MediaService.ets b/XiaoyiAgentDemo/entry/src/main/ets/utils/audioplayer/MediaService.ets index 8dc6c036f77a8d620a9eaaa69bbb71630d18138e..ebc5ca741baf92dcb9762e837c72c06ff9f78a6d 100644 --- a/XiaoyiAgentDemo/entry/src/main/ets/utils/audioplayer/MediaService.ets +++ b/XiaoyiAgentDemo/entry/src/main/ets/utils/audioplayer/MediaService.ets @@ -1,3 +1,17 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ import { media } from '@kit.MediaKit'; import { common, wantAgent } from '@kit.AbilityKit'; @@ -114,22 +128,18 @@ export class MediaService { break; } }; - private avSessionPlayCall = () => { Logger.info(TAG, `avSessionPlayCall on play , do play task`); this.play(); }; - private avSessionPauseCall = () => { Logger.info(TAG, `avSessionPauseCall on pause , do pause task`); this.pause(); }; - private avSessionPlayNextCall = () => { Logger.info(TAG, `avSessionPlayNextCall on playNext , do playNext task`); this.playNext(); }; - private avSessionPlayPreviousCall = () => { Logger.info(TAG, `avSessionPlayPreviousCall on playPrevious , do playPrevious task`); this.playPrevious(); @@ -161,7 +171,6 @@ export class MediaService { } } - public static getInstance(): MediaService { if (!MediaService.instance) { MediaService.instance = new MediaService(); @@ -194,11 +203,19 @@ export class MediaService { } } - private async createSession(): Promise { - this.session = await avSession.createAVSession(this.context, 'SESSION_NAME', 'audio'); - this.session.activate(); - Logger.info(TAG, `session create done : sessionId : ${this.session.sessionId}`); + try { + this.session = await avSession.createAVSession(this.context, 'SESSION_NAME', 'audio'); + this.session.activate() + .then(() => { + Logger.info(TAG, `activate succeed.`); + }) + .catch((error: BusinessError) => { + Logger.error(TAG, `activate failed. code=${error.code}, message=${error.message}`); + }) + Logger.info(TAG, `session create done : sessionId : ${this.session.sessionId}`); + } catch (err) { + } this.setAVMetadata(); let wantAgentInfo: wantAgent.WantAgentInfo = { wants: [ @@ -211,29 +228,42 @@ export class MediaService { requestCode: 0, wantAgentFlags: [wantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG] } - wantAgent.getWantAgent(wantAgentInfo).then((agent) => { - this.session?.setLaunchAbility(agent); - }) + wantAgent.getWantAgent(wantAgentInfo) + .then((agent) => { + this.session?.setLaunchAbility(agent) + .catch((error: BusinessError) => { + Logger.error(TAG, `setLaunchAbility failed. code=${error.code}, message=${error.message}`); + }) + }) + .catch((error: BusinessError) => { + Logger.error(TAG, `getWantAgent failed. code=${error.code}, message=${error.message}`); + }) this.setListenerForMesFromController(); } - private setListenerForMesFromController(): void { if (this.session) { - this.session.on('play', this.avSessionPlayCall); - this.session.on('pause', this.avSessionPauseCall); - this.session.on('playNext', this.avSessionPlayNextCall); - this.session.on('playPrevious', this.avSessionPlayPreviousCall); + try { + this.session.on('play', this.avSessionPlayCall); + this.session.on('pause', this.avSessionPauseCall); + this.session.on('playNext', this.avSessionPlayNextCall); + this.session.on('playPrevious', this.avSessionPlayPreviousCall); + } catch (error) { + Logger.error(TAG, `setListenerForMesFromController failed. code=${error.code}, message=${error.message}`); + } } } - private unregisterSessionListener(): void { if (this.session) { - this.session.off('play'); - this.session.off('pause'); - this.session.off('playNext'); - this.session.off('playPrevious'); + try { + this.session.off('play'); + this.session.off('pause'); + this.session.off('playNext'); + this.session.off('playPrevious'); + } catch (error) { + Logger.error(TAG, `unregisterSessionListener failed. code=${error.code}, message=${error.message}`); + } } } @@ -346,11 +376,17 @@ export class MediaService { public async release(): Promise { if (this.avPlayer && this.session && this.context) { - this.avPlayer.release(); + this.avPlayer.release() + .catch((error: BusinessError) => { + Logger.error(TAG, `release error, code=${error.code}, message=${error.message}`); + }) this.songItemBuilder.release(); BackgroundUtil.stopContinuousTask(this.context); this.unregisterSessionListener(); - this.session.destroy(); + this.session.destroy() + .catch((error: BusinessError) => { + Logger.error(TAG, `destroy error, code=${error.code}, message=${error.message}`); + }) } } diff --git a/XiaoyiAgentDemo/entry/src/main/ets/utils/audioplayer/MediaTools.ets b/XiaoyiAgentDemo/entry/src/main/ets/utils/audioplayer/MediaTools.ets index bcc4db9af928a5001d2f73f9a56f6cbe3c6389ae..3a9bc05c337f51e4b7d64ddb30341bfa75408e77 100644 --- a/XiaoyiAgentDemo/entry/src/main/ets/utils/audioplayer/MediaTools.ets +++ b/XiaoyiAgentDemo/entry/src/main/ets/utils/audioplayer/MediaTools.ets @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -16,13 +16,22 @@ import { image } from '@kit.ImageKit'; import { common } from '@kit.AbilityKit'; import { resourceManager } from '@kit.LocalizationKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { BusinessError } from '@kit.BasicServicesKit'; export class MediaTools { static async getPixelMapFromResource(context: common.UIAbilityContext, name: resourceManager.Resource): Promise { let resourceMgr = context.resourceManager; - let fileData: Uint8Array = await resourceMgr.getMediaContent(name); - return await image.createImageSource(fileData.buffer as ArrayBuffer).createPixelMap(); + let fileData: Uint8Array | null = null; + resourceMgr.getMediaContent(name.id) + .then((data: Uint8Array) => { + fileData = data; + }) + .catch((error: BusinessError) => { + hilog.error(0x000, 'testTag', `getMediaContent failed. code=${error.code}, message=${error.message}`); + }) + return await image.createImageSource(fileData!.buffer as ArrayBuffer).createPixelMap(); } static async getPixelMapFromFile(path: string): Promise { diff --git a/XiaoyiAgentDemo/entry/src/main/ets/utils/audioplayer/SongItemBuilder.ets b/XiaoyiAgentDemo/entry/src/main/ets/utils/audioplayer/SongItemBuilder.ets index 70e66198dca7144f797485660fb70d6abd1e204e..23b5d25dc69cf5152a6efbf4a37e773903949925 100644 --- a/XiaoyiAgentDemo/entry/src/main/ets/utils/audioplayer/SongItemBuilder.ets +++ b/XiaoyiAgentDemo/entry/src/main/ets/utils/audioplayer/SongItemBuilder.ets @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -18,6 +18,7 @@ import { resourceManager } from '@kit.LocalizationKit'; import { BusinessError } from '@kit.BasicServicesKit'; import { SongItem } from '../../models/SongItem'; import { Logger } from '../Logger'; +import { hilog } from '@kit.PerformanceAnalysisKit'; const TAG = 'SongItemBuilder'; @@ -55,7 +56,10 @@ export default class SongItemBuilder { public async release(): Promise { if (this.context && this.context !== null && this.songItem !== null) { - this.context.resourceManager.closeRawFd(this.songItem.src); + this.context.resourceManager.closeRawFd(this.songItem.src) + .catch((err: BusinessError) => { + hilog.error(0x0000, 'testTag',`closeRawFd failed, Code:${err.code}, message:${err.message}`); + }) } this.songItem = null; } diff --git a/XiaoyiAgentDemo/entry/src/main/module.json5 b/XiaoyiAgentDemo/entry/src/main/module.json5 index ae47ef2b7fb46a7484468ed8c9ff155e64fdb7a1..d3639934dd9b9f0d619f5f96e74f473d9bc03423 100644 --- a/XiaoyiAgentDemo/entry/src/main/module.json5 +++ b/XiaoyiAgentDemo/entry/src/main/module.json5 @@ -24,8 +24,12 @@ // [Start module] "skills": [ { - "entities": ["entity.system.browsable"], + "entities": [ + "entity.system.home", + "entity.system.browsable" + ], "actions": [ + "ohos.want.action.home", "ohos.want.action.viewData" ], "uris": [ diff --git a/XiaoyiAgentDemo/screenshots/devices/page1.png b/XiaoyiAgentDemo/screenshots/devices/page1.png new file mode 100644 index 0000000000000000000000000000000000000000..836b3d957b377c03f3a16b9b02ee4c37a1aab592 Binary files /dev/null and b/XiaoyiAgentDemo/screenshots/devices/page1.png differ diff --git a/XiaoyiAgentDemo/screenshots/devices/page2.png b/XiaoyiAgentDemo/screenshots/devices/page2.png new file mode 100644 index 0000000000000000000000000000000000000000..a9c310262a0faac4f468803fe5d5c3674b3d62b2 Binary files /dev/null and b/XiaoyiAgentDemo/screenshots/devices/page2.png differ diff --git a/animation/.clang-format b/animation/.clang-format deleted file mode 100644 index 48439ed68073b99be118d374d1ebd43d04d4c4eb..0000000000000000000000000000000000000000 --- a/animation/.clang-format +++ /dev/null @@ -1,64 +0,0 @@ -Language: Cpp -# BasedOnStyle: LLVM -ColumnLimit: 120 -SortIncludes: CaseSensitive -TabWidth: 4 -IndentWidth: 4 -UseTab: Never -AccessModifierOffset: -4 -ContinuationIndentWidth: 4 -IndentCaseBlocks: false -IndentCaseLabels: false -IndentGotoLabels: true -IndentWrappedFunctionNames: false -SortUsingDeclarations: false -NamespaceIndentation: None -SpaceAfterCStyleCast: false -SpaceAfterLogicalNot: false -SpaceAfterTemplateKeyword: true -SpaceBeforeAssignmentOperators: true -SpaceBeforeCaseColon: false -SpaceBeforeCpp11BracedList: false -SpaceBeforeCtorInitializerColon: true -SpaceBeforeInheritanceColon: true -SpaceBeforeRangeBasedForLoopColon: true -SpaceBeforeSquareBrackets: false -SpaceInEmptyBlock: false -SpaceInEmptyParentheses: false -SpacesInAngles: false -SpacesInCStyleCastParentheses: false -SpacesInConditionalStatement: false -SpacesInParentheses: false -SpacesInSquareBrackets: false -AlignTrailingComments: true -AlignAfterOpenBracket: true -AllowShortCaseLabelsOnASingleLine: false -AllowShortEnumsOnASingleLine: true -AllowShortFunctionsOnASingleLine: All -AllowShortIfStatementsOnASingleLine: Never -AllowShortLambdasOnASingleLine: All -AllowShortLoopsOnASingleLine: false -AlwaysBreakTemplateDeclarations: MultiLine -BinPackArguments: true -BinPackParameters: true -BreakBeforeTernaryOperators: true -BreakConstructorInitializers: BeforeColon -BreakInheritanceList: BeforeColon -BreakStringLiterals: true -InsertBraces: false -IndentExternBlock: NoIndent -BreakBeforeBraces: Custom -BraceWrapping: - AfterCaseLabel: false - AfterClass: false - AfterControlStatement: Never - AfterEnum: false - AfterFunction: false - AfterNamespace: false - AfterStruct: false - AfterUnion: false - AfterExternBlock: false - BeforeCatch: false - BeforeElse: false -ReflowComments: true -MaxEmptyLinesToKeep: 2 \ No newline at end of file diff --git a/animation/.hvigor/cache/meta.json b/animation/.hvigor/cache/meta.json deleted file mode 100644 index 18f86af95573be1ca58a8494f7aac0c780d0dfac..0000000000000000000000000000000000000000 --- a/animation/.hvigor/cache/meta.json +++ /dev/null @@ -1 +0,0 @@ -{"compileSdkVersion":"5.0.4(16)","hvigorVersion":"5.16.2","toolChainsVersion":"5.0.4.150"} diff --git a/animation/.hvigor/dependencyMap/dependencyMap.json5 b/animation/.hvigor/dependencyMap/dependencyMap.json5 deleted file mode 100644 index 23dfe3afbb302ceb2d7f911f573df42924a8086c..0000000000000000000000000000000000000000 --- a/animation/.hvigor/dependencyMap/dependencyMap.json5 +++ /dev/null @@ -1 +0,0 @@ -{"basePath":"C:\\Users\\fy\\Desktop\\noproject\\BestPracticeSnippets\\animation\\.hvigor\\dependencyMap\\dependencyMap.json5","rootDependency":"./oh-package.json5","dependencyMap":{"entry":"./entry/oh-package.json5"},"modules":[{"name":"entry","srcPath":"..\\..\\..\\entry"}]} \ No newline at end of file diff --git a/animation/.hvigor/dependencyMap/entry/oh-package.json5 b/animation/.hvigor/dependencyMap/entry/oh-package.json5 deleted file mode 100644 index 50a51753855fc6efdf037d5db6ab2cc001f17bbc..0000000000000000000000000000000000000000 --- a/animation/.hvigor/dependencyMap/entry/oh-package.json5 +++ /dev/null @@ -1 +0,0 @@ -{"name":"entry","version":"1.0.0","description":"Please describe the basic information.","main":"","author":"","license":"","dependencies":{}} \ No newline at end of file diff --git a/animation/.hvigor/dependencyMap/oh-package.json5 b/animation/.hvigor/dependencyMap/oh-package.json5 deleted file mode 100644 index 0936308543ae8d95029dfc66391bef10a402c7ef..0000000000000000000000000000000000000000 --- a/animation/.hvigor/dependencyMap/oh-package.json5 +++ /dev/null @@ -1 +0,0 @@ -{"modelVersion":"5.0.2","description":"Please describe the basic information.","dependencies":{},"devDependencies":{"@ohos/hypium":"1.0.21","@ohos/hamock":"1.0.1-rc2"}} \ No newline at end of file diff --git a/animation/.hvigor/outputs/build-logs/build.log b/animation/.hvigor/outputs/build-logs/build.log deleted file mode 100644 index dbdd58a23753c14f79d997a7b84c0ca93e754b83..0000000000000000000000000000000000000000 --- a/animation/.hvigor/outputs/build-logs/build.log +++ /dev/null @@ -1,153 +0,0 @@ -[2025-05-14T16:09:39.463] [DEBUG] debug-file - env: nodejsVersion=v18.20.1 -[2025-05-14T16:09:40.069] [DEBUG] debug-file - Hvigor init with startParameters:{ - hvigorfileTypeCheck: false, - parallelExecution: true, - incrementalExecution: true, - printStackTrace: false, - daemon: false, - analyze: 0, - logLevel: Level { level: 20000, levelStr: 'INFO', colour: 'green' } -} -[2025-05-14T16:09:40.103] [DEBUG] debug-file - hvigorfile, resolving C:\Users\fy\Desktop\noproject\BestPracticeSnippets\animation\hvigorfile.ts -[2025-05-14T16:09:42.422] [DEBUG] debug-file - Start initialize project's product build option map with build mode debug. -[2025-05-14T16:09:42.428] [DEBUG] debug-file - Product 'default' using build option: { - "debuggable": true, - "strictMode": { - "caseSensitiveCheck": true, - "useNormalizedOHMUrl": true - } -} in this build. -[2025-05-14T16:09:42.443] [DEBUG] debug-file - Local scan or download HarmonyOS sdk components toolchains,ets,js,native,previewer -[2025-05-14T16:09:42.183] [DEBUG] debug-file - hvigorfile, require result: { default: { system: [Function: appTasks], plugins: [] } } -[2025-05-14T16:09:42.448] [DEBUG] debug-file - Local scan or download hmscore sdk components toolchains,ets,native -[2025-05-14T16:09:42.459] [DEBUG] debug-file - Start recording SDK configuration permission data. -[2025-05-14T16:09:42.494] [DEBUG] debug-file - Sdk init in 55 ms -[2025-05-14T16:09:42.539] [DEBUG] debug-file - Project task initialization takes 41 ms -[2025-05-14T16:09:42.554] [DEBUG] debug-file - hvigorfile, resolving C:\Users\fy\Desktop\noproject\BestPracticeSnippets\animation\entry\hvigorfile.ts -[2025-05-14T16:09:42.588] [DEBUG] debug-file - Start initialize module-target build option map, moduleName=entry, buildMode=debug -[2025-05-14T16:09:42.605] [DEBUG] debug-file - project has submodules:entry -[2025-05-14T16:09:42.633] [DEBUG] debug-file - Configuration task cost before running: 2 s 595 ms -[2025-05-14T16:09:42.599] [DEBUG] debug-file - Module entry task initialization takes 6 ms -[2025-05-14T16:09:42.640] [DEBUG] debug-file - Executing task :entry:clean -[2025-05-14T16:09:42.646] [DEBUG] debug-file - entry : clean cost memory 0.25525665283203125 -[2025-05-14T16:09:42.676] [DEBUG] debug-file - Module 'entry' target 'default' using build option: { - "debuggable": true, - "copyFrom": "default", - "strictMode": { - "caseSensitiveCheck": true, - "useNormalizedOHMUrl": true - }, - "name": "debug" -} in this build. -[2025-05-14T16:09:39.465] [DEBUG] debug-file - env: hvigor-config.json5 content = { - modelVersion: '5.0.2', - dependencies: {}, - execution: {}, - logging: {}, - debugging: {}, - nodeOptions: {} -} -[2025-05-14T16:09:42.706] [DEBUG] debug-file - Create resident worker with id: 0. -[2025-05-14T16:09:40.072] [DEBUG] debug-file - Since current hvigor version 5.16.2 differs from last hvigor version - undefined, delete file-cache.json and task-cache.json. -[2025-05-14T16:09:42.422] [DEBUG] debug-file - Picking option from product 'default' with build mode 'debug'. -[2025-05-14T16:09:42.429] [DEBUG] debug-file - not found resModel json file in : C:\Users\fy\Desktop\noproject\BestPracticeSnippets\animation\entry\src\ohosTest\module.json5 -[2025-05-14T16:09:42.184] [DEBUG] debug-file - hvigorfile, binding system plugins [Function: appTasks] -[2025-05-14T16:09:42.539] [DEBUG] debug-file - hvigorfile, binding custom plugins [] -[2025-05-14T16:09:42.565] [DEBUG] debug-file - hvigorfile, require result: { default: { system: [Function: hapTasks], plugins: [] } } -[2025-05-14T16:09:42.588] [DEBUG] debug-file - Target 'default' config: {} -[2025-05-14T16:09:42.606] [DEBUG] debug-file - start to load updatedOhPackageInfo to the disk -[2025-05-14T16:09:42.600] [DEBUG] debug-file - hvigorfile, binding custom plugins [] -[2025-05-14T16:09:42.641] [DEBUG] debug-file - clean: Worker pool is inactive. -[2025-05-14T16:09:42.646] [DEBUG] debug-file - runTaskFromQueue task cost before running: 2 s 607 ms -[2025-05-14T16:09:42.683] [DEBUG] debug-file - Module 'entry' target 'ohosTest' using build option: { - "debuggable": true, - "strictMode": { - "caseSensitiveCheck": true, - "useNormalizedOHMUrl": true - }, - "name": "default" -} in this build. -[2025-05-14T16:09:39.467] [DEBUG] debug-file - env: daemon=false -[2025-05-14T16:09:42.708] [DEBUG] debug-file - Create resident worker with id: 1. -[2025-05-14T16:09:40.073] [DEBUG] debug-file - Cache service initialization finished in 3 ms -[2025-05-14T16:09:42.423] [DEBUG] debug-file - Product 'default' build option: {} -[2025-05-14T16:09:42.438] [DEBUG] debug-file - No signingConfig found, initRemoteHspCache failed. -[2025-05-14T16:09:42.539] [DEBUG] debug-file - hvigorfile, no custom plugins were found in C:\Users\fy\Desktop\noproject\BestPracticeSnippets\animation\hvigorfile.ts -[2025-05-14T16:09:42.565] [DEBUG] debug-file - hvigorfile, binding system plugins [Function: hapTasks] -[2025-05-14T16:09:42.589] [DEBUG] debug-file - Target 'ohosTest' config: {} -[2025-05-14T16:09:42.611] [DEBUG] debug-file - load to the disk finished -[2025-05-14T16:09:42.600] [DEBUG] debug-file - hvigorfile, no custom plugins were found in C:\Users\fy\Desktop\noproject\BestPracticeSnippets\animation\entry\hvigorfile.ts -[2025-05-14T16:09:42.647] [INFO] debug-file - Finished :entry:clean... after 6 ms -[2025-05-14T16:09:42.702] [DEBUG] debug-file - Since there is no instance or instance is terminated, create a new worker pool. -[2025-05-14T16:09:39.467] [DEBUG] debug-file - no-daemon, use the parent process.execArgv --max-old-space-size=8192,--expose-gc -[2025-05-14T16:09:42.712] [DEBUG] debug-file - Current worker pool is stopped or closed. -[2025-05-14T16:09:42.423] [DEBUG] debug-file - End initialize project's product build option map with build mode 'debug'. -[2025-05-14T16:09:42.539] [DEBUG] debug-file - hvigorfile, resolve finished C:\Users\fy\Desktop\noproject\BestPracticeSnippets\animation\hvigorfile.ts -[2025-05-14T16:09:42.590] [DEBUG] debug-file - Module 'entry' target 'default' build option: { - "debuggable": true, - "copyFrom": "default", - "strictMode": { - "caseSensitiveCheck": true, - "useNormalizedOHMUrl": true - }, - "name": "debug" -} -[2025-05-14T16:09:42.612] [DEBUG] debug-file - Start to initialize dependency information. -[2025-05-14T16:09:42.600] [DEBUG] debug-file - hvigorfile, resolve finished C:\Users\fy\Desktop\noproject\BestPracticeSnippets\animation\entry\hvigorfile.ts -[2025-05-14T16:09:42.647] [DEBUG] debug-file - Executing task ::clean -[2025-05-14T16:09:42.702] [DEBUG] debug-file - Worker pool is initialized with config: { - minPoolNum: 2, - maxPoolNum: undefined, - maxCoreSize: undefined, - cacheCapacity: undefined, - cacheTtl: undefined -} -[2025-05-14T16:09:42.712] [DEBUG] debug-file - Clear worker 0. -[2025-05-14T16:09:42.590] [DEBUG] debug-file - Module 'entry' target 'ohosTest' build option: { - "debuggable": true, - "strictMode": { - "caseSensitiveCheck": true, - "useNormalizedOHMUrl": true - }, - "name": "default" -} -[2025-05-14T16:09:42.617] [DEBUG] debug-file - Module animation Collected Dependency: -[2025-05-14T16:09:42.647] [DEBUG] debug-file - clean: Worker pool is inactive. -[2025-05-14T16:09:42.712] [DEBUG] debug-file - Worker 0 has been cleared. -[2025-05-14T16:09:42.590] [DEBUG] debug-file - End initialize module-target build option map, moduleName=entry -[2025-05-14T16:09:42.617] [DEBUG] debug-file - Module animation's total dependency: 0 -[2025-05-14T16:09:42.648] [DEBUG] debug-file - animation : clean cost memory 0.03330230712890625 -[2025-05-14T16:09:42.712] [DEBUG] debug-file - Current idle worker size: 1. -[2025-05-14T16:09:42.590] [DEBUG] debug-file - Module 'entry' target 'default' using build option: { - "debuggable": true, - "copyFrom": "default", - "strictMode": { - "caseSensitiveCheck": true, - "useNormalizedOHMUrl": true - }, - "name": "debug" -} in this build. -[2025-05-14T16:09:42.619] [DEBUG] debug-file - Start to initialize dependency information. -[2025-05-14T16:09:42.648] [DEBUG] debug-file - runTaskFromQueue task cost before running: 2 s 610 ms -[2025-05-14T16:09:42.712] [DEBUG] debug-file - Current busy worker size: 0. -[2025-05-14T16:09:42.623] [DEBUG] debug-file - Module entry Collected Dependency: -[2025-05-14T16:09:42.648] [INFO] debug-file - Finished ::clean... after 1 ms -[2025-05-14T16:09:42.712] [DEBUG] debug-file - Clear worker 1. -[2025-05-14T16:09:42.623] [DEBUG] debug-file - Module entry's total dependency: 0 -[2025-05-14T16:09:42.649] [DEBUG] debug-file - Executing task :entry:init -[2025-05-14T16:09:42.712] [DEBUG] debug-file - Worker 1 has been cleared. -[2025-05-14T16:09:42.712] [DEBUG] debug-file - Current idle worker size: 0. -[2025-05-14T16:09:42.629] [DEBUG] debug-file - Configuration phase cost:2 s 543 ms -[2025-05-14T16:09:42.649] [DEBUG] debug-file - entry : init cost memory 0.01021575927734375 -[2025-05-14T16:09:42.712] [DEBUG] debug-file - Current busy worker size: 0. -[2025-05-14T16:09:42.649] [DEBUG] debug-file - runTaskFromQueue task cost before running: 2 s 610 ms -[2025-05-14T16:09:42.714] [DEBUG] debug-file - hvigor build process will be closed. -[2025-05-14T16:09:42.649] [INFO] debug-file - Finished :entry:init... after 1 ms -[2025-05-14T16:09:42.720] [DEBUG] debug-file - worker[0] exits with exit code 0. -[2025-05-14T16:09:42.649] [DEBUG] debug-file - Executing task ::init -[2025-05-14T16:09:42.725] [DEBUG] debug-file - worker[1] exits with exit code 0. -[2025-05-14T16:09:42.649] [DEBUG] debug-file - animation : init cost memory 0.00897216796875 -[2025-05-14T16:09:42.726] [DEBUG] debug-file - Current worker pool is terminated. -[2025-05-14T16:09:42.649] [DEBUG] debug-file - runTaskFromQueue task cost before running: 2 s 611 ms -[2025-05-14T16:09:42.649] [INFO] debug-file - Finished ::init... after 1 ms diff --git a/animation/.hvigor/outputs/sync/fileCache.json b/animation/.hvigor/outputs/sync/fileCache.json deleted file mode 100644 index 4808c3eaab8f234afc7952953ceec2cd3368db9f..0000000000000000000000000000000000000000 --- a/animation/.hvigor/outputs/sync/fileCache.json +++ /dev/null @@ -1 +0,0 @@ -{"CACHE_SYNC_FILE_HASH":{"C:\\Users\\fy\\Desktop\\noproject\\BestPracticeSnippets\\animation\\hvigor\\hvigor-config.json5":"e009c3e201887d5ff58922c9bca69f856521fdaedafd57bc145de6902f716f4f","C:\\Users\\fy\\Desktop\\noproject\\BestPracticeSnippets\\animation\\build-profile.json5":"eee615171f4e7512acd9accee9ac4a97161415b98f13ad8b01844894df100408","C:\\Users\\fy\\Desktop\\noproject\\BestPracticeSnippets\\animation\\hvigorfile.ts":"a2eed1714e57c09354a399245457c72417fc985659f20acf3dac697d92dedbe0","C:\\Users\\fy\\Desktop\\noproject\\BestPracticeSnippets\\animation\\oh-package.json5":"5cc9339e8b272a4b1cd2a427341724e076c4fd291ed4af7d516f134b99620685","C:\\Users\\fy\\Desktop\\noproject\\BestPracticeSnippets\\animation\\entry\\build-profile.json5":"8e9d18f03982155d6089df3dbe9926a8664a1756d5b4b05949c7dd01ca065695","C:\\Users\\fy\\Desktop\\noproject\\BestPracticeSnippets\\animation\\entry\\hvigorfile.ts":"47a33472c33b4c8d38bdac2f3b18b3b7e8d34f60677bd5d5ecf14b49fecc1117","C:\\Users\\fy\\Desktop\\noproject\\BestPracticeSnippets\\animation\\entry\\oh-package.json5":"79f0a85349331763382c95ae7267af8e5aefff06a36554bd04d407be5b4c24ea","C:\\Users\\fy\\Desktop\\noproject\\BestPracticeSnippets\\animation\\.hvigor\\outputs\\sync\\output.json":"ecc8be5aa1e7442a0818961a397e5fd1b40c75a5ca79f7008483bc282bb130f6","SDK_LOCATION":"C:/Program Files/Huawei/DevEco Studio/sdk"}} \ No newline at end of file diff --git a/animation/.hvigor/outputs/sync/output.json b/animation/.hvigor/outputs/sync/output.json deleted file mode 100644 index 14b28cf961e7b324d82877aca4dc1dee43cc157a..0000000000000000000000000000000000000000 --- a/animation/.hvigor/outputs/sync/output.json +++ /dev/null @@ -1,174 +0,0 @@ -{ - "ohos-module-entry": { - "SELECT_TARGET": "default", - "MODULE_BUILD_DIR": "C:\\Users\\fy\\Desktop\\noproject\\BestPracticeSnippets\\animation\\entry\\build", - "DEPENDENCY_INFO": {}, - "TARGETS": { - "default": { - "SOURCE_ROOT": "C:\\Users\\fy\\Desktop\\noproject\\BestPracticeSnippets\\animation\\entry\\src\\main", - "RESOURCES_PATH": [ - "C:\\Users\\fy\\Desktop\\noproject\\BestPracticeSnippets\\animation\\entry\\src\\main\\resources" - ], - "BUILD_PATH": { - "OUTPUT_PATH": "C:\\Users\\fy\\Desktop\\noproject\\BestPracticeSnippets\\animation\\entry\\build\\default\\outputs\\default", - "INTERMEDIA_PATH": "C:\\Users\\fy\\Desktop\\noproject\\BestPracticeSnippets\\animation\\entry\\build\\default\\intermediates", - "JS_ASSETS_PATH": "C:\\Users\\fy\\Desktop\\noproject\\BestPracticeSnippets\\animation\\entry\\build\\default\\intermediates\\loader_out\\default", - "JS_LITE_ASSETS_PATH": "C:\\Users\\fy\\Desktop\\noproject\\BestPracticeSnippets\\animation\\entry\\build\\default\\intermediates\\loader_out_lite\\default", - "RES_PATH": "C:\\Users\\fy\\Desktop\\noproject\\BestPracticeSnippets\\animation\\entry\\build\\default\\intermediates\\res\\default", - "RES_PROFILE_PATH": "C:\\Users\\fy\\Desktop\\noproject\\BestPracticeSnippets\\animation\\entry\\build\\default\\intermediates\\res\\default\\resources\\base\\profile", - "ETS_SUPER_VISUAL_PATH": "C:\\Users\\fy\\Desktop\\noproject\\BestPracticeSnippets\\animation\\entry\\build\\default\\cache\\default\\default@CompileArkTS\\esmodule", - "JS_SUPER_VISUAL_PATH": "C:\\Users\\fy\\Desktop\\noproject\\BestPracticeSnippets\\animation\\entry\\build\\default\\cache\\default\\default@CompileJS\\jsbundle", - "WORKER_LOADER": "C:\\Users\\fy\\Desktop\\noproject\\BestPracticeSnippets\\animation\\entry\\build\\default\\intermediates\\loader\\default\\loader.json", - "MANIFEST_JSON": "C:\\Users\\fy\\Desktop\\noproject\\BestPracticeSnippets\\animation\\entry\\build\\default\\intermediates\\manifest\\default", - "OUTPUT_METADATA_JSON": "C:\\Users\\fy\\Desktop\\noproject\\BestPracticeSnippets\\animation\\entry\\build\\default\\intermediates\\hap_metadata\\default\\output_metadata.json", - "SOURCE_MAP_DIR": "C:\\Users\\fy\\Desktop\\noproject\\BestPracticeSnippets\\animation\\entry\\build\\default\\intermediates\\source_map\\default" - }, - "BUILD_OPTION": { - "debuggable": true - } - }, - "ohosTest": { - "SOURCE_ROOT": "C:\\Users\\fy\\Desktop\\noproject\\BestPracticeSnippets\\animation\\entry\\src\\ohosTest", - "RESOURCES_PATH": [ - "C:\\Users\\fy\\Desktop\\noproject\\BestPracticeSnippets\\animation\\entry\\src\\ohosTest\\resources" - ], - "BUILD_PATH": { - "OUTPUT_PATH": "C:\\Users\\fy\\Desktop\\noproject\\BestPracticeSnippets\\animation\\entry\\build\\default\\outputs\\ohosTest", - "INTERMEDIA_PATH": "C:\\Users\\fy\\Desktop\\noproject\\BestPracticeSnippets\\animation\\entry\\build\\default\\intermediates", - "JS_ASSETS_PATH": "C:\\Users\\fy\\Desktop\\noproject\\BestPracticeSnippets\\animation\\entry\\build\\default\\intermediates\\loader_out\\ohosTest", - "JS_LITE_ASSETS_PATH": "C:\\Users\\fy\\Desktop\\noproject\\BestPracticeSnippets\\animation\\entry\\build\\default\\intermediates\\loader_out_lite\\ohosTest", - "RES_PATH": "C:\\Users\\fy\\Desktop\\noproject\\BestPracticeSnippets\\animation\\entry\\build\\default\\intermediates\\res\\ohosTest", - "RES_PROFILE_PATH": "C:\\Users\\fy\\Desktop\\noproject\\BestPracticeSnippets\\animation\\entry\\build\\default\\intermediates\\res\\ohosTest\\resources\\base\\profile", - "ETS_SUPER_VISUAL_PATH": "C:\\Users\\fy\\Desktop\\noproject\\BestPracticeSnippets\\animation\\entry\\build\\default\\cache\\ohosTest\\ohosTest@OhosTestCompileArkTS\\esmodule", - "JS_SUPER_VISUAL_PATH": "C:\\Users\\fy\\Desktop\\noproject\\BestPracticeSnippets\\animation\\entry\\build\\default\\cache\\ohosTest\\ohosTest@OhosTestCompileJS\\jsbundle", - "WORKER_LOADER": "C:\\Users\\fy\\Desktop\\noproject\\BestPracticeSnippets\\animation\\entry\\build\\default\\intermediates\\loader\\ohosTest\\loader.json", - "MANIFEST_JSON": "C:\\Users\\fy\\Desktop\\noproject\\BestPracticeSnippets\\animation\\entry\\build\\default\\intermediates\\manifest\\ohosTest", - "OUTPUT_METADATA_JSON": "C:\\Users\\fy\\Desktop\\noproject\\BestPracticeSnippets\\animation\\entry\\build\\default\\intermediates\\hap_metadata\\ohosTest\\output_metadata.json", - "SOURCE_MAP_DIR": "C:\\Users\\fy\\Desktop\\noproject\\BestPracticeSnippets\\animation\\entry\\build\\default\\intermediates\\source_map\\ohosTest" - }, - "BUILD_OPTION": { - "debuggable": true - } - } - }, - "BUILD_OPTION": { - "default-default": { - "debuggable": true, - "copyFrom": "default", - "strictMode": { - "caseSensitiveCheck": true, - "useNormalizedOHMUrl": true - }, - "name": "debug" - } - }, - "BUILD_PROFILE_OPT": { - "apiType": "stageMode", - "buildOption": {}, - "buildOptionSet": [ - { - "name": "release", - "arkOptions": { - "obfuscation": { - "ruleOptions": { - "enable": false, - "files": [ - "./obfuscation-rules.txt" - ] - } - } - } - }, - { - "name": "default" - }, - { - "name": "debug" - } - ], - "targets": [ - { - "name": "default" - }, - { - "name": "ohosTest" - } - ] - }, - "BUILD_CACHE_DIR": "" - }, - "ohos-project": { - "SELECT_PRODUCT_NAME": "default", - "MODULE_BUILD_DIR": "C:\\Users\\fy\\Desktop\\noproject\\BestPracticeSnippets\\animation\\build", - "BUNDLE_NAME": "com.example.animation", - "BUILD_PATH": { - "OUTPUT_PATH": "C:\\Users\\fy\\Desktop\\noproject\\BestPracticeSnippets\\animation\\build\\outputs\\default" - }, - "MODULES": [ - { - "name": "entry", - "srcPath": "C:\\Users\\fy\\Desktop\\noproject\\BestPracticeSnippets\\animation\\entry", - "targets": [ - { - "name": "default", - "applyToProducts": [ - "default" - ] - } - ], - "belongProjectPath": "C:\\Users\\fy\\Desktop\\noproject\\BestPracticeSnippets\\animation" - } - ], - "PROFILE_OPT": { - "app": { - "signingConfigs": [], - "products": [ - { - "name": "default", - "signingConfig": "default", - "compatibleSdkVersion": "5.0.0(12)", - "runtimeOS": "HarmonyOS", - "buildOption": { - "strictMode": { - "caseSensitiveCheck": true, - "useNormalizedOHMUrl": true - } - } - } - ], - "buildModeSet": [ - { - "name": "debug" - }, - { - "name": "release" - } - ] - }, - "modules": [ - { - "name": "entry", - "srcPath": "./entry", - "targets": [ - { - "name": "default", - "applyToProducts": [ - "default" - ] - } - ] - } - ] - }, - "CONFIG_PROPERTIES": { - "enableSignTask": true, - "skipNativeIncremental": false, - "hvigor.keepDependency": true - }, - "OVERALL_PROJECT_PATHS": [ - "C:\\Users\\fy\\Desktop\\noproject\\BestPracticeSnippets\\animation" - ], - "BUILD_CACHE_DIR": "" - }, - "version": 1 -} \ No newline at end of file diff --git a/animation/.idea/.deveco/module/entry.cache.json b/animation/.idea/.deveco/module/entry.cache.json deleted file mode 100644 index 2dfd35ed2731f01771bce719a919d0cb0f94634e..0000000000000000000000000000000000000000 --- a/animation/.idea/.deveco/module/entry.cache.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "CommonInfo":{ - "current.select.target":"default" - }, - "BuildOptions":{ - "SELECT_BUILD_TARGET":"default", - "BUILD_PATH":{ - } - } -} \ No newline at end of file diff --git a/animation/.idea/.deveco/project.cache.json b/animation/.idea/.deveco/project.cache.json deleted file mode 100644 index 536b8ad7c18807793776248d8c77505095582bf9..0000000000000000000000000000000000000000 --- a/animation/.idea/.deveco/project.cache.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "CommonInfo":{ - "project.ide.version":"5.0.11.100", - "current.select.product":"default", - "current.select.buildMode":"", - "crossplatform.projectType":"" - }, - "BuildOptions":{ - "SELECT_BUILD_PRODUCT":"default", - "BUNDLE_NAME":"com.example.animation", - "BUILD_PATH":{ - "OUTPUT_PATH":"C:\\Users\\fy\\Desktop\\5.26new\\BestPracticeSnippets_1\\animation\\build\\outputs\\default" - }, - "SELECT_BUILD_MODE":"" - } -} \ No newline at end of file diff --git a/animation/.idea/.gitignore b/animation/.idea/.gitignore deleted file mode 100644 index 359bb5307e8535ab7d59faf27a7377033291821e..0000000000000000000000000000000000000000 --- a/animation/.idea/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -# 默认忽略的文件 -/shelf/ -/workspace.xml diff --git a/animation/.idea/modules.xml b/animation/.idea/modules.xml deleted file mode 100644 index 11f57feea8f8052d3ae946815edb53c0ec30f355..0000000000000000000000000000000000000000 --- a/animation/.idea/modules.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/animation/.idea/modules/animation.iml b/animation/.idea/modules/animation.iml deleted file mode 100644 index c0be1d7c491147540d199ce55f0721012b7ff7b5..0000000000000000000000000000000000000000 --- a/animation/.idea/modules/animation.iml +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/animation/.idea/modules/entry/entry.iml b/animation/.idea/modules/entry/entry.iml deleted file mode 100644 index b630fe7f2a024b997f55fc5a52dea6c90a18c45d..0000000000000000000000000000000000000000 --- a/animation/.idea/modules/entry/entry.iml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/animation/.idea/vcs.xml b/animation/.idea/vcs.xml deleted file mode 100644 index 6c0b8635858dc7ad44b93df54b762707ce49eefc..0000000000000000000000000000000000000000 --- a/animation/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/animation/LICENSE b/animation/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..18795a48d6b12fcdc1aa7bac9a9cb99f83815267 --- /dev/null +++ b/animation/LICENSE @@ -0,0 +1,78 @@ + Copyright (c) 2025 Huawei Device Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + 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. + +Apache License, Version 2.0 +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. + +"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. + +2. Grant of Copyright License. + +Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. + +Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. + +You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: +1.You must give any other recipients of the Work or Derivative Works a copy of this License; and +2.You must cause any modified files to carry prominent notices stating that You changed the files; and +3.You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and +4.If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. + +You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. + +5. Submission of Contributions. + +Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. + +6. Trademarks. + +This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. + +Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. + +In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. + +While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/animation/README.md b/animation/README.md new file mode 100644 index 0000000000000000000000000000000000000000..1298364a19b5ac51de4f41a5c5404d7fa0a0c53b --- /dev/null +++ b/animation/README.md @@ -0,0 +1,52 @@ +# 布局优化指导 +## 介绍 +本例介绍了5种优化手段,分别为使用系统提供的动画接口、使用图形变换属性变化组件布局、参数相同时使用同一个animateTo、多次animateTo时统一更新状态变量、使用renderGroup。通过这些优化手段的单个使用或组合使用,可以对动画帧率、应用卡顿等方面带来优化,提升性能和用户体验。 + +## 预览效果 + +| 使用系统提供的动画接口 | 使用图形变换属性变化组件 | 参数相同时使用同一个animateTo | +|:---------------------------------:|:---------------------------------:|:---------------------------------:| +| ![image](screenshots/1.gif) | ![image](screenshots/2.gif) | ![image](screenshots/3.gif) | + +## 工程目录 +``` +├──entry/src/main/ets // 代码区 +│ ├──entryability +│ │ └──EntryAbility.ets // 程序入口类 +│ ├──entrybackupability +│ │ └──EntryBackupAbility.ets +│ └──pages +│ ├──CustomAnimation.ets // 自定义动画 +│ ├──ExplicitAnimateTo.ets // 显式动画实现按键缩放 +│ ├──IconItem.ets // Icon组件 +│ ├──ImageAnimation.ets // 改变布局属性 +│ ├──MultipleProperties.ets // 参数相同时使用同一个animateTo +│ ├──PropertyAnimateTo.ets // 属性动画实现按键缩放 +│ ├──RenderGroup.ets // 使用RenderGroup +│ ├──UpdateMultipleProperties.ets // 在多个animateTo之间更新状态变量 +│ └──Index.ets // 首页 +└──entry/src/main/resources // 应用资源目录 +``` + +## 相关权限 +无 + +## 约束与限制 +* 本示例仅支持标准系统上运行,支持设备:华为手机。 + +* HarmonyOS系统:HarmonyOS 5.0.5 Release及以上。 + +* DevEco Studio版本:DevEco Studio 5.0.5 Release及以上。 + +* HarmonyOS SDK版本:HarmonyOS 5.0.5 Release SDK及以上。 + +## 下载 + +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set animation +git checkout +``` \ No newline at end of file diff --git a/animation/build-profile.json5 b/animation/build-profile.json5 index ed2b75e17797558b7d6146c8745dc6bb1b25d2ba..c3f29b49536b9065f3fa23abe793f2babc7f12fa 100644 --- a/animation/build-profile.json5 +++ b/animation/build-profile.json5 @@ -6,7 +6,8 @@ { "name": "default", "signingConfig": "default", - "compatibleSdkVersion": "5.0.0(12)", + "compatibleSdkVersion": "5.0.5(17)", + "targetSdkVersion": "5.0.5(17)", "runtimeOS": "HarmonyOS", "buildOption": { "strictMode": { diff --git a/animation/entry/src/main/ets/entryability/EntryAbility.ets b/animation/entry/src/main/ets/entryability/EntryAbility.ets index 508880af8c33aa838016d1cd4b2c68be2f447540..5dc88ee15a2c6364acea0d44c9d5779e57544355 100644 --- a/animation/entry/src/main/ets/entryability/EntryAbility.ets +++ b/animation/entry/src/main/ets/entryability/EntryAbility.ets @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; import { hilog } from '@kit.PerformanceAnalysisKit'; import { window } from '@kit.ArkUI'; @@ -6,7 +21,11 @@ const DOMAIN = 0x0000; export default class EntryAbility extends UIAbility { onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { - this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + try { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + } catch (err) { + hilog.info(DOMAIN, 'testTag', '%{public}s', 'setColorMode fail'); + } hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); } diff --git a/animation/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets b/animation/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets index 8e4de99282050bad799ac892eb85ac5449364a51..0a97e21bd7a15599af76a806695860ff1eb0ebfe 100644 --- a/animation/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets +++ b/animation/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + import { hilog } from '@kit.PerformanceAnalysisKit'; import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit'; diff --git a/animation/entry/src/main/ets/pages/CustomAnimation.ets b/animation/entry/src/main/ets/pages/CustomAnimation.ets index 9c90f2bc6d0189fdf46df0dae175bc8d88c385f8..27bd183970753a4924379810d8318f6773dc0aeb 100644 --- a/animation/entry/src/main/ets/pages/CustomAnimation.ets +++ b/animation/entry/src/main/ets/pages/CustomAnimation.ets @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + // [Start custom_animation] @Component export struct CustomAnimation { diff --git a/animation/entry/src/main/ets/pages/ExplicitAnimateTo.ets b/animation/entry/src/main/ets/pages/ExplicitAnimateTo.ets index b1da9dc15669cc2be9e702830778c1e6b6540efc..ff5010b7715e47fe7ce24dc3c8501433610b9a45 100644 --- a/animation/entry/src/main/ets/pages/ExplicitAnimateTo.ets +++ b/animation/entry/src/main/ets/pages/ExplicitAnimateTo.ets @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + // [Start explicit_animate_to] @Component export struct ExplicitAnimateTo { diff --git a/animation/entry/src/main/ets/pages/IconItem.ets b/animation/entry/src/main/ets/pages/IconItem.ets index 51fa9c31e7fce2f4703ca2a3aa65580155d66314..f5759a85f99774020c3ca2e9c173615b7b3dc603 100644 --- a/animation/entry/src/main/ets/pages/IconItem.ets +++ b/animation/entry/src/main/ets/pages/IconItem.ets @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + // [Start icon_item] @Component export struct IconItem { diff --git a/animation/entry/src/main/ets/pages/ImageAnimation.ets b/animation/entry/src/main/ets/pages/ImageAnimation.ets index 77e3f9f0e5fdcd655da7cf422540af59751671ae..8fa737eb5d94c3f7f09c8d05581e3baca225de30 100644 --- a/animation/entry/src/main/ets/pages/ImageAnimation.ets +++ b/animation/entry/src/main/ets/pages/ImageAnimation.ets @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + // [Start image_animation] // [Start component_animation] @Component @@ -149,10 +164,9 @@ export struct ImageAnimation { }) .translate({ x: this.imageTranslateX, y: this.imageTranslateY }) }.width('33%') - // [EndExclude image_animation] } .height('25%') - + // [EndExclude image_animation] // [EndExclude component_animation] Column() { // [StartExclude component_animation] diff --git a/animation/entry/src/main/ets/pages/Index.ets b/animation/entry/src/main/ets/pages/Index.ets index 8d5ce7893a15268c924b355d59368997fc62f9f3..aaeb86ccee88fe0e95ff0ed7974f6de27e90849d 100644 --- a/animation/entry/src/main/ets/pages/Index.ets +++ b/animation/entry/src/main/ets/pages/Index.ets @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + import { CustomAnimation } from './CustomAnimation'; import { PropertyAnimateTo } from './PropertyAnimateTo'; import { ExplicitAnimateTo } from './ExplicitAnimateTo'; diff --git a/animation/entry/src/main/ets/pages/MultipleProperties.ets b/animation/entry/src/main/ets/pages/MultipleProperties.ets index 45fdf035d418c9e436e77d3c5fc12d7ebcf98417..50539d7f00325316b6aa81fda06cc72f856f8c4d 100644 --- a/animation/entry/src/main/ets/pages/MultipleProperties.ets +++ b/animation/entry/src/main/ets/pages/MultipleProperties.ets @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + // [Start multiple_properties] // [Start one_func] @Component diff --git a/animation/entry/src/main/ets/pages/PropertyAnimateTo.ets b/animation/entry/src/main/ets/pages/PropertyAnimateTo.ets index cd3133e7951ed5ec40d9b286714ec40108591a03..23fd73fc578028def104ba4922e3e69b49fe85cf 100644 --- a/animation/entry/src/main/ets/pages/PropertyAnimateTo.ets +++ b/animation/entry/src/main/ets/pages/PropertyAnimateTo.ets @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + // [Start property_animate_to] @Component export struct PropertyAnimateTo { diff --git a/animation/entry/src/main/ets/pages/RenderGroup.ets b/animation/entry/src/main/ets/pages/RenderGroup.ets index 66a05277de1fb6ad67cacdc14565e3a6664811c6..6059dea1b2f7b85245bf91aaf809704f4f7a4186 100644 --- a/animation/entry/src/main/ets/pages/RenderGroup.ets +++ b/animation/entry/src/main/ets/pages/RenderGroup.ets @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + // [Start render_group] import { IconItem } from './IconItem' diff --git a/animation/entry/src/main/ets/pages/UpdateMultipleProperties.ets b/animation/entry/src/main/ets/pages/UpdateMultipleProperties.ets index 315b2f9ff7d70b177addfe76f773c77f8afc0bfa..4028c7ee6a894bafaa340149c4d54fe30edaaf58 100644 --- a/animation/entry/src/main/ets/pages/UpdateMultipleProperties.ets +++ b/animation/entry/src/main/ets/pages/UpdateMultipleProperties.ets @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + // [Start update_multiple_properties1] // [Start update_multiple_properties2] // [Start update_multiple_properties3] diff --git a/animation/screenshots/1.gif b/animation/screenshots/1.gif new file mode 100644 index 0000000000000000000000000000000000000000..99a1251e624251af3232c9abada796a9aa177c82 Binary files /dev/null and b/animation/screenshots/1.gif differ diff --git a/animation/screenshots/2.gif b/animation/screenshots/2.gif new file mode 100644 index 0000000000000000000000000000000000000000..15d8d41dccd3d55f2385d10ed31763ddf21191ca Binary files /dev/null and b/animation/screenshots/2.gif differ diff --git a/animation/screenshots/3.gif b/animation/screenshots/3.gif new file mode 100644 index 0000000000000000000000000000000000000000..6d53e95270296af1ccfda40fe8e365ccb6a7e194 Binary files /dev/null and b/animation/screenshots/3.gif differ diff --git a/avscreen-capture-screen-record-master/README.en.md b/avscreen-capture-screen-record-master/README.en.md index 9b5ef2b1c06496dc74a482af292a2d4618e26f74..849f6d04f746667865f285ba0d9aa6555c329a85 100644 --- a/avscreen-capture-screen-record-master/README.en.md +++ b/avscreen-capture-screen-record-master/README.en.md @@ -1,36 +1,86 @@ -# AVScreenCaptureScreenRecord +# Screen Recording Based on AVScreenCapture -#### Description -{**When you're done, you can delete the content in this README and update the file with details for others getting started with your repository**} +### Overview -#### Software Architecture -Software architecture description +This sample demonstrates how to implement screen recording using AVScreenCapture, including recording to a file using ArkTS, recording to a file using C/C++, and recording and transcoding stream using C/C++. Based on this case, you can master the screen recording capabilities of AVScreenCapture. -#### Installation +### Preview -1. xxxx -2. xxxx -3. xxxx + -#### Instructions +### How to Use -1. xxxx -2. xxxx -3. xxxx +On the home page, the user taps the corresponding button to navigate to the page for a specific scenario. Each scenario page contains a video playback area and two buttons. Tapping **Record** will trigger a request for necessary permissions. After the user grants permissions, screen recording starts. During this period, recording can continue even if it exits to the background. The user taps **Stop**, or **Stop** in the screen capsule at the top left, to stop video recording. After recording is complete, the page refreshes to display the recorded file. With a tap on **Play**, it starts to play in the playback area. -#### Contribution +### Project Structure** -1. Fork the repository -2. Create Feat_xxx branch -3. Commit your code -4. Create Pull Request +``` +├──entry/src/main/cpp // C++ code area. +│ ├──CAVScreenCaptureToFile // Recording the video to the file module using C/C++. +│ │ ├──CAVScreenCaptureToFile.cpp +│ │ └──CAVScreenCaptureToFile.h +│ ├──CAVScreenCaptureToStream // Recording and transcoding stream module using C/C++. +│ │ ├──AudioCapturer.cpp // Audio recording file. +│ │ ├──AudioCapturer.h +│ │ ├──AudioEncoder.cpp // Audio encoder file. +│ │ ├──AudioEncoder.h +│ │ ├──CAVScreenCaptureToStream.cpp // Recording and transcoding stream. +│ │ ├──CAVScreenCaptureToStream.h +│ │ ├──Muxer.cpp // Multiplexer file. +│ │ ├──Muxer.h +│ │ ├──SampleInfo.h // Custom data type. +│ │ ├──VideoEncoder.cpp // Video encoder file. +│ │ └──VideoEncoder.h +│ ├──types +│ │ └──libentry // C++ APIs. +│ │ ├──Index.d.ts +│ │ └──oh-package.json5 +│ ├──CMakeLists.txt // CMake configuration file. +│ └──napi_init.cpp // Native-side code entry. +├──entry/src/main/ets // ArkTS code area. +│ ├──entryability +│ │ └──EntryAbility.ets +│ ├──entrybackupability +│ │ └──EntryBackupAbility.ets +│ ├──common +│ │ ├──constants // Constant definitions. +│ │ │ └──CommonConstants.ets +│ │ └──utils // Video time conversion utilities. +│ │ └──TimeUtils.ets +│ ├──model +│ │ └──MyAVScreenCapture.ets // Module for screen recording to files using ArkTS. +│ └──pages // ArkTS side pages. +│ ├──ArkTSAVScreenCapture.ets // Page for screen recording to files using ArkTS. +│ ├──CAVScreenCaptureToFile.ets // Page for screen recording to files using C/C++. +│ ├──CAVScreenCaptureToStream.ets // Page for recording and transcoding streams using C/C++. +│ └──Index.ets // Home page. +└──entry/src/main/resources // Application resource files. +``` +### Required Permissions -#### Gitee Feature +1. **ohos.permission.KEEP_BACKGROUND_RUNNING**: required for background continuous task permission. -1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md -2. Gitee blog [blog.gitee.com](https://blog.gitee.com) -3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore) -4. The most valuable open source project [GVP](https://gitee.com/gvp) -5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help) -6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) +2. **ohos.permission.MICROPHONE**: required for microphone permission. + +### References + +N/A + +### Restrictions + +1. This sample is only supported on Huawei phones running standard systems. +2. The HarmonyOS version must be HarmonyOS 5.1.0 Release or later. +3. The DevEco Studio version must be DevEco Studio 5.1.0 Release or later. +4. The HarmonyOS SDK version must be HarmonyOS 5.1.0 Release SDK or later. + +### Download + +To download this project separately, execute the following command: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set avscreen-capture-screen-record-master +git checkout +``` \ No newline at end of file diff --git a/avscreen-capture-screen-record-master/README.md b/avscreen-capture-screen-record-master/README.md index de281872d2b58a2ab4124deb42b609946305dc61..87cbfbcfe6c7c1500c338950d56720d62ffb4d11 100644 --- a/avscreen-capture-screen-record-master/README.md +++ b/avscreen-capture-screen-record-master/README.md @@ -71,4 +71,15 @@ 1. 本示例仅支持标准系统上运行,支持设备:华为手机。 2. HarmonyOS系统:HarmonyOS 5.1.0 Release及以上。 3. DevEco Studio版本:DevEco Studio 5.1.0 Release及以上。 -4. HarmonyOS SDK版本:HarmonyOS 5.1.0 Release SDK及以上。 \ No newline at end of file +4. HarmonyOS SDK版本:HarmonyOS 5.1.0 Release SDK及以上。 + +### 下载 + +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set avscreen-capture-screen-record-master +git checkout +``` \ No newline at end of file diff --git a/avscreen-capture-screen-record-master/entry/oh-package-lock.json5 b/avscreen-capture-screen-record-master/entry/oh-package-lock.json5 index 7c36300c3272430b97f5cda7cb1a835421298382..05149e9a0799aca540bf4cd16ae71233319d991b 100644 --- a/avscreen-capture-screen-record-master/entry/oh-package-lock.json5 +++ b/avscreen-capture-screen-record-master/entry/oh-package-lock.json5 @@ -12,7 +12,7 @@ "libentry.so@src/main/cpp/types/libentry": { "name": "libentry.so", "version": "1.0.0", - "resolved": "src/main/cpp/types/libentry", + "resolved": "", "registryType": "local" } } diff --git a/avscreen-capture-screen-record-master/entry/src/main/ets/entryability/EntryAbility.ets b/avscreen-capture-screen-record-master/entry/src/main/ets/entryability/EntryAbility.ets index 408df0cf25684feb1c1e10f58495a51bc12d0fb3..464cc12c729f50ae9713e8787a78081d42f0d7dd 100644 --- a/avscreen-capture-screen-record-master/entry/src/main/ets/entryability/EntryAbility.ets +++ b/avscreen-capture-screen-record-master/entry/src/main/ets/entryability/EntryAbility.ets @@ -54,6 +54,8 @@ export default class EntryAbility extends UIAbility { }).catch((err: BusinessError) => { hilog.error(DOMAIN, 'testTag', 'Failed to operation startBackgroundRunning. %{public}s', JSON.stringify(err)); }); + }).catch((err: BusinessError) => { + hilog.error(DOMAIN, 'testTag', 'Failed to operation getWantAgent. %{public}s', JSON.stringify(err)); }); } @@ -66,8 +68,13 @@ export default class EntryAbility extends UIAbility { } onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { - this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); - hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); + try { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); + } catch (error) { + let err = error as BusinessError; + hilog.error(0x0000, 'testTag', `setColorMode fail. code = ${err.code}, message = ${err.message}`); + } } onDestroy(): void { @@ -99,10 +106,16 @@ export default class EntryAbility extends UIAbility { } hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.'); }); - // [Start get_size] - let displayInfo = display.getDefaultDisplaySync(); - // [End get_size] - AppStorage.setOrCreate('displayInfo', displayInfo); + + try { + // [Start get_size] + let displayInfo = display.getDefaultDisplaySync(); + // [End get_size] + AppStorage.setOrCreate('displayInfo', displayInfo); + } catch (error) { + let err = error as BusinessError; + hilog.error(0x0000, 'testTag', `getDefaultDisplaySync fail. code = ${err.code}, message = ${err.message}`); + } } onWindowStageDestroy(): void { diff --git a/avscreen-capture-screen-record-master/entry/src/main/ets/model/MyAVScreenCapture.ets b/avscreen-capture-screen-record-master/entry/src/main/ets/model/MyAVScreenCapture.ets index d01bcceec9a4e174911849e4b1f1316bc3580d2a..6625e57e613e010fd382627d117ed7525d2e60eb 100644 --- a/avscreen-capture-screen-record-master/entry/src/main/ets/model/MyAVScreenCapture.ets +++ b/avscreen-capture-screen-record-master/entry/src/main/ets/model/MyAVScreenCapture.ets @@ -14,7 +14,7 @@ */ import { media } from '@kit.MediaKit'; import { fileIo as fs } from '@kit.CoreFileKit'; -import { systemDateTime } from '@kit.BasicServicesKit'; +import { systemDateTime, BusinessError } from '@kit.BasicServicesKit'; import { display } from '@kit.ArkUI'; import { hilog } from '@kit.PerformanceAnalysisKit'; import { CommonConstants } from '../common/constants/CommonConstants'; @@ -28,14 +28,19 @@ export class MyAVScreenCapture { private file: fs.File | null = null; private displayInfo: display.Display = AppStorage.get('displayInfo') as display.Display; - // 开始屏幕录制 public async startRecording(filesDir: string) { // [Start create_record] // 获取fd this.updateFileFd(filesDir); // 实例化对象 - this.screenCapture = await media.createAVScreenCaptureRecorder(); + try { + this.screenCapture = await media.createAVScreenCaptureRecorder(); + } catch (error) { + let err = error as BusinessError; + hilog.error(0x0000, 'testTag', + `createAVScreenCaptureRecorder fail. code = ${err.code}, message = ${err.message}`); + } if (this.screenCapture != undefined) { hilog.info(0xFF00, CommonConstants.LOG_TAG, 'ScreenCapture has been created successfully.'); } else { @@ -113,15 +118,20 @@ export class MyAVScreenCapture { displayId: 0, }; // [End set_config] - - // [Start init_config] - await this.screenCapture?.init(captureConfig); - // [End init_config] - - // [Start start_record] - await this.screenCapture?.startRecording(); - // [End start_record] + try { + // [Start init_config] + await this.screenCapture?.init(captureConfig); + // [End init_config] + + // [Start start_record] + await this.screenCapture?.startRecording(); + // [End start_record] + } catch (error) { + let err = error as BusinessError; + hilog.error(0x0000, 'testTag', `start fail. code = ${err.code}, message = ${err.message}`); + } } + // [Start stop_record] // 停止录屏 public async stopRecording() { @@ -129,14 +139,21 @@ export class MyAVScreenCapture { hilog.info(0xFF00, CommonConstants.LOG_TAG, 'ScreenCapture exception.'); return; } - await this.screenCapture?.stopRecording(); - // 调用release()方法来销毁实例并释放资源 - await this.screenCapture?.release(); + try { + await this.screenCapture?.stopRecording(); - // 关闭文件 - fs.close((this.file as fs.File).fd); + // 调用release()方法来销毁实例并释放资源 + await this.screenCapture?.release(); + + // 关闭文件 + fs.close((this.file as fs.File).fd); + } catch (error) { + let err = error as BusinessError; + hilog.error(0x0000, 'testTag', `stop fail. code = ${err.code}, message = ${err.message}`); + } } + // [End stop_record] // [Start get_file_fd] @@ -144,8 +161,14 @@ export class MyAVScreenCapture { // 获取文件fd this.fileName = systemDateTime.getTime(true).toString() + '.mp4'; this.path = filesDir + '/' + this.fileName; - this.file = fs.openSync(this.path, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); + try { + this.file = fs.openSync(this.path, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); + } catch (error) { + let err = error as BusinessError; + hilog.error(0x0000, 'testTag', `openSync fail. code = ${err.code}, message = ${err.message}`); + } } + // [End get_file_fd] public getPath(): string { diff --git a/avscreen-capture-screen-record-master/entry/src/main/ets/pages/CAVScreenCaptureToFile.ets b/avscreen-capture-screen-record-master/entry/src/main/ets/pages/CAVScreenCaptureToFile.ets index 47dfc247c18f840146801f7a45cab218cf6f399c..9014ba7ba82fca0fde2831e5a8432069f8c09fab 100644 --- a/avscreen-capture-screen-record-master/entry/src/main/ets/pages/CAVScreenCaptureToFile.ets +++ b/avscreen-capture-screen-record-master/entry/src/main/ets/pages/CAVScreenCaptureToFile.ets @@ -51,29 +51,41 @@ export struct CAVScreenCaptureToFile { this.filepath = this.getUIContext().getHostContext()?.filesDir + '/' + this.tmpFileNameTwo; hilog.info(0xFF00, CommonConstants.LOG_TAG, 'filepath uri: %{public}s', this.filepath); - // 获取文件信息 - this.file = fs.openSync(this.filepath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); - // [StartExclude create_file_fd1] - avScreenCapture.setStopCallbackToFile(this.StopCallback); - // [EndExclude create_file_fd1] + try { + // 获取文件信息 + this.file = fs.openSync(this.filepath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); + // [StartExclude create_file_fd1] + avScreenCapture.setStopCallbackToFile(this.StopCallback); + // [EndExclude create_file_fd1] - // 调用native方法开启录制并传递fd、宽高 - avScreenCapture.startScreenCaptureToFile(this.file.fd, this.displayInfo.width, this.displayInfo.height); + // 调用native方法开启录制并传递fd、宽高 + avScreenCapture.startScreenCaptureToFile(this.file.fd, this.displayInfo.width, this.displayInfo.height); - // [StartExclude create_file_fd1] - this.videoSrc = 'file://' + this.filepath; - AppStorage.setOrCreate('videoSrcTwo', this.videoSrc); - // [EndExclude create_file_fd1] + // [StartExclude create_file_fd1] + this.videoSrc = 'file://' + this.filepath; + AppStorage.setOrCreate('videoSrcTwo', this.videoSrc); + // [EndExclude create_file_fd1] + } catch (error) { + let err = error as BusinessError; + hilog.error(0x0000, 'testTag', `startScreenCaptureToFile fail. code = ${err.code}, message = ${err.message}`); + } } + // [End create_file_fd1] // [Start release_fd1] async releaseFD() { if (this.file?.fd != undefined && this.file.fd?.valueOf() > 0) { // 关闭文件 - fs.close(this.file.fd); + try { + fs.close(this.file.fd); + } catch (error) { + let err = error as BusinessError; + hilog.error(0x0000, 'testTag', `close fail. code = ${err.code}, message = ${err.message}`); + } } } + // [End release_fd1] diff --git a/avscreen-capture-screen-record-master/entry/src/main/ets/pages/CAVScreenCaptureToStream.ets b/avscreen-capture-screen-record-master/entry/src/main/ets/pages/CAVScreenCaptureToStream.ets index c707ac072a08cb4ada1d2d05c971f294e82e5fa0..9cecce608823286cce0cae1cc1b5491ce4d77da1 100644 --- a/avscreen-capture-screen-record-master/entry/src/main/ets/pages/CAVScreenCaptureToStream.ets +++ b/avscreen-capture-screen-record-master/entry/src/main/ets/pages/CAVScreenCaptureToStream.ets @@ -50,31 +50,42 @@ export struct CAVScreenCaptureToStream { // [EndExclude create_file_fd2] this.filepath = this.getUIContext().getHostContext()?.filesDir + '/' + this.tmpFileNameThree; hilog.info(0xFF00, CommonConstants.LOG_TAG, 'filepath uri: %{public}s', this.filepath); + try { + // 获取文件信息 + this.file = fs.openSync(this.filepath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); - // 获取文件信息 - this.file = fs.openSync(this.filepath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); + // [StartExclude create_file_fd2] + avScreenCapture.setStopCallbackToStream(this.StopCallback); + // [EndExclude create_file_fd2] - // [StartExclude create_file_fd2] - avScreenCapture.setStopCallbackToStream(this.StopCallback); - // [EndExclude create_file_fd2] - - // 调用native方法开启录制并传递fd、宽高 - avScreenCapture.startScreenCaptureToStream(this.file.fd, this.displayInfo.width, this.displayInfo.height) + // 调用native方法开启录制并传递fd、宽高 + avScreenCapture.startScreenCaptureToStream(this.file.fd, this.displayInfo.width, this.displayInfo.height) - // [StartExclude create_file_fd2] - this.videoSrc = 'file://' + this.filepath; - AppStorage.setOrCreate('videoSrcThree', this.videoSrc); - // [EndExclude create_file_fd2] + // [StartExclude create_file_fd2] + this.videoSrc = 'file://' + this.filepath; + AppStorage.setOrCreate('videoSrcThree', this.videoSrc); + // [EndExclude create_file_fd2] + } catch (error) { + let err = error as BusinessError; + hilog.error(0x0000, 'testTag', `startScreenCaptureToStream fail. code = ${err.code}, message = ${err.message}`); + } } + // [End create_file_fd2] // [Start release_fd2] async releaseFD() { if (this.file?.fd != undefined && this.file.fd?.valueOf() > 0) { // 关闭文件 - fs.close(this.file.fd); + try { + fs.close(this.file.fd); + } catch (error) { + let err = error as BusinessError; + hilog.error(0x0000, 'testTag', `close fail. code = ${err.code}, message = ${err.message}`); + } } } + // [End release_fd2] build() { diff --git a/avscreen-capture-screen-record-master/screenshots/device/PreviewImage_EN.png b/avscreen-capture-screen-record-master/screenshots/device/PreviewImage_EN.png index 826c4e01d43f0aece5e00b52d92c8c0133865072..3557d96be7da5c39d338d51477f15e7db5ea334b 100644 Binary files a/avscreen-capture-screen-record-master/screenshots/device/PreviewImage_EN.png and b/avscreen-capture-screen-record-master/screenshots/device/PreviewImage_EN.png differ diff --git a/avscreen-capture-screen-record-master/screenshots/device/PreviewImage_ZH.png b/avscreen-capture-screen-record-master/screenshots/device/PreviewImage_ZH.png index 5bb4150a2091c6dede9102b8e97e75393a3e626a..7f2c08aa88a7b35130053f4087a0edf13bd6af42 100644 Binary files a/avscreen-capture-screen-record-master/screenshots/device/PreviewImage_ZH.png and b/avscreen-capture-screen-record-master/screenshots/device/PreviewImage_ZH.png differ diff --git a/bptaMultiWindow/.gitignore b/bptaMultiWindow/.gitignore deleted file mode 100644 index d2ff20141ceed86d87c0ea5d99481973005bab2b..0000000000000000000000000000000000000000 --- a/bptaMultiWindow/.gitignore +++ /dev/null @@ -1,12 +0,0 @@ -/node_modules -/oh_modules -/local.properties -/.idea -**/build -/.hvigor -.cxx -/.clangd -/.clang-format -/.clang-tidy -**/.test -/.appanalyzer \ No newline at end of file diff --git a/MultMusicHome/LICENSE b/bptaMultiWindow/LICENSE similarity index 100% rename from MultMusicHome/LICENSE rename to bptaMultiWindow/LICENSE diff --git a/bptaMultiWindow/README.en.md b/bptaMultiWindow/README.en.md deleted file mode 100644 index 9f58522a1c6372359a64d4981820dd914e4a78fc..0000000000000000000000000000000000000000 --- a/bptaMultiWindow/README.en.md +++ /dev/null @@ -1,4 +0,0 @@ - -### Introduction - -Sample code accompanying the best practice article "A Multi-Window Adaptation Development Practice" diff --git a/bptaMultiWindow/README.md b/bptaMultiWindow/README.md index 5098cbad8e0cc318f494713793547714d09077a3..f987ab0e543cdf9fda6e7335d5be6f003c5b4c37 100644 --- a/bptaMultiWindow/README.md +++ b/bptaMultiWindow/README.md @@ -1,4 +1,56 @@ +# 一多窗口适配开发实践 ### 简介 +与最佳实践文章《一多窗口适配开发实践》配套的示例代码。 -与最佳实践文章《一多窗口适配开发实践》配套的示例代码 +### 预览效果 +不涉及 + +### 使用说明 +工程本身不具备实际功能,开发者请直接阅读文档结合源码来理解多设备功能开发。 + +### 工程目录 + +``` +├──entry/src/main/ets +| ├──components +| │ └──WindowUtil.ets // 窗口工具类 +| ├──entryability +| │ ├──EntryAbility.ets // 程序入口类 +| │ ├──EntryAbility1.ets // 程序入口类同源代码块 +| │ ├──EntryAbility2.ets // 程序入口类同源代码块 +| │ └──EntryAbility3.ets // 程序入口类同源代码块 +| ├──entrybackupability +| │ └──EntryBackupAbility.ets // 数据备份恢复类 +| └──pages +| ├──FreeMultiWindowMode.ets // 自由多窗口模式 +| ├──FreeMultiWindowObserver.ets // 自由多窗口Observer +| └──Index.ets // 首页 +└──entry/src/main/resources // 应用资源目录 +``` + +### 具体实现 +不涉及 + +### 相关权限 +无 + +### 约束与限制 +* 本示例仅支持标准系统上运行,支持设备:华为手机。 + +* HarmonyOS系统:HarmonyOS 5.0.5 Release及以上。 + +* DevEco Studio版本:DevEco Studio 5.0.5 Release及以上。 + +* HarmonyOS SDK版本:HarmonyOS 5.0.5 Release SDK及以上。 + +### Download + +To download this project separately, execute the following command: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set bptaMultiWindow +git checkout +``` diff --git a/bptaMultiWindow/build-profile.json5 b/bptaMultiWindow/build-profile.json5 index 03ac3a3ae9dd397844173066e5d5ee21b49455a1..492123c253881f5bbd9bc76553bfb74e842dfb40 100644 --- a/bptaMultiWindow/build-profile.json5 +++ b/bptaMultiWindow/build-profile.json5 @@ -5,7 +5,8 @@ { "name": "default", "signingConfig": "default", - "compatibleSdkVersion": "5.0.4(16)", + "compatibleSdkVersion": "5.0.5(17)", + "targetSdkVersion": "5.0.5(17)", "runtimeOS": "HarmonyOS", "buildOption": { "strictMode": { diff --git a/bptaMultiWindow/entry/.gitignore b/bptaMultiWindow/entry/.gitignore deleted file mode 100644 index e2713a2779c5a3e0eb879efe6115455592caeea5..0000000000000000000000000000000000000000 --- a/bptaMultiWindow/entry/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -/node_modules -/oh_modules -/.preview -/build -/.cxx -/.test \ No newline at end of file diff --git a/bptaMultiWindow/entry/build-profile.json5 b/bptaMultiWindow/entry/build-profile.json5 index 4d611879c7913fb0610c686e2399258ab3a6dad1..0311b505dbf43f0d22662c8d783c5f4464d15b15 100644 --- a/bptaMultiWindow/entry/build-profile.json5 +++ b/bptaMultiWindow/entry/build-profile.json5 @@ -20,9 +20,6 @@ "targets": [ { "name": "default" - }, - { - "name": "ohosTest", } ] } \ No newline at end of file diff --git a/bptaMultiWindow/entry/src/main/ets/components/WindowUtil.ets b/bptaMultiWindow/entry/src/main/ets/components/WindowUtil.ets index f5b8a250176b404894868fd0e782a45c097748a4..d368655860d0aae449831d6463189e2105a711d5 100644 --- a/bptaMultiWindow/entry/src/main/ets/components/WindowUtil.ets +++ b/bptaMultiWindow/entry/src/main/ets/components/WindowUtil.ets @@ -20,37 +20,47 @@ // [Start maximize] // [Start recover] import { BusinessError } from '@kit.BasicServicesKit'; -import { window } from '@kit.ArkUI'; import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; @Observed export class WindowUtil { private mainWindowClass?: window.Window; + // [StartExclude recover] maximize(): void { - if (this.mainWindowClass!.getWindowStatus() === window.WindowStatusType.FLOATING) { - this.mainWindowClass!.maximize() - .then(() => { - hilog.info(0x0000, 'testTag', '%{public}s', `Succeed in maximizing the window.`); - }) - .catch((err: BusinessError) => { - hilog.error(0x0000, 'testTag', `Failed to maximize the window. Code: ${err.code}, message: ${err.message}`, - JSON.stringify(err) ?? ''); - }); + try { + if (this.mainWindowClass!.getWindowStatus() === window.WindowStatusType.FLOATING) { + this.mainWindowClass!.maximize() + .then(() => { + hilog.info(0x0000, 'testTag', '%{public}s', `Succeed in maximizing the window.`); + }) + .catch((err: BusinessError) => { + hilog.error(0x0000, 'testTag', `Failed to maximize the window. Code: ${err.code}, message: ${err.message}`, + JSON.stringify(err) ?? ''); + }); + } + } catch (error) { + hilog.warn(0x000, 'testTag', `getWindowStatus failed, code: ${error.code}, message: ${error.message}`); } } + // [EndExclude recover] // [StartExclude maximize] recover(): void { - if (this.mainWindowClass!.getWindowStatus() === window.WindowStatusType.FULL_SCREEN) { - this.mainWindowClass!.recover() - .then(() => { - hilog.info(0x0000, 'testTag', '%{public}s', `Succeed in recovering the window.`); - }) - .catch((err: BusinessError) => { - hilog.error(0x0000, 'testTag', `Failed to recover the window. Code: ${err.code}, message: ${err.message}`, - JSON.stringify(err) ?? ''); - }); + try { + if (this.mainWindowClass!.getWindowStatus() === window.WindowStatusType.FULL_SCREEN) { + this.mainWindowClass!.recover() + .then(() => { + hilog.info(0x0000, 'testTag', '%{public}s', `Succeed in recovering the window.`); + }) + .catch((err: BusinessError) => { + hilog.error(0x0000, 'testTag', `Failed to recover the window. Code: ${err.code}, message: ${err.message}`, + JSON.stringify(err) ?? ''); + }); + } + } catch (error) { + hilog.warn(0x000, 'testTag', `getWindowStatus failed, code: ${error.code}, message: ${error.message}`); } } // [EndExclude maximize] diff --git a/bptaMultiWindow/entry/src/main/ets/entryability/EntryAbility.ets b/bptaMultiWindow/entry/src/main/ets/entryability/EntryAbility.ets index f0fae342ef4da7a1158c4483a17084a2dd626961..b3df1f9aaabad95d3a138f560413ca6212a43bfd 100644 --- a/bptaMultiWindow/entry/src/main/ets/entryability/EntryAbility.ets +++ b/bptaMultiWindow/entry/src/main/ets/entryability/EntryAbility.ets @@ -16,10 +16,11 @@ /* * 最佳实践: 一多窗口适配开发实践 */ + // [Start onWindowStageCreate] import { UIAbility } from '@kit.AbilityKit'; import { window } from '@kit.ArkUI'; -import { deviceInfo } from '@kit.BasicServicesKit'; +import { BusinessError, deviceInfo } from '@kit.BasicServicesKit'; import hilog from '@ohos.hilog'; export default class EntryAbility extends UIAbility { @@ -34,12 +35,21 @@ export default class EntryAbility extends UIAbility { }); // [EndExclude onWindowStageCreate] let windowClass: window.Window | null = null; - windowStage.getMainWindow().then((data: window.Window) => { - windowClass = data; - if (deviceInfo.deviceType !== '2in1') { - windowClass.setWindowLayoutFullScreen(true); - } - }); + windowStage.getMainWindow() + .then((data: window.Window) => { + windowClass = data; + if (deviceInfo.deviceType !== '2in1') { + windowClass.setWindowLayoutFullScreen(true) + .catch((err: BusinessError) => { + hilog.error(0x000, 'testTag', + `setWindowLayoutFullScreen failed, code: ${err.code}, message: ${err.message}`) + }) + } + }) + .catch((err: BusinessError) => { + hilog.error(0x000, 'testTag', `getMainWindow failed, code: ${err.code}, message: ${err.message}`) + }) } } + // [End onWindowStageCreate] \ No newline at end of file diff --git a/bptaMultiWindow/entry/src/main/ets/entryability/EntryAbility1.ets b/bptaMultiWindow/entry/src/main/ets/entryability/EntryAbility1.ets index d76b66cc777ec1be7146ffb159ef8174427b188f..bacdb2dccde7182ba4dd7fbcc662dd0d0fa33b13 100644 --- a/bptaMultiWindow/entry/src/main/ets/entryability/EntryAbility1.ets +++ b/bptaMultiWindow/entry/src/main/ets/entryability/EntryAbility1.ets @@ -18,30 +18,42 @@ */ // [Start setdefaultorientation] -import { hilog } from "@kit.PerformanceAnalysisKit"; -import { BusinessError } from "@kit.BasicServicesKit"; -import { window } from "@kit.ArkUI"; -import { UIAbility } from "@kit.AbilityKit"; + +import { BusinessError } from '@kit.BasicServicesKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { UIAbility } from '@kit.AbilityKit'; +import { window } from '@kit.ArkUI'; export default class EntryAbility extends UIAbility { windowObj?: window.Window; uiContext?: UIContext; - onWindowSizeChange: (data: window.Size) => void = (data: window.Size) => { + onWindowSizeChange: (data: window.Size) => void = () => { this.setDefaultOrientation(); } setDefaultOrientation(): void { - let windowRect: window.Rect = this.windowObj!.getWindowProperties().windowRect; - let windowWidthVp: number = this.uiContext!.px2vp(windowRect.width); - let windowHeightVp: number = this.uiContext!.px2vp(windowRect.height); + try { + let windowRect: window.Rect = this.windowObj!.getWindowProperties().windowRect; + let windowWidthVp: number = this.uiContext!.px2vp(windowRect.width); + let windowHeightVp: number = this.uiContext!.px2vp(windowRect.height); - // If this condition is met, the window can be rotated. - if (Math.min(windowWidthVp, windowHeightVp) > 348) { - this.windowObj?.setPreferredOrientation(window.Orientation.AUTO_ROTATION_RESTRICTED); - } - // Otherwise, the window is displayed in portrait mode. - else { - this.windowObj?.setPreferredOrientation(window.Orientation.PORTRAIT); + // If this condition is met, the window can be rotated. + if (Math.min(windowWidthVp, windowHeightVp) > 348) { + this.windowObj?.setPreferredOrientation(window.Orientation.AUTO_ROTATION_RESTRICTED) + .catch((err: BusinessError) => { + hilog.error(0x000, 'testTag', `setPreferredOrientation failed, code=${err.code}, message=${err.message}`) + }) + } + // Otherwise, the window is displayed in portrait mode. + else { + this.windowObj?.setPreferredOrientation(window.Orientation.PORTRAIT) + .catch((err: BusinessError) => { + hilog.error(0x000, 'testTag', `setPreferredOrientation failed, code=${err.code}, message=${err.message}`) + }) + } + } catch (error) { + let err = error as BusinessError; + hilog.warn(0x000, 'testTag', `getWindowProperties failed, code=${err.code}, message=${err.message}`); } } @@ -51,18 +63,26 @@ export default class EntryAbility extends UIAbility { windowStage.getMainWindow().then((windowObj) => { this.windowObj = windowObj; }).catch((err: BusinessError) => { - hilog.error(0x0000, 'testTag', `Failed to obtain the main window. Cause code: ${err.code}, message: ${err.message}`); + hilog.error(0x0000, 'testTag', + `Failed to obtain the main window. Cause code: ${err.code}, message: ${err.message}`); }); windowStage.loadContent('pages/Index', (err) => { if (err.code) { hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); return; } - this.uiContext = this.windowObj!.getUIContext(); - this.setDefaultOrientation(); - this.windowObj!.on('windowSizeChange', this.onWindowSizeChange); - hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.'); + try { + this.uiContext = this.windowObj!.getUIContext(); + this.setDefaultOrientation(); + this.windowObj!.on('windowSizeChange', this.onWindowSizeChange); + hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.'); + } catch (error) { + let err = error as BusinessError; + hilog.warn(0x000, 'testTag', `getUIContext failed, code=${err.code}, message=${err.message}`); + } + }); } } + // [End setdefaultorientation] \ No newline at end of file diff --git a/bptaMultiWindow/entry/src/main/ets/entryability/EntryAbility2.ets b/bptaMultiWindow/entry/src/main/ets/entryability/EntryAbility2.ets index 46c5c4073f6f5ea6d9e6573725e2681d16630a3f..5fdaeb870a91fee4bfd0b8c12a648bdf679d96e0 100644 --- a/bptaMultiWindow/entry/src/main/ets/entryability/EntryAbility2.ets +++ b/bptaMultiWindow/entry/src/main/ets/entryability/EntryAbility2.ets @@ -18,20 +18,23 @@ */ // [Start onavoid_areachange] -import { UIAbility } from '@kit.AbilityKit'; +import { BusinessError } from '@kit.BasicServicesKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; import { window as arkWindow } from '@kit.ArkUI'; // Renamed the imported window +import { UIAbility } from '@kit.AbilityKit'; export default class EntryAbility extends UIAbility { - private onAvoidAreaChange: (avoidArea: arkWindow.AvoidAreaOptions) => void = (avoidArea: arkWindow.AvoidAreaOptions) => { - const uiContext: UIContext | undefined = AppStorage.get('uiContext'); - if (avoidArea.type === arkWindow.AvoidAreaType.TYPE_SYSTEM) { - // Updates the height of the top status bar. - AppStorage.setOrCreate('topAvoidHeight', uiContext?.px2vp(avoidArea.area.topRect.height)); - } else if (avoidArea.type === arkWindow.AvoidAreaType.TYPE_NAVIGATION_INDICATOR) { - // Updated the bottom navigation bar. - AppStorage.setOrCreate('bottomAvoidHeight', uiContext?.px2vp(avoidArea.area.bottomRect.height)); - } - }; + private onAvoidAreaChange: (avoidArea: arkWindow.AvoidAreaOptions) => void = + (avoidArea: arkWindow.AvoidAreaOptions) => { + const uiContext: UIContext | undefined = AppStorage.get('uiContext'); + if (avoidArea.type === arkWindow.AvoidAreaType.TYPE_SYSTEM) { + // Updates the height of the top status bar. + AppStorage.setOrCreate('topAvoidHeight', uiContext?.px2vp(avoidArea.area.topRect.height)); + } else if (avoidArea.type === arkWindow.AvoidAreaType.TYPE_NAVIGATION_INDICATOR) { + // Updated the bottom navigation bar. + AppStorage.setOrCreate('bottomAvoidHeight', uiContext?.px2vp(avoidArea.area.bottomRect.height)); + } + }; onWindowStageCreate(windowStage: arkWindow.WindowStage): void { windowStage.getMainWindow((err, window: arkWindow.Window) => { @@ -39,16 +42,25 @@ export default class EntryAbility extends UIAbility { console.error('Failed to get main window. Error: ' + JSON.stringify(err)); return; } - window.setWindowLayoutFullScreen(true); - AppStorage.setOrCreate('uiContext', windowStage.getMainWindowSync().getUIContext()); - const uiContext: UIContext | undefined = AppStorage.get('uiContext'); - let topAvoidHeight: arkWindow.AvoidArea = window.getWindowAvoidArea(arkWindow.AvoidAreaType.TYPE_SYSTEM); - AppStorage.setOrCreate('topAvoidHeight', uiContext?.px2vp(topAvoidHeight.topRect.height)); - let bottomAvoidHeight: arkWindow.AvoidArea = - window.getWindowAvoidArea(arkWindow.AvoidAreaType.TYPE_NAVIGATION_INDICATOR); - AppStorage.setOrCreate('bottomAvoidHeight', uiContext?.px2vp(bottomAvoidHeight.bottomRect.height)); - window.on('avoidAreaChange', this.onAvoidAreaChange); + window.setWindowLayoutFullScreen(true) + .catch((err: BusinessError) => { + hilog.error(0x000, 'testTag', `setWindowLayoutFullScreen failed, code=${err.code}, message=${err.message}`) + }) + try { + AppStorage.setOrCreate('uiContext', windowStage.getMainWindowSync().getUIContext()); + const uiContext: UIContext | undefined = AppStorage.get('uiContext'); + let topAvoidHeight: arkWindow.AvoidArea = window.getWindowAvoidArea(arkWindow.AvoidAreaType.TYPE_SYSTEM); + AppStorage.setOrCreate('topAvoidHeight', uiContext?.px2vp(topAvoidHeight.topRect.height)); + let bottomAvoidHeight: arkWindow.AvoidArea = + window.getWindowAvoidArea(arkWindow.AvoidAreaType.TYPE_NAVIGATION_INDICATOR); + AppStorage.setOrCreate('bottomAvoidHeight', uiContext?.px2vp(bottomAvoidHeight.bottomRect.height)); + window.on('avoidAreaChange', this.onAvoidAreaChange); + } catch (error) { + let err = error as BusinessError; + hilog.warn(0x000, 'testTag', `getWindowAvoidArea failed, code=${err.code}, message=${err.message}`); + } }); } } + // [End onavoid_areachange] \ No newline at end of file diff --git a/bptaMultiWindow/entry/src/main/ets/entryability/EntryAbility3.ets b/bptaMultiWindow/entry/src/main/ets/entryability/EntryAbility3.ets index adbe5136b6c7c320ad657f5125beb4546ea107bf..ee0fd257bd8b5b66672d841db8452dbeab552ee0 100644 --- a/bptaMultiWindow/entry/src/main/ets/entryability/EntryAbility3.ets +++ b/bptaMultiWindow/entry/src/main/ets/entryability/EntryAbility3.ets @@ -18,10 +18,10 @@ */ // [Start onwindowstagecreate1] +import { BusinessError, deviceInfo } from '@kit.BasicServicesKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; import { UIAbility } from '@kit.AbilityKit'; import { window } from '@kit.ArkUI'; -import { deviceInfo } from '@kit.BasicServicesKit'; -import { hilog } from '@kit.PerformanceAnalysisKit'; export default class EntryAbility extends UIAbility { onWindowStageCreate(windowStage: window.WindowStage): void { @@ -35,12 +35,20 @@ export default class EntryAbility extends UIAbility { windowStage.getMainWindow().then((data: window.Window) => { let deviceTypeInfo: string = deviceInfo.deviceType; if (deviceTypeInfo === '2in1') { - // Set the title bar of the 2in1 device to be invisible after the loadContent() call takes effect. - data.setWindowDecorVisible(false); - // When the title bar is invisible, set the height of the title bar and control the height of the three buttons (full screen/restore, maximize, and close) in the upper right corner. - data.setWindowDecorHeight(64); + try { + // Set the title bar of the 2in1 device to be invisible after the loadContent() call takes effect. + data.setWindowDecorVisible(false); + // When the title bar is invisible, set the height of the title bar and control the height of the three buttons (full screen/restore, maximize, and close) in the upper right corner. + data.setWindowDecorHeight(64); + } catch (error) { + let err = error as BusinessError; + hilog.warn(0x000, 'testTag', `set windowDecor size failed, code=${err.code}, message=${err.message}`); + } } + }).catch((err: BusinessError) => { + hilog.error(0x000, 'testTag', `setWindowLayoutFullScreen failed, code=${err.code}, message=${err.message}`) }) } } + // [End onwindowstagecreate1] \ No newline at end of file diff --git a/bptaMultiWindow/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets b/bptaMultiWindow/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets index 8e4de99282050bad799ac892eb85ac5449364a51..205676f032f1acd769341fa4ae6a702cafcf8ab2 100644 --- a/bptaMultiWindow/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets +++ b/bptaMultiWindow/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets @@ -1,16 +1,31 @@ -import { hilog } from '@kit.PerformanceAnalysisKit'; +/* +* Copyright (C) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ + import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; const DOMAIN = 0x0000; export default class EntryBackupAbility extends BackupExtensionAbility { async onBackup() { - hilog.info(DOMAIN, 'testTag', 'onBackup ok'); + hilog.info(DOMAIN, 'EntryBackupAbility', 'onBackup ok'); await Promise.resolve(); } async onRestore(bundleVersion: BundleVersion) { - hilog.info(DOMAIN, 'testTag', 'onRestore ok %{public}s', JSON.stringify(bundleVersion)); + hilog.info(DOMAIN, 'EntryBackupAbility', 'onRestore ok %{public}s', JSON.stringify(bundleVersion)); await Promise.resolve(); } } \ No newline at end of file diff --git a/bptaMultiWindow/entry/src/main/ets/pages/FreeMultiWindowMode.ets b/bptaMultiWindow/entry/src/main/ets/pages/FreeMultiWindowMode.ets index 04687cf7a58cc4b396765c30c4c3f7b8258f432c..e60ffd56a26a802b289b31f456c8f88c75e82221 100644 --- a/bptaMultiWindow/entry/src/main/ets/pages/FreeMultiWindowMode.ets +++ b/bptaMultiWindow/entry/src/main/ets/pages/FreeMultiWindowMode.ets @@ -1,14 +1,35 @@ /* +* Copyright (C) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ +/* * 最佳实践: 一多窗口适配开发实践 */ + +import { hilog } from '@kit.PerformanceAnalysisKit'; import { settings } from '@kit.BasicServicesKit'; +const DOMAIN = 0x0000; +const TAG = 'FreeMultiWindowMode'; +const FORMAT = '%{public}s'; + // [Start FreeMultiWindowMode] const context: UIContext | undefined = AppStorage.get('uiContext'); -settings.getValue(context?.getHostContext(), 'window_pcmode_switch_status', settings.domainName.USER_PROPERTY).then((data) => { - if (data) { - console.info(`get settings value window_pcmode_switch_status:${JSON.stringify(data)}`); - return; - } -}); +settings.getValue(context?.getHostContext(), 'window_pcmode_switch_status', settings.domainName.USER_PROPERTY) + .then((data) => { + if (data) { + hilog.info(DOMAIN, TAG, FORMAT, `get settings value window_pcmode_switch_status: ${JSON.stringify(data)}`); + return; + } + }); // [End FreeMultiWindowMode] \ No newline at end of file diff --git a/bptaMultiWindow/entry/src/main/ets/pages/FreeMultiWindowObserver.ets b/bptaMultiWindow/entry/src/main/ets/pages/FreeMultiWindowObserver.ets index 60aeeb1e57ec5946ab20be9724d2fe1dbeb45a80..359b9f381f7d17f561d797afa2a958e0f2035fbf 100644 --- a/bptaMultiWindow/entry/src/main/ets/pages/FreeMultiWindowObserver.ets +++ b/bptaMultiWindow/entry/src/main/ets/pages/FreeMultiWindowObserver.ets @@ -1,17 +1,38 @@ /* +* Copyright (C) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* 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. +*/ +/* * 最佳实践: 一多窗口适配开发实践 */ + +import { hilog } from '@kit.PerformanceAnalysisKit'; import { settings } from '@kit.BasicServicesKit'; +const DOMAIN = 0x0000; +const TAG = 'FreeMultiWindowObserver'; +const FORMAT = '%{public}s'; + // [Start FreeMultiWindowObserver] const context: UIContext | undefined = AppStorage.get('uiContext'); -settings.registerKeyObserver(context?.getHostContext(), 'window_pcmode_switch_status', settings.domainName.USER_PROPERTY, () => { - settings.getValue(context?.getHostContext(), 'window_pcmode_switch_status', - settings.domainName.USER_PROPERTY).then((data) => { - if (data) { - console.info(`settings value changed, window_pcmode_switch_status:${JSON.stringify(data)}`); - return; - } +settings.registerKeyObserver(context?.getHostContext(), 'window_pcmode_switch_status', + settings.domainName.USER_PROPERTY, () => { + settings.getValue(context?.getHostContext(), 'window_pcmode_switch_status', + settings.domainName.USER_PROPERTY).then((data) => { + if (data) { + hilog.info(DOMAIN, TAG, FORMAT, `settings value changed, window_pcmode_switch_status: ${JSON.stringify(data)}`); + return; + } + }); }); -}); // [End FreeMultiWindowObserver] \ No newline at end of file diff --git a/bptaMultiWindow/entry/src/main/module.json5 b/bptaMultiWindow/entry/src/main/module.json5 index fcdaa9811225ae4c9d69e9e07bb705bee2d03979..1f29d4e617bf0519fa5e751863f46324bcebc818 100644 --- a/bptaMultiWindow/entry/src/main/module.json5 +++ b/bptaMultiWindow/entry/src/main/module.json5 @@ -25,8 +25,6 @@ "mainElement": "EntryAbility", "deviceTypes": [ "phone", - "tablet", - "2in1" ], "deliveryWithInstall": true, "installationFree": false, diff --git a/bptaMultiWindow/entry/src/main/resources/base/element/string.json b/bptaMultiWindow/entry/src/main/resources/base/element/string.json index f94595515a99e0c828807e243494f57f09251930..ec82b1cca12321f74047ddfce0cf93ae0c18c418 100644 --- a/bptaMultiWindow/entry/src/main/resources/base/element/string.json +++ b/bptaMultiWindow/entry/src/main/resources/base/element/string.json @@ -10,7 +10,7 @@ }, { "name": "EntryAbility_label", - "value": "label" + "value": "bptaMultiWindow" } ] } \ No newline at end of file diff --git a/bptaMultiWindow/entry/src/mock/mock-config.json5 b/bptaMultiWindow/entry/src/mock/mock-config.json5 deleted file mode 100644 index 7a73a41bfdf76d6f793007240d80983a52f15f97..0000000000000000000000000000000000000000 --- a/bptaMultiWindow/entry/src/mock/mock-config.json5 +++ /dev/null @@ -1,2 +0,0 @@ -{ -} \ No newline at end of file diff --git a/bptaMultiWindow/entry/src/ohosTest/ets/test/Ability.test.ets b/bptaMultiWindow/entry/src/ohosTest/ets/test/Ability.test.ets deleted file mode 100644 index 85c78f67579d6e31b5f5aeea463e216b9b141048..0000000000000000000000000000000000000000 --- a/bptaMultiWindow/entry/src/ohosTest/ets/test/Ability.test.ets +++ /dev/null @@ -1,35 +0,0 @@ -import { hilog } from '@kit.PerformanceAnalysisKit'; -import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; - -export default function abilityTest() { - describe('ActsAbilityTest', () => { - // Defines a test suite. Two parameters are supported: test suite name and test suite function. - beforeAll(() => { - // Presets an action, which is performed only once before all test cases of the test suite start. - // This API supports only one parameter: preset action function. - }) - beforeEach(() => { - // Presets an action, which is performed before each unit test case starts. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: preset action function. - }) - afterEach(() => { - // Presets a clear action, which is performed after each unit test case ends. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: clear action function. - }) - afterAll(() => { - // Presets a clear action, which is performed after all test cases of the test suite end. - // This API supports only one parameter: clear action function. - }) - it('assertContain', 0, () => { - // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. - hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); - let a = 'abc'; - let b = 'b'; - // Defines a variety of assertion methods, which are used to declare expected boolean conditions. - expect(a).assertContain(b); - expect(a).assertEqual(a); - }) - }) -} \ No newline at end of file diff --git a/bptaMultiWindow/entry/src/ohosTest/ets/test/List.test.ets b/bptaMultiWindow/entry/src/ohosTest/ets/test/List.test.ets deleted file mode 100644 index 794c7dc4ed66bd98fa3865e07922906e2fcef545..0000000000000000000000000000000000000000 --- a/bptaMultiWindow/entry/src/ohosTest/ets/test/List.test.ets +++ /dev/null @@ -1,5 +0,0 @@ -import abilityTest from './Ability.test'; - -export default function testsuite() { - abilityTest(); -} \ No newline at end of file diff --git a/bptaMultiWindow/entry/src/ohosTest/module.json5 b/bptaMultiWindow/entry/src/ohosTest/module.json5 deleted file mode 100644 index 55725a929993a8a18b3808d41ef037759440488b..0000000000000000000000000000000000000000 --- a/bptaMultiWindow/entry/src/ohosTest/module.json5 +++ /dev/null @@ -1,13 +0,0 @@ -{ - "module": { - "name": "entry_test", - "type": "feature", - "deviceTypes": [ - "phone", - "tablet", - "2in1" - ], - "deliveryWithInstall": true, - "installationFree": false - } -} diff --git a/bptaMultiWindow/entry/src/test/List.test.ets b/bptaMultiWindow/entry/src/test/List.test.ets deleted file mode 100644 index bb5b5c3731e283dd507c847560ee59bde477bbc7..0000000000000000000000000000000000000000 --- a/bptaMultiWindow/entry/src/test/List.test.ets +++ /dev/null @@ -1,5 +0,0 @@ -import localUnitTest from './LocalUnit.test'; - -export default function testsuite() { - localUnitTest(); -} \ No newline at end of file diff --git a/bptaMultiWindow/entry/src/test/LocalUnit.test.ets b/bptaMultiWindow/entry/src/test/LocalUnit.test.ets deleted file mode 100644 index 165fc1615ee8618b4cb6a622f144a9a707eee99f..0000000000000000000000000000000000000000 --- a/bptaMultiWindow/entry/src/test/LocalUnit.test.ets +++ /dev/null @@ -1,33 +0,0 @@ -import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; - -export default function localUnitTest() { - describe('localUnitTest', () => { - // Defines a test suite. Two parameters are supported: test suite name and test suite function. - beforeAll(() => { - // Presets an action, which is performed only once before all test cases of the test suite start. - // This API supports only one parameter: preset action function. - }); - beforeEach(() => { - // Presets an action, which is performed before each unit test case starts. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: preset action function. - }); - afterEach(() => { - // Presets a clear action, which is performed after each unit test case ends. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: clear action function. - }); - afterAll(() => { - // Presets a clear action, which is performed after all test cases of the test suite end. - // This API supports only one parameter: clear action function. - }); - it('assertContain', 0, () => { - // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. - let a = 'abc'; - let b = 'b'; - // Defines a variety of assertion methods, which are used to declare expected boolean conditions. - expect(a).assertContain(b); - expect(a).assertEqual(a); - }); - }); -} \ No newline at end of file diff --git a/bptaMultiWindow/oh-package-lock.json5 b/bptaMultiWindow/oh-package-lock.json5 deleted file mode 100644 index 7fcf818273347b97063c0c0a151bb14770ca1c79..0000000000000000000000000000000000000000 --- a/bptaMultiWindow/oh-package-lock.json5 +++ /dev/null @@ -1,27 +0,0 @@ -{ - "meta": { - "stableOrder": true - }, - "lockfileVersion": 3, - "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", - "specifiers": { - "@ohos/hamock@1.0.0": "@ohos/hamock@1.0.0", - "@ohos/hypium@1.0.21": "@ohos/hypium@1.0.21" - }, - "packages": { - "@ohos/hamock@1.0.0": { - "name": "@ohos/hamock", - "version": "1.0.0", - "integrity": "sha512-K6lDPYc6VkKe6ZBNQa9aoG+ZZMiwqfcR/7yAVFSUGIuOAhPvCJAo9+t1fZnpe0dBRBPxj2bxPPbKh69VuyAtDg==", - "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hamock/-/hamock-1.0.0.har", - "registryType": "ohpm" - }, - "@ohos/hypium@1.0.21": { - "name": "@ohos/hypium", - "version": "1.0.21", - "integrity": "sha512-iyKGMXxE+9PpCkqEwu0VykN/7hNpb+QOeIuHwkmZnxOpI+dFZt6yhPB7k89EgV1MiSK/ieV/hMjr5Z2mWwRfMQ==", - "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hypium/-/hypium-1.0.21.har", - "registryType": "ohpm" - } - } -} \ No newline at end of file diff --git a/customPlugin/README.md b/customPlugin/README.md index 309c9d43746c2a3ca26ca1b7acc39dc23e04ae80..8c2e81e8e0a5e11aac8a51c2f1ca89e40abf37ec 100644 --- a/customPlugin/README.md +++ b/customPlugin/README.md @@ -3,39 +3,49 @@ ### 介绍 在进行编译构建的过程中,开发者可以通过定制hvigor插件,扩展构建逻辑,实现个性化的打包流程。 -定制hvigor插件,通常有以下目的: -满足自定义任务需求。 -每个项目可能有独特的构建需求和流程,定制插件可以根据项目的具体要求来扩展hvigor构建的功能。 +### 使用说明 -加强构建任务可维护性。 -定制插件可以将某些复杂的构建逻辑封装在同一个地方,使得项目的构建配置更加清晰和易于维护。可以自动化执行某些特定任务,减少手动干预,确保构建过程的一致可靠。 +不涉及。 -提升团队协作效率。 -在团队开发中,定制插件可以确保所有团队成员使用相同的构建流程和标准,减少因个人配置差异导致的问题,从而提升团队协作的效率。 - -### 工程结构&模块类型 +### 工程结构 ``` ├──entry/src/main/ets/ -│ ├──mock -│ │ └──GoodsMock.ets // 模拟数据类 │ ├──entryability -│ │ └──EntryAbility.ets // 配置类 -│ └──model -│ │ └──GoodsModel.ets // 类型声明 +│ │ └──EntryAbility.ets // 入口类 +│ ├──entrybackupability +│ │ └──EntryBackupAbility.ets // 备份恢复类 │ └──pages -│ └──Index.ets // 程序入口类 -└──entry/src/main/resource // 应用静态资源目录 +│ └──Index.ets // 示例页面 +├──entry/src/main/resource // 应用资源目录 +├──library/src/main/ets +│ └──components +│ └──MainPage.ets // library模块中MainPage +└──library/src/main/resource // lib资源目录 ``` +### 相关权限 + +不涉及。 ### 约束与限制 -1. 本示例仅支持标准系统上运行,支持设备:华为手机。 +* 本示例仅支持标准系统上运行,支持设备:华为手机。 + +* HarmonyOS系统:HarmonyOS 5.0.5 Release及以上。 -2. HarmonyOS 系统:HarmonyOS NEXT Developer Beta1 及以上。 +* DevEco Studio版本:DevEco Studio 5.0.5 Release及以上。 -3. DevEco Studio 版本:DevEco Studio NEXT Developer Beta1 及以上。 +* HarmonyOS SDK版本:HarmonyOS 5.0.5 Release SDK及以上。 -4. HarmonyOS SDK 版本:HarmonyOS NEXT Developer Beta1 SDK 及以上。 +### 下载 + +如需单独下载本工程,执行如下命令: +``` +git clone --filter=blob:none --no-checkout https://gitee.com/harmonyos_samples/BestPracticeSnippets.git +cd BestPracticeSnippets +git sparse-checkout init --cone +git sparse-checkout set customPlugin +git checkout +``` diff --git a/customPlugin/entry/src/main/ets/entryability/EntryAbility.ets b/customPlugin/entry/src/main/ets/entryability/EntryAbility.ets index 508880af8c33aa838016d1cd4b2c68be2f447540..d6c8a8e454f830409bd59e18826cd56e0412125c 100644 --- a/customPlugin/entry/src/main/ets/entryability/EntryAbility.ets +++ b/customPlugin/entry/src/main/ets/entryability/EntryAbility.ets @@ -1,12 +1,33 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; import { hilog } from '@kit.PerformanceAnalysisKit'; import { window } from '@kit.ArkUI'; +import { BusinessError } from '@kit.BasicServicesKit'; const DOMAIN = 0x0000; export default class EntryAbility extends UIAbility { onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { - this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + try { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + } catch (e) { + let err = e as BusinessError; + hilog.error(DOMAIN, 'testTag', `failed code=${err.code}, message=${err.message}`); + } hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); } diff --git a/customPlugin/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets b/customPlugin/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets index 8e4de99282050bad799ac892eb85ac5449364a51..0a97e21bd7a15599af76a806695860ff1eb0ebfe 100644 --- a/customPlugin/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets +++ b/customPlugin/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + import { hilog } from '@kit.PerformanceAnalysisKit'; import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit'; diff --git a/customPlugin/entry/src/main/ets/pages/Index.ets b/customPlugin/entry/src/main/ets/pages/Index.ets index 766a658345715dec1cc6b6a626f9a2864861c73f..0f481f696485b8c840d49ad9e7d7dff7f6b71241 100644 --- a/customPlugin/entry/src/main/ets/pages/Index.ets +++ b/customPlugin/entry/src/main/ets/pages/Index.ets @@ -1,4 +1,18 @@ -import handover from '@hms.networkboost.handover'; +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + @Entry @Component struct Index { diff --git a/customPlugin/entry/src/main/module.json5 b/customPlugin/entry/src/main/module.json5 index a1cea8b6a4560cee7bda7a2db52f310c035ab6c8..ad219d733f6afa5ea07f85f580208b08cc3b9041 100644 --- a/customPlugin/entry/src/main/module.json5 +++ b/customPlugin/entry/src/main/module.json5 @@ -5,9 +5,7 @@ "description": "$string:module_desc", "mainElement": "EntryAbility", "deviceTypes": [ - "phone", - "tablet", - "2in1" + "phone" ], "deliveryWithInstall": true, "installationFree": false, diff --git a/customPlugin/entry/src/main/resources/base/element/string.json b/customPlugin/entry/src/main/resources/base/element/string.json index f94595515a99e0c828807e243494f57f09251930..71113f812d5120034ec203e97aa448873fde7398 100644 --- a/customPlugin/entry/src/main/resources/base/element/string.json +++ b/customPlugin/entry/src/main/resources/base/element/string.json @@ -10,7 +10,7 @@ }, { "name": "EntryAbility_label", - "value": "label" + "value": "customPlugin" } ] } \ No newline at end of file diff --git a/customPlugin/entry/src/mock/mock-config.json5 b/customPlugin/entry/src/mock/mock-config.json5 deleted file mode 100644 index 7a73a41bfdf76d6f793007240d80983a52f15f97..0000000000000000000000000000000000000000 --- a/customPlugin/entry/src/mock/mock-config.json5 +++ /dev/null @@ -1,2 +0,0 @@ -{ -} \ No newline at end of file diff --git a/customPlugin/entry/src/ohosTest/ets/test/Ability.test.ets b/customPlugin/entry/src/ohosTest/ets/test/Ability.test.ets deleted file mode 100644 index 85c78f67579d6e31b5f5aeea463e216b9b141048..0000000000000000000000000000000000000000 --- a/customPlugin/entry/src/ohosTest/ets/test/Ability.test.ets +++ /dev/null @@ -1,35 +0,0 @@ -import { hilog } from '@kit.PerformanceAnalysisKit'; -import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; - -export default function abilityTest() { - describe('ActsAbilityTest', () => { - // Defines a test suite. Two parameters are supported: test suite name and test suite function. - beforeAll(() => { - // Presets an action, which is performed only once before all test cases of the test suite start. - // This API supports only one parameter: preset action function. - }) - beforeEach(() => { - // Presets an action, which is performed before each unit test case starts. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: preset action function. - }) - afterEach(() => { - // Presets a clear action, which is performed after each unit test case ends. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: clear action function. - }) - afterAll(() => { - // Presets a clear action, which is performed after all test cases of the test suite end. - // This API supports only one parameter: clear action function. - }) - it('assertContain', 0, () => { - // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. - hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); - let a = 'abc'; - let b = 'b'; - // Defines a variety of assertion methods, which are used to declare expected boolean conditions. - expect(a).assertContain(b); - expect(a).assertEqual(a); - }) - }) -} \ No newline at end of file diff --git a/customPlugin/entry/src/ohosTest/ets/test/List.test.ets b/customPlugin/entry/src/ohosTest/ets/test/List.test.ets deleted file mode 100644 index 794c7dc4ed66bd98fa3865e07922906e2fcef545..0000000000000000000000000000000000000000 --- a/customPlugin/entry/src/ohosTest/ets/test/List.test.ets +++ /dev/null @@ -1,5 +0,0 @@ -import abilityTest from './Ability.test'; - -export default function testsuite() { - abilityTest(); -} \ No newline at end of file diff --git a/customPlugin/entry/src/ohosTest/module.json5 b/customPlugin/entry/src/ohosTest/module.json5 deleted file mode 100644 index 55725a929993a8a18b3808d41ef037759440488b..0000000000000000000000000000000000000000 --- a/customPlugin/entry/src/ohosTest/module.json5 +++ /dev/null @@ -1,13 +0,0 @@ -{ - "module": { - "name": "entry_test", - "type": "feature", - "deviceTypes": [ - "phone", - "tablet", - "2in1" - ], - "deliveryWithInstall": true, - "installationFree": false - } -} diff --git a/customPlugin/entry/src/test/List.test.ets b/customPlugin/entry/src/test/List.test.ets deleted file mode 100644 index bb5b5c3731e283dd507c847560ee59bde477bbc7..0000000000000000000000000000000000000000 --- a/customPlugin/entry/src/test/List.test.ets +++ /dev/null @@ -1,5 +0,0 @@ -import localUnitTest from './LocalUnit.test'; - -export default function testsuite() { - localUnitTest(); -} \ No newline at end of file diff --git a/customPlugin/entry/src/test/LocalUnit.test.ets b/customPlugin/entry/src/test/LocalUnit.test.ets deleted file mode 100644 index 165fc1615ee8618b4cb6a622f144a9a707eee99f..0000000000000000000000000000000000000000 --- a/customPlugin/entry/src/test/LocalUnit.test.ets +++ /dev/null @@ -1,33 +0,0 @@ -import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; - -export default function localUnitTest() { - describe('localUnitTest', () => { - // Defines a test suite. Two parameters are supported: test suite name and test suite function. - beforeAll(() => { - // Presets an action, which is performed only once before all test cases of the test suite start. - // This API supports only one parameter: preset action function. - }); - beforeEach(() => { - // Presets an action, which is performed before each unit test case starts. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: preset action function. - }); - afterEach(() => { - // Presets a clear action, which is performed after each unit test case ends. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: clear action function. - }); - afterAll(() => { - // Presets a clear action, which is performed after all test cases of the test suite end. - // This API supports only one parameter: clear action function. - }); - it('assertContain', 0, () => { - // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. - let a = 'abc'; - let b = 'b'; - // Defines a variety of assertion methods, which are used to declare expected boolean conditions. - expect(a).assertContain(b); - expect(a).assertEqual(a); - }); - }); -} \ No newline at end of file diff --git a/customPlugin/library/BuildProfile.ets b/customPlugin/library/BuildProfile.ets deleted file mode 100644 index 3a501e5ddee8ea6d28961648fc7dd314a5304bd4..0000000000000000000000000000000000000000 --- a/customPlugin/library/BuildProfile.ets +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Use these variables when you tailor your ArkTS code. They must be of the const type. - */ -export const HAR_VERSION = '1.0.0'; -export const BUILD_MODE_NAME = 'debug'; -export const DEBUG = true; -export const TARGET_NAME = 'default'; - -/** - * BuildProfile Class is used only for compatibility purposes. - */ -export default class BuildProfile { - static readonly HAR_VERSION = HAR_VERSION; - static readonly BUILD_MODE_NAME = BUILD_MODE_NAME; - static readonly DEBUG = DEBUG; - static readonly TARGET_NAME = TARGET_NAME; -} \ No newline at end of file diff --git a/customPlugin/library/build-profile.json5 b/customPlugin/library/build-profile.json5 index e6773f9f5d76a66d6d19fddc9c6ddb3f5621d3b1..cda3307123ec7c43181580a86ef7e82a18319a34 100644 --- a/customPlugin/library/build-profile.json5 +++ b/customPlugin/library/build-profile.json5 @@ -23,9 +23,6 @@ "targets": [ { "name": "default" - }, - { - "name": "ohosTest" } ] } diff --git a/customPlugin/library/src/main/ets/components/MainPage.ets b/customPlugin/library/src/main/ets/components/MainPage.ets index 563edbf06ce6f9d09ea65a30b7ca236173ac43e1..0cd44d4716ac19350f57ce86a23e9b54b5c86472 100644 --- a/customPlugin/library/src/main/ets/components/MainPage.ets +++ b/customPlugin/library/src/main/ets/components/MainPage.ets @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + @Preview @Component export struct MainPage { diff --git a/customPlugin/library/src/main/module.json5 b/customPlugin/library/src/main/module.json5 index dd30f8e0de7154e00da5009b23df656940652a64..39f9cdc6a027938963e6f8cdc77dde030fee223c 100644 --- a/customPlugin/library/src/main/module.json5 +++ b/customPlugin/library/src/main/module.json5 @@ -3,9 +3,7 @@ "name": "library", "type": "har", "deviceTypes": [ - "default", - "tablet", - "2in1" + "phone" ] } } diff --git a/customPlugin/library/src/ohosTest/ets/test/Ability.test.ets b/customPlugin/library/src/ohosTest/ets/test/Ability.test.ets deleted file mode 100644 index 85c78f67579d6e31b5f5aeea463e216b9b141048..0000000000000000000000000000000000000000 --- a/customPlugin/library/src/ohosTest/ets/test/Ability.test.ets +++ /dev/null @@ -1,35 +0,0 @@ -import { hilog } from '@kit.PerformanceAnalysisKit'; -import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; - -export default function abilityTest() { - describe('ActsAbilityTest', () => { - // Defines a test suite. Two parameters are supported: test suite name and test suite function. - beforeAll(() => { - // Presets an action, which is performed only once before all test cases of the test suite start. - // This API supports only one parameter: preset action function. - }) - beforeEach(() => { - // Presets an action, which is performed before each unit test case starts. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: preset action function. - }) - afterEach(() => { - // Presets a clear action, which is performed after each unit test case ends. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: clear action function. - }) - afterAll(() => { - // Presets a clear action, which is performed after all test cases of the test suite end. - // This API supports only one parameter: clear action function. - }) - it('assertContain', 0, () => { - // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. - hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); - let a = 'abc'; - let b = 'b'; - // Defines a variety of assertion methods, which are used to declare expected boolean conditions. - expect(a).assertContain(b); - expect(a).assertEqual(a); - }) - }) -} \ No newline at end of file diff --git a/customPlugin/library/src/ohosTest/ets/test/List.test.ets b/customPlugin/library/src/ohosTest/ets/test/List.test.ets deleted file mode 100644 index 794c7dc4ed66bd98fa3865e07922906e2fcef545..0000000000000000000000000000000000000000 --- a/customPlugin/library/src/ohosTest/ets/test/List.test.ets +++ /dev/null @@ -1,5 +0,0 @@ -import abilityTest from './Ability.test'; - -export default function testsuite() { - abilityTest(); -} \ No newline at end of file diff --git a/customPlugin/library/src/ohosTest/module.json5 b/customPlugin/library/src/ohosTest/module.json5 deleted file mode 100644 index 2d357bce9c10ce2146bf57f966d4e29f770ab067..0000000000000000000000000000000000000000 --- a/customPlugin/library/src/ohosTest/module.json5 +++ /dev/null @@ -1,13 +0,0 @@ -{ - "module": { - "name": "library_test", - "type": "feature", - "deviceTypes": [ - "default", - "tablet", - "2in1" - ], - "deliveryWithInstall": true, - "installationFree": false - } -} diff --git a/customPlugin/library/src/test/List.test.ets b/customPlugin/library/src/test/List.test.ets deleted file mode 100644 index bb5b5c3731e283dd507c847560ee59bde477bbc7..0000000000000000000000000000000000000000 --- a/customPlugin/library/src/test/List.test.ets +++ /dev/null @@ -1,5 +0,0 @@ -import localUnitTest from './LocalUnit.test'; - -export default function testsuite() { - localUnitTest(); -} \ No newline at end of file diff --git a/customPlugin/library/src/test/LocalUnit.test.ets b/customPlugin/library/src/test/LocalUnit.test.ets deleted file mode 100644 index 165fc1615ee8618b4cb6a622f144a9a707eee99f..0000000000000000000000000000000000000000 --- a/customPlugin/library/src/test/LocalUnit.test.ets +++ /dev/null @@ -1,33 +0,0 @@ -import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; - -export default function localUnitTest() { - describe('localUnitTest', () => { - // Defines a test suite. Two parameters are supported: test suite name and test suite function. - beforeAll(() => { - // Presets an action, which is performed only once before all test cases of the test suite start. - // This API supports only one parameter: preset action function. - }); - beforeEach(() => { - // Presets an action, which is performed before each unit test case starts. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: preset action function. - }); - afterEach(() => { - // Presets a clear action, which is performed after each unit test case ends. - // The number of execution times is the same as the number of test cases defined by **it**. - // This API supports only one parameter: clear action function. - }); - afterAll(() => { - // Presets a clear action, which is performed after all test cases of the test suite end. - // This API supports only one parameter: clear action function. - }); - it('assertContain', 0, () => { - // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. - let a = 'abc'; - let b = 'b'; - // Defines a variety of assertion methods, which are used to declare expected boolean conditions. - expect(a).assertContain(b); - expect(a).assertEqual(a); - }); - }); -} \ No newline at end of file diff --git a/customPlugin/npm_plugin/pure_plugin.ts b/customPlugin/npm_plugin/pure_plugin.ts index c55be6a34b269952bb644365a96e872aecd5f873..c091863dd86db61673070f44b3d18599d043bb7c 100644 --- a/customPlugin/npm_plugin/pure_plugin.ts +++ b/customPlugin/npm_plugin/pure_plugin.ts @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + // [Start custom_plugin] import fs from 'fs';