鸿蒙生态下广告统一跳转能力的探索与工程实践
广告跳转能力是广告生态的核心环节,针对鸿蒙生态架构特性与路由体系迭代,本文围绕广告 SDK 统一跳转能力展开三阶段实践:第一阶段基于 @ohos.router 实现 H5 落地页基础跳转,完成路由组件封装与 Web 页面权限适配;第二阶段应对系统 Router 接口废弃,重构为 HMRouter 组件实现无界面依赖的页面跳转;第三阶段适配 DeepLink 直呼能力,通过 openLink 接口、页内拦截、白名单机制实现应用间安全跳转。最终形成一套标准化、可扩展的鸿蒙广告统一跳转方案,保障了广告跳转的稳定性、安全性与兼容性。
01
前言
在移动互联网商业化体系中,广告跳转能力是连接广告创意、用户交互与业务转化的关键基础功能,直接影响广告投放效率、变现效果与用户体验,更是广告生态不可或缺的核心环节。然而,鸿蒙(HarmonyOS)作为面向全场景的分布式操作系统,其底层架构、版本演进节奏与应用运行机制,与 iOS/Android 存在本质性差异,这一差异直接决定了传统广告跳转方案无法直接复用,必须针对鸿蒙平台进行定制化开发。
随着鸿蒙操作系统的快速迭代与生态规模化落地,越来越多的应用与服务加速向鸿蒙生态迁移。原有基于 iOS/Android 平台构建的广告跳转逻辑与 SDK 实现,已难以适配鸿蒙系统的分布式架构特性、严格的安全规范以及多设备协同场景,无法满足广告业务的正常投放与高效转化需求。为此,为支撑鸿蒙生态下广告业务的持续演进,保障广告跳转流程的统一性、稳定性、安全性与兼容性,我们亟需针对性设计并实现一套标准化、可扩展的鸿蒙广告统一跳转能力,填补传统方案在鸿蒙平台的适配空白。
相较于 iOS/Android 数十年沉淀的成熟生态,鸿蒙的分布式架构设计从底层层面,决定了其广告跳转逻辑的独特性与适配复杂性,二者在核心技术维度的差异具体如下:
| 对比维度 | 鸿蒙 (HarmonyOS) | iOS (Apple) | Android | 对广告跳转的核心影响 |
|---|---|---|---|---|
| 开发语言 | ArkTS | Swift | Kotlin | |
| 应用框架 | ArkUI | UIKit | Jetpack Compose | |
| 路由体系 | ||||
| Web 能力 | ||||
| 生态特点 |
结合鸿蒙系统演进节奏与生态发展现状,我们发现初期难以在广告场景中落地 DeepLink 跳转能力,主要受限于以下三方面核心因素,这也是我们后续开展适配工作时需重点突破的难点:
• 系统接口未标准化:鸿蒙 API 12 之前,缺乏类似 openLink 的标准化应用间跳转接口,早期仅能通过显式 Want 实现跳转,而显式 Want 需明确指定目标应用包名。彼时京东、淘宝等广告投放高频目标应用的鸿蒙版包名尚未稳定,无法满足线上商用的稳定性要求。
• 第三方生态适配滞后:广告业务中高频调用的电商、社交等第三方应用,其鸿蒙原生版本的开发、测试与上架进度缓慢,即便客户端完成 DeepLink 跳转逻辑开发,也无对应的鸿蒙版应用承接跳转流量,导致功能无法落地。
• 安全管控机制不完善:鸿蒙平台初期未建立成熟的 Scheme 白名单、权限校验与风险拦截机制,若直接开放应用间跳转能力,易出现恶意唤起、违规跳转等安全与合规风险,不符合平台安全管控要求。
面对上述核心问题,我们并未直接切入 DeepLink 能力开发,而是基于鸿蒙生态的演进节奏、广告业务的核心诉求(稳定性、兼容性、安全性),先梳理出 “阶梯式落地” 的整体解题思路,并对不同阶段的技术选型做了针对性评估:
• 短期适配选型:优先基于鸿蒙基础 Web 能力搭建自定义路由组件,保障 H5 跳转的 “可用”,解决广告跳转的基础诉求;
• 中期重构选型:针对系统 Router 接口废弃的兼容性问题,重构统一的 HMRouter 框架,适配接口变更的同时沉淀可复用的路由能力;
• 长期攻坚选型:待鸿蒙系统接口标准化、第三方生态适配成熟后,攻坚 DeepLink 直呼能力,并同步补齐安全管控机制,实现跳转能力从 “可用” 到 “好用” 的升级。
基于这一 “先解决基础诉求、再适配系统变更、最后攻坚核心能力” 的选型思路,广告 SDK 所依赖的路由与跳转体系,伴随系统架构的持续升级、开发范式的迭代优化以及广告业务场景的不断深化,整体呈现 “阶梯式演进、问题驱动迭代” 的清晰路径。下文将分三个阶段,系统阐述鸿蒙广告统一跳转能力的技术探索、工程实现与关键问题解决方案,清晰呈现我们在适配过程中的实践思路与核心成果。
02
第一阶段:自定义RouteUtil组件及H5落地页支
目前已有的 iOS 与 Android 广告 SDK 支持多种跳转能力,包括 DeepLink、H5 落地页、微信小程序,以及 iOS 平台的 universal link。其中,DeepLink 与 H5 落地页是投放量最大、使用最广泛的两种跳转方式。
在鸿蒙生态发展初期,官方提供的 API 仅支持打开 H5 Web 页面,应用间的 DeepLink 跳转能力暂无法在广告场景中使用(具体原因将在后续说明);同时,微信相关能力在鸿蒙平台上尚未完善。因此,初代鸿蒙广告 SDK 仅实现了 H5 落地页跳转这一种能力。
在 iOS 广告 SDK 中,我们开发了名为 Router 的路由组件,使用 CocoaPods 集成到 SDK,这一组件对应用内所有页面跳转能力进行统一收敛与封装。该组件对外提供统一调用入口,支持将各类跳转链接以参数形式传入,内部根据跳转类型完成路由分发与逻辑处理,实现了跳转逻辑与业务模块的解耦。
为保持多端架构设计一致性,并满足后续功能迭代与扩展需求,本次在鸿蒙生态中同样设计并实现了一套统一路由组件。该组件沿用统一入口、统一调度、统一分发的设计思路,将所有跳转能力收拢至同一组件内部,对外提供简洁、标准的调用方式,便于后续维护、扩展与多端对齐。
2.2.1 RouteUtil入口
为方便各广告位统一使用,将接口设计为单例模式。各广告模块调用统一入口时,无需重复创建实例、赋值属性再调用接口,可大幅简化调用流程,减少冗余操作。
class RouteUtil {
...
private static instance: RouteUtil = new RouteUtil();
static getInstance(): RouteUtil {
if (!RouteUtil.instance) {
RouteUtil.instance = new RouteUtil();
}
return RouteUtil.instance;
}
...
}
const routeUtil = RouteUtil.getInstance();
export default routeUtil as RouteUtil接口设计思路
为统一广告位跳转逻辑、降低各业务模块接入成本,同时保证后续功能可平滑扩展,接口统一封装全场景跳转能力。当前仅需使用核心参数即可满足现有业务,后续新增跳转场景无需重构接口。
当前业务场景仅需使用 context 与 landingUrl 即可满足 H5 落地页跳转需求。接口已提前预留 DeepLink、微信小程序等全场景跳转能力,后续业务迭代时可直接启用对应参数,无需修改接口结构,具备良好扩展性。
/**
*
* @param context HarmonyOS 环境必需参数,作为页面跳转、能力调用的上下文媒介
* @param supportDeepLink 业务逻辑标识,用于标记当前广告是否支持 DeepLink 跳转
* @param deepLinkUrl DeepLink 跳转地址,用于直接唤起 App 内指定页面
* @param landingUrl H5 落地页地址,用于跳转外部 H5 页面
* @param wxId 微信小程序原始 ID/AppID,用于唤起微信小程序
* @param wxPath 微信小程序跳转路径,配合 wxId 实现小程序指定页面打开
*/
route(context: common.UIAbilityContext, supportDeepLink: number, deepLinkUrl: string, landingUrl: string,
wxId: string, wxPath: string): void {
...
}基于鸿蒙 @ohos.router 模块实现页面跳转,共享包内页面跳转使用 pushNamedRoute 接口。
router.pushNamedRoute({
name:'WebPage',
params:data
})
.then(()=>{
AdLog.i(TAG, `null ad`)
})
.catch((err:BusinessError) => {
AdLog.e(TAG, `pushUrl failed failed, code is ${err.code}, message is ${err.message}`);
})2.2.2 独立的WebPage页面
为实现 H5 落地页的展示需求,需单独开发一个支持 Web 渲染能力的 Page 页面,专门用于承载并渲染落地页内容。技术选型上,我们引入鸿蒙原生的 ArkWeb(方舟 Web)组件库,该库提供的 Web 组件可直接在应用内完成 Web 页面内容的加载与展示。
首先,需要引入ArkWeb组件。
import { webview } from '@kit.ArkWeb';在 WebPage 页面中需定义WebviewController是 Web 组件的唯一控制入口:需先完成实例化,并将其绑定至 Web 组件的controller属性后,才能具备操控能力。
其核心作用是实现对 Web 组件的主动操控,涵盖网页加载、导航控制、页面刷新 / 停止、JS 交互等核心能力;相较于被动监听 Web 组件事件的模式,WebviewController支持主动干预 Web 组件行为 —— 所有对 Web 组件的主动操作均需通过该控制器完成,若未配置控制器,Web 组件仅能被动展示网页内容,无法进行任何主动干预。
webController: webview.WebviewController = new webview.WebviewController();在自定义界面中集成 Web 组件,实现 Web页面的加载展示。
Web({ src: this.webdata.landing, controller: this.webController })其中,webdata 为 SDK 自定义的数据类,landing为落地页的URL地址,controller 为当前页面定义的WebviewController控制器。
Web 组件核心事件处理:实现进度条隐藏、页面加载回调、DNS 预解析、标题渲染等交互逻辑。
至此,我们的广告SDK统一跳转Router已初具结构。
在初始版本上线后,我们发现部分特殊落地页出现打开空白的问题,同时部分需要特殊权限(如定位权限)的落地页也无法正常加载。
经排查,鸿蒙平台的 Web 组件存在一套独立于 iOS、Android 的权限配置体系。因此,要完整支持各类广告落地页,必须对相关权限进行适配与配置。
为了实现权限的灵活管控,我们新增了从后端动态读取落地页权限配置的能力,确保不同类型的落地页均可按需获取所需权限并正常展示。
从广告配置中心后端拉取 Web 组件权限配置,遍历配置列表匹配当前落地页 URL,匹配成功后赋值对应的权限参数(如定位、JS、存储等),以下为配置示例:
{
"url": "mapapi.qq.com",
"domStorageAccess": true,
"fileAccess": false,
"imageAccess": true,
"javaScriptAccess": true,
"onlineImageAccess": true,
"zoomAccess": true,
"overviewModeAccess": true,
"databaseAccess": false,
"geolocationAccess": false,
"mediaPlayGestureAccess": true,
"multiWindowAccess": false,
"horizontalScrollBarAccess": true,
"verticalScrollBarAccess": true
}将上述读取并赋值的权限参数,逐一绑定至 Web 组件的对应属性,完成落地页权限适配。
Web({ src: this.webdata.landing, controller: this.webController })
.width('100%')
.height('100%')
.domStorageAccess(this.domStorageAccess)
.fileAccess(this.fileAccess)
.imageAccess(this.imageAccess)
.javaScriptAccess(this.javaScriptAccess)
.onlineImageAccess(this.onlineImageAccess)
.zoomAccess(this.zoomAccess)
.overviewModeAccess(this.overviewModeAccess)
.databaseAccess(this.databaseAccess)
.geolocationAccess(this.geolocationAccess)
.mediaPlayGestureAccess(this.mediaPlayGestureAccess)
.multiWindowAccess(this.multiWindowAccess)
.horizontalScrollBarAccess(this.horizontalScrollBarAccess)
.verticalScrollBarAccess(this.verticalScrollBarAccess)针对需获取地理位置权限的落地页场景,开发了以下地理位置权限申请弹窗。
.onGeolocationShow((event) => { // 地理位置权限申请通知
AlertDialog.show({
title: '位置权限请求',
message: '是否允许获取位置信息',
primaryButton: {
value: 'cancel',
action: () => {
if (event) {
event.geolocation.invoke(event.origin, false, false); // 不允许此站点地理位置权限请求
}
}
},
secondaryButton: {
value: 'ok',
action: () => {
if (event) {
event.geolocation.invoke(event.origin, true, false); // 允许此站点地理位置权限请求
}
}
},
cancel: () => {
if (event) {
event.geolocation.invoke(event.origin, false, false); // 不允许此站点地理位置权限请求
}
}
})
})HarmonyOS 早期的应用间跳转依赖 startAbility 方式,并需通过显式 Want 实现跳转,而显式 Want 必须指定目标应用的包名。
在项目初期,京东、淘宝等广告常用的目标应用尚未完全适配鸿蒙平台,其对应的鸿蒙版包名也未确定或无法获取,因此不具备线上商用条件。
基于上述限制,DeepLink 跳转能力仅在 Demo 环境中完成验证,暂未上线到正式版本。
以下为基于显式 Want 的跳转实现示例,该方案不适用于线上环境。
deeplinkOtherApp(context:common.UIAbilityContext, supportDeepLink: number, deepLinkUrl :string): boolean{
let want:Want = {
// entities can be omitted
deviceId: '',
bundleName: 'ohos.samples.stagemodel',
abilityName: 'JumpAbility',
uri: deepLinkUrl
};
try {
context.startAbility(want)
.then(()=>{
// 执行正常业务
AdLog.i(TAG, `startAbilityForResult succeed`);
return true;
})
.catch((err: BusinessError)=>{ // 处理业务逻辑错误
AdLog.e(TAG,`startAbilityForResult failed, code is ${err.code}, message is ${err.message}`);
return false;
})
} catch (err) {
// 处理入参错误异常
let code = (err as BusinessError).code;
let message = (err as BusinessError).message;
AdLog.e(TAG, `startAbilityForResult failed, code is ${code}, message is ${message}`);
}
return false;
}综上,初代方案仅满足 H5 落地页基础跳转需求,既面临 DeepLink 能力缺失导致的业务损失,又存在系统 Router 接口废弃的技术风险,因此启动第二阶段的路由架构重构工作。
03
第二阶段:Router接口废弃后的HMRouter重构
原项目中使用的 @ohos.router 接口自 API Version 18 起被官方废弃,因此亟需适配一款可替代的 API 来承接广告跳转核心能力。
方案评估 1:Navigation 组件(官方推荐替换方案)
鸿蒙官网将 Navigation 组件作为 @ohos.router 的替代方案,该组件基于导航逻辑实现页面管理,但强依赖界面上下文,与广告业务场景适配性极低。
广告类型中包含「由搜狐视频客户端接收我方数据并自主绘制界面」的场景,若采用 Navigation 实现跳转,需客户端在其界面层适配广告落地页跳转逻辑,不仅大幅增加客户端开发工作量,还会导致广告功能的维护、拓展成本剧增,因此该方案不可行。
方案评估 2:HMRouter 组件(最终选定方案)
HMRouter 是 HarmonyOS 官方开源的路由管理组件,自 HarmonyOS 5.0.0(API Version 10)起正式可用,核心解决页面间跳转问题。该框架底层封装了 Navigation 相关能力,可降低开发者对 Navigation 底层细节的关注、提升开发效率;同时增强了路由拦截、单例页面等核心能力。
作为 Navigation 组件的高层封装,HMRouter 整合了路由拦截、生命周期管理、自定义动画等能力,支持多模块解耦开发;核心优势是不依赖界面上下文,可通过数据接口直接触发页面跳转,与当前广告业务的适配度达到最优。
3.2.1 HMRouter插件引入
插件安装
使用 ohpm 安装hmrouter插件。
# 安装路由框架核心库
ohpm install @hadss/hmrouter#####依赖配置
修改工程根目录下的hvigor/hvigor-config.json 文件,加入路由编译插件。
"dependencies": {
"@hadss/hmrouter-plugin": "^1.2.0"
}#####插件配置
修改工程根目录下的hvigorfile.ts,使用路由编译插件。
import { hapTasks } from '@ohos/hvigor-ohos-plugin';
import { hapPlugin } from '@hadss/hmrouter-plugin';
export default {
system: hapTasks,
plugins: [hapPlugin()] // 使用HMRouter标签的模块均需要配置,与模块类型保持一致
}初始化路由框架
在主工程代码 EntryAbility 中初始化路由框架。
export default class EntryAbility extends UIAbility {
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
AdLog.SHOW_LOG = true // 打开日志显示
HMRouterMgr.init({
context: this.context
})定义路由入口
在主工程代码中定义路由入口。
class MyNavModifier extends AttributeUpdater<NavigationAttribute> {
initializeModifier(instance: NavigationAttribute): void {
instance.hideNavBar(false);
}
}
@Entry
@Component
struct Index {
modifier: MyNavModifier = new MyNavModifier();
build() {
Column() {
HMNavigation({
navigationId: 'mainNavigationId', homePageUrl: 'mptctvadhomepage', options: {
standardAnimator: HMDefaultGlobalAnimator.STANDARD_ANIMATOR,
modifier: this.modifier
}
});
}
}
}3.2.2 RouteUtil组件改造
入口逻辑改造
原基于 @ohos.router 的页面跳转入口全部替换为 HMRouter 框架的 HMRouterMgr.push 方法,实现广告落地页的定向跳转能力:
• 核心调用方法:HMRouterMgr.push(HMRouter 核心跳转 API);
• 核心参数 1(pageUrl):指定目标跳转页面的唯一标识路径,用于精准定位需拉起的广告落地页承载页面;
• 核心参数 2(param):封装跳转所需的关键业务数据,包含但不限于落地页 URL 路径、广告位标识、权限配置等核心信息,作为页面跳转的业务上下文传递。
import { HMRouterMgr } from '@hadss/hmrouter';
...
HMRouterMgr.push({
pageUrl: 'MPTCTVADWebPage', param: data
}, {
onArrival: () => {
AdLog.i(TAG, `pushUrl success `);
}
});
...
WebPage改造
在承载广告落地页的 WebPage 页面中,显式声明该页面在 HMRouter 路由体系下的唯一标识 pageUrl(路由路径)。
该 pageUrl 作为 HMRouter 路由匹配的核心标识,RouteUtil 组件可通过识别此路径,精准判定需跳转的目标页面为 WebPage,从而完成广告落地页的定向拉起。
//引入HMRouter
import {HMRouterMgr,HMInterceptor } from '@hadss/hmrouter';
//声明HMRouter的关键pageUrl,RouteUtil根据该路径识别需跳转的页面
@HMRouter({
pageUrl: 'MPTCTVADWebPage'
})针对广告落地页的返回交互场景,将原基于 @ohos.router 的页面回退逻辑替换为 HMRouter 框架的 HMRouterMgr.pop 方法。
当用户触发页面回退操作(如点击导航栏返回按钮、物理返回键)时,调用 HMRouterMgr.pop 方法,该方法会遵循 HMRouter 路由栈的管理规则,将当前广告落地页(WebPage)从路由栈中移除,精准回退到跳转前的上一级页面,保证页面导航的一致性与稳定性。
.onClick(() =>{
AdLog.i(TAG, `onClick = 后退`)
this.webdata.closePage();
HMRouterMgr.pop() //页面回退时增加HMRouterMgr.pop,可以定向指向回退到上一级页面
})HMRouter 的集成与改造解决了系统接口废弃的核心问题,实现了广告落地页跳转的稳定性保障,但广告业务核心的 DeepLink 直呼能力仍未落地,因此进入第三阶段的 DeepLink 适配实践。
04
第三阶段:DeepLink直呼能力适配
Deep Linking(应用间跳转)能力自 HarmonyOS API 12 及以上版本正式支持,而广告 DeepLink 跳转是核心业务功能 —— 线上大量广告为「应用呼起类」,但鸿蒙平台此前未适配该能力,导致广告点击量大幅流失。为提升广告点击转化率,亟需为鸿蒙广告 SDK 接入「直呼」功能。
搜狐视频客户端 10.0.60 版本已完成呼起能力开发及部分 Scheme 配置,为鸿蒙广告 SDK 适配 DeepLink 奠定了前置条件。
鸿蒙官网提供以下 3 种应用间跳转实现方式,结合广告业务场景评估如下:
| 跳转方案 | 核心逻辑 | 适配性 | 淘汰/选用原因 |
|---|---|---|---|
4.3.1 基于 openLink 适配 DeepLink
采用 openLink 接口基于 Deep Linking 方式实现 UIAbility 启动,该接口特性如下:
1. 支持通过 Promise 异步回调接收被拉起 UIAbility 退出时的返回结果;
2. 仅允许在主线程调用;
3. 因广告采用 DeepLink 方式打开应用,需将参数 appLinkingOnly 配置为 false;
4. Catch 中跳转 H5 落地页,保证广告跳转无空窗,提升用户体验,让代码逻辑的业务价值更清晰。
4.3.2 H5 页内 DeepLink 能力实现
针对 H5 落地页内触发的 DeepLink 跳转场景,基于 Web 组件的 onLoadIntercept 拦截回调实现精准管控:
1. 核心拦截逻辑:onLoadIntercept 作为 Web 组件的加载拦截回调,可捕获 H5 页面内所有链接的加载请求,是实现页内跳转管控的核心入口;
2. DeepLink 允许场景:若当前业务配置为「允许 DeepLink 跳转」,且拦截到的链接为 DeepLink 类型(Scheme 格式),则调用 openLink 接口唤起对应应用,完成页内 Deeplink 跳转;
3. DeepLink 禁止场景:若当前业务配置为「不允许 DeepLink 跳转」,则仅放行 HTTP/HTTPS 协议的链接请求,对 Scheme 等非 HTTP/HTTPS 类型的链接请求进行拦截,避免非预期的应用跳转,保障广告展示的安全性与可控性。
为保障广告 DeepLink 跳转的安全性与可控性,鸿蒙平台沿用 iOS、Android 端的成熟方案,设计并实现 DeepLink 白名单管控机制:
1. 核心设计逻辑:
预先维护一份包含可合法唤起应用的 DeepLink 规则白名单(涵盖应用 Scheme、域名、包名等核心标识)。
2. 跳转管控规则:
• 匹配白名单:当检测到待跳转的 DeepLink 链接匹配白名单内的规则时,允许调用 openLink 接口完成应用拉起。
• 未匹配白名单:若待跳转的 DeepLink 链接不在白名单范围内,则直接拦截跳转请求,禁止应用唤起。
3. 核心价值:
通过白名单机制规避非预期应用的恶意唤起、违规跳转风险,同时统一管控广告可唤起的应用范围,符合平台合规要求。
05
方案成果与价值总结
本次鸿蒙广告统一跳转能力的落地,实现了三大核心目标:
• 架构统一:沿用多端一致的路由组件设计思路,完成鸿蒙端 RouteUtil 组件封装,降低多端维护成本;
• 能力闭环:覆盖 H5 落地页、DeepLink 应用呼起核心场景,解决了特殊落地页权限异常、系统接口废弃、应用间跳转安全管控等关键问题;
• 可扩展性:接口预留小程序等跳转参数,路由组件基于 HMRouter 封装,后续可低成本适配鸿蒙生态新增跳转场景。
• 业务侧:DeepLink 能力的上线修复了呼起类广告点击流失问题,广告点击转化率提升;技术侧,形成了鸿蒙生态下广告跳转的标准化实现范式,适配 API 12 + 多版本兼容要求。
06
未来规划
本次落地的统一跳转方案已具备良好的可扩展基础,后续将重点跟进两大方向:
1. 生态能力拓展:待微信完成鸿蒙平台小程序功能适配后,快速启用接口预留的wxId/wxPath参数,支持小程序跳转场景。
2. 体验优化:基于HMRouter的路由拦截能力,进一步优化广告跳转的动画效果、异常兜底逻辑,提升用户交互体验。