├── .gitignore
├── AppScope
├── app.json5
└── resources
│ ├── base
│ ├── element
│ │ └── string.json
│ └── media
│ │ └── app_icon.png
│ └── rawfile
│ └── agconnect-services.json
├── README.md
├── base
├── README.md
├── fast_ui
│ ├── .gitignore
│ ├── BuildProfile.ets
│ ├── Index.ets
│ ├── build-profile.json5
│ ├── consumer-rules.txt
│ ├── hvigorfile.ts
│ ├── obfuscation-rules.txt
│ ├── oh-package.json5
│ └── src
│ │ └── main
│ │ ├── ets
│ │ ├── components
│ │ │ ├── FastLoading.ets
│ │ │ ├── FastToast.ets
│ │ │ └── FoldStatusContainer.ets
│ │ └── styles
│ │ │ ├── CommonButtonStyle.ets
│ │ │ └── CommonTextStyle.ets
│ │ ├── module.json5
│ │ └── resources
│ │ ├── base
│ │ └── element
│ │ │ ├── color.json
│ │ │ ├── float.json
│ │ │ └── string.json
│ │ ├── en_US
│ │ └── element
│ │ │ └── string.json
│ │ └── zh_CN
│ │ └── element
│ │ └── string.json
├── fast_util
│ ├── .gitignore
│ ├── BuildProfile.ets
│ ├── Index.ets
│ ├── build-profile.json5
│ ├── consumer-rules.txt
│ ├── hvigorfile.ts
│ ├── obfuscation-rules.txt
│ ├── oh-package.json5
│ └── src
│ │ └── main
│ │ ├── ets
│ │ ├── EventBus.ets
│ │ ├── FastLog.ts
│ │ ├── FastNavRouter.ets
│ │ ├── FastPermisttion.ts
│ │ ├── FastRouter.ets
│ │ ├── FastTool.ets
│ │ ├── ObjectUtil.ts
│ │ ├── PreferencesUtil.ets
│ │ └── ThrottleTool.ts
│ │ ├── module.json5
│ │ └── resources
│ │ ├── base
│ │ └── element
│ │ │ └── string.json
│ │ ├── en_US
│ │ └── element
│ │ │ └── string.json
│ │ └── zh_CN
│ │ └── element
│ │ └── string.json
└── global_constant
│ ├── .gitignore
│ ├── BuildProfile.ets
│ ├── Index.ets
│ ├── build-profile.json5
│ ├── consumer-rules.txt
│ ├── hvigorfile.ts
│ ├── obfuscation-rules.txt
│ ├── oh-package.json5
│ └── src
│ └── main
│ ├── ets
│ └── PagePathConstants.ets
│ ├── module.json5
│ └── resources
│ ├── base
│ └── element
│ │ └── string.json
│ ├── en_US
│ └── element
│ │ └── string.json
│ └── zh_CN
│ └── element
│ └── string.json
├── build-profile.json5
├── business
├── feature_home
│ ├── .gitignore
│ ├── BuildProfile.ets
│ ├── Index.ets
│ ├── build-profile.json5
│ ├── consumer-rules.txt
│ ├── hvigorfile.ts
│ ├── obfuscation-rules.txt
│ ├── oh-package-lock.json5
│ ├── oh-package.json5
│ └── src
│ │ └── main
│ │ ├── ets
│ │ ├── HomePage.ets
│ │ ├── cloudDb
│ │ │ └── LogReport.ets
│ │ ├── config
│ │ │ └── HomeCategoricalData.ets
│ │ ├── dialog
│ │ │ ├── CustomDialogContainer.ets
│ │ │ └── MyCustomDialog.ets
│ │ └── pages
│ │ │ ├── AttributeModifierExample.ets
│ │ │ ├── BuilderNodeExample.ets
│ │ │ ├── CloudDatabaseExample.ets
│ │ │ ├── CloudFuncExample.ets
│ │ │ ├── ComponentFactoryExample.ets
│ │ │ ├── CustomDialogExample.ets
│ │ │ ├── EventBusExample.ets
│ │ │ ├── FixFoldUiExample.ets
│ │ │ ├── HttpRequestExample.ets
│ │ │ ├── PermissionExample.ets
│ │ │ ├── RouterCallbackExample.ets
│ │ │ ├── TestNavPathJumpPage.ets
│ │ │ └── ThrottleExample.ets
│ │ ├── module.json5
│ │ └── resources
│ │ ├── base
│ │ └── element
│ │ │ ├── color.json
│ │ │ └── string.json
│ │ ├── en_US
│ │ └── element
│ │ │ └── string.json
│ │ └── zh_CN
│ │ └── element
│ │ └── string.json
└── feature_setting
│ ├── .gitignore
│ ├── BuildProfile.ets
│ ├── Index.ets
│ ├── build-profile.json5
│ ├── consumer-rules.txt
│ ├── hvigorfile.ts
│ ├── obfuscation-rules.txt
│ ├── oh-package-lock.json5
│ ├── oh-package.json5
│ └── src
│ └── main
│ ├── ets
│ ├── pages
│ │ ├── SettingPage.ets
│ │ └── TestDynamicNavPage.ets
│ ├── utils
│ │ └── LoginUtils.ets
│ └── widget
│ │ ├── AccountQuickLoginButton.ets
│ │ └── QuickVerifyPhoneButton.ets
│ ├── module.json5
│ └── resources
│ ├── base
│ └── element
│ │ └── string.json
│ ├── en_US
│ └── element
│ │ └── string.json
│ └── zh_CN
│ └── element
│ └── string.json
├── certificate
└── debug
│ ├── codeLab-Debug.cer
│ ├── codeLab-DebugDebug.p7b
│ ├── codeLab.csr
│ ├── code_lab.p12
│ ├── material
│ ├── ac
│ │ └── 98d170fbd9c64931ae1251a4ef7ad9b9
│ ├── ce
│ │ └── d02c2145e7a044529b5c2afc8c34e4b8
│ └── fd
│ │ ├── 0
│ │ └── 0bf6a1d2cc754daab6e81da1adc21ac4
│ │ ├── 1
│ │ └── 011c3f245f584ee38b45718d70fc6d72
│ │ └── 2
│ │ └── 7cf2883100094a19a63fea5ec47172ff
│ ├── rex_code_lab_debug.cer
│ ├── rex_code_lab_debug.csr
│ ├── rex_code_lab_debug.p12
│ └── rex_code_lab_debugDebug.p7b
├── entry
├── .gitignore
├── build-profile.json5
├── hvigorfile.ts
├── obfuscation-rules.txt
├── oh-package-lock.json5
├── oh-package.json5
└── src
│ └── main
│ ├── ets
│ ├── entryability
│ │ ├── EntryAbility.ets
│ │ └── FoldStatusObserver.ets
│ └── pages
│ │ └── MainPage.ets
│ ├── module.json5
│ └── resources
│ ├── base
│ ├── element
│ │ ├── color.json
│ │ └── string.json
│ ├── media
│ │ ├── ic_home_normal.png
│ │ ├── ic_home_select.png
│ │ ├── ic_mine_normal.png
│ │ ├── ic_mine_select.png
│ │ ├── labelIcon.png
│ │ └── startIcon.png
│ └── profile
│ │ └── main_pages.json
│ ├── rawfile
│ └── schema.json
│ └── zh_CN
│ └── element
│ └── string.json
├── features
└── feature_hsp_page
│ ├── .gitignore
│ ├── Index.ets
│ ├── build-profile.json5
│ ├── hvigorfile.ts
│ ├── obfuscation-rules.txt
│ ├── oh-package-lock.json5
│ ├── oh-package.json5
│ └── src
│ └── main
│ ├── ets
│ └── pages
│ │ ├── TestHspNavPathPage.ets
│ │ └── TestHspRoutePage.ets
│ ├── module.json5
│ └── resources
│ └── base
│ ├── element
│ ├── color.json
│ └── string.json
│ └── profile
│ ├── main_pages.json
│ └── route_map.json
├── hvigor
└── hvigor-config.json5
├── hvigorfile.ts
├── oh-package-lock.json5
├── oh-package.json5
└── screenshots
├── cloud_db_demo.png
├── cloud_func_demo.png
└── sh_1.png
/.gitignore:
--------------------------------------------------------------------------------
1 | /node_modules
2 | /oh_modules
3 | /local.properties
4 | /.idea
5 | **/build
6 | /.hvigor
7 | .cxx
8 | /.clangd
9 | /.clang-format
10 | /.clang-tidy
11 | **/.test
--------------------------------------------------------------------------------
/AppScope/app.json5:
--------------------------------------------------------------------------------
1 | {
2 | "app": {
3 | "bundleName": "com.atomicservice.5765880207855149405",
4 | "bundleType": "atomicService",
5 | "vendor": "example",
6 | "versionCode": 1000000,
7 | "versionName": "1.0.0",
8 | "icon": "$media:app_icon",
9 | "label": "$string:app_name"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/AppScope/resources/base/element/string.json:
--------------------------------------------------------------------------------
1 | {
2 | "string": [
3 | {
4 | "name": "app_name",
5 | "value": "HarmonyAtomicService"
6 | }
7 | ]
8 | }
9 |
--------------------------------------------------------------------------------
/AppScope/resources/base/media/app_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liyufengrex/HarmonyAtomicService/27d237fb097a7f92e7bead55c16abc65a0e42f88/AppScope/resources/base/media/app_icon.png
--------------------------------------------------------------------------------
/AppScope/resources/rawfile/agconnect-services.json:
--------------------------------------------------------------------------------
1 | {
2 | "agcgw":{
3 | "backurl":"connect-drcn.hispace.hicloud.com",
4 | "url":"connect-drcn.dbankcloud.cn",
5 | "websocketbackurl":"connect-ws-drcn.hispace.dbankcloud.com",
6 | "websocketurl":"connect-ws-drcn.hispace.dbankcloud.cn"
7 | },
8 | "agcgw_all":{
9 | "CN":"connect-drcn.dbankcloud.cn",
10 | "CN_back":"connect-drcn.hispace.hicloud.com",
11 | "DE":"connect-dre.dbankcloud.cn",
12 | "DE_back":"connect-dre.hispace.hicloud.com",
13 | "RU":"connect-drru.hispace.dbankcloud.ru",
14 | "RU_back":"connect-drru.hispace.dbankcloud.cn",
15 | "SG":"connect-dra.dbankcloud.cn",
16 | "SG_back":"connect-dra.hispace.hicloud.com"
17 | },
18 | "websocketgw_all":{
19 | "CN":"connect-ws-drcn.hispace.dbankcloud.cn",
20 | "CN_back":"connect-ws-drcn.hispace.dbankcloud.com",
21 | "DE":"connect-ws-dre.hispace.dbankcloud.cn",
22 | "DE_back":"connect-ws-dre.hispace.dbankcloud.com",
23 | "RU":"connect-ws-drru.hispace.dbankcloud.ru",
24 | "RU_back":"connect-ws-drru.hispace.dbankcloud.cn",
25 | "SG":"connect-ws-dra.hispace.dbankcloud.cn",
26 | "SG_back":"connect-ws-dra.hispace.dbankcloud.com"
27 | },
28 | "client":{
29 | "cp_id":"80086000309322325",
30 | "product_id":"388421841222390963",
31 | "client_id":"1487780195799663360",
32 | "client_secret":"[!00A7EA2F13A2C8A607EA96551329C20F0B5FAA4232FC6F4D2779547FEC3BAFE77A3FF364A036123A9CFE02662C6BB3DB6BC9566CF05BCACDE8E5440ECBD7660AD61F6D22B7D15778C690208B85A0723A6A020EB9A7CB89D670636D597E23230F97]",
33 | "project_id":"388421841222390963",
34 | "app_id":"111763805",
35 | "api_key":"[!00B0B168064C01754237F459E0319EEF4D7C9591A3D422A2A86A4534EC0F0CFEFD866E81E09037C510221011E69B682A15A4262CA1A399FFEC0BC515867599446088E0D3F250A7690CAF4A60EF3C8D87C8A3B8B0387FCC56B104252D485ADA1C8962C876693EA568DD77BF4AE7E87D711550629613092E92BAEE8EE663FB5D6E6C]",
36 | "package_name":"com.atomicservice.5765880207855149405"
37 | },
38 | "oauth_client":{
39 | "client_id":"111763805",
40 | "client_type":30
41 | },
42 | "app_info":{
43 | "app_id":"5765880207855149405",
44 | "package_name":"com.atomicservice.5765880207855149405"
45 | },
46 | "code":{
47 | "code1":"1D01A8E64ECEE62089AF7384AF84865D",
48 | "code2":"255224E32E231466019D3E61A510F41F",
49 | "code3":"27A0408730DF6FD4CDC58EACAC7DCF4D",
50 | "code4":"D891458E6E722B9130B7CD9420530701"
51 | },
52 | "service":{
53 | "analytics":{
54 | "collector_url":"datacollector-drcn.dt.hicloud.com,datacollector-drcn.dt.dbankcloud.cn",
55 | "collector_url_ru":"datacollector-drru.dt.dbankcloud.ru,datacollector-drru.dt.hicloud.com",
56 | "collector_url_sg":"datacollector-dra.dt.hicloud.com,datacollector-dra.dt.dbankcloud.cn",
57 | "collector_url_de":"datacollector-dre.dt.hicloud.com,datacollector-dre.dt.dbankcloud.cn",
58 | "collector_url_cn":"datacollector-drcn.dt.hicloud.com,datacollector-drcn.dt.dbankcloud.cn",
59 | "resource_id":"p1",
60 | "channel_id":""
61 | },
62 | "edukit":{
63 | "edu_url":"edukit.cloud.huawei.com.cn",
64 | "dh_url":"edukit.cloud.huawei.com.cn"
65 | },
66 | "search":{
67 | "url":"https://search-drcn.cloud.huawei.com"
68 | },
69 | "cloudstorage":{
70 | "storage_url_sg_back":"https://agc-storage-dra.cloud.huawei.asia",
71 | "storage_url_ru_back":"https://agc-storage-drru.cloud.huawei.ru",
72 | "storage_url_ru":"https://agc-storage-drru.cloud.huawei.ru",
73 | "storage_url_de_back":"https://agc-storage-dre.cloud.huawei.eu",
74 | "storage_url_de":"https://ops-dre.agcstorage.link",
75 | "storage_url":"https://agc-storage-drcn.platform.dbankcloud.cn",
76 | "storage_url_sg":"https://ops-dra.agcstorage.link",
77 | "storage_url_cn_back":"https://agc-storage-drcn.cloud.huawei.com.cn",
78 | "storage_url_cn":"https://agc-storage-drcn.platform.dbankcloud.cn"
79 | },
80 | "ml":{
81 | "mlservice_url":"ml-api-drcn.ai.dbankcloud.com,ml-api-drcn.ai.dbankcloud.cn"
82 | }
83 | },
84 | "region":"CN",
85 | "configuration_version":"3.0",
86 | "appInfos":[
87 | {
88 | "package_name":"com.atomicservice.5765880207855149405",
89 | "client":{
90 | "client_secret":"[!000F1F5B045C2BDCE2DA9EBBEA750C3826473994885B1FD08556AC2A11BC4791AB74D919D95E6AF94892A3B884460F354BB2E715D75F790824FD56FE9D6986DF1A9232C6CC2642A122371A8F31B523BAEAD5FF74761EA95FE6FE39CEBBEF561DC9]",
91 | "app_id":"5765880207855149405",
92 | "api_key":"[!0085E354C30D98A3788625B774D27296FB548D2F7F2B697FB2C003EEDACE530E859C55E44522BDFD9558407CF32459C8F62954EFF5FB0AFAF85DF6247E555591B1D328706C284ED8DE413B5681A540FCBB292DA1AE42437B3F8C06075FA7FA9E32CE3634A0596F1771CDD5075202B97A2A957229C89C31ECFD5B47F10411746902]"
93 | },
94 | "code":{
95 | "code1":"AFF26D1BC98CC684D7E0BB8A0DF91E5D0D40582C4F02A7B3AB3378F0C2C39A61",
96 | "code2":"C544698B71827FAE2513B7C95E9480BEA0748BCEDDC5BFF9E1D4017F318943AE",
97 | "code3":"3A2FDB99DAD35B6F7DC02AB9DA155AE4F00BCC48FF29BC475B489896D2FAF398",
98 | "code4":"5C777F269B2AACC7C3B48F91FDCEEE36"
99 | }
100 | }
101 | ]
102 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## HarmonyOS NEXT 元服务设计示例
2 |
3 | 基于 API11,开发的程序示例,适用于 NEXT 及以上版本运行。
4 |
5 | 项目包含如下:
6 |
7 | + 静态库+动态包+多模块设计
8 | + 状态管理
9 | + 统一路由管理(router+navPathStack)
10 | + 网络请求、Loading、Toast、数据持久化 等工具库封装
11 | + 自定义组件、自定义弹窗(解耦)
12 | + EventBus 事件通知
13 | + 扩展修饰器,实现 节流、防抖、权限申请
14 | + 动态路由 (navPathStack + 动态import + WrappedBuilder)
15 | + UI动态节点操作 (BuilderNode + NodeController)
16 | + 折叠屏适配示例
17 | + 组件工厂示例
18 | + 组件动态属性设置示例
19 | + 云函数、云数据库使用示例
20 | + 华为账号服务示例(快速登陆、快速验证手机号)
21 |
22 | 项目结构描述
23 |
24 | #### 基础库
25 |
26 | | 模块名称 | 描述 | 备注 |
27 | |---------------------|---------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
28 | | **fast_util** | 工具类 | FastLog(日志打印)
EventBus(消息通知)
FastRouter(基于Route封装的路由管理)
FastNavRouter(动态路由)
ThrottleTool (节流、防抖)
FastPermission (修饰器实现权限申请)
PreferencesUtil (数据持久化封装) |
29 | | **fast_ui** | 提供 UI 封装、样式、toast 等 | CommonText(统一文本)
CommonButton(统一按键)
FastToast
FastLoading |
30 | | **global_constant** | 记录全局常量配置 | PagePathConstants (路由路径管理) |
31 |
32 | #### 业务库
33 | | 模块名称 | 描述 | 备注 |
34 | |----------------------|------------|--|
35 | | **feature_home** | 主要存放代码示例 | 静态包(har) |
36 | | **feature_setting** | 存放华为账号服务示例 | 静态包(har) |
37 | | **feature_hsp_page** | 存放动态包交互示例 | 动态包(hsp/share) |
38 |
39 | #### 工程目录
40 | ```ts
41 | ├──entry // ets代码区
42 | │ └──src/main/ets
43 | │ ├──entryability
44 | │ │ ├──FoldStatusObserver.ets // 折叠屏幕变化监听
45 | │ │ └──EntryAbility.ets
46 | │ ├──pages
47 | │ │ └──MainPage.ets // 首页
48 | ├──business // 放置静态包的文件夹(业务模块)
49 | │ ├──feature_home // 放置首页Tab里的一些示例页面
50 | │ │ └──/src/main/ets/pages
51 | │ │ ├──HomePage.ets //首页的第一个Tab
52 | │ │ ├──BuilderNodeExample.ets //动态节点操作示例
53 | │ │ ├──CustomDialogExample.ets //自定义弹窗解耦
54 | │ │ ├──EventBusExample.ets //消息通知
55 | │ │ ├──HttpRequestExample.ets //网络请求示例
56 | │ │ ├──PermissionExample.ets //使用注解请求权限
57 | │ │ ├──RouterCallbackExample.ets //使用 NavPathStack 与 Route 两种方式实现页面跳转及回调(HSP、HAR)
58 | │ │ ├──FixFoldUiExample.ets //折叠屏适配示例
59 | │ │ ├──ComponentFactoryExample.ets //组件工厂示例
60 | │ │ ├──AttributeModifierExample.ets //组件动态属性设置示例
61 | │ │ ├──CloudFuncExample.ets //云函数调用示例
62 | │ │ ├──CloudDatabaseExample.ets //云数据库使用示例(增删改查)
63 | │ │ └──ThrottleExample.ets //使用注解防抖
64 | │ ├──feature_setting
65 | │ │ └──/src/main/ets
66 | │ │ ├──pages
67 | │ │ │ ├──SettingPages.ets //首页的第二个Tab(包含了华为账号服务示例)
68 | │ │ │ └──TestDynamicNavPage.ets //测试动态路由示例
69 | │ │ ├──widget
70 | │ │ │ ├──AccountQuickLoginButton.ets //华为账号快速登陆按钮
71 | │ │ │ └──QuickVerifyPhoneButton.ets //快速验证手机号按钮
72 | │ │ └──utils
73 | │ │ └──LoginUtils.ets //Account-Kit 获取 UnionID 能力封装
74 | ├──features //放置动态包的文件夹
75 | │ ├──feature_has_page
76 | │ │ └──/src/main/ets/pages
77 | │ │ ├──TestHspNavPathPage.ets //测试 NavPath 跳转 HSP 内页面
78 | │ │ └──TestHspRouterPage.ets //测试 Route 跳转 HSP 内页面
79 | ├──base
80 | │ ├──fast_ui //封装公共UI
81 | │ │ ├──/src/main/ets/compnents
82 | │ │ │ ├──FoldStatusContainer.ets // 折叠屏变化响应组件封装
83 | │ │ │ ├──FastLoading.ets // loading工具
84 | │ │ │ └──FastToast.ets // toast工具
85 | │ │ └──/src/main/ets/styles // 公共样式
86 | │ ├──fast_util // 通用工具
87 | │ │ ├──/src/main/ets
88 | │ │ ├──EventBus.ets // 消息通知+监听
89 | │ │ ├──FastLog.ets // 日志打印
90 | │ │ ├──FastNavRouter.ets // 用于动态路由
91 | │ │ ├──FastPermission.ets // 请求权限注解器
92 | │ │ ├──FastRouter.ets // 基于 router 库封装,为了实现页面回调
93 | │ │ ├──FastTool.ets
94 | │ │ ├──PreferencesUtil.ets // 数据持久化工具
95 | │ │ └──ThrottleTool.ets // 防抖注解器
96 | │ ├──global_constant
97 | │ │
98 | ├──entry/src/main/resources // 应用资源目录
99 | └──module.json5 // 添加卡片拓展能力
100 | ```
101 |
102 | 
103 |
104 |
105 | #### 让开发更简单,部分技巧总结
106 |
107 | + [网络库使用](https://juejin.cn/post/7347851786164437002)
108 | ```ts
109 | class GetRequest extends HttpRequest> {
110 | ...省略入参
111 | }
112 |
113 | // 发送请求
114 | let request = new GetRequest()
115 | request.excute().then((data)=>{
116 | // 这里获取的 data 类型为 CommonResponseModel
117 | })
118 | ```
119 | #### [路由如何选择和使用](https://juejin.cn/post/7369120920148213795)
120 | #### [自定义弹窗解耦](https://juejin.cn/post/7352100456334721034)
121 | #### [面相对象的 EventBus 封装](https://juejin.cn/post/7352075796712964122)
122 | #### [实现NFC碰一碰快捷唤起](https://juejin.cn/post/7469591708692332570)
123 | #### [扩展修饰器,实现节流、防抖、权限申请](https://juejin.cn/post/7373194499530244136)
124 | ```ts
125 | // 修饰器实现节流,示例如下,2秒内多次点击只会触发第一次
126 |
127 | @Throttle(2000)
128 | onClickTap(name: string) {
129 | // consolve.log(name)
130 | this.count++
131 | }
132 | ```
133 | ```ts
134 | // 修饰器实现权限申请,示例如下
135 |
136 | @Permission(
137 | getContext(this) as common.UIAbilityContext,
138 | ['ohos.permission.LOCATION', 'ohos.permission.APPROXIMATELY_LOCATION']
139 | )
140 | onClickTap(name: string) {
141 | // 授权成功后,才会进入方法内执行 count++
142 | this.count++
143 | }
144 | ```
145 | #### [动态路由]()
146 | ```ts
147 | // 示例请看 FastNavRouter,下面为关键代码
148 |
149 | // 路由管理
150 | static builderMap: Map> = new Map>();
151 |
152 | // 注册页面组件到路由表,builderName是路由名字,builder参数是包裹了页面组件的WrappedBuilder对象
153 | public static registerBuilder(
154 | builderName: string,
155 | builder: WrappedBuilder<[object]>
156 | ): void {
157 | builderMap.set(builderName, builder);
158 | }
159 |
160 | // 动态路由对应的页面
161 | @Builder
162 | export function TestDynamicNavPageBuilder(params: object) {}
163 |
164 | // 在页面首次加载时触发执行
165 | const builderName: string = '@ohos/feature_setting*./src/main/ets/TestDynamicNavPage';
166 |
167 | // 判断表中是否已存在路由信息,避免重复注册
168 | if (!FastNavRouter.getBuilder(builderName)) {
169 | // 通过系统提供的wrapBuilder接口封装@Builder装饰的方法
170 | let builder: WrappedBuilder<[object]> = wrapBuilder(TestDynamicNavPageBuilder);
171 | // 注册页面到全局路由表
172 | FastNavRouter.registerBuilder(builderName, builder);
173 | }
174 |
175 | // 跟页面路由管理中转
176 | @Builder
177 | PageMap(name: string, params?: RouterModel) {
178 | if (FastNavRouter.getBuilder(name) !== undefined) {
179 | // 测试动态路由 (TestDynamicNavPage)
180 | FastNavRouter.getBuilder(name).builder(params)
181 | }
182 | }
183 | ```
184 | #### [适配折叠屏](https://juejin.cn/post/7392252402496389172)
185 | #### [UI动态节点操作(NodeController)](https://juejin.cn/post/7379423024556064803)
186 | #### [组件工厂 + 动态组件(AttributeModifier)](https://juejin.cn/post/7399478677396881443)
187 | ```ts
188 | // 声明
189 | @Builder
190 | function UI1(text: string) {
191 | Text(text).fontColor(Color.Green)
192 | }
193 |
194 | @Builder
195 | function UI2(text: string) {
196 | Text(text).fontColor(Color.Blue)
197 | }
198 |
199 | let factoryMap: Map = new Map();
200 |
201 | factoryMap.set('UI1', wrapBuilder(UI1))
202 | factoryMap.set('UI2', wrapBuilder(UI2))
203 |
204 | // 使用
205 | (factoryMap.get('UI1') as WrappedBuilder<[string]>).builder('工厂组件 - 1');
206 | ```
207 | #### 云函数
208 | 文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/cloudfoundation-call-function-V5
209 | 云函数对应配置文件: AppScope/resources/rawfile/agconnect-services.json(在AGC对应项目中导出)
210 | ```ts
211 | // 云函数依赖
212 | "@hw-agconnect/api-ohos": "^1.1.2",
213 | "@hw-agconnect/core-ohos": "^1.1.2",
214 | "@hw-agconnect/function-ohos": "^1.1.2",
215 | "@hw-agconnect/credential-ohos": "^1.1.2",
216 | "@hw-agconnect/base-ohos": "^1.1.2"
217 |
218 | 关键代码:
219 | cloudFunction.call({
220 | name: "cloundfunction", //对应创建的云函数名称
221 | version: "$latest", //如果不传入版本号,默认为“$latest”。
222 | timeout: 10 * 1000, //单位为毫秒,默认为70*1000毫秒。
223 | data: {
224 | year: this.year,
225 | }
226 | }).then((value: cloudFunction.FunctionResult) => {
227 | // 返回结果
228 | }).catch((err: BusinessError) => {
229 | })
230 | ```
231 | 
232 | #### 云数据库
233 | 文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/cloudfoundation-database-initialize-V5
234 | 云数据库对应配置文件: entry/src/main/resources/rawfile/schema.json(AGC中选中云数据库,导出的对象类型模版)
235 | ```ts
236 | 关键代码:
237 | // CodeLabDemo 是AGC开发平台上创建的存储区名称
238 |
239 | let databaseZone = cloudDatabase.zone("CodeLabDemo");
240 | let log = new LogReport();
241 | log.id = new Date().getMilliseconds()
242 | log.content = this.logContent;
243 | log.time = this.getCurrentTime();
244 | await databaseZone.upsert(log);
245 | FastToast.shortToast(`写入成功`);
246 | ```
247 | 示例中数据库对象名称为`LogReport`,包含字段如下:
248 |
249 | | 字段 | 类型 | 备注 |
250 | |---------|--------|-------|
251 | | id | int | 主键 |
252 | | content | string | 上传的内容 |
253 | | time | string | 修改的时间 |
254 |
255 | 
256 | #### 华为账号服务(华为账号快速登陆)
257 |
258 | 文档: https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/account-quick-login-V5
259 | + 开发准备
260 | 1. [配置client ID](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/account-client-id-V5)
261 | 2. [配置权限](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/account-config-permissions-V5),需要配置敏感权限
262 |
263 |
264 | #### 持续更新中......
265 |
--------------------------------------------------------------------------------
/base/README.md:
--------------------------------------------------------------------------------
1 | ### 基础库
2 |
3 | | 模块名称 | 描述 | 备注 |
4 | |---------------------|---------------------|--------------------------------------------------------------------------|
5 | | **fast_util** | 工具类 | FastLog(日志打印)
EventBus(消息通知) |
6 | | **fast_ui** | 提供 UI 封装、样式、toast 等 | CommonText(统一文本)
CommonButton(统一按键)
FastToast
FastLoading |
7 | | **global_constant** | 记录全局常量配置 | PagePathConstants(路由路径管理) |
--------------------------------------------------------------------------------
/base/fast_ui/.gitignore:
--------------------------------------------------------------------------------
1 | /node_modules
2 | /oh_modules
3 | /.preview
4 | /build
5 | /.cxx
6 | /.test
--------------------------------------------------------------------------------
/base/fast_ui/BuildProfile.ets:
--------------------------------------------------------------------------------
1 | /**
2 | * Use these variables when you tailor your ArkTS code. They must be of the const type.
3 | */
4 | export const HAR_VERSION = '1.0.0';
5 | export const BUILD_MODE_NAME = 'debug';
6 | export const DEBUG = true;
7 | export const TARGET_NAME = 'default';
8 |
9 | /**
10 | * BuildProfile Class is used only for compatibility purposes.
11 | */
12 | export default class BuildProfile {
13 | static readonly HAR_VERSION = HAR_VERSION;
14 | static readonly BUILD_MODE_NAME = BUILD_MODE_NAME;
15 | static readonly DEBUG = DEBUG;
16 | static readonly TARGET_NAME = TARGET_NAME;
17 | }
--------------------------------------------------------------------------------
/base/fast_ui/Index.ets:
--------------------------------------------------------------------------------
1 | export { CommonMainTitle, CommonSubTitle } from './src/main/ets/styles/CommonTextStyle'
2 |
3 | export { CommonFillButton, CommonLineButton } from './src/main/ets/styles/CommonButtonStyle'
4 |
5 | export { FastLoading, FastLoadingDialog } from './src/main/ets/components/FastLoading'
6 |
7 | export { FastToast } from './src/main/ets/components/FastToast'
8 |
9 | export { FoldStatusContainer } from './src/main/ets/components/FoldStatusContainer'
--------------------------------------------------------------------------------
/base/fast_ui/build-profile.json5:
--------------------------------------------------------------------------------
1 | {
2 | "apiType": "stageMode",
3 | "buildOption": {
4 | },
5 | "buildOptionSet": [
6 | {
7 | "name": "release",
8 | "arkOptions": {
9 | "obfuscation": {
10 | "ruleOptions": {
11 | "enable": true,
12 | "files": [
13 | "./obfuscation-rules.txt"
14 | ]
15 | },
16 | "consumerFiles": [
17 | "./consumer-rules.txt"
18 | ]
19 | }
20 | },
21 | },
22 | ],
23 | "targets": [
24 | {
25 | "name": "default"
26 | }
27 | ]
28 | }
29 |
--------------------------------------------------------------------------------
/base/fast_ui/consumer-rules.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liyufengrex/HarmonyAtomicService/27d237fb097a7f92e7bead55c16abc65a0e42f88/base/fast_ui/consumer-rules.txt
--------------------------------------------------------------------------------
/base/fast_ui/hvigorfile.ts:
--------------------------------------------------------------------------------
1 | import { harTasks } from '@ohos/hvigor-ohos-plugin';
2 |
3 | export default {
4 | system: harTasks, /* Built-in plugin of Hvigor. It cannot be modified. */
5 | plugins:[] /* Custom plugin to extend the functionality of Hvigor. */
6 | }
7 |
--------------------------------------------------------------------------------
/base/fast_ui/obfuscation-rules.txt:
--------------------------------------------------------------------------------
1 | # Define project specific obfuscation rules here.
2 | # You can include the obfuscation configuration files in the current module's build-profile.json5.
3 | #
4 | # For more details, see
5 | # https://gitee.com/openharmony/arkcompiler_ets_frontend/blob/master/arkguard/README.md
6 |
7 | # Obfuscation options:
8 | # -disable-obfuscation: disable all obfuscations
9 | # -enable-property-obfuscation: obfuscate the property names
10 | # -enable-toplevel-obfuscation: obfuscate the names in the global scope
11 | # -compact: remove unnecessary blank spaces and all line feeds
12 | # -remove-log: remove all console.* statements
13 | # -print-namecache: print the name cache that contains the mapping from the old names to new names
14 | # -apply-namecache: reuse the given cache file
15 |
16 | # Keep options:
17 | # -keep-property-name: specifies property names that you want to keep
18 | # -keep-global-name: specifies names that you want to keep in the global scope
--------------------------------------------------------------------------------
/base/fast_ui/oh-package.json5:
--------------------------------------------------------------------------------
1 | {
2 | "name": "fast_ui",
3 | "version": "1.0.0",
4 | "description": "Please describe the basic information.",
5 | "main": "Index.ets",
6 | "author": "",
7 | "license": "Apache-2.0",
8 | "dependencies": {}
9 | }
10 |
--------------------------------------------------------------------------------
/base/fast_ui/src/main/ets/components/FastLoading.ets:
--------------------------------------------------------------------------------
1 | @Extend(Column)
2 | function cardStyle() {
3 | .backgroundColor(0xB3000000)
4 | .alignItems(HorizontalAlign.Center)
5 | .justifyContent(FlexAlign.Center)
6 | .padding(10)
7 | .borderRadius(14)
8 | .shadow({
9 | radius: 14,
10 | type: ShadowType.BLUR,
11 | })
12 | }
13 |
14 | @Extend(Text)
15 | function messageStyle(
16 | fontSize: number | Resource | string,
17 | fontWeight: number | FontWeight | string
18 | ) {
19 | .fontSize(fontSize)
20 | .fontWeight(fontWeight)
21 | }
22 |
23 | @Component
24 | export struct FastLoading {
25 | loadingSize: Length = '40vp'
26 | messageFontSize: number | Resource | string = '16fp'
27 | messageFontWeight: number | FontWeight | string = FontWeight.Medium
28 | message: string | Resource | null = $r('app.string.loading')
29 |
30 | build() {
31 | Row({ space: 3 }) {
32 | Text(this.message)
33 | .messageStyle(
34 | this.messageFontSize,
35 | this.messageFontWeight
36 | )
37 | .visibility(this.message != null ? Visibility.Visible : Visibility.None)
38 | LoadingProgress()
39 | .width(this.loadingSize)
40 | .height(this.loadingSize)
41 | .color($r('app.color.secondary'))
42 | }
43 | .padding('10vp')
44 | .justifyContent(FlexAlign.Center)
45 | }
46 | }
47 |
48 | @CustomDialog
49 | export struct FastLoadingDialog {
50 | private controller: CustomDialogController;
51 |
52 | build() {
53 | Column() {
54 | FastLoading()
55 | }.cardStyle()
56 | }
57 | }
58 |
59 | // dialog 的形式样式loading
60 | // let LoadingDialog = new CustomDialogController(
61 | // {
62 | // builder: FastLoadingDialog(),
63 | // alignment: DialogAlignment.Center,
64 | // customStyle: true,
65 | // maskColor: Color.Transparent,
66 | // }
67 | // )
68 | // loadingDialog.open()
--------------------------------------------------------------------------------
/base/fast_ui/src/main/ets/components/FastToast.ets:
--------------------------------------------------------------------------------
1 | import { promptAction } from '@kit.ArkUI';
2 |
3 | export class FastToast {
4 | static showToast(message: ResourceStr | string, duration: number) {
5 | promptAction.showToast({ message: message, duration: duration });
6 | }
7 |
8 | static shortToast(message: ResourceStr | string) {
9 | FastToast.showToast(message, 1000);
10 | }
11 |
12 | static longToast(message: ResourceStr | string) {
13 | FastToast.showToast(message, 3000);
14 | }
15 | }
--------------------------------------------------------------------------------
/base/fast_ui/src/main/ets/components/FoldStatusContainer.ets:
--------------------------------------------------------------------------------
1 | /// 响应折叠屏变化的父容器
2 |
3 | @Component
4 | export struct FoldStatusContainer {
5 | @StorageProp('foldStatusKey') isFold: boolean = false
6 | // 非折叠状态 UI 布局
7 | @BuilderParam unFoldBodyContainer: () => void = this.defaultContainer
8 | // 折叠状态 UI 布局
9 | @BuilderParam foldBodyContainer: () => void = this.defaultContainer
10 |
11 | @Builder
12 | defaultContainer() {
13 | Column()
14 | }
15 |
16 | build() {
17 | Stack() {
18 | if (this.isFold) {
19 | this.foldBodyContainer()
20 | } else {
21 | this.unFoldBodyContainer()
22 | }
23 | }
24 | .width('100%')
25 | .height('100%')
26 | }
27 | }
--------------------------------------------------------------------------------
/base/fast_ui/src/main/ets/styles/CommonButtonStyle.ets:
--------------------------------------------------------------------------------
1 | /// 统一的按钮样式
2 | interface CommonButtonOption {
3 | backGroundColor?: Resource;
4 | borderColor?: Resource;
5 | fontColor?: Resource;
6 | fontSize?: number | Resource;
7 | fontWeight?: number | FontWeight;
8 | horizontalPadding?: number | Resource | string;
9 | verticalPadding?: number | Resource | string;
10 | marginLeft?: number | Resource | string;
11 | marginTop?: number | Resource | string;
12 | marginRight?: number | Resource | string;
13 | marginBottom?: number | Resource | string;
14 | borderRadius?: number | Resource | string;
15 | text: string | Resource;
16 | event: () => void;
17 | }
18 |
19 | // 颜色填充的样式按钮
20 | @Builder
21 | function CommonFillButton(
22 | option: CommonButtonOption
23 | ) {
24 | Text(option.text)
25 | .fontSize(option.fontSize ?? $r('app.float.font_default'))
26 | .fontWeight(option.fontWeight ?? FontWeight.Normal)
27 | .fontColor(option.fontColor ?? $r('app.color.primary'))
28 | .backgroundColor(option.backGroundColor ?? $r('app.color.secondary'))
29 | .padding({
30 | left: option.horizontalPadding ?? '11vp',
31 | top: option.verticalPadding ?? '6vp',
32 | right: option.horizontalPadding ?? '11vp',
33 | bottom: option.verticalPadding ?? '6vp',
34 | })
35 | .margin(
36 | {
37 | left: option.marginLeft,
38 | top: option.marginTop,
39 | right: option.marginRight,
40 | bottom: option.marginBottom,
41 | }
42 | )
43 | .borderRadius(option.borderRadius ?? '5vp')
44 | .onClick(option.event)
45 | }
46 |
47 | // 边框线样式的按钮
48 | @Builder
49 | function CommonLineButton(
50 | option: CommonButtonOption
51 | ) {
52 | Text(option.text)
53 | .fontColor(option.fontColor ?? $r('app.color.text_button_2'))
54 | .fontWeight(option.fontWeight ?? FontWeight.Normal)
55 | .fontSize(option.fontSize ?? $r('app.float.font_default'))
56 | .backgroundColor(option.backGroundColor ?? $r('app.color.primary'))
57 | .borderColor(option.borderColor ?? $r('app.color.border_color'))
58 | .borderWidth(1)
59 | .padding({
60 | left: option.horizontalPadding ?? '11vp',
61 | top: option.verticalPadding ?? '6vp',
62 | right: option.horizontalPadding ?? '11vp',
63 | bottom: option.verticalPadding ?? '6vp',
64 | })
65 | .borderRadius(option.borderRadius ?? '5vp')
66 | .onClick(option.event)
67 | }
68 |
69 | @Builder
70 | function FillFlexButton(
71 | option: CommonButtonOption
72 | ) {
73 | Text(option.text)
74 | .textAlign(TextAlign.Center)
75 | .fontSize(option.fontSize ?? $r('app.float.font_default'))
76 | .fontWeight(option.fontWeight ?? FontWeight.Normal)
77 | .fontColor(option.fontColor ?? $r('app.color.primary'))
78 | .backgroundColor(option.backGroundColor ?? $r('app.color.secondary'))
79 | .padding({
80 | top: option.verticalPadding ?? '6vp',
81 | bottom: option.verticalPadding ?? '6vp',
82 | })
83 | .margin(
84 | {
85 | left: option.marginLeft,
86 | top: option.marginTop,
87 | right: option.marginRight,
88 | bottom: option.marginBottom,
89 | }
90 | )
91 | .borderRadius(option.borderRadius ?? '24vp')
92 | .width('100%')
93 | .layoutWeight(1)
94 | .onClick(option.event)
95 | }
96 |
97 | export { CommonFillButton, CommonLineButton, FillFlexButton }
98 |
99 |
100 | /// 使用方式预览
101 | @Entry
102 | @Component
103 | struct PreviewTest {
104 | build() {
105 | Column({ space: 20 }) {
106 | CommonFillButton({
107 | text: "abc",
108 | event: () => {
109 |
110 | }
111 | })
112 | CommonLineButton({
113 | text: "abc",
114 | event: () => {
115 |
116 | }
117 | })
118 | }
119 | .width('100%')
120 | .height('100%')
121 | .alignItems(HorizontalAlign.Center)
122 | .justifyContent(FlexAlign.Center)
123 | }
124 | }
125 |
126 |
--------------------------------------------------------------------------------
/base/fast_ui/src/main/ets/styles/CommonTextStyle.ets:
--------------------------------------------------------------------------------
1 | /// 统一样式的 Text
2 |
3 | interface CommonTextOption {
4 | fontColor?: string | Resource;
5 | fontSize?: number | Resource | string;
6 | fontWeight?: number | FontWeight;
7 | lineHeight?: number | string | Resource;
8 | textAlign?: TextAlign
9 | overflow?: TextOverflow
10 | maxLines?: number
11 | text: string | Resource;
12 | }
13 |
14 | @Builder
15 | function CommonMainTitle(
16 | option: CommonTextOption
17 | ) {
18 | Text(option.text)
19 | .fontSize(option.fontSize ?? $r('app.float.font_title'))
20 | .fontColor(option.fontColor ?? $r('app.color.text_main'))
21 | .fontWeight(option.fontWeight ?? FontWeight.Medium)
22 | .lineHeight(option.lineHeight)
23 | .textAlign(option.textAlign)
24 | .maxLines(option.maxLines)
25 | .textOverflow({ overflow: option.overflow ?? TextOverflow.None })
26 | }
27 |
28 | @Builder
29 | function CommonSubTitle(
30 | option: CommonTextOption
31 | ) {
32 | Text(option.text)
33 | .fontSize(option.fontSize ?? $r('app.float.font_sub_title'))
34 | .fontColor(option.fontColor ?? $r('app.color.text_sub'))
35 | .fontWeight(option.fontWeight ?? FontWeight.Normal)
36 | .lineHeight(option.lineHeight)
37 | .textAlign(option.textAlign)
38 | .maxLines(option.maxLines)
39 | .textOverflow({ overflow: option.overflow ?? TextOverflow.None })
40 | }
41 |
42 | export { CommonMainTitle, CommonSubTitle }
43 |
44 | /// 使用方式预览
45 | @Entry
46 | @Component
47 | struct PreviewTest {
48 | build() {
49 | Column({ space: 20 }) {
50 | CommonMainTitle({
51 | text: 'MainTitle',
52 | })
53 | CommonSubTitle({
54 | text: 'SubTitle'
55 | })
56 | }
57 | .width('100%')
58 | .height('100%')
59 | .alignItems(HorizontalAlign.Center)
60 | .justifyContent(FlexAlign.Center)
61 | }
62 | }
--------------------------------------------------------------------------------
/base/fast_ui/src/main/module.json5:
--------------------------------------------------------------------------------
1 | {
2 | "module": {
3 | "name": "fast_ui",
4 | "type": "har",
5 | "deviceTypes": [
6 | "default",
7 | "tablet"
8 | ]
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/base/fast_ui/src/main/resources/base/element/color.json:
--------------------------------------------------------------------------------
1 | {
2 | "color": [
3 | {
4 | "name": "primary",
5 | "value": "#F3F4F5"
6 | },
7 | {
8 | "name": "secondary",
9 | "value": "#698D04"
10 | },
11 | {
12 | "name": "disabled",
13 | "value": "#C4C4C4"
14 | },
15 | {
16 | "name": "text_main",
17 | "value": "#242524"
18 | },
19 | {
20 | "name": "text_sub",
21 | "value": "#6F7275"
22 | },
23 | {
24 | "name": "text_button_2",
25 | "value": "#FFA0A4A7"
26 | },
27 | {
28 | "name": "text_desc",
29 | "value": "#86888B"
30 | },
31 | {
32 | "name": "divider",
33 | "value": "#FFE2E5E7"
34 | },
35 | {
36 | "name": "border_color",
37 | "value": "#FFA0A4A7"
38 | }
39 | ]
40 | }
--------------------------------------------------------------------------------
/base/fast_ui/src/main/resources/base/element/float.json:
--------------------------------------------------------------------------------
1 | {
2 | "float": [
3 | {
4 | "name": "font_nav_title",
5 | "value": "17fp"
6 | },
7 | {
8 | "name": "font_title",
9 | "value": "15fp"
10 | },
11 | {
12 | "name": "font_sub_title",
13 | "value": "11fp"
14 | },
15 | {
16 | "name": "font_default",
17 | "value": "14fp"
18 | },
19 | {
20 | "name": "font_small",
21 | "value": "12fp"
22 | },
23 | {
24 | "name": "font_smaller",
25 | "value": "10fp"
26 | },
27 | {
28 | "name": "button_default_height",
29 | "value": "40vp"
30 | },
31 | {
32 | "name": "button_default_radius",
33 | "value": "20vp"
34 | },
35 | {
36 | "name": "padding_default",
37 | "value": "15vp"
38 | }
39 | ]
40 | }
--------------------------------------------------------------------------------
/base/fast_ui/src/main/resources/base/element/string.json:
--------------------------------------------------------------------------------
1 | {
2 | "string": [
3 | {
4 | "name": "module_desc",
5 | "value": "基础UI库"
6 | },
7 | {
8 | "name": "loading",
9 | "value": "加载中..."
10 | }
11 | ]
12 | }
13 |
--------------------------------------------------------------------------------
/base/fast_ui/src/main/resources/en_US/element/string.json:
--------------------------------------------------------------------------------
1 | {
2 | "string": [
3 | {
4 | "name": "page_show",
5 | "value": "page from package"
6 | }
7 | ]
8 | }
9 |
--------------------------------------------------------------------------------
/base/fast_ui/src/main/resources/zh_CN/element/string.json:
--------------------------------------------------------------------------------
1 | {
2 | "string": [
3 | {
4 | "name": "page_show",
5 | "value": "page from package"
6 | }
7 | ]
8 | }
9 |
--------------------------------------------------------------------------------
/base/fast_util/.gitignore:
--------------------------------------------------------------------------------
1 | /node_modules
2 | /oh_modules
3 | /.preview
4 | /build
5 | /.cxx
6 | /.test
--------------------------------------------------------------------------------
/base/fast_util/BuildProfile.ets:
--------------------------------------------------------------------------------
1 | /**
2 | * Use these variables when you tailor your ArkTS code. They must be of the const type.
3 | */
4 | export const HAR_VERSION = '1.0.0';
5 | export const BUILD_MODE_NAME = 'debug';
6 | export const DEBUG = true;
7 | export const TARGET_NAME = 'default';
8 |
9 | /**
10 | * BuildProfile Class is used only for compatibility purposes.
11 | */
12 | export default class BuildProfile {
13 | static readonly HAR_VERSION = HAR_VERSION;
14 | static readonly BUILD_MODE_NAME = BUILD_MODE_NAME;
15 | static readonly DEBUG = DEBUG;
16 | static readonly TARGET_NAME = TARGET_NAME;
17 | }
--------------------------------------------------------------------------------
/base/fast_util/Index.ets:
--------------------------------------------------------------------------------
1 | export { EventBus } from './src/main/ets/EventBus'
2 |
3 | export { FastLog } from './src/main/ets/FastLog'
4 |
5 | export { FastRouter, RouterModel } from './src/main/ets/FastRouter'
6 |
7 | export { Throttle, Debounce } from './src/main/ets/ThrottleTool'
8 |
9 | export { Permission } from './src/main/ets/FastPermisttion'
10 |
11 | export { FastNavRouter, FastNavRouterModel } from './src/main/ets/FastNavRouter'
12 |
13 | export { PreferencesUtil } from './src/main/ets/PreferencesUtil'
14 |
15 | export { ObjectUtil } from './src/main/ets/ObjectUtil'
--------------------------------------------------------------------------------
/base/fast_util/build-profile.json5:
--------------------------------------------------------------------------------
1 | {
2 | "apiType": "stageMode",
3 | "buildOption": {
4 | },
5 | "buildOptionSet": [
6 | {
7 | "name": "release",
8 | "arkOptions": {
9 | "obfuscation": {
10 | "ruleOptions": {
11 | "enable": true,
12 | "files": [
13 | "./obfuscation-rules.txt"
14 | ]
15 | },
16 | "consumerFiles": [
17 | "./consumer-rules.txt"
18 | ]
19 | }
20 | },
21 | },
22 | ],
23 | "targets": [
24 | {
25 | "name": "default"
26 | }
27 | ]
28 | }
29 |
--------------------------------------------------------------------------------
/base/fast_util/consumer-rules.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liyufengrex/HarmonyAtomicService/27d237fb097a7f92e7bead55c16abc65a0e42f88/base/fast_util/consumer-rules.txt
--------------------------------------------------------------------------------
/base/fast_util/hvigorfile.ts:
--------------------------------------------------------------------------------
1 | import { harTasks } from '@ohos/hvigor-ohos-plugin';
2 |
3 | export default {
4 | system: harTasks, /* Built-in plugin of Hvigor. It cannot be modified. */
5 | plugins:[] /* Custom plugin to extend the functionality of Hvigor. */
6 | }
7 |
--------------------------------------------------------------------------------
/base/fast_util/obfuscation-rules.txt:
--------------------------------------------------------------------------------
1 | # Define project specific obfuscation rules here.
2 | # You can include the obfuscation configuration files in the current module's build-profile.json5.
3 | #
4 | # For more details, see
5 | # https://gitee.com/openharmony/arkcompiler_ets_frontend/blob/master/arkguard/README.md
6 |
7 | # Obfuscation options:
8 | # -disable-obfuscation: disable all obfuscations
9 | # -enable-property-obfuscation: obfuscate the property names
10 | # -enable-toplevel-obfuscation: obfuscate the names in the global scope
11 | # -compact: remove unnecessary blank spaces and all line feeds
12 | # -remove-log: remove all console.* statements
13 | # -print-namecache: print the name cache that contains the mapping from the old names to new names
14 | # -apply-namecache: reuse the given cache file
15 |
16 | # Keep options:
17 | # -keep-property-name: specifies property names that you want to keep
18 | # -keep-global-name: specifies names that you want to keep in the global scope
--------------------------------------------------------------------------------
/base/fast_util/oh-package.json5:
--------------------------------------------------------------------------------
1 | {
2 | "name": "fast_util",
3 | "version": "1.0.0",
4 | "description": "Please describe the basic information.",
5 | "main": "Index.ets",
6 | "author": "",
7 | "license": "Apache-2.0",
8 | "dependencies": {}
9 | }
10 |
--------------------------------------------------------------------------------
/base/fast_util/src/main/ets/EventBus.ets:
--------------------------------------------------------------------------------
1 | import { emitter } from '@kit.BasicServicesKit';
2 |
3 | /// 事件通知工具类
4 | export abstract class EventBus {
5 | static send(
6 | eventID: string,
7 | eventData?: Object | Record | null,
8 | ) {
9 | let data: string | undefined
10 | if (eventData !== null && eventData !== undefined) {
11 | if (typeof eventData === 'string') {
12 | data = eventData
13 | } else {
14 | data = JSON.stringify(eventData)
15 | }
16 | }
17 |
18 | emitter.emit(
19 | eventID,
20 | {
21 | priority: emitter.EventPriority.HIGH
22 | },
23 | {
24 | data: {
25 | 'data': data
26 | }
27 | },
28 | );
29 | }
30 |
31 | static listen(
32 | eventID: string,
33 | callback: (data?: T) => void,
34 | ) {
35 | emitter.on(
36 | eventID,
37 | (eventData: emitter.EventData) => {
38 | let data: string | undefined = eventData.data!['data']
39 | if (data == undefined) {
40 | callback(undefined)
41 | } else {
42 | if (data.startsWith("{") && data.endsWith("}")) {
43 | callback(JSON.parse(data) as T)
44 | } else {
45 | callback(data as T)
46 | }
47 | }
48 | },
49 | );
50 | }
51 |
52 | static cancel(eventID: string) {
53 | emitter.off(eventID);
54 | }
55 | }
--------------------------------------------------------------------------------
/base/fast_util/src/main/ets/FastLog.ts:
--------------------------------------------------------------------------------
1 | class FastLogOptions {
2 | tag?: string
3 | domain?: number
4 | close?: boolean
5 | isHilog?: boolean
6 | showLogLocation?: boolean
7 | logSize?: number
8 | }
9 |
10 | import hilog from '@ohos.hilog'
11 |
12 |
13 | class FastLog {
14 | private static mTag: string = "FastLog"
15 | private static mDomain: number = 0x0000
16 | private static mClose: boolean = false
17 | private static mHilog: boolean = true //默认是用hilog进行打印
18 | private static mShowLogLocation: boolean = true //展示点击的位置
19 | private static mLogSize = 800 //打印的最大长度,默认是800
20 |
21 | /*
22 | * 日志输出级别
23 | * */
24 | static setDomain(domain: number) {
25 | FastLog.mDomain = domain
26 | }
27 |
28 | /*
29 | * 初始化tag、domain等属性
30 | * */
31 | static init(object: FastLogOptions) {
32 | const tag: string = object.tag //日志输出Tag
33 | const domain: number = object.domain //日志输出级别
34 | const close: boolean = object.close //是否关闭日志
35 | const isHilog: boolean = object.isHilog //是否是hilog打印
36 | const showLogLocation: boolean = object.showLogLocation //是否展示日志位置
37 | const logSize: number = object.logSize //日志输出大小
38 | if (tag != undefined) {
39 | this.mTag = tag
40 | }
41 | if (domain != undefined) {
42 | this.mDomain = domain
43 | }
44 | if (close != undefined) {
45 | this.mClose = close
46 | }
47 | if (isHilog != undefined) {
48 | this.mHilog = isHilog
49 | }
50 | if (showLogLocation != undefined) {
51 | this.mShowLogLocation = showLogLocation
52 | }
53 | if (logSize != undefined) {
54 | this.mLogSize = logSize
55 | }
56 |
57 | }
58 |
59 | //需要先调用isLoggable确认某个domain、tag和日志级别是否被禁止打印日志
60 | static isLoggable(level: hilog.LogLevel): boolean {
61 | return hilog.isLoggable(this.mDomain, this.mTag, level)
62 | }
63 |
64 | /*
65 | * console形式打印log日志,只支持console
66 | * */
67 | static log(message: any, tag?: string) {
68 | console.log(this.getMessage(hilog.LogLevel.INFO, tag == undefined ? this.mTag : tag, message))
69 | }
70 |
71 | /*
72 | * info日志
73 | * */
74 | static info(message: any, tag?: string) {
75 | this.logLevel(hilog.LogLevel.INFO, tag, message)
76 | }
77 |
78 | /*
79 | * debug日志
80 | * */
81 | static debug(message: any, tag?: string) {
82 | this.logLevel(hilog.LogLevel.DEBUG, tag, message)
83 | }
84 |
85 |
86 | /*
87 | * error日志,不带标签
88 | * */
89 | static error(message: any, tag?: string) {
90 | this.logLevel(hilog.LogLevel.ERROR, tag, message)
91 | }
92 |
93 |
94 | /*
95 | * warn日志
96 | * */
97 | static warn(message: any, tag?: string) {
98 | this.logLevel(hilog.LogLevel.WARN, tag, message)
99 | }
100 |
101 | /*
102 | * fatal日志
103 | * */
104 | static fatal(message: any, tag?: string) {
105 | this.logLevel(hilog.LogLevel.FATAL, tag, message)
106 | }
107 |
108 | /*
109 | *统一输出日志
110 | * */
111 | private static logLevel(level: hilog.LogLevel, tag: string, message: any) {
112 | //如果关闭状态,则不打印日志
113 | if (this.mClose) {
114 | return
115 | }
116 |
117 | //未传递时
118 | if (tag == undefined) {
119 | tag = this.mTag
120 | }
121 |
122 | const content = this.getMessage(level, tag, message) //最终的内容展示
123 |
124 | const len = content.length / this.mLogSize
125 | for (var i = 0; i < len; i++) {
126 | var con = content.substring(i * this.mLogSize, (i + 1) * this.mLogSize)
127 | if (i != 0) {
128 | con = "|" + con
129 | }
130 | //打印日志
131 | if (this.mHilog) {
132 | //使用hilog
133 | switch (level) {
134 | case hilog.LogLevel.INFO: //info
135 | hilog.info(this.mDomain, tag, con)
136 | break
137 | case hilog.LogLevel.WARN: //WARN
138 | hilog.warn(this.mDomain, tag, con)
139 | break
140 | case hilog.LogLevel.DEBUG: //DEBUG
141 | hilog.debug(this.mDomain, tag, con)
142 | break
143 | case hilog.LogLevel.ERROR: //ERROR
144 | hilog.error(this.mDomain, tag, con)
145 | break
146 | case hilog.LogLevel.FATAL: //FATAL
147 | hilog.fatal(this.mDomain, tag, con)
148 | break
149 | }
150 | } else {
151 | //使用console
152 | switch (level) {
153 | case hilog.LogLevel.INFO: //info
154 | console.info(con)
155 | break
156 | case hilog.LogLevel.WARN: //WARN
157 | console.warn(con)
158 | break
159 | case hilog.LogLevel.DEBUG: //DEBUG
160 | console.debug(con)
161 | break
162 | case hilog.LogLevel.ERROR: //ERROR
163 | console.error(con)
164 | break
165 | case hilog.LogLevel.FATAL: //FATAL
166 | console.log(con)
167 | break
168 | }
169 | }
170 |
171 | }
172 |
173 | }
174 |
175 | /**
176 | * 获取输出位置
177 | * */
178 | static getMessage(level: hilog.LogLevel, tag: string, message: any): string {
179 | var log = "┌───────" + tag + "────────────────────────────────────────────────────────────────────────────────"
180 | log = log.substring(0, log.length - tag.length) + "\n"
181 |
182 | try {
183 | if (this.mShowLogLocation && level == hilog.LogLevel.ERROR) {
184 | //展示位置
185 | const stackTrace = new Error().stack
186 | const traceArray = stackTrace.split('\n')
187 | const trace = traceArray[traceArray.length-2]
188 | log = log + "|" + trace
189 | }
190 |
191 | var type = typeof message
192 | if (type == "object") {
193 | message = this.getObjectToJson(message)
194 | } else if (type == "string") {
195 | //判断是否包含大括号
196 | const content = message + ""
197 | if (content.startsWith("{") && content.endsWith("}")) {
198 | //对象
199 | const obj = JSON.parse(message)
200 | message = this.getObjectToJson(obj)
201 | } else {
202 | message = content
203 | }
204 | }
205 | log = log + "\n| " + message
206 | } catch (e) {
207 |
208 | }
209 | log = log + "\n└───────────────────────────────────────────────────────────────────────────────────────"
210 | return log
211 | }
212 |
213 | private static getObjectToJson(message: object): String {
214 | const json = JSON.stringify(message, null, 2)
215 | const endMessage = json.replace(/\n/g, "\n| ")
216 | return endMessage
217 | }
218 | }
219 |
220 | export { FastLogOptions, FastLog }
--------------------------------------------------------------------------------
/base/fast_util/src/main/ets/FastNavRouter.ets:
--------------------------------------------------------------------------------
1 | export class FastNavRouterModel {
2 | // 路由页面别名,形式为${包名}*${页面名},例如:@ohos/feature_setting*./src/main/ets/TestDynamicNavPage
3 | builderName: string = "";
4 | // 传递的参数
5 | param?: object;
6 | }
7 |
8 | export class FastNavRouter {
9 | static builderMap: Map> = new Map>();
10 | static navPathStack: NavPathStack = new NavPathStack();
11 |
12 | // 注册页面组件到路由表,builderName是路由名字,builder参数是包裹了页面组件的WrappedBuilder对象
13 | public static registerBuilder(
14 | builderName: string,
15 | builder: WrappedBuilder<[object]>
16 | ): void {
17 | FastNavRouter.builderMap.set(builderName, builder);
18 | }
19 |
20 | // 获取路由表中指定的页面组件
21 | public static getBuilder(builderName: string): WrappedBuilder<[object]> {
22 | const builder = FastNavRouter.builderMap.get(builderName);
23 | if (!builder) {
24 | console.info('not found builder ' + builderName);
25 | }
26 | return builder as WrappedBuilder<[object]>;
27 | }
28 |
29 | public static async push(router: FastNavRouterModel): Promise {
30 | const harName = router.builderName.split('*')[0];
31 | if (harName !== undefined) {
32 | // 动态导入页面所在 har 模块
33 | let ns: ESObject = await import(harName);
34 | await ns.harInit(router.builderName);
35 | } else {
36 | // 例如自己模块内的单文件 '../Calc'
37 | await import(router.builderName);
38 | }
39 | FastNavRouter.navPathStack.pushPath({
40 | name: router.builderName,
41 | param: router.param
42 | });
43 | }
44 | }
--------------------------------------------------------------------------------
/base/fast_util/src/main/ets/FastPermisttion.ts:
--------------------------------------------------------------------------------
1 | // 定义装饰器函数
2 | import abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl';
3 | import bundleManager from '@ohos.bundle.bundleManager';
4 | import { common } from '@kit.AbilityKit';
5 |
6 | export function Permission(context: common.UIAbilityContext, permissions: Permissions[]) {
7 | return function (
8 | target: any,
9 | propertyKey: string,
10 | descriptor: PropertyDescriptor
11 | ) {
12 | const originalMethod = descriptor.value;
13 | descriptor.value = function (...args: any[]) {
14 | checkPermission(permissions)
15 | .then((grantStatusList: abilityAccessCtrl.GrantStatus[]) => {
16 | console.log('权限校验结果:', grantStatusList)
17 | const allPermissionsGranted =
18 | grantStatusList.every(status => status === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED)
19 | if (allPermissionsGranted) {
20 | return originalMethod.apply(this, args)
21 | }
22 | // 如果没有权限,请求权限
23 | requestPermission(permissions, context)
24 | .then(() => {
25 | // 获取权限成功后重新调用方法
26 | return originalMethod.apply(this, args)
27 | })
28 | .catch(() => {
29 | // 获取权限失败,执行用户注入的处理函数或默认处理逻辑
30 | const errorHandler = target.permissionErrorHandler || defaultPermissionErrorHandler
31 | errorHandler()
32 | })
33 | })
34 | .catch((error) => {
35 | const errorHandler = target.permissionErrorHandler || defaultPermissionErrorHandler
36 | errorHandler()
37 | })
38 | }
39 | return descriptor
40 | }
41 | }
42 |
43 | // 默认权限处理失败的逻辑
44 | function defaultPermissionErrorHandler() {
45 | console.log('没有权限执行该方法')
46 | }
47 |
48 | async function checkAccessToken(permission: Permissions): Promise {
49 | let atManager = abilityAccessCtrl.createAtManager()
50 | let grantStatus: abilityAccessCtrl.GrantStatus
51 | // 获取应用程序的accessTokenID
52 | let tokenId: number
53 | try {
54 | let bundleInfo: bundleManager.BundleInfo =
55 | await bundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION)
56 | let appInfo: bundleManager.ApplicationInfo = bundleInfo.appInfo
57 | tokenId = appInfo.accessTokenId
58 | } catch (err) {
59 | console.error(`getBundleInfoForSelf failed, code is ${err.code}, message is ${err.message}`)
60 | }
61 |
62 | try {
63 | grantStatus = await atManager.checkAccessToken(tokenId, permission)
64 | } catch (err) {
65 | console.error(`checkAccessToken failed, code is ${err.code}, message is ${err.message}`)
66 | }
67 |
68 | return grantStatus
69 | }
70 |
71 | async function checkPermission(permissions: Permissions[]): Promise {
72 |
73 | let grantStatusList: abilityAccessCtrl.GrantStatus[] = []
74 | for (let index = 0; index < permissions.length; index++) {
75 | let grantStatus: abilityAccessCtrl.GrantStatus = await checkAccessToken(permissions[index])
76 | grantStatusList.push(grantStatus)
77 | }
78 | return grantStatusList
79 | }
80 |
81 | function requestPermission(permissions: Permissions[], context: common.UIAbilityContext): Promise {
82 | let atManager = abilityAccessCtrl.createAtManager()
83 | return new Promise((resolve, reject) => {
84 | atManager.requestPermissionsFromUser(context, permissions).then((data) => {
85 | let grantStatus: Array = data.authResults
86 | const allGrant = grantStatus.every(status => status === 0)
87 | if (allGrant) {
88 | resolve()
89 | } else {
90 | reject()
91 | }
92 | }).catch((err) => {
93 | reject()
94 | console.error(`requestPermissionsFromUser failed, code is ${err.code}, message is ${err.message}`)
95 | })
96 | })
97 | }
98 |
--------------------------------------------------------------------------------
/base/fast_util/src/main/ets/FastRouter.ets:
--------------------------------------------------------------------------------
1 | import { router } from '@kit.ArkUI'
2 |
3 | /// 基于 router 库封装,为了实现页面回调
4 | export class FastRouter {
5 | public readonly routerStack: RouterModel[] = []
6 |
7 | /// 跨 hsp 使用这种方式实现单例
8 | public static instance(): FastRouter {
9 | const storageKey = 'REX_FAST_ROUTER'
10 | if (!AppStorage.has(storageKey)) {
11 | AppStorage.setOrCreate(storageKey, new FastRouter())
12 | }
13 | return AppStorage.get(storageKey)!
14 | }
15 |
16 | /// 获取路由传递的入参
17 | public static get getRouterCurrentParams(): RouterModel | undefined {
18 | const stack = FastRouter.instance().routerStack
19 | if (stack.length === 0) {
20 | return undefined
21 | }
22 | return stack[stack.length - 1]
23 | }
24 |
25 | /// push 页面
26 | public static async push(route: RouterModel): Promise {
27 | try {
28 | await router.pushUrl({ url: route.url, params: route.params })
29 | FastRouter.instance().routerStack.push(route)
30 | } catch (_) {
31 | console.log('>>>>')
32 | }
33 | }
34 |
35 | /// replace 页面
36 | public static async replace(route: RouterModel): Promise {
37 | try {
38 | await router.replaceUrl({ url: route.url, params: route.params })
39 | const instance = FastRouter.instance()
40 | const list = instance.routerStack
41 | if (list.length > 0) {
42 | instance.routerStack.splice(instance.routerStack.length - 1, 1, route)
43 | }
44 | } catch (_) {
45 | // 暂无处理
46 | }
47 | }
48 |
49 | /// 退出栈顶页面
50 | public static async pop(animated?: boolean): Promise {
51 | router.back()
52 | const routerStack = FastRouter.instance().routerStack
53 | routerStack.pop()
54 | }
55 | }
56 |
57 | export interface RouterModel {
58 | // 页面路径
59 | // 例如 : 1. 本地包内,或者直接依赖的静态包内页面 : pages/Page1
60 | // 2. 分包内的页面 :@bundle:包名/featureName/ets/pages/Page2
61 | url?: string
62 | params?: Object, // 要传递给跳转页面的参数
63 | popCallback?: (value: Object | undefined) => void // 用于页面回调
64 | }
--------------------------------------------------------------------------------
/base/fast_util/src/main/ets/FastTool.ets:
--------------------------------------------------------------------------------
1 | import { bundleManager } from '@kit.AbilityKit';
2 |
3 | abstract class FastTool {
4 | /// 获取应用包名的方法
5 | public static get bundleName(): string {
6 | const info = bundleManager.getBundleInfoForSelfSync(bundleManager.BundleFlag.GET_BUNDLE_INFO_DEFAULT)
7 | return info.name;
8 | }
9 | }
--------------------------------------------------------------------------------
/base/fast_util/src/main/ets/ObjectUtil.ts:
--------------------------------------------------------------------------------
1 | export type ObjectOrNull = Object | undefined | null
2 |
3 | export abstract class ObjectUtil {
4 | /**
5 | * 将对象转换成hashCode,用于对象的唯一标识
6 | * @param obj
7 | * @returns
8 | */
9 | static hashCode(obj: object): number {
10 | let hash = 0
11 | let i = 0
12 | let chr: number = 0;
13 | let str = JSON.stringify(obj)
14 | if (str.length === 0) {
15 | return hash;
16 | }
17 | for (i = 0; i < str.length; i++) {
18 | chr = str.charCodeAt(i);
19 | hash = ((hash << 5) - hash) + chr;
20 | hash |= 0; // 将 hash 转换为 32 位整数
21 | }
22 | return hash
23 | }
24 |
25 | /**
26 | * 判断是否是对象
27 | * @param obj
28 | * @returns
29 | */
30 | static isObject(obj: ObjectOrNull): boolean {
31 | return typeof obj === 'object' && obj !== null
32 | }
33 |
34 | /**
35 | * 判断是否为空
36 | * @param obj
37 | * @returns
38 | */
39 | static isEmpty(obj: ObjectOrNull): boolean {
40 | let isEmpty = obj === undefined || obj === null
41 | if (typeof obj === 'string') {
42 | isEmpty = isEmpty || obj.trim().length === 0
43 | }
44 | return isEmpty
45 | }
46 |
47 | /**
48 | * 判断是否不为空
49 | * @param obj
50 | * @returns
51 | */
52 | static isNotEmpty(obj: ObjectOrNull): boolean {
53 | return !ObjectUtil.isEmpty(obj)
54 | }
55 |
56 | /**
57 | * 判断是否存在属性
58 | * @param obj
59 | * @param propertyName
60 | * @returns
61 | */
62 | static hasProperty(obj: ObjectOrNull, propertyName: string): boolean {
63 | if (!ObjectUtil.isObject(obj)) {
64 | return false
65 | }
66 | for (const key of Object.keys(obj!)) {
67 | if (key === propertyName) {
68 | return true
69 | }
70 | }
71 | return false
72 | }
73 |
74 | /**
75 | * 对象深拷贝
76 | * @param obj
77 | * @returns
78 | */
79 | static deepCopy(obj: object): object {
80 | let newObj: Record | Object[] = Array.isArray(obj) ? [] : {};
81 | for (let key of Object.keys(obj)) {
82 | if (ObjectUtil.isObject(obj[key])) {
83 | newObj[key] = ObjectUtil.deepCopy(obj[key]);
84 | } else {
85 | newObj[key] = obj[key];
86 | }
87 | }
88 | return newObj;
89 | }
90 |
91 | /**
92 | * 对象浅拷贝
93 | * @param obj
94 | * @returns
95 | */
96 | static shallowCopy(obj: object): object {
97 | let newObj: Record = {};
98 | for (let key of Object.keys(obj)) {
99 | newObj[key] = obj[key];
100 | }
101 | return newObj;
102 | }
103 |
104 | /**
105 | * 对象转map
106 | * @param obj
107 | * @returns
108 | */
109 | static objectToMap(obj: Object): Map {
110 | let map = new Map();
111 | if (obj instanceof Array) {
112 | for (let i = 0; i < obj.length; i++) {
113 | if (ObjectUtil.isObject(obj[i])) {
114 | map.set(i.toString(), ObjectUtil.objectToMap(obj[i]));
115 | } else {
116 | map.set(i.toString(), obj[i]);
117 | }
118 | }
119 | } else if (ObjectUtil.isObject(obj)) {
120 | for (let key in obj) {
121 | if (ObjectUtil.isObject(obj[key])) {
122 | map.set(key, ObjectUtil.objectToMap(obj[key]));
123 | } else {
124 | map.set(key, obj[key]);
125 | }
126 | }
127 | }
128 | return map;
129 | }
130 | }
--------------------------------------------------------------------------------
/base/fast_util/src/main/ets/PreferencesUtil.ets:
--------------------------------------------------------------------------------
1 | import dataPreferences from '@ohos.data.preferences';
2 | import { FastLog } from './FastLog';
3 |
4 | let preference: dataPreferences.Preferences;
5 |
6 | /// 数据持久化工具
7 | export class PreferencesUtil {
8 | static readonly TAG: string = "preferences_util";
9 | static readonly KEY_PREFERENCES = "preferences"
10 | static readonly PREFERENCES_NAME: string = "fast_preferences";
11 |
12 | // 在 Entity create 进行调用
13 | static async createPreferences(context: Context) {
14 | try {
15 | preference = await dataPreferences.getPreferences(context, PreferencesUtil.PREFERENCES_NAME);
16 | } catch (err) {
17 | FastLog.error(PreferencesUtil.TAG, `Failed to get preferences, Cause: ${err}`);
18 | }
19 | }
20 |
21 | // 外部可通过这个方法进行监听
22 | // preference.on('change',(data) => {})
23 | static async getPreferences(context: Context): Promise {
24 | if (!preference) {
25 | await PreferencesUtil.createPreferences(context);
26 | }
27 | return preference
28 | }
29 |
30 | static async deletePreferences(context: Context): Promise {
31 | try {
32 | await dataPreferences.deletePreferences(context, PreferencesUtil.PREFERENCES_NAME);
33 | return true
34 | } catch (err) {
35 | FastLog.error(PreferencesUtil.TAG, `Failed to delete preferences, Cause: ${err}`);
36 | return false
37 | }
38 | }
39 |
40 | static async put(key: string, value: Object) {
41 | try {
42 | if (typeof value === "object") {
43 | if (Array.isArray(value)) {
44 | await preference.put(key, JSON.stringify(value));
45 | } else {
46 | await preference.put(key, JSON.stringify(value));
47 | }
48 | } else {
49 | await preference.put(key, value);
50 | }
51 | } catch (err) {
52 | FastLog.error(PreferencesUtil.TAG, `Failed to put value, Cause: ${err}`);
53 | }
54 | await preference.flush();
55 | }
56 |
57 | static async get(key: string): Promise