1. 问题描述

使用环境与设备: 两台 OpenHarmony L2 富设备(润和 DAYU200 / RK3568 开发板)做富对富文件互传;双端打开蓝牙、Wi-Fi 与「统一互联分享」开关,近场互传;发送端从图库/文件管理器分享约 1G 视频。涉及组件:

  • 应用层:Share 应用(包名 com.ohos.oneconnect.share),接收端由 SinkModel 处理传输状态与界面
  • 服务层:FileShare SA,SendManager 负责收发与状态回调

问题现象(必现): 接收约 1G(或接近 1G)大文件视频时,界面提示「传输错误」;但文件已落盘,图库中可正常打开。
也就是说:底层接收已成功,应用层因超时把结果误报成失败。

设备环境

img

2. 分析过程

正常预期:文件收完 → 服务上报「传输成功」→ SinkModel 收尾并提示成功。
实际:文件已保存,界面却报错误。说明问题在「成功状态何时上报 / 应用如何判超时」,而不是传输通道本身。

步骤一:确认传输通道是否正常

先核对 Source / Sink 两端日志:

  • Source:发出文件的一侧
  • Sink:接收文件的一侧
  • session:软总线传输会话

发送端:session 正常打开并开始传文件。

image.png

发送端日志未见可疑错误。

接收端:通道同样正常打开并收完文件。

image.png

与「图库已保存」一致,可排除「文件没传成功」,继续查界面为何仍报错。

步骤二:确认错误提示来自哪里

继续看接收端相关日志:

image.png

「传输错误」不是底层通道直接抛的,而是 Share 应用根据 sendChange 状态与看门狗自行判定后提示的
对应逻辑在 SinkModel.sendChangeCallback:若超时回调触发,会把 deviceStatus 置为 Error 并刷新界面。

步骤三:对比正常与异常的状态上报

@ohos.oneConnect.fileShare 中 SendState 定义为:

枚举含义
0UNKNOWN初始/会话就绪
1PROCESSING传输中
2SUCCESS传输成功
3FAILURE传输失败

正常应依次上报:

  1. state = 1(PROCESSING),进度 0→100
  2. state = 2(SUCCESS),进度 100

问题日志里只有 PROCESSING,缺少 SUCCESS,分享流程没有正常收尾。
根因收敛为:FileShare 服务未及时向应用上报 SUCCESS,应用侧看门狗把结果判成错误。

步骤四:定位 PROCESSING(100) 到 SUCCESS 之间卡住的原因

服务侧收文件完成回调在 FileShare 的 SendManager::OnReceiveFileFinished:

image.png

当时在上报 SUCCESS 之前会调用 SendManager::CheckFileHash(),对接收文件做 MD5(FileHash::HashWithMD5)完整性校验;通过后再 HandleMediaAsset 入库,最后才 NotifyEvent(..., SendState::SUCCESS, ...)。

应用侧 SinkModel 在收到 PROCESSING 且 progress == 100 时,会把消息看门狗切到「等待成功」超时(常量 SINK_MESSAGE_TRANSFER_SUCCESS_TIMEOUT_MS)。超时则走 messageTimeoutCallback,界面报传输错误。

关键时间关系:

  • 约 1G 文件的 MD5 校验大约 30 秒
  • 应用侧等待 SUCCESS 的超时窗口 短于该校验耗时(问题复现时即因此触发看门狗)

因果链:

大文件 MD5 校验过久 → 服务迟迟不上报 SUCCESS → SinkModel 看门狗超时误报错误 → 界面显示失败,文件其实已收完并入库。

3. 解决方案

在 OnReceiveFileFinished 中去掉接收侧 CheckFileHash 调用,发送侧同步去掉 HashFile 预计算。该校验对当前互传业务并非必需;去掉后可立刻进入媒体入库并上报 SUCCESS,界面结果与实际传输一致,成功提示更快,大文件发送成功率提升。

若业务上仍需完整性校验,则应二选一或组合:把校验挪到异步后台、或把应用侧「等待 SUCCESS」超时调到大于最坏校验耗时,避免误报失败。

整体流程如下:

image.png

Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐