| @@ -1,13 +1,496 @@ | |||
| 1 | -# @react-native-ohos/react-native-background-timer | 1 | +> 文档模板:v0.4.2 |
| 2 | 2 | ||
| 3 | -This project is based on [react-native-background-timer](https://github.com/ocetnik/react-native-background-timer)@2.4.1 | 3 | +<p align="center"> |
| 4 | + <h1 align="center"> <code>react-native-background-timer</code> </h1> | ||
| 5 | +</p> | ||
| 4 | 6 | ||
| 5 | -## Documentation | 7 | +本项目基于 [react-native-background-timer](https://github.com/ocetnik/react-native-background-timer) 开发。 |
| 6 | 8 | ||
| 7 | -- [中文](https://gitcode.com/OpenHarmony-RN/usage-docs/blob/master/zh-cn/react-native-background-timer.md) | 9 | +该第三方库的仓库已迁移至 Gitcode,且支持直接从 npm 下载,新的包名为:`@react-native-ohos/react-native-background-timer` 版本所属关系如下: |
| 8 | 10 | ||
| 9 | -- [English](https://gitcode.com/OpenHarmony-RN/usage-docs/blob/master/en/react-native-background-timer.md) | 11 | +| 三方库名称 | 三方库版本(npm地址) | 发布信息 | 支持RN版本 | Autolink | 编译API版本 | 社区基线版本 | 源码地址 | |
| 12 | +| ------------ | ------------ | ------------------------------ | ------------- | ------------- |------------------------ | ------------- | ------------- | | ||
| 13 | +| @react-native-ohos/react-native-background-timer | [~ 2.4.2](https://www.npmjs.com/package/@react-native-ohos/react-native-background-timer) | [Gitcode Releases](https://gitcode.com/CPF-RN/rntpc_react-native-background-timer/releases) | 0.72.* | 是 | API12+ | v2.4.1 | [br_rnoh0.72](https://gitcode.com/CPF-RN/rntpc_react-native-background-timer/tree/br_rnoh0.72) | | ||
| 14 | +| @react-native-oh-tpl/react-native-background-timer | [<= 2.4.1-0.0.2@deprecated](https://www.npmjs.com/package/@react-native-oh-tpl/react-native-background-timer) | [Github Releases(deprecated)](https://github.com/react-native-oh-library/react-native-background-timer/releases) | 0.72.* | 否 | API12+ | v2.4.1 | [sig](https://github.com/react-native-oh-library/react-native-background-timer/tree/sig) | | ||
| 10 | 15 | ||
| 11 | -## License | 16 | +## 简介 |
| 12 | 17 | ||
| 13 | -This library is licensed under [The MIT License (MIT)](https://gitee.com/openharmony-sig/rntpc_react-native-background-timer/blob/master/LICENSE) | 18 | +定期触发事件(即使应用处于后台运行状态)。 |
| 19 | + | ||
| 20 | +## 下载安装 | ||
| 21 | + | ||
| 22 | +进入到工程目录并输入以下命令: | ||
| 23 | + | ||
| 24 | +**npm** | ||
| 25 | + | ||
| 26 | +```bash | ||
| 27 | +npm install @react-native-ohos/react-native-background-timer | ||
| 28 | +``` | ||
| 29 | + | ||
| 30 | +**yarn** | ||
| 31 | + | ||
| 32 | +```bash | ||
| 33 | +yarn add @react-native-ohos/react-native-background-timer | ||
| 34 | +``` | ||
| 35 | + | ||
| 36 | +## Link | ||
| 37 | + | ||
| 38 | +| | 是否支持autolink | RN框架版本 | | ||
| 39 | +|--------------------------------------|-----------------|-----------| | ||
| 40 | +| ~2.4.2 | Yes | 0.72 | | ||
| 41 | +| <= 2.4.1-0.0.2@deprecated | No | 0.72 | | ||
| 42 | + | ||
| 43 | +使用AutoLink的工程需要根据该文档配置,Autolink框架指导文档:https://gitcode.com/CPF-RN/ohos_react_native/blob/master/docs/zh-cn/Autolinking.md | ||
| 44 | + | ||
| 45 | +如您使用的版本支持 Autolink,并且工程已接入 Autolink,可跳过ManualLink配置。 | ||
| 46 | + | ||
| 47 | +### 必要的配置项 | ||
| 48 | + | ||
| 49 | +> [!TIP] 该模块的内容无法通过autolink自动生成,始终需要手动配置。 | ||
| 50 | + | ||
| 51 | +### 配置TurboModule运行在worker线程(该模块始终需要手动配置) | ||
| 52 | + | ||
| 53 | +打开 `entry/src/main/ets/entryability/EntryAbility.ets`,添加: | ||
| 54 | + | ||
| 55 | +```diff | ||
| 56 | +import {RNAbility} from '@rnoh/react-native-openharmony'; | ||
| 57 | + | ||
| 58 | +export default class EntryAbility extends RNAbility { | ||
| 59 | ++ override getRNOHWorkerScriptUrl() { | ||
| 60 | ++ return "entry/ets/workers/RNOHWorker.ets" | ||
| 61 | ++ } | ||
| 62 | +... | ||
| 63 | +} | ||
| 64 | +``` | ||
| 65 | + | ||
| 66 | +在ets路径下右击,选择 `New` 选项,右侧展开菜单选择 `Worker` 选项: | ||
| 67 | + | ||
| 68 | +  | ||
| 69 | + 选择后在弹出的窗口中取名 `RNOHWorker.ets`: | ||
| 70 | + | ||
| 71 | +  | ||
| 72 | + 此时目录结构为: | ||
| 73 | + ``` | ||
| 74 | + └── ets | ||
| 75 | + ├── entryability | ||
| 76 | + ├── page | ||
| 77 | + └── workers | ||
| 78 | + └── RNOHWorker.ets | ||
| 79 | + ``` | ||
| 80 | + 修改 `RNOHWorker.ets` 为下列代码: | ||
| 81 | + ```typescript | ||
| 82 | + // entry/src/main/ets/workers/RNOHWorker.ets | ||
| 83 | + import { setupRNOHWorker } from "@rnoh/react-native-openharmony/src/main/ets/setupRNOHWorker"; | ||
| 84 | + import { createRNPackages } from '../RNPackagesFactory'; | ||
| 85 | + | ||
| 86 | + setupRNOHWorker({ | ||
| 87 | + createWorkerRNInstanceConfig: (_rnInstanceName) => { | ||
| 88 | + return { thirdPartyPackagesFactory: createRNPackages } | ||
| 89 | + } | ||
| 90 | + }) | ||
| 91 | + ``` | ||
| 92 | + | ||
| 93 | +<details> | ||
| 94 | + <summary>ManualLink: 此步骤为手动配置原生依赖项的指导</summary> | ||
| 95 | + | ||
| 96 | +首先需要使用 DevEco Studio 打开项目里的 HarmonyOS 工程 `harmony`。 | ||
| 97 | + | ||
| 98 | +### 1. Overrides RN SDK | ||
| 99 | + | ||
| 100 | +为了让工程依赖同一个版本的 RN SDK,需要在工程根目录的 `oh-package.json5` 添加 overrides 字段,指向工程需要使用的 RN SDK 版本。替换的版本既可以是一个具体的版本号,也可以是一个模糊版本,还可以是本地存在的 HAR 包或源码目录。 | ||
| @@ -0,0 +1,498 @@ | |||
| 1 | +> Document Template: v0.4.2 | ||
| 2 | + | ||
| 3 | +<p align="center"> | ||
| 4 | + <h1 align="center"> <code>react-native-background-timer</code> </h1> | ||
| 5 | +</p> | ||
| 6 | + | ||
| 7 | +This project is based on [react-native-background-timer](https://github.com/ocetnik/react-native-background-timer). | ||
| 8 | + | ||
| 9 | +This third-party library has been migrated to Gitcode and is now available for direct download from npm, the new package name is: `@react-native-ohos/react-native-background-timer`, The version correspondence details are as follows: | ||
| 10 | + | ||
| 11 | +| Name | Version(Npm Address) | Release Information | Supported RN Version | Supported Autolink | Compile API Version | Community Baseline Version | Source code address | | ||
| 12 | +| --------------| -------------- | ------------------------------ | ------------- | ------------- |------------------------ | ------------ | ------------- | | ||
| 13 | +| @react-native-ohos/react-native-background-timer | [~ 2.4.2](https://www.npmjs.com/package/@react-native-ohos/react-native-background-timer) | [Gitcode Releases](https://gitcode.com/CPF-RN/rntpc_react-native-background-timer/releases) | 0.72.* | Yes | API12+ | v2.4.1 | [br_rnoh0.72](https://gitcode.com/CPF-RN/rntpc_react-native-background-timer/tree/br_rnoh0.72) | | ||
| 14 | +| @react-native-oh-tpl/react-native-background-timer | [<= 2.4.1-0.0.2@deprecated](https://www.npmjs.com/package/@react-native-oh-tpl/react-native-background-timer) | [Github Releases(deprecated)](https://github.com/react-native-oh-library/react-native-background-timer/releases) | 0.72.* | No | API12+ | v2.4.1 | [sig](https://github.com/react-native-oh-library/react-native-background-timer/tree/sig) | | ||
| 15 | + | ||
| 16 | +## Introduction | ||
| 17 | + | ||
| 18 | +Emit event periodically (even when app is in the background). | ||
| 19 | + | ||
| 20 | +## Installation | ||
| 21 | + | ||
| 22 | +Go to the project directory and execute the following instruction: | ||
| 23 | + | ||
| 24 | +**npm** | ||
| 25 | + | ||
| 26 | +```bash | ||
| 27 | +npm install @react-native-ohos/react-native-background-timer | ||
| 28 | +``` | ||
| 29 | + | ||
| 30 | +**yarn** | ||
| 31 | + | ||
| 32 | +```bash | ||
| 33 | +yarn add @react-native-ohos/react-native-background-timer | ||
| 34 | +``` | ||
| 35 | + | ||
| 36 | +## Link | ||
| 37 | + | ||
| 38 | +| | Supported Autolink | Supported RN Version | | ||
| 39 | +|--------------------------------------|--------------------|----------------------| | ||
| 40 | +| ~2.4.2 | Yes | 0.72 | | ||
| 41 | +| <= 2.4.1-0.0.2@deprecated | No | 0.72 | | ||
| 42 | + | ||
| 43 | +Projects using AutoLink need to be configured according to this document, AutoLink framework guide: https://gitcode.com/CPF-RN/ohos_react_native/blob/master/docs/zh-cn/Autolinking.md | ||
【AI-Review】【一般】【基础代码问题】【可读性问题】英文版 README 链接到中文版 Autolinking 文档 ● 问题: 第43行 AutoLink 框架指导文档的链接指向 触发路径:英文用户阅读 README_en.md → 点击第43行 "AutoLink framework guide" 链接 → 跳转到中文版 Autolinking.md( 对比:同文件第145行的 "Directly Linking Source Code" 链接正确指向了英文版 ● 影响: 一般。英文用户无法正常使用 Autolink 配置文档,影响接入体验。 ● 建议: 将第43行链接中的 ![]() ![]() | |||
| 44 | + | ||
| 45 | +If the version you are using supports Autolink and the project has integrated Autolink, you can skip the ManualLink configuration. | ||
| 46 | + | ||
| 47 | +### Necessary configuration items | ||
| 48 | + | ||
| 49 | +> [!TIP] The content of this module cannot be automatically generated by autolink and must always be manually configured. | ||
| 50 | + | ||
| 51 | +### Configure TurboModule to run on worker thread(This module always requires manual configuration) | ||
| 52 | + | ||
| 53 | +Open the `entry/src/main/ets/entryability/EntryAbility.ets`file and add the following code: | ||
| 54 | + | ||
| 55 | +```diff | ||
| 56 | +import {RNAbility} from '@rnoh/react-native-openharmony'; | ||
| 57 | + | ||
| 58 | +export default class EntryAbility extends RNAbility { | ||
| 59 | ++ override getRNOHWorkerScriptUrl() { | ||
| 60 | ++ return "entry/ets/workers/RNOHWorker.ets" | ||
| 61 | ++ } | ||
| 62 | +... | ||
| 63 | +} | ||
| 64 | +``` | ||
| 65 | + | ||
| 66 | +Right click on the ETS path and select the `New` option. Expand the menu on the right and choose the `Worker` option: | ||
| 67 | + | ||
| 68 | +  | ||
| 69 | + After selection, name `RNOHWorker.ets` in the pop-up window: | ||
| 70 | + | ||
| 71 | +  | ||
| 72 | + At this point, the directory structure is: | ||
| 73 | + ``` | ||
| 74 | + └── ets | ||
| 75 | + ├── entryability | ||
| 76 | + ├── page | ||
| 77 | + └── workers | ||
| 78 | + └── RNOHWorker.ets | ||
| 79 | + ``` | ||
| 80 | + | ||
| 81 | + Modify `RNOHWorker.ets` to the following code: | ||
| 82 | + ```typescript | ||
| 83 | + // entry/src/main/ets/workers/RNOHWorker.ets | ||
| 84 | + import { setupRNOHWorker } from "@rnoh/react-native-openharmony/src/main/ets/setupRNOHWorker"; | ||
| 85 | + import { createRNPackages } from '../RNPackagesFactory'; | ||
| 86 | + | ||
| 87 | + setupRNOHWorker({ | ||
| 88 | + createWorkerRNInstanceConfig: (_rnInstanceName) => { | ||
| 89 | + return { thirdPartyPackagesFactory: createRNPackages } | ||
| 90 | + } | ||
| 91 | + }) | ||
| 92 | + ``` | ||
| 93 | + | ||
| 94 | +<details> | ||
| 95 | + <summary>ManualLink: This step provides guidance for manually configuring native dependencies.</summary> | ||
| 96 | + | ||
| 97 | +Open the `harmony` directory of the OpenHarmony project in DevEco Studio. | ||
| 98 | + | ||
| 99 | +### 1. Overrides RN SDK | ||
| 100 | + | ||
| 101 | +To ensure the project relies on the same version of the RN SDK, you need to add an `overrides` field in the project's root `oh-package.json5` file, specifying the RN SDK version to be used. The replacement version can be a specific version number, a semver range, or a locally available HAR package or source directory. | ||
| 102 | + | ||
| 103 | +For more information about the purpose of this field, please refer to the [official documentation](https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V5/ide-oh-package-json5-V5#en-us_topic_0000001792256137_overrides). | ||
| 104 | + | ||
| 105 | +```json | ||
| 106 | +{ | ||
| 107 | + "overrides": { | ||
| 108 | + "@rnoh/react-native-openharmony": "^0.72.139" // ohpm version | ||
| 109 | + // "@rnoh/react-native-openharmony" : "./react_native_openharmony.har" // a locally available HAR package | ||
| 110 | + // "@rnoh/react-native-openharmony" : "./react_native_openharmony" // source code directory | ||
| 111 | + } | ||
| 112 | +} | ||
| 113 | +``` | ||
| 114 | + | ||
| 115 | +### 2. Introducing Native Code | ||
| 116 | + | ||
| 117 | +Currently, two methods are available: | ||
| 118 | + | ||
| 119 | +- Use the HAR file. | ||
| 120 | +- Directly link to the source code. | ||
| 121 | + | ||
| 122 | +Method 1 (recommended): Use the HAR file. | ||
| 123 | + | ||
| 124 | +> [!TIP] The HAR file is stored in the `harmony` directory in the installation path of the third-party library. | ||
| 125 | + | ||
| 126 | +Open `entry/oh-package.json5` file and add the following dependencies: | ||
| 127 | + | ||
| 128 | +```json | ||
| 129 | +"dependencies": { | ||
| 130 | + "@react-native-ohos/react-native-background-timer": "file:../../node_modules/@react-native-ohos/react-native-background-timer/harmony/background_timer.har" | ||
| 131 | + } | ||
| 132 | +``` | ||
| 133 | + | ||
| 134 | +Click the `sync` button in the upper right corner. | ||
| 135 | + | ||
| 136 | +Alternatively, run the following instruction on the terminal: | ||
| 137 | + | ||
| 138 | +```bash | ||
| 139 | +cd entry | ||
| 140 | +ohpm install | ||
| 141 | +``` | ||
| 142 | + | ||
| 143 | +Method 2: Directly link to the source code. | ||
| 144 | + | ||
| 145 | +> [!TIP] For details, see [Directly Linking Source Code](https://gitcode.com/CPF-RN/usage-docs/blob/master/en/link-source-code.md). | ||
| 146 | + | ||
| 147 | +### 3. Configuring CMakeLists and Introducing ReactNativeOhosReactNativeBackgroundTimerPackage | ||
| 148 | + | ||
| 149 | +Open `entry/src/main/cpp/CMakeLists.txt` and add the following code: | ||
| 150 | + | ||
| 151 | +```diff | ||
| 152 | +project(rnapp) | ||
| 153 | +cmake_minimum_required(VERSION 3.4.1) | ||
| 154 | +set(CMAKE_SKIP_BUILD_RPATH TRUE) | ||
| 155 | +set(RNOH_APP_DIR "${CMAKE_CURRENT_SOURCE_DIR}") | ||
| 156 | +set(NODE_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../node_modules") | ||
| 157 | ++ set(OH_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules") | ||
| 158 | +set(RNOH_CPP_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../react-native-harmony/harmony/cpp") | ||
| 159 | +set(LOG_VERBOSITY_LEVEL 1) | ||
| 160 | +set(CMAKE_ASM_FLAGS "-Wno-error=unused-command-line-argument -Qunused-arguments") | ||
| 161 | +set(CMAKE_CXX_FLAGS "-fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -s -fPIE -pie") | ||
| 162 | +set(WITH_HITRACE_SYSTRACE 1) # for other CMakeLists.txt files to use | ||
| 163 | +add_compile_definitions(WITH_HITRACE_SYSTRACE) | ||
| 164 | + | ||
| 165 | +add_subdirectory("${RNOH_CPP_DIR}" ./rn) | ||
| 166 | + | ||
| 167 | +# RNOH_BEGIN: manual_package_linking_1 | ||
| 168 | +add_subdirectory("../../../../sample_package/src/main/cpp" ./sample-package) | ||
| 169 | ++ add_subdirectory("${OH_MODULES}/@react-native-ohos/react-native-background-timer/src/main/cpp" ./background_timer) | ||
| 170 | +# RNOH_END: manual_package_linking_1 | ||
| 171 | + | ||
| 172 | +file(GLOB GENERATED_CPP_FILES "./generated/*.cpp") | ||
| 173 | + | ||
| 174 | +add_library(rnoh_app SHARED | ||
| 175 | + ${GENERATED_CPP_FILES} | ||
| 176 | + "./PackageProvider.cpp" | ||
| 177 | + "${RNOH_CPP_DIR}/RNOHAppNapiBridge.cpp" | ||
| 178 | +) | ||
| 179 | +target_link_libraries(rnoh_app PUBLIC rnoh) | ||
| 180 | + | ||
| 181 | +# RNOH_BEGIN: manual_package_linking_2 | ||
| 182 | +target_link_libraries(rnoh_app PUBLIC rnoh_sample_package) | ||
| 183 | ++ target_link_libraries(rnoh_app PUBLIC rnoh_background_timer) | ||
| 184 | +# RNOH_END: manual_package_linking_2 | ||
| 185 | +``` | ||
| 186 | + | ||
| 187 | +Open `entry/src/main/cpp/PackageProvider.cpp` and add the following code: | ||
| 188 | + | ||
| 189 | +```diff | ||
| 190 | +#include "RNOH/PackageProvider.h" | ||
| 191 | +#include "SamplePackage.h" | ||
| 192 | ++ #include "ReactNativeOhosReactNativeBackgroundTimerPackage.h" | ||
| 193 | + | ||
| 194 | +using namespace rnoh; | ||
| 195 | + | ||
| 196 | +std::vector<std::shared_ptr<Package>> PackageProvider::getPackages(Package::Context ctx) { | ||
| 197 | + return { | ||
| 198 | + std::make_shared<SamplePackage>(ctx), | ||
| 199 | ++ std::make_shared<BackgroundTimerPackage>(ctx) | ||
| 200 | + }; | ||
| 201 | +} | ||
| 202 | +``` | ||
| 203 | + | ||
| 204 | +### 4. Introducing BackgroundTimerTurboModulePackage to ArkTS | ||
| 205 | + | ||
| 206 | +Open `entry/src/main/ets/RNPackagesFactory.ts` and add: | ||
| 207 | + | ||
| 208 | +```diff | ||
| 209 | + ... | ||
| 210 | ++ import { BackgroundTimerTurboModulePackage } from '@react-native-ohos/react-native-background-timer/ts'; | ||
| 211 | + | ||
| 212 | +export function createRNPackages(ctx: RNPackageContext): RNPackage[] { | ||
| 213 | + return [ | ||
| 214 | ++ new BackgroundTimerTurboModulePackage(ctx) | ||
| 215 | + ]; | ||
| 216 | +} | ||
| 217 | +``` | ||
| 218 | +</details> | ||
| 219 | + | ||
| 220 | +## Running | ||
| 221 | + | ||
| 222 | +Click the `sync` button in the upper right corner. | ||
| 223 | + | ||
| 224 | +Alternatively, run the following instruction on the terminal: | ||
| 225 | + | ||
| 226 | +```bash | ||
| 227 | +cd entry | ||
| 228 | +ohpm install | ||
| 229 | +``` | ||
| 230 | + | ||
| 231 | +Then build and run the code. | ||
| 232 | + | ||
| 233 | + | ||
| 234 | +## Constraints | ||
| 235 | + | ||
| 236 | +### Compatibility | ||
| 237 | + | ||
| 238 | +This document is verified based on the following versions: | ||
| 239 | + | ||
| 240 | +1. RNOH: 0.72.96; SDK: HarmonyOS 6.0.0 Release SDK; IDE: DevEco Studio 6.0.0.858; ROM: 6.0.0.112; | ||
| 241 | +2. RNOH: 0.72.33; SDK: HarmonyOS NEXT B1; IDE: DevEco Studio: 5.0.3.900; ROM: Next.0.0.71; | ||
【AI-Review】【一般】【基础代码问题】【代码逻辑错误】兼容性验证版本与依赖声明不一致 ● 问题:README_en.md 第241行声明 "RNOH: 0.72.33" 为文档验证通过的版本。但 harmony/background_timer/oh-package.json5 第9行声明依赖 ● 影响:一般。用户根据 README 兼容性说明,在工程中使用 RNOH 0.72.33 版本,执行 ohpm install 安装本库时,ohpm 会因 ● 建议:将第2条验证版本中的 RNOH 版本更新为满足 ![]() ![]() | |||
| 242 | + | ||
| 243 | +### Permission Requirements | ||
| 244 | + | ||
| 245 | +None | ||
| 246 | + | ||
| 247 | +## Example | ||
| 248 | + | ||
| 249 | +The following code shows the basic use scenario of the repository: | ||
| 250 | + | ||
| 251 | +> [!WARNING] The name of the imported repository remains unchanged. | ||
| 252 | + | ||
| 253 | +```javascript | ||
| 254 | +import {View, Button, StyleSheet, Text,TextInput} from 'react-native'; | ||
| 255 | +import React, {useState} from 'react'; | ||
| 256 | +import BackgroundTimer from "react-native-background-timer"; | ||
| 257 | +export function BackgroundTimerExample() { | ||
| 258 | + let [count, setCount] = useState(0); | ||
| 259 | + let [text, setText] = useState(""); | ||
| 260 | + let [delay, setDelay] = useState("1000"); | ||
| 261 | + let [timeoutDelay, setTimeoutDelay] = useState("1000"); | ||
| 262 | + let [intervalDelay, setIntervalDelay] = useState("1000"); | ||
| 263 | + let timeoutList:number[] = [] | ||
【AI-Review】【严重】【基础代码问题】【代码逻辑错误】示例代码 timeoutList 未持久化导致 clearTimeout 失效 ● 问题:README_en.md 第263行将 ● 影响:严重。用户复制该示例代码运行后,"clearTimeout" 按钮点击后定时器不会被清除,后台仍持续触发回调。这与示例预期行为不符,会让用户误以为 ● 建议:将
![]() ![]() | |||
| 264 | + let [intervalList, setIntervalList] = useState<number[]>([]); | ||
| 265 | + | ||
| 266 | + // runBackgroundTimer | ||
| 267 | + function onPressStart(){ | ||
| 268 | + setText("Turn on the timer...") | ||
| 269 | + BackgroundTimer.runBackgroundTimer(()=>{ | ||
| 270 | + setCount(count+=1) | ||
【AI-Review】【一般】【基础代码问题】【代码逻辑错误】setCount(count+=1) 直接修改 state 变量导致定时器运行中 Reset 后计数跳变 ● 问题:README_en.md 第270行 ● 影响:一般。用户在定时器运行期间点击 Reset 后,计数器不会从 0 重新开始递增,而是跳变到定时器闭包中累积的旧值+1,与用户预期不符,示例代码行为不正确。 ● 建议:使用函数式更新获取最新 state,避免直接修改 state 变量:
BackgroundTimer.runBackgroundTimer(() => {
setCount(prev => prev + 1)
}, parseInt(delay))
第298行 setInterval 回调也应同样修改为 ![]() ![]() | |||
| 271 | + },parseInt(delay)) | ||
| 272 | + } | ||
| 273 | + function onPressStop(){ | ||
| 274 | + setText("Turn off the timer") | ||
| 275 | + BackgroundTimer.stopBackgroundTimer() | ||
| 276 | + } | ||
| 277 | + | ||
| 278 | + // setTimeout | ||
| 279 | + function setTimeoutStart(){ | ||
| 280 | + setText("Turn on the timer...") | ||
| 281 | + let timeoutId = BackgroundTimer.setTimeout(()=>{ | ||
| 282 | + setCount(count+=1) | ||
| 283 | + },parseInt(timeoutDelay)) | ||
| 284 | + timeoutList.push(timeoutId) | ||
| 285 | + } | ||
| 286 | + function setTimeoutStop(){ | ||
| 287 | + setText("Turn off the timer") | ||
| 288 | + if(timeoutList.length>0){ | ||
| 289 | + BackgroundTimer.clearTimeout(timeoutList[0]) | ||
| 290 | + timeoutList.shift() | ||
| 291 | + } | ||
| 292 | + } | ||
| 293 | + | ||
| 294 | + // setInterval | ||
| 295 | + function setIntervalStart(){ | ||
| 296 | + setText("Turn on the timer...") | ||
| 297 | + let intervalId = BackgroundTimer.setInterval(()=>{ | ||
| 298 | + setCount(count+=1) | ||
| 299 | + },parseInt(intervalDelay)) | ||
| 300 | + setIntervalList([...intervalList,intervalId]) | ||
| 301 | + } | ||
| 302 | + function setIntervalStop(){ | ||
| 303 | + setText("Turn off the timer") | ||
| 304 | + if(intervalList.length>0){ | ||
| 305 | + BackgroundTimer.clearInterval(intervalList[0]) | ||
| 306 | + intervalList.shift() | ||
【AI-Review】【一般】【基础代码问题】【代码逻辑错误】intervalList.shift() mutates React state without setState update ● 问题: Line 306 in Trigger path: User clicks "setInterval" button → ● 影响: General. Directly mutating state is a React anti-pattern that can cause UI-state desynchronization: after clicking clearInterval, the UI may still show the cleared interval; subsequent ● 建议: Use ![]() ![]() | |||
| 307 | + } | ||
| 308 | + } | ||
| 309 | + function resetNumber(){ | ||
| 310 | + setCount(0) | ||
| 311 | + setText("") | ||
| 312 | + } | ||
| 313 | + return ( | ||
| 314 | + <View style={{flexDirection: 'column', flex: 1,backgroundColor:'white'}}> | ||
| 315 | + <View style={styles.container}> | ||
| 316 | + <View style={styles.viewStyle}> | ||
| 317 | + <Button | ||
| 318 | + onPress={onPressStart} | ||
| 319 | + title="runBackgroundTimer" | ||
| 320 | + /> | ||
| 321 | + <TextInput | ||
| 322 | + style={{ height: 40, borderColor: 'gray', borderWidth: 1 }} | ||
| 323 | + placeholder="BackgroundTimer delay" | ||
| 324 | + onChangeText={(value)=>{setDelay(value)}} | ||
| 325 | + value={delay} | ||
| 326 | + /> | ||
| 327 | + </View> | ||
| 328 | + <View style={[styles.viewStyle]}> | ||
| 329 | + <Button | ||
| 330 | + onPress={onPressStop} | ||
| 331 | + title="stopBackgroundTimer" | ||
| 332 | + /> | ||
| 333 | + </View> | ||
| 334 | + </View> | ||
| 335 | + | ||
| 336 | + <View style={styles.container}> | ||
| 337 | + <View style={styles.viewStyle}> | ||
| 338 | + <Button | ||
| 339 | + onPress={setTimeoutStart} | ||
| 340 | + title="setTimeout" | ||
| 341 | + /> | ||
| 342 | + <TextInput | ||
| 343 | + style={{ height: 40, borderColor: 'gray', borderWidth: 1 }} | ||
| 344 | + placeholder="setTimeout delay" | ||
| 345 | + onChangeText={(value)=>{setTimeoutDelay(value)}} | ||
| 346 | + value={timeoutDelay} | ||
| 347 | + /> | ||
| 348 | + </View> | ||
| 349 | + <View style={[styles.viewStyle]}> | ||
| 350 | + <Button | ||
| 351 | + onPress={setTimeoutStop} | ||
| 352 | + title="clearTimeout" | ||
| 353 | + /> | ||
| 354 | + </View> | ||
| 355 | + </View> | ||
| 356 | + | ||
| 357 | + <View style={styles.container}> | ||
| 358 | + <View style={styles.viewStyle}> | ||
| 359 | + <Button | ||
| 360 | + onPress={setIntervalStart} | ||
| 361 | + title="setInterval" | ||
| 362 | + /> | ||
| 363 | + <TextInput | ||
| 364 | + style={{ height: 40, borderColor: 'gray', borderWidth: 1 }} | ||
| 365 | + placeholder="setInterval delay" | ||
| 366 | + onChangeText={(value)=>{setIntervalDelay(value)}} | ||
| 367 | + value={intervalDelay} | ||
| 368 | + /> | ||
| 369 | + </View> | ||
| 370 | + <View style={[styles.viewStyle]}> | ||
| 371 | + <Button | ||
| 372 | + onPress={setIntervalStop} | ||
| 373 | + title="clearInterval" | ||
| 374 | + /> | ||
| 375 | + </View> | ||
| 376 | + </View> | ||
| 377 | + | ||
| 378 | + <View style={[styles.viewStyle,styles.resetStyle]}> | ||
| 379 | + <Button | ||
| 380 | + onPress={resetNumber} | ||
| 381 | + title="Reset" | ||
| 382 | + /> | ||
| 383 | + </View> | ||
| 384 | + <Text style={styles.textStyle}>{count}</Text> | ||
| 385 | + <Text style={styles.textStyle}>{text}</Text> | ||
| 386 | + </View> | ||
| 387 | + ); | ||
| 388 | +} | ||
| 389 | + | ||
| 390 | +const styles = StyleSheet.create({ | ||
| 391 | + container: { | ||
| 392 | + borderColor: 'black', | ||
| 393 | + borderTopWidth: 0, | ||
| 394 | + borderBottomWidth: 5, | ||
| 395 | + borderLeftWidth: 0, | ||
| 396 | + borderRightWidth: 0, | ||
| 397 | + padding: 10, | ||
| 398 | + }, | ||
| 399 | + resetStyle: { | ||
| 400 | + paddingTop: 10, | ||
| 401 | + }, | ||
| 402 | + viewStyle:{ | ||
| 403 | + marginBottom: 10, | ||
| 404 | + }, | ||
| 405 | + textStyle: { | ||
| 406 | + fontSize: 30, | ||
| 407 | + }, | ||
| 408 | +}); | ||
| 409 | +``` | ||
| 410 | + | ||
| 411 | +## How to Use | ||
| 412 | + | ||
| 413 | +**Periodic background task** | ||
| 414 | + | ||
| 415 | +```javascript | ||
| 416 | +// Start a background timer that executes the callback every `delay` milliseconds, | ||
| 417 | +// even when the app is running in the background. | ||
| 418 | +BackgroundTimer.runBackgroundTimer(() => { | ||
| 419 | + // Periodic task, e.g. polling data or updating a countdown | ||
| 420 | +}, 2000); | ||
| 421 | + | ||
| 422 | +// Stop the background timer | ||
| 423 | +BackgroundTimer.stopBackgroundTimer(); | ||
| 424 | +``` | ||
| 425 | + | ||
| 426 | +**One-shot delayed task** | ||
| 427 | + | ||
| 428 | +```javascript | ||
| 429 | +// Executes only once when the timer expires; still fires when the app is in the background | ||
| 430 | +const timeoutId = BackgroundTimer.setTimeout(() => { | ||
| 431 | + // Delayed task, e.g. timeout reminder or delayed navigation | ||
| 432 | +}, 3000); | ||
| 433 | + | ||
| 434 | +// Cancel it before the timer expires | ||
| 435 | +BackgroundTimer.clearTimeout(timeoutId); | ||
| 436 | +``` | ||
| 437 | + | ||
| 438 | +**Repeating interval task** | ||
| 439 | + | ||
| 440 | +```javascript | ||
| 441 | +// Repeats at a fixed interval; multiple timers can run simultaneously and independently, | ||
| 442 | +// each returning its own timer ID | ||
| 443 | +const intervalId = BackgroundTimer.setInterval(() => { | ||
| 444 | + // Repeating task, e.g. heartbeat reporting or polling refresh | ||
| 445 | +}, 1000); | ||
| 446 | + | ||
| 447 | +// Stop the specified timer | ||
| 448 | +BackgroundTimer.clearInterval(intervalId); | ||
| 449 | +``` | ||
| 450 | + | ||
| 451 | +## Available APIs | ||
| 452 | + | ||
| 453 | +> [!TIP] The **Platform** column indicates the platform where the properties are supported in the original third-party library. | ||
| 454 | + | ||
| 455 | +> [!TIP] If the value of **HarmonyOS Support** is **yes**, it means that the OpenHarmony platform supports this property; **no** means the opposite; **partially** means some capabilities of this property are supported. The usage method is the same on different platforms and the effect is the same as that of iOS or Android. | ||
| 456 | + | ||
| 457 | +### API | ||
| 458 | +| Name | Type | Parameter Type | Return Value | Required | Platform | OpenHarmony Platform Support | Description | | ||
| 459 | +|--------|-------|----------|---------|-------|--------|-----|-----------------| | ||
| 460 | +| runBackgroundTimer | Function | callback: Function, delay: number | void | No | All | Yes | Starts a timer to repeatedly execute specified code at a fixed interval. | | ||
| 461 | +| stopBackgroundTimer | Function | / | void | No | All | Yes | Stops the timer started by **runBackgroundTimer**. | | ||
| 462 | +| start | Function | delay?: number | void | No | All | No | Starts a new task in the background. **delay** is optional and defaults to 0. | | ||
| 463 | +| stop | Function | / | void | No | All | No | Stops a background task. | | ||
| 464 | +| setTimeout | Function | callback: Function, timeout: number | number | No | All | Yes | Starts a timer to execute the specified code only once when the timer expires. | | ||
| 465 | +| clearTimeout | Function | timeoutId: number | void | No | All | Yes | Stops the timer started by **setTimeout**. | | ||
| 466 | +| setInterval | Function | callback: Function, timeout: number | number | No | All | Yes | Starts a timer to repeatedly execute specified code at a fixed interval. | | ||
| 467 | +| clearInterval | Function | intervalId: number | void | No | All | Yes | Stops the timer started by **setInterval**. | | ||
| 468 | + | ||
| 469 | +## Known Issues | ||
| 470 | + | ||
| 471 | +- The underlying OS does not support RNOHContext serialized transfer in the new thread created by Worker. As a result, events cannot be sent in the new thread. The underlying OS framework needs to implement related service functionality. If no thread is started, the timer is not affected because **setTimeout** is an asynchronous method. The **start** and **stop** APIs of the Worker thread are not supported in HarmonyOS RN: [issue#2](https://gitcode.com/CPF-RN/rntpc_react-native-background-timer/issues/2). | ||
| 472 | + | ||
| 473 | +## Other | ||
| 474 | + | ||
| 475 | +None | ||
| 476 | + | ||
| 477 | +## Directory Structure | ||
| 478 | +```` | ||
| 479 | +/rntpc_react-native-background-timer # Project root directory | ||
| 480 | +├── harmony # HarmonyOS adaptation code | ||
| 481 | +│ └─ background_timer.har # har package | ||
| 482 | +│ └─ background_timer # HarmonyOS adaptation core code | ||
| 483 | +│ └─ Index.ets # HarmonyOS adaptation code entry point | ||
| 484 | +│ └─ src/main/ets | ||
| 485 | +│ └─ BackgroundTimerTurboModule.ts # Background timer TurboModule file | ||
| 486 | +├── src # React Native code | ||
| 487 | +│ └─ RNBackgroundTimerSpec.ts # JS interface declaration file for the background timer TurboModule | ||
| 488 | +├── README.md # Chinese installation and usage instructions | ||
| 489 | +├── README_en.md # English installation and usage instructions | ||
| 490 | +```` | ||
| 491 | + | ||
| 492 | +## How to Contribute | ||
| 493 | + | ||
| 494 | +If you find any problem when using react-native-background-timer, submit an [issue](https://gitcode.com/CPF-RN/rntpc_react-native-background-timer/issues) or a [PR](https://gitcode.com/CPF-RN/rntpc_react-native-background-timer/pulls). | ||
| 495 | + | ||
| 496 | +## License | ||
| 497 | + | ||
| 498 | +The repository is based on [MIT License](https://gitcode.com/CPF-RN/rntpc_react-native-background-timer/blob/br_rnoh0.72/LICENSE). | ||
| @@ -4,7 +4,7 @@ | |||
| 4 | { | 4 | { |
| 5 | "name": 'default', | 5 | "name": 'default', |
| 6 | "signingConfig": 'default', | 6 | "signingConfig": 'default', |
| 7 | - "compileSdkVersion": '5.0.1(13)', | 7 | + "compileSdkVersion": '6.0.1(21)', |
| 8 | "compatibleSdkVersion": '5.0.0(12)', | 8 | "compatibleSdkVersion": '5.0.0(12)', |
| 9 | "runtimeOS": 'HarmonyOS' | 9 | "runtimeOS": 'HarmonyOS' |
| 10 | }, | 10 | }, |
| @@ -8,7 +8,7 @@ | |||
| 8 | "start": "hdc rport tcp:8081 tcp:8081 && react-native start", | 8 | "start": "hdc rport tcp:8081 tcp:8081 && react-native start", |
| 9 | "codegen": "react-native codegen-harmony --rnoh-module-path ./harmony/entry/oh_modules/@rnoh/react-native-openharmony", | 9 | "codegen": "react-native codegen-harmony --rnoh-module-path ./harmony/entry/oh_modules/@rnoh/react-native-openharmony", |
| 10 | "pack:pkg": "cd ../ && npm pack && cd ./example", | 10 | "pack:pkg": "cd ../ && npm pack && cd ./example", |
| 11 | - "install:pkg": "npm uninstall @react-native-ohos/react-native-background-timer && npm run pack:pkg && npm i @react-native-ohos/react-native-background-timer@file:../react-native-ohos-react-native-background-timer-2.4.2-rc.4.tgz", | 11 | + "install:pkg": "npm uninstall @react-native-ohos/react-native-background-timer && npm run pack:pkg && npm i @react-native-ohos/react-native-background-timer@file:../react-native-ohos-react-native-background-timer-2.4.2.tgz", |
| 12 | "dev": "npm run codegen && react-native bundle-harmony --dev --minify=false", | 12 | "dev": "npm run codegen && react-native bundle-harmony --dev --minify=false", |
| 13 | "prod": "npm run codegen && react-native bundle-harmony --dev=false --minify=true", | 13 | "prod": "npm run codegen && react-native bundle-harmony --dev=false --minify=true", |
| 14 | "postinstall": "node ./scripts/create-build-profile", | 14 | "postinstall": "node ./scripts/create-build-profile", |
| @@ -16,7 +16,7 @@ | |||
| 16 | }, | 16 | }, |
| 17 | "dependencies": { | 17 | "dependencies": { |
| 18 | "@gorhom/portal": "^1.0.14", | 18 | "@gorhom/portal": "^1.0.14", |
| 19 | - "@react-native-ohos/react-native-background-timer": "file:../react-native-ohos-react-native-background-timer-2.4.2-rc.4.tgz", | 19 | + "@react-native-ohos/react-native-background-timer": "file:../react-native-ohos-react-native-background-timer-2.4.2.tgz", |
| 20 | "react": "18.2.0", | 20 | "react": "18.2.0", |
| 21 | "react-native": "0.72.5", | 21 | "react-native": "0.72.5", |
| 22 | "react-native-harmony": "npm:@react-native-oh/react-native-harmony@^0.72.32" | 22 | "react-native-harmony": "npm:@react-native-oh/react-native-harmony@^0.72.32" |
| @@ -1,7 +1,7 @@ | |||
| 1 | { | 1 | { |
| 2 | name: '@react-native-ohos/react-native-background-timer', | 2 | name: '@react-native-ohos/react-native-background-timer', |
| 3 | version: '2.4.2', | 3 | version: '2.4.2', |
| 4 | - description: 'Please describe the basic information.', | 4 | + description: 'Emit event periodically (even when app is in the background)', |
| 5 | main: 'Index.ets', | 5 | main: 'Index.ets', |
| 6 | author: '', | 6 | author: '', |
| 7 | license: 'MIT', | 7 | license: 'MIT', |


【AI-Review】【一般】【基础代码问题】【代码逻辑错误】英文 README 的 Autolink 指南链接指向中文文档
● 问题:README_en.md 第43行将 Autolink 框架指南链接指向
https://gitcode.com/CPF-RN/ohos_react_native/blob/master/docs/zh-cn/Autolinking.md,该 URL 路径包含zh-cn,是中文版文档。README_en.md 是面向英文用户的文档,英文用户点击该链接后会进入中文页面,无法理解内容。通过 GitCode API 验证(GET /api/v5/repos/CPF-RN/ohos_react_native/contents/docs/en?ref=master),ohos_react_native仓库的docs/en/目录下不存在Autolinking.md文件,该目录仅有 Codegen.md、TurboModule.md、architecture.md 等文件,即 Autolink 指南目前仅有中文版,没有对应的英文翻译。● 影响:一般。英文用户按照文档操作时,点击 Autolink 指南链接会进入中文页面,无法获取英文操作指导,影响文档可用性。
● 建议:在链接后补充说明该指南目前仅提供中文版,例如:"AutoLink framework guide (currently available in Chinese only): https://gitcode.com/CPF-RN/ohos_react_native/blob/master/docs/zh-cn/Autolinking.md",待英文版翻译完成后更新为
docs/en/Autolinking.md链接。