@hxa-rn/react-native-background-upload
v6.6.0-beta.1
Published
Cross platform http post file uploader with android and iOS background support
Readme
react-native-background-upload
本项目基于 react-native-background-upload开发。如果在使用过程中有任何问题,欢迎在AtomGit提交Issue,会及时跟进。
项目介绍
@hxa-rn/react-native-background-upload 是 react-native-background-upload 6.6.0 的 HarmonyOS 适配包,提供 HTTP(S) 文件上传 TurboModule。公开能力包括 raw 原始字节上传、multipart 表单上传、任务取消、文件信息查询、任务状态查询,以及 progress、completed、error、cancelled 事件。该包含 ETS/C++ 原生实现,并支持 RNOH Autolinking。
集成指南
npm install @hxa-rn/react-native-background-upload对等依赖:
react-native>= 0.72
包通过 harmony.alias 映射原包名 react-native-background-upload。配置 alias 后,业务代码仍按原库名称导入:import Upload from 'react-native-background-upload'。
该包含原生 TurboModule,RNOH Autolinking 会注册 BackgroundUploadPackage(C++ 目标名 background_upload)。若工程未自动生成注册,在应用的 RNOHPackagesFactory 中补上:
import BackgroundUploadPackage from '@hxa-rn/react-native-background-upload';
export function createRNOHPackages(ctx: RNPackageContext): RNOHPackage[] {
return [new BackgroundUploadPackage(ctx)];
}应用还需声明库模块已请求的系统权限,并在 UIAbility 配置 backgroundModes: ['dataTransfer']。
使用说明
上传前先用 getFileInfo 确认文件存在。startUpload 返回任务 ID 后订阅事件;页面卸载时调用订阅对象的 remove()。需要中止时调用 cancelUpload。
import Upload from 'react-native-background-upload';
export async function runRawUpload() {
const info = await Upload.getFileInfo('internal://cache/upload-test.bin');
if (!info.exists) {
throw new Error('file does not exist');
}
const uploadId = await Upload.startUpload({
url: 'https://example.com/upload',
path: 'internal://cache/upload-test.bin',
type: 'raw',
method: 'POST',
headers: {'content-type': 'application/octet-stream'},
maxRetries: 2,
});
const progressSubscription = Upload.addListener(
'progress',
uploadId,
event => {
console.info(`progress ${event.progress ?? 0}`);
},
);
const completedSubscription = Upload.addListener(
'completed',
uploadId,
event => {
console.info(`completed ${event.responseCode ?? 0}`);
},
);
const errorSubscription = Upload.addListener(
'error',
uploadId,
event => {
console.info(`error ${event.error ?? ''}`);
},
);
const cancelledSubscription = Upload.addListener(
'cancelled',
uploadId,
event => {
console.info(`cancelled ${event.id}`);
},
);
const status = await Upload.getUploadStatus(uploadId);
await Upload.cancelUpload(uploadId);
progressSubscription.remove();
completedSubscription.remove();
errorSubscription.remove();
cancelledSubscription.remove();
return {uploadId, status, info};
}multipart 必须提供 field。附加表单字段放在 parameters 中,仅对 multipart 生效。
import Upload from 'react-native-background-upload';
export async function runMultipartUpload() {
const uploadId = await Upload.startUpload({
url: 'https://example.com/upload',
path: 'internal://cache/sample.jpg',
type: 'multipart',
method: 'POST',
field: 'uploaded_media',
parameters: {scene: 'avatar'},
});
return uploadId;
}path 支持应用沙箱路径、internal://cache/... 以及已授权的媒体 URI。method 仅允许 POST 或 PUT。
接口文档
| API | 参数 | 返回值 | 说明 |
| --- | --- | --- | --- |
| startUpload(options) | StartUploadArgs | Promise<string> | 启动 raw 或 multipart 上传并返回上传 ID |
| cancelUpload(uploadId) | string | Promise<boolean> | 取消活动任务;参数必须是字符串,否则 Promise 拒绝 |
| getFileInfo(path) | string | Promise<FileInfo> | 返回 name、exists,以及文件存在时的 size、extension、mimeType |
| getUploadStatus(uploadId) | string | Promise<UploadStatus> | 查询任务是否存在、当前状态及 0~100 的进度;空 ID 会抛错 |
| addListener(eventType, uploadId, listener) | 事件类型、可空上传 ID、回调 | EmitterSubscription | 监听 progress、completed、error、cancelled;uploadId 为 null 时监听全部任务。调用返回值的 remove() 解除订阅 |
StartUploadArgs
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| url | string | 必填,仅支持 HTTP(S) 地址 |
| path | string | 必填,待上传文件路径或已授权 URI |
| method | POST \| PUT | 默认 POST |
| type | raw \| multipart | 默认 raw |
| field | string | multipart 必填,文件表单字段名 |
| customUploadId | string | 可选自定义任务 ID,活动任务间必须唯一 |
| parameters | Record<string, string> | multipart 附加表单字段;raw 不支持 |
| headers | Record<string, string> | 请求头 |
| notification | NotificationArgs | 通知标题、消息等兼容配置,部分 Android 字段在 HarmonyOS 无等同行为 |
| maxRetries | number | raw 为应用层重试次数,默认 2;对端直接掐连接时系统 HTTP 可能再多打 1 次。multipart 仅映射为允许/禁止重试 |
| retryOnConnectionFailure | boolean | 显式控制连接失败是否重试,优先于 maxRetries 的启停判断 |
| followRedirects / followSslRedirects | boolean | raw 与 multipart 的底层能力不同;multipart 合并为单一开关 |
| connectTimeout / writeTimeout / readTimeout | number | 超时秒数 |
| useUtf8Charset | boolean | Android 专属兼容参数,HarmonyOS 无对应行为 |
| appGroup | string | iOS 专属兼容参数,HarmonyOS 无对应行为 |
返回类型
| 类型 | 字段 |
| --- | --- |
| FileInfo | name、exists、可选的 size、extension、mimeType |
| UploadStatus | id、found、state、progress;state 为 initialized、waiting、running、retrying、paused、stopped、completed、failed、removed、unknown |
| UploadEventData | id,以及按事件提供的 progress、error、responseCode、responseBody、responseHeaders |
addListener 的 eventType 仅允许 progress、error、completed、cancelled。
快速验证(运行 Example)
前置条件
| 依赖 | 版本要求 | |------|----------| | Node.js | >= 18 | | DevEco Studio | 5.0+ / 6.0+ | | HarmonyOS SDK | API 21+ |
运行步骤
1. 克隆仓库
git clone https://gitcode.com/hxa-rn/react-native-background-upload.git
cd react-native-background-upload
git checkout br_rnoh0.722. 安装仓库开发依赖
npm install --legacy-peer-depsExample 已改为从 npm 公仓安装 @hxa-rn/[email protected],不再使用本地 file:../xxx.tgz,运行 Example 不必再执行 npm pack。
3. 进入 example 目录,安装依赖
cd example
npm install --legacy-peer-deps4. 生成 JS Bundle
npm run dev产物:harmony/entry/src/main/resources/rawfile/bundle.harmony.js
5. 用 DevEco Studio 打开鸿蒙工程
- 打开 DevEco Studio
- 选择
example/harmony目录 - 等待 Sync 完成
6. 编译并运行 HAP
在 DevEco Studio 中点击运行按钮,将 HAP 安装到设备/模拟器。
注意:Example 中已预置插件依赖和 Package 注册,无需手动配置 Link。
约束与限制
| 项目 | 说明 |
| --- | --- |
| React Native / RNOH | 对等依赖为 React Native 0.72 及以上。示例工程使用 React Native 0.72.5 与 @react-native-oh/react-native-harmony 0.72.139 |
| HarmonyOS SDK | 库 HAR compatibleSdkVersion 为 21。example 与 example_auto 的 compatibleSdkVersion 均为 6.0.1(21) |
| Node | engines.node 为 >=18 |
| 权限 | 库模块声明 ohos.permission.INTERNET、ohos.permission.KEEP_BACKGROUND_RUNNING。应用 UIAbility 需配置 backgroundModes: ['dataTransfer'] |
| raw 上传 | 文件会一次性读入 ArrayBuffer,上限为 64 MiB;超过上限会拒绝并提示改用 multipart。raw 使用 HTTP 连续任务,应用退至后台可继续,但进程终止后不能由系统恢复 |
| multipart 上传 | 使用系统 request.agent 托管;应用沙箱文件可使用系统后台模式,公共媒体 URI 因授权生命周期使用前台模式 |
| method | 仅允许 POST 与 PUT |
| maxRetries | raw 按该次数做应用层重试,默认 2 次;对端直接掐连接时系统 HTTP 可能再多打 1 次。multipart 不能保证精确次数 |
| 重定向 | multipart 将 followRedirects 与 followSslRedirects 合并为一个系统重定向开关 |
| 平台专属参数 | appGroup 为 iOS 专属、useUtf8Charset 为 Android 专属;HarmonyOS 仅接受参数以保持调用兼容 |
| 通知参数 | Android 专属的通知频道、铃声、自动清除等参数无法一一映射;系统要求的连续任务通知不保证可由 notification.enabled: false 关闭 |
开源license
本项目基于 MIT 协议,详见 LICENSE 文件。
问题反馈渠道
- https://gitcode.com/hxa-rn/react-native-background-upload
- https://gitcode.com/hxa-rn/react-native-background-upload/issues
