广告
showRewardAd(options)
Section titled “showRewardAd(options)”展示激励视频广告。用户观看完整视频后获得奖励。
const result = await SuperSDK.showRewardAd({ adUnitId: 'ca-app-pub-xxx/yyy', // 广告单元 ID adSource: 'ADMOB' // 广告来源: 'ADMOB' | 'APPLOVIN'});console.log(result.rewarded); // true = 用户获得了奖励console.log(result.dismissed); // true = 广告已关闭| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| options.adUnitId | string | 是 | 广告单元 ID |
| options.adSource | string | 否 | 广告来源,默认 ‘ADMOB’ |
返回值: { dismissed: boolean, rewarded: boolean }
错误码:
| code | 说明 |
|---|---|
| NOT_IMPLEMENTED | 宿主未提供 AdService |
| AD_ALREADY_SHOWING | 已有全屏广告正在展示或加载中 |
| NO_ACTIVITY | Activity/ViewController 不可用或已销毁 |
| LOAD_FAILED | 广告加载失败 |
| ERROR | 其他错误 |
showRewardedInterstitialAd(options)
Section titled “showRewardedInterstitialAd(options)”展示激励插屏广告。调用前 H5/宿主必须先展示奖励内容说明,并提供明确的“跳过/继续”入口,只有用户继续时才调用本方法。
// 业务先展示自己的奖励说明/跳过 UIconst result = await SuperSDK.showRewardedInterstitialAd({ adUnitId: 'ca-app-pub-xxx/yyy', adSource: 'ADMOB'});console.log(result.rewarded);console.log(result.dismissed);| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| options.adUnitId | string | 是 | Rewarded Interstitial 广告单元 ID |
| options.adSource | string | 否 | 广告来源,默认 ‘ADMOB’ |
返回值:{ dismissed: boolean, rewarded: boolean }
错误码同 showRewardAd;旧版原生桥不支持该能力时会立即拒绝 NOT_SUPPORTED,不会等待 120 秒超时。
showInterstitialAd(options)
Section titled “showInterstitialAd(options)”展示插屏广告。全屏展示,用户可关闭。
const result = await SuperSDK.showInterstitialAd({ adUnitId: 'ca-app-pub-xxx/yyy', adSource: 'ADMOB'});console.log(result.dismissed); // true = 广告已关闭参数和错误码同 showRewardAd。
返回值: { dismissed: boolean, rewarded: false }
showBannerAd(options)
Section titled “showBannerAd(options)”展示 Banner 横幅广告。Banner 会持续显示在页面顶部或底部,直到调用 hideBannerAd 隐藏。
const result = await SuperSDK.showBannerAd({ adUnitId: 'ca-app-pub-xxx/yyy', adSource: 'ADMOB', position: 'bottom' // 'top' | 'bottom',默认 'bottom'});const adId = result.adId; // 保存 adId 用于后续隐藏
// 隐藏 Bannerawait SuperSDK.hideBannerAd(adId);| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| options.adUnitId | string | 是 | 广告单元 ID |
| options.adSource | string | 否 | 广告来源,默认 ‘ADMOB’ |
| options.position | string | 否 | 位置,‘top’ 或 ‘bottom’,默认 ‘bottom’ |
返回值: { adId: string }
额外错误码:
| code | 说明 |
|---|---|
| CONTAINER_UNSUPPORTED | WebView 父容器不支持叠加 Banner |
hideBannerAd(adId)
Section titled “hideBannerAd(adId)”隐藏并销毁指定 Banner 广告。
await SuperSDK.hideBannerAd(adId);| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| adId | string | 是 | showBannerAd 返回的 adId |
getAttribution(onlyFirst)
Section titled “getAttribution(onlyFirst)”获取归因数据,返回包含首次归因和当前归因两部分的数据。
// 获取完整归因(首次归因 + 当前归因网络请求)const { first, current } = await SuperSDK.getAttribution(false);console.log('首次归因:', first);console.log('当前归因:', current);
// 只获取首次归因(从缓存读取,跳过网络请求,速度更快)const { first } = await SuperSDK.getAttribution(true);参数说明:
| 参数 | 类型 | 说明 |
|---|---|---|
| onlyFirst | boolean | 是否只返回首次归因。true: 只返回 first 字段;false: 返回 first + current 两个字段。注意:如果没有首次归因缓存,无论该参数值如何都会发起网络请求尝试获取 |
返回值:
{ first: { // 首次归因(从缓存读取),无则为 null attrFrom: "facebook_ad", // 归因来源 attrCmd: "open_page", // 归因指令 attrParam: "page=home", // 归因参数 recordId: "attr_xxx" // 归因记录 ID }, current: { // 当前归因(网络请求),onlyFirst=true 时为 undefined matched: true, // 是否匹配到归因 attrFrom: "google_ad", // 归因来源 attrCmd: "view_product", // 归因指令 attrParam: "...", // 归因参数 recordId: "..." // 归因记录 ID }}first 对象:
| 参数 | 类型 | 说明 |
|---|---|---|
| attrFrom | string | 归因来源(如 facebook_ad, google_ad) |
| attrCmd | string | 归因指令(如 open_page) |
| attrParam | string | 归因参数 |
| recordId | string | 归因记录 ID |
current 对象:
| 参数 | 类型 | 说明 |
|---|---|---|
| matched | boolean | 是否匹配到归因 |
| attrFrom | string | 归因来源 |
| attrCmd | string | 归因指令 |
| attrParam | string | 归因参数 |
| recordId | string | 归因记录 ID |
使用场景:
// 场景1:只关心首次归因(如统计用户来源渠道)async function init() { // 如果有缓存直接返回,无缓存会发起网络请求 const { first } = await SuperSDK.getAttribution(true); if (first) { console.log('用户来源:', first.attrFrom); trackUserSource(first.attrFrom); }}
// 场景2:需要首次归因和当前归因(如动态广告投放)async function onShareClick() { const { first, current } = await SuperSDK.getAttribution(false); // first: 首次归因(用于统计) // current: 当前归因(用于动态内容) console.log('首次归因:', first); console.log('当前归因:', current);}注意:
- 首次归因(first)是用户安装 App 后首次匹配的归因,会持久化保存
- 当
onlyFirst=true时,如果没有首次归因缓存,会发起网络请求尝试获取- 当
onlyFirst=false时,总是发起网络请求获取 current- 若 current 匹配成功且无首次归因,会自动保存为首次归因
Native Block(原生组件嵌入)
Section titled “Native Block(原生组件嵌入)”Native Block 模块提供 H5 与 Native View 的”伪同层渲染”能力,允许在 H5 页面中嵌入由宿主 App 提供的原生视图(如广告、视频播放器等)。
nativeBlock.init()
Section titled “nativeBlock.init()”初始化 Native Block 模块,扫描页面中的静态 <native-block> 元素并注册。建议在 DOMContentLoaded 后调用。
document.addEventListener('DOMContentLoaded', function() { SuperSDK.nativeBlock.init();});静态声明方式
Section titled “静态声明方式”在 HTML 中直接声明 <native-block> 元素:
<native-block block-id="ad-1" block-type="ad-banner" block-config='{"adUnitId":"xxx"}' style="width:320px;height:50px;"></native-block>属性说明:
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
| block-id | string | 是 | 唯一标识 |
| block-type | string | 是 | 组件类型(宿主 App 定义,如 “ad-banner”) |
| block-config | string | 否 | JSON 格式的配置,透传给宿主 App |
nativeBlock.create(options)
Section titled “nativeBlock.create(options)”动态创建 Native Block。
const block = await SuperSDK.nativeBlock.create({ blockId: 'video-1', blockType: 'video-player', config: { videoUrl: 'https://example.com/video.mp4' }, container: document.getElementById('video-container'), style: { width: '100%', height: '200px' }});
// 销毁该 Blockblock.destroy();参数说明:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| blockId | string | 是 | 唯一标识 |
| blockType | string | 是 | 组件类型(宿主 App 定义) |
| config | object | 否 | 传递给宿主 App 的配置 |
| container | HTMLElement | 否 | 插入到哪个容器,默认 document.body |
| style | object | 否 | CSS 样式对象 |
返回值:
| 参数 | 类型 | 说明 |
|---|---|---|
| blockId | string | Block 的唯一标识 |
| element | HTMLElement | 占位的 DOM 元素 |
| destroy | function | 销毁该 Block 的方法 |
nativeBlock.updatePositions()
Section titled “nativeBlock.updatePositions()”手动更新所有 Block 的位置。通常不需要手动调用,SDK 会自动监听滚动和窗口大小变化。
SuperSDK.nativeBlock.updatePositions();nativeBlock.destroy(blockId)
Section titled “nativeBlock.destroy(blockId)”销毁指定的 Native Block。
SuperSDK.nativeBlock.destroy('ad-1');nativeBlock.destroyAll()
Section titled “nativeBlock.destroyAll()”销毁所有 Native Block。
SuperSDK.nativeBlock.destroyAll();<!DOCTYPE html><html><head> <script src="supersdk.js"></script> <style> .ad-container { margin: 20px 0; } native-block { display: block; } </style></head><body> <h1>Native Block 示例</h1>
<!-- 静态声明的广告位 --> <div class="ad-container"> <native-block block-id="banner-1" block-type="ad-banner" block-config='{"adUnitId":"ca-app-pub-xxx"}' style="width:320px;height:50px;"> </native-block> </div>
<p>页面内容...</p>
<!-- 动态创建的容器 --> <div id="dynamic-ad"></div>
<script> // 初始化静态 Block document.addEventListener('DOMContentLoaded', function() { SuperSDK.nativeBlock.init(); });
// 动态创建 Block async function createDynamicAd() { try { const block = await SuperSDK.nativeBlock.create({ blockId: 'dynamic-banner', blockType: 'ad-banner', config: { adUnitId: 'ca-app-pub-yyy' }, container: document.getElementById('dynamic-ad'), style: { width: '300px', height: '250px' } }); console.log('广告创建成功:', block.blockId); } catch (e) { console.error('广告创建失败:', e); } } </script></body></html>注意事项:
- Native Block 的内容由宿主 App 提供,SDK 只负责位置同步
- 宿主 App 需要实现
INativeBlockProvider接口并注册blockType由宿主 App 定义,需要与宿主约定好支持的类型- 页面关闭时会自动清理所有 Block,也可手动调用
destroyAll()
响应编码(suenc)
Section titled “响应编码(suenc)”suenc 是 SuperSDK 统一维护的轻量响应混淆协议:客户端显式请求时,服务端用自定义 Base64 表编码 JSON 响应体,并回 X-Su-Enc: b64t1。
⚠️ 它只用于降低通用关键字扫描与规则匹配的有效性,不是加密。不提供机密性、防篡改、防重放,也挡不住已取得客户端代码的攻击者还原编码表。
SuperSDK 自身发出的请求会自动解码(settings / reportEvent / 归因 / 短链等),业务方无需介入。下面两个 API 面向业务方自己发起的 fetch。
getSuEncCapabilities()
Section titled “getSuEncCapabilities()”查询当前运行时支持的 codec,据此决定是否发送 suenc=1。老版本 SDK 上该方法不存在,务必先做存在性判断。
const capabilities = SuperSDK.getSuEncCapabilities();// { supported: true, codecs: ['b64t1'] }
const canUseSuEnc = typeof SuperSDK.getSuEncCapabilities === 'function' && capabilities.supported && capabilities.codecs.includes('b64t1');返回值:{ supported: boolean, codecs: string[] }(同步返回,冻结对象)
decodeSuEnc(encodedData, codec)
Section titled “decodeSuEnc(encodedData, codec)”解码 suenc 响应体,返回原始 UTF-8 JSON 文本。同步纯函数,不经 JSBridge 往返。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| encodedData | string | 是 | 服务端返回的完整编码响应体 |
| codec | string | 是 | X-Su-Enc header 的原始值,不接受自定义编码表 |
// 只有在确认支持后才追加 suenc=1const url = canUseSuEnc ? `${api}?suenc=1` : api;const response = await fetch(url);
const codec = response.headers.get('X-Su-Enc');if (codec) { const decoded = SuperSDK.decodeSuEnc(await response.text(), codec); return JSON.parse(decoded);}
// 🔴 若本次请求带了 suenc=1 却收到无 header 的响应,必须判定为失败(防明文降级),// 不得把明文响应直接交给业务if (canUseSuEnc) throw new Error('SUENC_DOWNGRADE');return response.json();错误码(均为 SuperSDKError,error.code 可判别):
| 错误码 | 触发条件 |
|---|---|
UNSUPPORTED_SUENC_CODEC | X-Su-Enc 指向本端未知的 codec;不会尝试其他编码表 |
SUENC_DECODE_FAILED | 非法字符、长度非 4 的倍数、padding 位置或数量非法 |
SUENC_INVALID_UTF8 | 解码结果不是合法 UTF-8 |
注意事项:
codec必须直接用响应 header 的值,不要硬编码,这样未来新增b64t2时无需改业务代码- 解码失败一律视为请求失败,绝不允许回落读取明文——那正是该协议要防的降级
- 编码后体积约增加 33%;二进制响应(APK / ZIP / 图片 / 文件流)不参与混淆
- 编码表在 SDK 发布后永不变更;新表一定使用新的 codec key