【HarmonyOS NEXT】跨工程扫码从“无反应” 到 “崩溃” 的踩坑记录
摘要: 在鸿蒙项目中实现主工程跨工程调用扫码功能时,遇到三个主要问题:1) 扫码按钮无反应,发现是未注册自定义服务IAddDeviceRouterService,通过EntryAbility初始化时调用bindService解决;2) 注册服务后应用崩溃,因缺少百度地图依赖包@bdmap/verify,添加后仍报错;3) 需引入配套的@bdmap/base等4个包并通过oh-package.jso
一、背景
在开发鸿蒙项目时,需要实现“主工程跨工程调用扫码功能”,出现以下几个坑,记录下踩坑过程;
坑:“扫码按钮无反应” → “注册服务后应用崩溃” → “依赖包引入仍报错”,最终靠版本匹配 + 配置优化解决。
二、项目情况:
2.1、项目背景
扫码功能我们是封装在一个工程模块中,目前已有一个上线的app使用了该功能,那现在新开发的app引入该模块扫码能力即可
2.2、核心需求
点击主工程 “扫码” 按钮,通过ServiceManager调用扫码服务,跳转到扫码页面
三、踩坑记录
3.1、坑1:跨工程扫码按钮无反应,控制台无报错
3.1.1、现象:
在主工程中添加扫码按钮,调用扫码模块的IAddDeviceRouterService服务跳转扫码页,但点击后无任何反应,控制台打印日志发现是undefined,无其他报错:
Text('扫码').fontColor('#ffffff')
.onClick(()=>{
console.log('lucy== 999',ServiceManager.getService<IAddDeviceRouterService>('IAddDeviceRouterService'))
ServiceManager.getService<IAddDeviceRouterService>('IAddDeviceRouterService')?.toScanPage()
})
3.1.2、过程:
一开始以为是相机权限问题,检查module.json5已配置ohos.permission.CAMERA,但仍无反应;但日志打印是undefined,意识到可能是服务未注册的原因
3.1.3、原因分析:
IAddDeviceRouterService是项目的自定义服务(非鸿蒙原生),需通过ServiceManager.registerService手动注册,主工程未执行注册逻辑,导致获取服务实例为undefined,toScanPage()方法从未执行。
3.1.4、解决方案:在应用启动时注册服务
该服务在另一个模块方法内已经注册,引入即可
1、找到项目的bindService方法(负责服务注册),在需要使用扫码功能的工程中引入该方法;
2、在工程EntryAbility初始化时调用bindService,传递应用上下文:
// 主工程EntryManager.ts
import { bindService } from '@xxx/device-config';
export class EntryManager {
onCreateInit(want: Want, context: common.UIAbilityContext) {
this.context = context;
bindService(this.context); // 注册IAddDeviceRouterService等服务
// 其他初始化逻辑...
}
}
3、注册逻辑(@xxx/device-config中的bindService):
@xxx/device-config是公司内部封装的基础工具模块,注册逻辑在该模块已封装,项目中引入该模块即可
// 服务注册代码
export function bindService(context:Context) {
ServiceManager.registerService<IAddDeviceRouterService>(
"IAddDeviceRouterService",
BHAddDeviceRouterService.getInstance(context)
);
// 其他服务注册...
}
3.2、坑 2:注册服务后应用崩溃,报错 “找不到 bdmap 模块”
3.2.1、现象:
执行服务注册后,应用启动即崩溃,日志核心报错:
Error message:cannot find record '&@bdmap/verify/Index&1.0.4',please check the request path.'/data/storage/el1/bundle/entry/ets/modules.abc'.

3.2.2、过程
1、刚开始以为是服务注册代码错误,注释IAddDeviceRouterService注册后,应用正常启动,确定是该服务依赖导致;
2、查看报错信息,发现其内部引用了@bdmap/verify/Index模块(百度地图验证组件),主工程未引入该依赖。
3.2.3、原因分析
那就说明问题不是出现服务注册代码上,问题出在百度地图依赖包没有引入的原因,导致加载服务实现类时,触发 “模块未找到” 的错误。
3.2.4、解决方案:引入@bdmap/verify私有 HAR 包
在主工程oh-package.json5中添加依赖,并npm install安装依赖
{
"dependencies": {
"@bdmap/verify": "1.0.4" // 版本需与已上线app版本一致
}
}
3.3、坑 3:引入@bdmap/verify后仍崩溃,单一依赖不够
3.3.1、现象:
仅引入@bdmap/verify@1.0.4后,应用仍崩溃,报错与之前一致,无任何变化。
3.3.2、过程
1、检查@bdmap/verify包是安装正常,那就排除依赖未安装问题
2、尝试单独引入@bdmap/verify的依赖包@bdmap/base,配置后仍报错;
3、逐一尝试引入@bdmap/map、@bdmap/search等相关包,最终加全 4 个包后报错消失。
3.3.3、原因分析
@bdmap/verify@1.0.4是强耦合的组合包,内部依赖 4 个配套底层包,仅引入单一依赖无法满足模块加载需求
鸿蒙编译时不会校验私有包的内部依赖,仅在运行时触发 “模块未找到” 错误,且日志不明确提示缺失哪个依赖,只能反向试错。
3.3.4、解决方案:用overrides强制统一配套版本
在主工程oh-package.json5中添加overrides配置,强制项目中所有@bdmap/*包使用与@bdmap/verify@1.0.4配套的版本:
备注:以下这几个依赖的版本是同事在开发已上线app时引入该能力发现版本太高无法编译,通过一步步调式试错才得出以下版本
{
"overrides": {
"@bdmap/base": "^1.2.1",
"@bdmap/map": "^1.2.8",
"@bdmap/search": "^1.2.8",
"@bdmap/locsdk": "1.1.5"
}
}
说明:官网里面根据这一场景也给了解决方法 ⬇️
四、避坑总结
1、跨工程服务调用:先注册,再使用
既然用了,就要找到是哪里注册的,需注册后才能用,否则返回undefined
2、私有 HAR 包依赖:版本配套是最关键
私有 HAR 包(如@bdmap/verify)常存在 “强耦合依赖”,需找到完整的配套版本组合;
overrides是强制统一所有子依赖版本,可以解决 “版本不配套导致的模块解析失败”
3、通过日志,查看问题根源
鸿蒙ARKTS 的 “cannot find record” 错误,本质是 “模块未找到 / 解析失败”,
可能原因:依赖包未安装+依赖版本不兼容+模块导出 / 导入路径错误;
排查思路:先查依赖是否完整→再查版本是否配套→最后查代码引用是否正确
更多推荐





所有评论(0)