【DAYU200】基于 DAYU200(RK3568)的镜像投屏 Sink 端连接回调失效与播放页异常疑难攻关
本文汇总 Miracast Sink 应用侧三类问题:连接回调收不到、未打开应用界面导致连不上、息屏后再投屏时播放页进入两次。其中「未进应用界面无法建连」复现设备为大禹 200 → 大禹 200;「息屏后播放页双开」分析对象为 dayu200(并与大屏对比);「连接监听收不到回调」按 Sink 应用侧问题定位,联调环境多为大禹 200。
Miracast Sink 是镜像投屏的收屏端:负责被发现、接受投屏会话,并在本地播放对端画面。应用通过 ServiceExtAbility 提供后台收屏能力,页面侧注册连接监听后由服务回调 onConnect / onDisconnect;底层依赖投播框架与 WFD(castengine_wifi_display)。
设备环境

案例疑难分析:Sink 已注册连接监听却收不到连接与断开回调
1. 问题描述
使用环境与设备: Miracast Sink 应用(com.ohos.miracastplayer)侧问题——页面把 listener stub 交给后台 Service 后收不到回调。联调多为大禹 200,按 Sink 应用问题定位即可。
【镜像投屏】Sink 端把连接状态监听对象交给后台服务后,一直收不到连接成功、断开等通知。
补充说明:
- Source / Sink:发屏端 / 收屏端
- IDeviceConnectListener:应用侧连接状态回调接口(onConnect / onDisconnect)
- stub / proxy:IDL 生成的跨 Ability 传递监听对象的代理
- 后台服务:ServiceExtAbility + MiracastPlayerServiceImpl,保证退后台后仍可收投屏
2. 分析过程
Sink 应用通过 ServiceExtAbility 提供后台投屏能力。页面(如 PlayerPage / Index)经 connectServiceExtensionAbility 连上服务后,调用 registerDeviceConnectListener,把 IDeviceConnectListener 以 stub 形式交给 MiracastPlayerServiceImpl。服务在 onDeviceStateCallback 里设备 CONNECTED / DISCONNECTED 时,再通过 DeviceConnectListenerProxy 回调应用。


开发中始终收不到回调。打开调试日志后,IPC 传递阶段出现 napi_remoteObject 报错:

也就是说:应用已发起注册,但同进程内 JS stub 传递失败,监听链路未真正建立,后续连接状态变化通知不到应用。
3. 解决方案
跟踪 IPC NAPI 层后确认:系统侧已有针对同一进程内、以 JS stub 形式传递监听对象失败的补丁。本场景与之吻合:
- Client(页面)向 Service(ServiceExtAbility)注册 listener
- listener 以 stub 传递
- Service 与 Client 同属应用主进程
合入该 IPC 补丁后,registerDeviceConnectListener 可成功建立代理链路,onConnect / onDisconnect 恢复正常。
案例疑难分析:未打开投屏应用界面时无法建立投屏连接
1. 问题描述
使用环境与设备: 两台大禹 200(DAYU200 / RK3568)互投——一台 Source、一台 Sink。Sink 打开投屏开关后不进入 Miracast 应用界面,再用另一台大禹 200 发起投屏。
问题现象: Sink 只开投屏开关、不进应用界面时,Source 发起投屏无法建连。
一句话概括:Sink 若只靠后台服务、没走过完整 UI 入口初始化,权限确认页会崩溃,投屏连不上。
2. 分析过程
复现操作:
- Sink 打开 Miracast 投屏开关
- 开机后不进入应用界面
- Source 发起投屏 → 无法建立连接
近期 app / framework / wfd 无相关功能改动,从日志定位。关键异常:
07-07 14:02:47.563 1101 1101 I A03d00/JSAPP: MiracastPlayerApp PermissionChoosePage --->>> scaling = 0.5796296296296297
07-07 14:02:47.564 1101 1101 E C03f00/ArkCompiler: TypeError: Cannot read property getStringValue of undefined
07-07 14:02:47.564 1101 1101 E C03f00/ArkCompiler: at aboutToAppear (PermissionChoosePage.ets:38:5)
...
07-07 14:02:47.568 1101 1101 E C01317/AppKit: com.ohos.miracastplayer is about to exit due to RuntimeError
权限确认页 PermissionChoosePage.aboutToAppear 读文案时崩溃:

问题代码原先使用 globalThis.resourceManager.getStringValue(...)。
而 globalThis.resourceManager 只在 EntryAbility.onCreate 里赋值:

本场景只拉起了 ServiceExtAbility(及权限浮窗),未走 EntryAbility,globalThis.resourceManager 为空 → getStringValue 抛 TypeError → 进程被杀 → 投屏连不上。
因果链:
仅启动后台服务 → 未初始化 globalThis.resourceManager → 权限页崩溃 → 应用退出 → 无法建链。
3. 解决方案
权限页改为通过当前页面 context 取资源管理器,不依赖 EntryAbility 预置的全局变量:
getContext().resourceManager.getStringValue($r('app.string.first_connect'))

这样即使只拉起后台服务与权限浮窗,权限页也能正常取文案,进程不再因 TypeError 退出,投屏可建连。
案例疑难分析:息屏后再被投屏时播放页面重复进入两次
1. 问题描述
使用环境与设备: Sink 为大禹 200(DAYU200 / RK3568)+ com.ohos.miracastplayer,应用在前台时息屏;Source 发起投屏并点亮 Sink。分析中对比了大屏息屏后不可被搜到、而 dayu200 往往未深睡仍可被发现(Source 型号未单独限定)。
问题现象: Sink 应用在前台但已息屏;Source 发起投屏并点亮 Sink 屏幕后,播放页会进入两次。
2. 分析过程
直接现象:
- 息屏时收到投屏请求,MiracastPlayerServiceImpl.startPlayerPage 会 startAbility 打开 EntryAbility(参数 startPlayer: true)
- 用户解锁后系统再次派发同类 want
- 两次都生效 → PlayerPage 进入两次
即同一轮投屏被处理了两次。
设备侧背景(非本次页面双开的直接原因):对比大屏与 dayu200 息屏后能否被搜到。dayu200 执行 echo mem > /sys/power/state 后往往只有 PM 休眠入口日志、未走完整深睡;大屏有深睡尝试但 Wi-Fi 恢复异常导致搜不到。故 dayu200 息屏后仍可被投——使本问题容易复现。

大屏相关日志摘要:进入 deep suspend 后出现 CPU kill/up、wlan open 失败等,息屏后搜不到设备。
本次优先修:亮屏后播放页进两次。
3. 解决方案
暂不处理 dayu200「不睡眠仍可被发现」;针对双开做两处防护:
- MiracastPlayerServiceImpl.startPlayerPage:用 power.isActive() 判断;若息屏则先 power.wakeup('MiracastPlayer'),短暂延迟后再 startAbility,避免息屏路径与亮屏路径各发一次混乱
- EntryAbility.onNewWant:若 router 当前已是 PlayerPage,直接 return,忽略重复 want
这样灭屏再投屏时只会进入一次播放页,用户解锁后不会再叠一层。
更多推荐
所有评论(0)