From 70e6a6aae5da1238f97e4548098cd89029b1261d Mon Sep 17 00:00:00 2001 From: rentangyu Date: Tue, 16 Dec 2025 16:47:00 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9Ejscrash=E6=A1=88=E4=BE=8B:?= =?UTF-8?q?=E5=90=8C=E6=BA=90=E4=BB=A3=E7=A0=81=20https://gitee.com/harmon?= =?UTF-8?q?yos=5Fsamples/BestPracticeSnippets/issues/IDDBPS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: rentangyu --- JSCrash/README.md | 45 ++++++--- JSCrash/entry/build-profile.json5 | 70 ++++++++----- JSCrash/entry/oh-package-lock.json5 | 19 ++++ JSCrash/entry/oh-package.json5 | 21 ++-- JSCrash/entry/src/main/cpp/CMakeLists.txt | 15 +++ JSCrash/entry/src/main/cpp/napi_init.cpp | 69 +++++++++++++ .../src/main/cpp/types/libentry/Index.d.ts | 2 + .../main/cpp/types/libentry/oh-package.json5 | 6 ++ .../entrybackupability/EntryBackupAbility.ets | 30 +++--- .../main/ets/pages/JSCrashCaseAnalyse10.ets | 11 +++ .../main/ets/pages/JSCrashCaseAnalyse11.ets | 13 +++ .../main/ets/pages/JSCrashCaseAnalyse12.ets | 11 +++ .../main/ets/pages/JSCrashCaseAnalyse13.ets | 13 +++ .../main/ets/pages/JSCrashCaseAnalyse14.ets | 39 ++++++++ .../main/ets/pages/JSCrashCaseAnalyse4.ets | 4 - .../main/ets/pages/JSCrashCaseAnalyse5.ets | 8 -- .../src/main/ets/pages/JSCrashCaseAnalyse6.js | 13 +++ .../src/main/ets/pages/JSCrashCaseAnalyse7.js | 13 +++ .../main/ets/pages/JSCrashCaseAnalyse8.ets | 50 ++++++++++ .../main/ets/pages/JSCrashCaseAnalyse9.ets | 51 ++++++++++ JSCrash/entry/src/main/ets/pages/utils.ets | 5 + JSCrash/entry/src/main/module.json5 | 98 +++++++++---------- .../main/resources/base/element/color.json | 14 +-- .../main/resources/base/element/float.json | 16 +-- .../resources/base/profile/backup_config.json | 4 +- .../main/resources/dark/element/color.json | 14 +-- JSCrash/entry/src/mock/Libentry.mock.ets | 7 ++ JSCrash/entry/src/mock/mock-config.json5 | 5 + .../src/ohosTest/ets/test/Ability.test.ets | 35 +++++++ .../entry/src/ohosTest/ets/test/List.test.ets | 5 + JSCrash/entry/src/ohosTest/module.json5 | 11 +++ JSCrash/entry/src/test/List.test.ets | 5 + JSCrash/entry/src/test/LocalUnit.test.ets | 33 +++++++ JSCrash/hvigor/hvigor-config.json5 | 44 ++++----- 34 files changed, 625 insertions(+), 174 deletions(-) create mode 100644 JSCrash/entry/oh-package-lock.json5 create mode 100644 JSCrash/entry/src/main/cpp/CMakeLists.txt create mode 100644 JSCrash/entry/src/main/cpp/napi_init.cpp create mode 100644 JSCrash/entry/src/main/cpp/types/libentry/Index.d.ts create mode 100644 JSCrash/entry/src/main/cpp/types/libentry/oh-package.json5 create mode 100644 JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse10.ets create mode 100644 JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse11.ets create mode 100644 JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse12.ets create mode 100644 JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse13.ets create mode 100644 JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse14.ets create mode 100644 JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse6.js create mode 100644 JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse7.js create mode 100644 JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse8.ets create mode 100644 JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse9.ets create mode 100644 JSCrash/entry/src/mock/Libentry.mock.ets create mode 100644 JSCrash/entry/src/mock/mock-config.json5 create mode 100644 JSCrash/entry/src/ohosTest/ets/test/Ability.test.ets create mode 100644 JSCrash/entry/src/ohosTest/ets/test/List.test.ets create mode 100644 JSCrash/entry/src/ohosTest/module.json5 create mode 100644 JSCrash/entry/src/test/List.test.ets create mode 100644 JSCrash/entry/src/test/LocalUnit.test.ets diff --git a/JSCrash/README.md b/JSCrash/README.md index e8b94af7..e33f5942 100644 --- a/JSCrash/README.md +++ b/JSCrash/README.md @@ -11,21 +11,36 @@ ### 工程目录 ``` -├──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 // 应用资源目录 +├──entry/src/main/ +│ ├──cpp +│ │ ├──types/libentry +│ │ │ └──Index.d.ts +│ │ ├── CMakeLists.txt +│ │ └── napi_init.cpp // C++ 样例代码 +│ └──ets +│ ├──pages +│ │ ├──Index.ets // 首页 +│ │ ├── JSCrashCaseAnalyse1.ets // ArkTS样例代码 +│ │ ├── JSCrashCaseAnalyse2.ets // ArkTS样例代码 +│ │ ├── JSCrashCaseAnalyse3.ets // ArkTS样例代码 +│ │ ├── JSCrashCaseAnalyse4.ets // ArkTS样例代码 +│ │ ├── JSCrashCaseAnalyse5.ets // ArkTS样例代码 +│ │ ├── JSCrashCaseAnalyse6.js // ArkTS样例代码 +│ │ ├── JSCrashCaseAnalyse7.js // ArkTS样例代码 +│ │ ├── JSCrashCaseAnalyse8.ets // ArkTS样例代码 +│ │ ├── JSCrashCaseAnalyse9.ets // ArkTS样例代码 +│ │ ├── JSCrashCaseAnalyse10.ets // ArkTS样例代码 +│ │ ├── JSCrashCaseAnalyse11.ets // ArkTS样例代码 +│ │ ├── JSCrashCaseAnalyse12.ets // ArkTS样例代码 +│ │ ├── JSCrashCaseAnalyse13.ets // ArkTS样例代码 +│ │ ├── JSCrashCaseAnalyse14.ets // ArkTS样例代码 +│ │ ├── JSCrashQuestionCheck.ets // ArkTS样例代码 +│ │ └── utils.ets // 工具类 +│ ├──entryability +│ │ └──EntryAbility.ets // Ability的生命周期回调内容 +│ └──entrybackupability +│ └──EntryBackupAbility.ets // 应用数据备份恢复类 +└──entry/src/main/resources // 应用资源目录 ``` ### 具体实现 diff --git a/JSCrash/entry/build-profile.json5 b/JSCrash/entry/build-profile.json5 index 4d611879..a198928a 100644 --- a/JSCrash/entry/build-profile.json5 +++ b/JSCrash/entry/build-profile.json5 @@ -1,28 +1,44 @@ -{ - "apiType": "stageMode", - "buildOption": { - }, - "buildOptionSet": [ - { - "name": "release", - "arkOptions": { - "obfuscation": { - "ruleOptions": { - "enable": false, - "files": [ - "./obfuscation-rules.txt" - ] - } - } - } - }, - ], - "targets": [ - { - "name": "default" - }, - { - "name": "ohosTest", - } - ] +{ + "apiType": "stageMode", + "buildOption": { + "resOptions": { + "copyCodeResource": { + "enable": false + } + }, + "externalNativeOptions": { + "path": "./src/main/cpp/CMakeLists.txt", + "arguments": "", + "cppFlags": "", + } + }, + "buildOptionSet": [ + { + "name": "release", + "arkOptions": { + "obfuscation": { + "ruleOptions": { + "enable": false, + "files": [ + "./obfuscation-rules.txt" + ] + } + } + }, + "nativeLib": { + "debugSymbol": { + "strip": true, + "exclude": [] + } + } + }, + ], + "targets": [ + { + "name": "default" + }, + { + "name": "ohosTest", + } + ] } \ No newline at end of file diff --git a/JSCrash/entry/oh-package-lock.json5 b/JSCrash/entry/oh-package-lock.json5 new file mode 100644 index 00000000..85dbf092 --- /dev/null +++ b/JSCrash/entry/oh-package-lock.json5 @@ -0,0 +1,19 @@ +{ + "meta": { + "stableOrder": true, + "enableUnifiedLockfile": false + }, + "lockfileVersion": 3, + "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", + "specifiers": { + "libentry.so@src/main/cpp/types/libentry": "libentry.so@src/main/cpp/types/libentry" + }, + "packages": { + "libentry.so@src/main/cpp/types/libentry": { + "name": "libentry.so", + "version": "1.0.0", + "resolved": "src/main/cpp/types/libentry", + "registryType": "local" + } + } +} \ No newline at end of file diff --git a/JSCrash/entry/oh-package.json5 b/JSCrash/entry/oh-package.json5 index 248c3b75..b9c1d4cc 100644 --- a/JSCrash/entry/oh-package.json5 +++ b/JSCrash/entry/oh-package.json5 @@ -1,10 +1,11 @@ -{ - "name": "entry", - "version": "1.0.0", - "description": "Please describe the basic information.", - "main": "", - "author": "", - "license": "", - "dependencies": {} -} - +{ + "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/JSCrash/entry/src/main/cpp/CMakeLists.txt b/JSCrash/entry/src/main/cpp/CMakeLists.txt new file mode 100644 index 00000000..4eb665c9 --- /dev/null +++ b/JSCrash/entry/src/main/cpp/CMakeLists.txt @@ -0,0 +1,15 @@ +# the minimum version of CMake. +cmake_minimum_required(VERSION 3.5.0) +project(JSCrash) + +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/JSCrash/entry/src/main/cpp/napi_init.cpp b/JSCrash/entry/src/main/cpp/napi_init.cpp new file mode 100644 index 00000000..9a58aaa4 --- /dev/null +++ b/JSCrash/entry/src/main/cpp/napi_init.cpp @@ -0,0 +1,69 @@ +#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; + +} + + // [Start TestLeak] +static napi_value TestLeak(napi_env env, napi_callback_info info) +{ + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_get_cb_info(env, info, &argc, args , nullptr, nullptr); + napi_value proxy = args[0]; + napi_ref task_ref; + napi_create_reference(env, proxy, 1, &task_ref); + // 由于未调用napi_delete_reference发生内存泄漏 + // napi_delete_reference(env, task_ref->ref); + return nullptr; +} + // [End TestLeak] + +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 }, + { "TestLeak", nullptr, TestLeak, 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/JSCrash/entry/src/main/cpp/types/libentry/Index.d.ts b/JSCrash/entry/src/main/cpp/types/libentry/Index.d.ts new file mode 100644 index 00000000..8e5eb0bb --- /dev/null +++ b/JSCrash/entry/src/main/cpp/types/libentry/Index.d.ts @@ -0,0 +1,2 @@ +export const add: (a: number, b: number) => number; +export const TestLeak: (Proxy) => void; \ No newline at end of file diff --git a/JSCrash/entry/src/main/cpp/types/libentry/oh-package.json5 b/JSCrash/entry/src/main/cpp/types/libentry/oh-package.json5 new file mode 100644 index 00000000..56322781 --- /dev/null +++ b/JSCrash/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/JSCrash/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets b/JSCrash/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets index 8e4de992..fae19f9d 100644 --- a/JSCrash/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets +++ b/JSCrash/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets @@ -1,16 +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(); - } +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/JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse10.ets b/JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse10.ets new file mode 100644 index 00000000..0538f08a --- /dev/null +++ b/JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse10.ets @@ -0,0 +1,11 @@ +/** + * 最佳实践:JSCrash问题案例分析 + */ + +// [Start JSCrashCaseAnalyse10] +import { Animal } from './JSCrashCaseAnalyse11' +export let a = "this is A"; +export function A() { + return new Animal; +} +// [End JSCrashCaseAnalyse10] \ No newline at end of file diff --git a/JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse11.ets b/JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse11.ets new file mode 100644 index 00000000..9daf626e --- /dev/null +++ b/JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse11.ets @@ -0,0 +1,13 @@ +/** + * 最佳实践:JSCrash问题案例分析 + */ + +// [Start JSCrashCaseAnalyse11] +import { a } from './JSCrashCaseAnalyse10' +export class Animal { + static { + console.log("this is in class"); + let str = a; // 报错信息:a is not initialized + } +} +// [End JSCrashCaseAnalyse11] diff --git a/JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse12.ets b/JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse12.ets new file mode 100644 index 00000000..f6a1d6e8 --- /dev/null +++ b/JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse12.ets @@ -0,0 +1,11 @@ +/** + * 最佳实践:JSCrash问题案例分析 + */ + +// [Start JSCrashCaseAnalyse12] +import { Animal } from './JSCrashCaseAnalyse11' +export let a = "this is A"; +export function A() { + return new Animal; +} +// [End JSCrashCaseAnalyse12] \ No newline at end of file diff --git a/JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse13.ets b/JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse13.ets new file mode 100644 index 00000000..ba44399c --- /dev/null +++ b/JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse13.ets @@ -0,0 +1,13 @@ +/** + * 最佳实践:JSCrash问题案例分析 + */ + +// [Start JSCrashCaseAnalyse13] +import { a } from './JSCrashCaseAnalyse10' +export class Animal { + static { + console.log("this is in class"); + } + str = a; // 修改点 +} +// [End JSCrashCaseAnalyse13] diff --git a/JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse14.ets b/JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse14.ets new file mode 100644 index 00000000..e8a7b78f --- /dev/null +++ b/JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse14.ets @@ -0,0 +1,39 @@ +/** + * 最佳实践:JSCrash问题案例分析 + */ + +// [Start JSCrashCaseAnalyse14] +import { hilog } from '@kit.PerformanceAnalysisKit'; +import testNapi from 'libentry.so'; + +const DOMAIN = 0x0000; + +@Entry +@Component +struct Index { + @State message: string = 'Hello World'; + + build() { + Row() { + Column() { + Text(this.message) + .fontSize($r('app.float.page_text_font_size')) + .fontWeight(FontWeight.Bold) + .onClick(() => { + this.message = 'Welcome'; + hilog.info(DOMAIN, 'testTag', 'Test NAPI 2 + 3 = %{public}d', testNapi.add(2, 3)); + let obj = new Object(); + let proxy11 = new Proxy(testYY, obj); + testNapi.TestLeak(proxy11); + }) + } + .width('100%') + } + .height('100%') + } +} + +function testYY() { + console.log("test leak"); +} +// [End JSCrashCaseAnalyse8] \ No newline at end of file diff --git a/JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse4.ets b/JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse4.ets index c51f19fa..e10d6d18 100644 --- a/JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse4.ets +++ b/JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse4.ets @@ -24,10 +24,6 @@ class Index extends BaseComponent{ this.isConnected = data === 1 ? true : false; this.handleUpdateState(); }); - wifiManager.on('wifiStateChange', (data) => { - this.isWifiActive = data === 1 ? true : false; - this.handleUpdateState(); - }); } // [End JSCrashCaseAnalyse4] diff --git a/JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse5.ets b/JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse5.ets index 01d39745..ef57b2fa 100644 --- a/JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse5.ets +++ b/JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse5.ets @@ -28,14 +28,6 @@ class Index extends BaseComponent{ } catch (error) { log.showError('wifiConnectionChange error'); } - try { - wifiManager.on('wifiStateChange', (data) => { - this.isWifiActive = data === 1 ? true : false; - this.handleUpdateState(); - }); - } catch (error) { - log.showError('wifiStateChange error'); - } } // [End JSCrashCaseAnalyse5] diff --git a/JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse6.js b/JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse6.js new file mode 100644 index 00000000..9a66efe8 --- /dev/null +++ b/JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse6.js @@ -0,0 +1,13 @@ +/** + * 最佳实践:JSCrash问题案例分析 + */ + +// [Start JSCrashCaseAnalyse6] +function b(a) { + a.trim(); // 报错undefined is not callable; +} +export function c() { + let a = 123; + b(a); +} +// [End JSCrashCaseAnalyse6] \ No newline at end of file diff --git a/JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse7.js b/JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse7.js new file mode 100644 index 00000000..319f443c --- /dev/null +++ b/JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse7.js @@ -0,0 +1,13 @@ +/** + * 最佳实践:JSCrash问题案例分析 + */ + +// [Start JSCrashCaseAnalyse7] +function b(a) { + a.trim(); +} +export function c() { + let a = 123; + b(a.toString()); // 转换为字符串 +} +// [End JSCrashCaseAnalyse7] \ No newline at end of file diff --git a/JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse8.ets b/JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse8.ets new file mode 100644 index 00000000..8c15bc01 --- /dev/null +++ b/JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse8.ets @@ -0,0 +1,50 @@ +/** + * 最佳实践:JSCrash问题案例分析 + */ + +// [Start JSCrashCaseAnalyse8] +import taskpool from '@ohos.taskpool' +import {printArgs} from './utils' +import {BusinessError} from '@ohos.base' +@Concurrent +function createTask(a:number, b:number) { + let sum = a + b; + let task:taskpool.Task = new taskpool.Task(printArgs, sum); + return task; //返回值task任务是无法被序列化,导致问题产生 +} +function resultError() { + let task: taskpool.Task = new taskpool.Task(createTask, 1, 2); + taskpool.execute(task).then((res)=>{ + }).catch((e:BusinessError)=>{ + console.error("resultError task catch message:" + e.message) + }) +} + +@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'; + }) + Button("resultError") + .onClick(() => { + resultError() + }) + } + .height('100%') + .width('100%') + } +} +// [End JSCrashCaseAnalyse8] \ No newline at end of file diff --git a/JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse9.ets b/JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse9.ets new file mode 100644 index 00000000..ab74a817 --- /dev/null +++ b/JSCrash/entry/src/main/ets/pages/JSCrashCaseAnalyse9.ets @@ -0,0 +1,51 @@ +/** + * 最佳实践:JSCrash问题案例分析 + */ + +// [Start JSCrashCaseAnalyse9] +import taskpool from '@ohos.taskpool' +import {printArgs} from './utils' +import {BusinessError} from '@ohos.base' +@Concurrent +function createTask(a:number, b:number) { + let sum = a + b; + return sum; +} +function resultError() { + let task: taskpool.Task = new taskpool.Task(createTask, 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) + }) +} + +@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'; + }) + Button("resultError") + .onClick(() => { + resultError() + }) + } + .height('100%') + .width('100%') + } +} +// [End JSCrashCaseAnalyse9] \ No newline at end of file diff --git a/JSCrash/entry/src/main/ets/pages/utils.ets b/JSCrash/entry/src/main/ets/pages/utils.ets index 98e8e576..d0aa5942 100644 --- a/JSCrash/entry/src/main/ets/pages/utils.ets +++ b/JSCrash/entry/src/main/ets/pages/utils.ets @@ -5,6 +5,11 @@ const TAG: string = 'ZCM_Default'; const DOMAIN: number = 0x0011; const SYMBOL: string = " --> "; +@Concurrent +export function printArgs(args: number): number { + return args +} + export class Log { /** * Outputs info-level logs. diff --git a/JSCrash/entry/src/main/module.json5 b/JSCrash/entry/src/main/module.json5 index ad219d73..5aa1f123 100644 --- a/JSCrash/entry/src/main/module.json5 +++ b/JSCrash/entry/src/main/module.json5 @@ -1,50 +1,50 @@ -{ - "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" - ] - } - ] - } - ], - "extensionAbilities": [ - { - "name": "EntryBackupAbility", - "srcEntry": "./ets/entrybackupability/EntryBackupAbility.ets", - "type": "backup", - "exported": false, - "metadata": [ - { - "name": "ohos.extension.backup", - "resource": "$profile:backup_config" - } - ], - } - ] - } +{ + "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": [ + "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/JSCrash/entry/src/main/resources/base/element/color.json b/JSCrash/entry/src/main/resources/base/element/color.json index 3c712962..d66f9a7d 100644 --- a/JSCrash/entry/src/main/resources/base/element/color.json +++ b/JSCrash/entry/src/main/resources/base/element/color.json @@ -1,8 +1,8 @@ -{ - "color": [ - { - "name": "start_window_background", - "value": "#FFFFFF" - } - ] +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] } \ No newline at end of file diff --git a/JSCrash/entry/src/main/resources/base/element/float.json b/JSCrash/entry/src/main/resources/base/element/float.json index 33ea2230..a8a5d404 100644 --- a/JSCrash/entry/src/main/resources/base/element/float.json +++ b/JSCrash/entry/src/main/resources/base/element/float.json @@ -1,8 +1,8 @@ -{ - "float": [ - { - "name": "page_text_font_size", - "value": "50fp" - } - ] -} +{ + "float": [ + { + "name": "page_text_font_size", + "value": "50fp" + } + ] +} diff --git a/JSCrash/entry/src/main/resources/base/profile/backup_config.json b/JSCrash/entry/src/main/resources/base/profile/backup_config.json index 78f40ae7..d742c2f9 100644 --- a/JSCrash/entry/src/main/resources/base/profile/backup_config.json +++ b/JSCrash/entry/src/main/resources/base/profile/backup_config.json @@ -1,3 +1,3 @@ -{ - "allowToBackupRestore": true +{ + "allowToBackupRestore": true } \ No newline at end of file diff --git a/JSCrash/entry/src/main/resources/dark/element/color.json b/JSCrash/entry/src/main/resources/dark/element/color.json index 79b11c27..438d5bc4 100644 --- a/JSCrash/entry/src/main/resources/dark/element/color.json +++ b/JSCrash/entry/src/main/resources/dark/element/color.json @@ -1,8 +1,8 @@ -{ - "color": [ - { - "name": "start_window_background", - "value": "#000000" - } - ] +{ + "color": [ + { + "name": "start_window_background", + "value": "#000000" + } + ] } \ No newline at end of file diff --git a/JSCrash/entry/src/mock/Libentry.mock.ets b/JSCrash/entry/src/mock/Libentry.mock.ets new file mode 100644 index 00000000..c2171716 --- /dev/null +++ b/JSCrash/entry/src/mock/Libentry.mock.ets @@ -0,0 +1,7 @@ +const NativeMock: Record = { + 'add': (a: number, b: number) => { + return a + b; + }, +}; + +export default NativeMock; \ No newline at end of file diff --git a/JSCrash/entry/src/mock/mock-config.json5 b/JSCrash/entry/src/mock/mock-config.json5 new file mode 100644 index 00000000..6540976c --- /dev/null +++ b/JSCrash/entry/src/mock/mock-config.json5 @@ -0,0 +1,5 @@ +{ + "libentry.so": { + "source": "src/mock/Libentry.mock.ets" + } +} \ 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 new file mode 100644 index 00000000..85c78f67 --- /dev/null +++ b/JSCrash/entry/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,35 @@ +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 new file mode 100644 index 00000000..794c7dc4 --- /dev/null +++ b/JSCrash/entry/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,5 @@ +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 new file mode 100644 index 00000000..fb0d7837 --- /dev/null +++ b/JSCrash/entry/src/ohosTest/module.json5 @@ -0,0 +1,11 @@ +{ + "module": { + "name": "entry_test", + "type": "feature", + "deviceTypes": [ + "phone" + ], + "deliveryWithInstall": true, + "installationFree": false + } +} diff --git a/JSCrash/entry/src/test/List.test.ets b/JSCrash/entry/src/test/List.test.ets new file mode 100644 index 00000000..bb5b5c37 --- /dev/null +++ b/JSCrash/entry/src/test/List.test.ets @@ -0,0 +1,5 @@ +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 new file mode 100644 index 00000000..165fc161 --- /dev/null +++ b/JSCrash/entry/src/test/LocalUnit.test.ets @@ -0,0 +1,33 @@ +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/JSCrash/hvigor/hvigor-config.json5 b/JSCrash/hvigor/hvigor-config.json5 index 5bebc975..3cff4b81 100644 --- a/JSCrash/hvigor/hvigor-config.json5 +++ b/JSCrash/hvigor/hvigor-config.json5 @@ -1,22 +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*/ - } -} +{ + "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*/ + } +} -- Gitee