Skip to content

自定义广告网络

ToBid支持自定义广告平台功能,您可以通过本功能,添加ToBid暂未聚合的广告平台

本章节将引导您实现HarmonyOS端的自定义广告平台(Adapter)。

1、支持广告类型

目前支持的广告类型如下;

  • 原生广告(Native)
  • 开屏广告(Splash)
  • 激励视频广告(RewardedVideo)
  • 插屏广告(Interstitial)
  • 横幅广告(Banner)

2、核心实现流程

  • ToBid后台添加自定义广告平台以及配置自定义平台所支持的广告类型的适配器类名;
  • 在工程中创建对应自定义平台的适配器类
  • 自定义适配器类遵循对应广告类型的协议

3、常见问题

  1. 自定义Adapter需要按照示例中相应方法含义调用,否则会影响收益。
  2. 自定义Adapter时,需要在对应模块的build-profile.json5正确添加runtimeOnly配置,否则可能导致加载Adapter错误。
  3. 自定义Adapter广告load之前需要确保开发者实现了对应广告类型的协议并初始化network成功。
  4. 所有调用自定义adapter的方法均在主线程,请勿进行耗时操作。
  5. 自定义Adapter不支持Service bidding,支持Client bidding。
  6. 自定义Adapter广告对象的show、click等回调需要在load广告回调之后。

4、初始化配置

由于ToBid通过动态import导入自定义适配器类,需要在build-profile.json5正确添加runtimeOnly配置packages,否则可能导致加载Adapter错误。

4.1、协议内容

自定义Adapter必须要有配置类,在配置类中完成Adapter及对应network的信息采集,对应协议为TBCustomConfigAdapter,接口实现如下所示:

typescript

export abstract class TBCustomConfigAdapter {
  /**
   * 适配器初始化
   * @param config 初始化渠道信息
   * @param bridge 回传信息使用TBCustomConfigAdapterBridge
   */
  abstract initializedAdapter(config: TBInitializedConfig, bridge: TBCustomConfigAdapterBridge): void;

  /**
   * 适配器版本号
   * @returns
   */
    abstract adapterVersion(): string;

  /**
   * 渠道SDK版本号
   * @returns
   */
  abstract networkSdkVersion(): string;

  /**
   * 隐私更新,用户更新隐私配置时触发,初始化方法调用前一定会触发一次
   */
  abstract adPrivacyUpdate(privacy: TBPrivacyConfig): void;
}

4.2、回调协议

渠道初始化结果通过TBCustomConfigAdapterBridge通知给ToBid

typescript
export interface TBCustomConfigAdapterBridge {
  /**
   * 渠道SDK初始化成功
   * @param adapter
   */
  initializeSuccessed(adapter: TBCustomConfigAdapter): void;

  /**
   * 渠道SDK初始化失败
   * @param adapter
   * @param error
   */
  initializeFailed(adapter: TBCustomConfigAdapter, error: BusinessError): void;
}

5、自定义开屏广告

5.1、协议内容

自定义广告网络实现开屏广告时必须要有配置类,且配置类需要继承TBCustomSplashAdAdapter,接口实现如下所示:

typescript
export abstract class TBCustomSplashAdAdapter extends TBCustomAdapter {

  /**
   * 广告是否处于可播放状态
   * @returns
   */
  abstract isReady(): boolean;

  /**
   * 加载广告
   * @param parameter 广告参数
   */
  abstract loadAdData(parameter: TBParameter): void;

  /**
   * 播放广告
   * @param parameter 广告参数
   */
  showAd(parameter: TBParameter): void;

  /**
   * 广告组件
   * @param parameter
   * @returns 
   */
  registerWrapBuilder(parameter: TBParameter): tbnode.Data | undefined;

}

tbnode.Data参考接口说明

5.2、回调协议

开屏的各回调结果通过TBCustomSplashAdAdapterBridge通知给ToBid

typescript

export abstract class TBCustomSplashAdAdapterBridge extends TBCustomAdapterBridge {
  /**
   * 广告数据返回,此时广告只是返回还未预加载完成
   * @param adapter
   */
  abstract onAdLoad(adapter: TBCustomSplashAdAdapter, params: ReportParameter): void;

  /**
   * 广告缓存成功
   * @param adapter
   */
  abstract onAdDidLoad(adapter: TBCustomSplashAdAdapter): void;

  /**
   * 广告加载失败
   * @param adapter
   * @param error
   */
  abstract onAdDidLoadError(adapter: TBCustomSplashAdAdapter, error: BusinessError): void;

  /**
   * 广告开始播放
   * @param adapter
   */
  abstract onAdShow(adapter: TBCustomSplashAdAdapter): void;

  /**
   * 广告播放失败
   * @param adapter
   */
  abstract onAdShowError(adapter: TBCustomSplashAdAdapter, error: BusinessError): void;


  /**
   * 广告曝光成功
   * @param adapter
   */
  abstract onAdImpression(adapter: TBCustomSplashAdAdapter): void;

  /**
   * 广告点击
   * @param adapter
   */
  abstract onAdClick(adapter: TBCustomSplashAdAdapter): void;


  /**
   * 广告跳过
   * @param adapter
   */
  abstract onAdSkip(adapter: TBCustomSplashAdAdapter): void;

  /**
   * 广告关闭
   * @param adapter
   */
  abstract onAdClose(adapter: TBCustomSplashAdAdapter): void;

  /**
   * 广告倒计时结束
   * @param adapter
   */
  abstract onAdCounterZero(adapter: TBCustomSplashAdAdapter): void;
}

6、自定义激励视频广告

6.1、协议内容

自定义广告网络实现激励视频广告时必须要有配置类,且配置类需要继承TBCustomRewardVideoAdAdapter,接口实现如下所示:

typescript

export abstract class TBCustomRewardVideoAdAdapter extends TBCustomAdapter {

  /**
   * 广告是否处于可播放状态
   * @returns
   */
  abstract isReady(): boolean;

  /**
   * 加载广告
   * @param parameter 广告参数
   */
  abstract loadAdData(parameter: TBParameter): void;

  /**
   * 播放广告
   * @param parameter 广告参数
   */
  abstract showAd(parameter: TBParameter): void;

  /**
   * 销毁资源
   */
  abstract destroy(): void;
}

6.2、回调协议

激励视频广告的各回调结果通过TBCustomRewardVideoAdAdapterBridge通知给ToBid

typescript
export abstract class TBCustomRewardVideoAdAdapterBridge extends TBCustomAdapterBridge {
  /**
   * 广告数据返回,此时广告只是返回还未预加载完成
   * @param adapter
   */
  abstract onAdRequstSuccess(adapter: TBCustomRewardVideoAdAdapter, params: ReportParameter): void;

  /**
   * 广告缓存成功
   * @param adapter
   */
  abstract onAdDidLoad(adapter: TBCustomRewardVideoAdAdapter): void;

  /**
   * 广告加载失败
   * @param adapter
   * @param error
   */
  abstract onAdDidLoadError(adapter: TBCustomRewardVideoAdAdapter, error: BusinessError, extra?: Record<string, Object>): void;

  /**
   * 激励视频广告达到奖励条件触发激励回调
   * @param adapter
   * @param reward
   */
  abstract onRewardArrived(adapter: TBCustomRewardVideoAdAdapter, reward: TBReward): void;

  /**
   * 广告开始播放
   * @param adapter
   */
  abstract onAdShow(adapter: TBCustomRewardVideoAdAdapter): void;

  /**
   * 广告播放失败
   * @param adapter
   */
  abstract onAdShowError(adapter: TBCustomRewardVideoAdAdapter, error: BusinessError): void;


  /**
   * 广告曝光成功
   * @param adapter
   */
  abstract onAdImpression(adapter: TBCustomRewardVideoAdAdapter): void;

  /**
   * 广告点击
   * @param adapter
   */
  abstract onAdClick(adapter: TBCustomRewardVideoAdAdapter): void;


  /**
   * 广告跳过
   * @param adapter
   */
  abstract onAdSkip(adapter: TBCustomRewardVideoAdAdapter): void;

  /**
   * 广告关闭
   * @param adapter
   */
  abstract onAdClose(adapter: TBCustomRewardVideoAdAdapter): void;

  /**
   * 广告视频播放完成
   * @param adapter
   */
  abstract onAdVideoComplete(adapter: TBCustomRewardVideoAdAdapter): void;

  /**
   * 广告视频播放出错
   * @param adapter
   * @param error
   */
  abstract onAdVideoError(adapter: TBCustomRewardVideoAdAdapter, error: BusinessError): void;
}

7、自定义插屏广告

7.1、协议内容

自定义广告网络实现激励视频广告时必须要有配置类,且配置类需要继承TBCustomInterstitialAdAdapter,接口实现如下所示:

typescript
export abstract class TBCustomInterstitialAdAdapter extends TBCustomAdapter {

  /**
   * 广告是否处于可播放状态
   * @returns
   */
  abstract isReady(): boolean;

  /**
   * 加载广告
   * @param parameter 广告参数
   */
  abstract loadAdData(parameter: TBParameter): void;

  /**
   * 播放广告
   * @param parameter 广告参数
   */
  showAd(parameter: TBParameter): void;

  /**
   * 播放组件
   */
  registerWrapBuilder(parameter: TBParameter): tbnode.Data | undefined;

}

tbnode.Data参考接口说明

7.2、回调协议

插屏广告的各回调结果通过TBCustomInterstitialAdAdapterBridge通知给ToBid

typescript
export abstract class TBCustomInterstitialAdAdapterBridge extends TBCustomAdapterBridge {
  /**
   * 广告数据返回,此时广告只是返回还未预加载完成
   * @param adapter
   */
  abstract onAdRequstSuccess(adapter: TBCustomInterstitialAdAdapter, params: ReportParameter): void;

  /**
   * 广告缓存成功
   * @param adapter
   */
  abstract onAdDidLoad(adapter: TBCustomInterstitialAdAdapter): void;

  /**
   * 广告加载失败
   * @param adapter
   * @param error
   */
  abstract onAdDidLoadError(adapter: TBCustomInterstitialAdAdapter, error: BusinessError, extra?: Record<string, Object>): void;

  /**
   * 广告开始播放
   * @param adapter
   */
  abstract onAdShow(adapter: TBCustomInterstitialAdAdapter): void;

  /**
   * 广告播放失败
   * @param adapter
   */
  abstract onAdShowError(adapter: TBCustomInterstitialAdAdapter, error: BusinessError): void;


  /**
   * 广告曝光成功
   * @param adapter
   */
  abstract onAdImpression(adapter: TBCustomInterstitialAdAdapter): void;

  /**
   * 广告点击
   * @param adapter
   */
  abstract onAdClick(adapter: TBCustomInterstitialAdAdapter): void;


  /**
   * 广告跳过
   * @param adapter
   */
  abstract onAdSkip(adapter: TBCustomInterstitialAdAdapter): void;

  /**
   * 广告关闭
   * @param adapter
   */
  abstract onAdClose(adapter: TBCustomInterstitialAdAdapter): void;

  /**
   * 广告视频播放完成
   * @param adapter
   */
  abstract onAdVideoComplete(adapter: TBCustomInterstitialAdAdapter): void;

  /**
   * 广告视频播放出错
   * @param adapter
   * @param error
   */
  abstract onAdVideoError(adapter: TBCustomInterstitialAdAdapter, error: BusinessError): void;
}

8、自定义原生广告

8.1、协议内容

typescript
export abstract class TBCustomNativeAdAdapter extends TBCustomAdapter {

  /**
   * 加载广告
   * @param parameter 广告参数
   */
  abstract loadAdData(parameter: TBParameter): void;

}

8.2、回调协议

typescript
export abstract class TBCustomNativeAdAdapterBridge extends TBCustomAdapterBridge {

  /**
   * 广告数据返回,此时广告只是返回还未预加载完成
   * @param adapter
   */
  abstract onAdRequstSuccess(adapter: TBCustomNativeAdAdapter, params: ReportParameter): void;

  /**
   * 广告缓存成功
   * @param adapter
   */
  abstract onAdDidLoad(adapter: TBCustomNativeAdAdapter, datas: TBMediaNativeAd[]): void;

  /**
   * 广告加载失败
   * @param adapter
   * @param error
   */
  abstract onAdDidLoadError(adapter: TBCustomNativeAdAdapter, error: BusinessError, extra?: Record<string, Object>): void;

  /**
   * 广告开始播放
   * @param adapter
   * @param orign 渠道广告数据对象
   */
  abstract onAdShow(adapter: TBCustomNativeAdAdapter, origin: Object): void;

  /**
   * 广告曝光成功
   * @param adapter
   */
  abstract onAdImpression(adapter: TBCustomNativeAdAdapter, origin: Object): void;

  /**
   * 广告点击
   * @param adapter
   * @param orign 渠道广告数据对象
   */
  abstract onAdClick(adapter: TBCustomNativeAdAdapter, origin: Object): void;


  /**
   * 广告关闭
   * @param adapter
   * @param orign 渠道广告数据对象
   */
  abstract onAdClose(adapter: TBCustomNativeAdAdapter, origin: Object): void;



  /**
   * 模板渲染成功
   * @param adapter
   * @param orign 渠道广告数据对象
   * @param width  返回view的宽 单位 vp
   * @param height 返回view的高 单位 vp
   */
  onRenderSuccess(adapter: TBCustomNativeAdAdapter, origin: Object, width: number, height: number);

  /**
   * 模板渲染失败
   * @param adapter
   * @param orign 渠道广告数据对象
   * @param error 错误描述信息
   */
  onRenderFail(adapter: TBCustomNativeAdAdapter, origin: Object, error: BusinessError);


  /**
   * 视频开始播放
   */
  onVideoPlayStart(adapter: TBCustomNativeAdAdapter, origin: Object): void;

  /**
   * 视频播放结束
   */
  onVideoPlayComplete(adapter: TBCustomNativeAdAdapter, origin: Object): void;

  /**
   * 视频播放失败
   */
  onVideoPlayError(adapter: TBCustomNativeAdAdapter, origin: Object, error: BusinessError): void;

  /**
   * dislike 弹窗show
   */
  onDislikeShow(adapter: TBCustomNativeAdAdapter, origin: Object): void;
  /**
   * dislike 弹窗取消
   */
  onDislikeCancel(adapter: TBCustomNativeAdAdapter, origin: Object): void;

  /**
   * dislike 弹窗条目被选中
   */
  onDislikeSelected(adapter: TBCustomNativeAdAdapter, origin: Object, dislike: TBDislikeInfo): void;
}

8.3、TBMediaNativeAd

在原生广告加载成功时,需通过回调协议中abstract onAdDidLoad(adapter: TBCustomNativeAdAdapter, datas: TBMediaNativeAd[]): void;方法通知聚合广告加载成功,其中TBMediaNativeAd定义了自渲染和模版渲染所所要的全部信息。

typescript
export abstract class TBMediaNativeAd {
  /**
   * 渲染类型 模版渲染 or 自渲染
   */
  abstract getRenderType(): TBType.RenderType;

  /**
   * 信息流广告类型 信息流 or DrawVideo
   */
  abstract getNativeType(): TBType.NativeType;

  /**
   * 原始渠道返回的数据对象
   */
  abstract getOriginAd(): Object;

  /**
   * 组件渲染管理器
   * @returns
   */
  abstract viewCreator(): TBMediaViewCreator | undefined;


  /**
   * 素材类型
   * 【模版渲染为空】
   */
  getMaterialType(): TBType.MaterialType {
    return TBType.MaterialType.unknow;
  }

  /**
   * 广告交互类型
   * 【模版渲染时为空】
   */
  getInteractionType(): TBType.AdInteractionType {
    return TBType.AdInteractionType.unknow;
  }

  /**
   * CTA按钮文案
   * 【模版渲染时为空】
   */
  getActionDescription(): string {
    if (this.getInteractionType() === TBType.AdInteractionType.download) {
      return '立即下载';
    } else {
      return '查看详情';
    }
  }

  /**
   * 应用下载相关合规信息
   * @returns
   */
  getComplianceInfo(): TBMediaComplianceInfo | undefined {
    return undefined;
  }

  /**
   * 广告标题
   * 【模版渲染时为空】
   */
  getAdTitle(): string {
    return '';
  }

  /**
   * 广告描述
   * 【模版渲染时为空】
   */
  getAdDescription(): string {
    return '';
  }

  /**
   * 广告来源,可能为空
   * 【模版渲染时为空】
   */
  getAdSource(): string {
    return '';
  }

  /**
   * 获取广告⻆标的logo
   * 当返回string类型时,可能为标准url,(csj)adx广告场景时可能文字描述
   * 【模版渲染时为空】
   */
  getAdLogo(): string | Resource | undefined {
    return undefined
  }

  /**
   * 广告图片集合,单图和组图类型广告素材有返回,视频类素材返回为空
   * 【模版渲染时为空】
   */
  getImageList(): TBAdImage[] {
    return [];
  }

  /**
   * 广告Icon链接
   * 【模版渲染时为空】
   */
  getAppIconUrl(): string | undefined {
    return undefined
  }

  /**
   * 应用下载次数文案,非下载返回为空 eg:1000W此下载
   * 【模版渲染时为空】
   */
  getAppDownloadCountDes(): string | undefined {
    return undefined
  }

  /**
   * 应用评论数
   * @returns
   */
  getAppCommentNum(): number {
    return 0;
  }

  /**
   * 应用下载评分,取值0~5.0; 非下载返回为0
   * 【模版渲染时为空】
   */
  getAppScore(): number {
    return 0;
  }

  /**
   * 视频封面url
   * [支持渠道:快手]
   * 【模版渲染时为空】
   */
  getCoverUrl(): TBAdImage | undefined {
    return undefined;
  }

  /**
   * 视频url
   * 【模版渲染时为空】
   */
  getVideoUrl(): string | undefined {
    return undefined
  }

  /**
   * 视频时⻓
   * 【模版渲染时为空】
   */
  getVideoDuration(): number {
    return 0;
  }


  /**
   * 可⻅区域监听数组
   * @returns
   */
  getVisibleAreaRatios(): number[] {
    return [0, 1];
  }

  /**
   * 可⻅区域监听方法,用于三方SDK内部判断⻚面展示比例,处理广告曝光&视频播放等
   * @param isVisible
   * @param currentRatio
   * @returns true: 三方SDK处理组件展示逻辑;false: 三方SDK不处理
   */
  getVisibleAreaChangeListener(isVisible: boolean, currentRatio: number): boolean {
    return false;
  }

  /**
   * 执行广告点击逻辑【仅快手】
   * @param context
   * @param event
   */
  clickAd(context: common.UIAbilityContext, event: ClickEvent);

  /**
   * 注册原生自渲染广告点击组件ID
   * @param rootAdComponentId 广告布局根节点Id
   * @param uiContext 当前组件的上下文
   * @param clickViewIds 普通点击Id集合,点击之后,会跳转到落地页,然后再进行后续广告转化
   * @param creativeViewIds: 创意点击Id集合,点击之后,会直接进行转化
   */
  registerViewForInteraction(rootAdComponentId: string, uiContext: UIContext, clickViewIds: TBClickViewIdList<string>,
    creativeViewIds: TBClickViewIdList<string>);

  /**
   * 渲染模板广告
   * @param context
   */
  render(context: UIContext): void;
  
    /**
   * 释放资源
   */
  destroy(): void;
}

8.4、TBMediaViewCreator

typescript
export abstract class TBMediaViewCreator {
  /**
   * 自渲染的视频组件
   */
  getMediaWrapBuilder(): tbnode.Data | undefined {
    return undefined;
  }


  /**
   * 模版渲染组件
   */
  getViewWrapBuilder(): tbnode.Data | undefined {
    return undefined;
  }
}

8.5、TBMediaComplianceInfo

应用下载类合规信息

typescript

   * 获取App Name
   * @returns
   */
  abstract getAppName(): string;

  /**
   * 获取应用版本
   * @returns
   */
  abstract getAppVersion(): string;

  /**
   * 获取开发者名称
   * @returns
   */
  abstract getDeveloperName(): string;

  /**
   * 获取隐私协议
   * @returns
   */
  abstract getPrivacyUrl(): string;

  /**
   * 获取权限名称及权限描述列表
   * @returns
   */
  abstract getPermissionsMap(): Map<string, string>;

  /**
   * 获取权限列表url
   * @returns
   */
  abstract getPermissionUrl(): string;

  /**
   * 获取产品功能url
   * @returns
   */
  abstract getIntroductionInfoUrl(): string;
}

9、自定义横幅广告

9.1、协议内容

typescript
export abstract class TBCustomBannerAdAdapter extends TBCustomAdapter {

  /**
   * 加载广告
   * @param parameter 广告参数
   */
  abstract loadAdData(parameter: TBParameter): void;

}

9.2、回调协议

typescript
export abstract class TBCustomBannerAdAdapterBridge extends TBCustomAdapterBridge {

  /**
   * 广告数据返回,此时广告只是返回还未预加载完成
   * @param adapter
   */
  abstract onAdRequstSuccess(adapter: TBCustomNativeAdAdapter, params: ReportParameter): void;

  /**
   * 广告缓存成功
   * @param adapter
   */
  abstract onAdDidLoad(adapter: TBCustomNativeAdAdapter, datas: TBMediaNativeAd[]): void;

  /**
   * 广告加载失败
   * @param adapter
   * @param error
   */
  abstract onAdDidLoadError(adapter: TBCustomNativeAdAdapter, error: BusinessError, extra?: Record<string, Object>): void;

  /**
   * 广告开始播放
   * @param adapter
   * @param orign 渠道广告数据对象
   */
  abstract onAdShow(adapter: TBCustomNativeAdAdapter, origin: Object): void;

  /**
   * 广告曝光成功
   * @param adapter
   */
  abstract onAdImpression(adapter: TBCustomNativeAdAdapter, origin: Object): void;

  /**
   * 广告点击
   * @param adapter
   * @param orign 渠道广告数据对象
   */
  abstract onAdClick(adapter: TBCustomNativeAdAdapter, origin: Object): void;


  /**
   * 广告关闭
   * @param adapter
   * @param orign 渠道广告数据对象
   */
  abstract onAdClose(adapter: TBCustomNativeAdAdapter, origin: Object): void;



  /**
   * 模板渲染成功
   * @param adapter
   * @param orign 渠道广告数据对象
   * @param width  返回view的宽 单位 vp
   * @param height 返回view的高 单位 vp
   */
  onRenderSuccess(adapter: TBCustomNativeAdAdapter, origin: Object, width: number, height: number);

  /**
   * 模板渲染失败
   * @param adapter
   * @param orign 渠道广告数据对象
   * @param error 错误描述信息
   */
  onRenderFail(adapter: TBCustomNativeAdAdapter, origin: Object, error: BusinessError);


  /**
   * 视频开始播放
   */
  onVideoPlayStart(adapter: TBCustomNativeAdAdapter, origin: Object): void;

  /**
   * 视频播放结束
   */
  onVideoPlayComplete(adapter: TBCustomNativeAdAdapter, origin: Object): void;

  /**
   * 视频播放失败
   */
  onVideoPlayError(adapter: TBCustomNativeAdAdapter, origin: Object, error: BusinessError): void;

  /**
   * dislike 弹窗show
   */
  onDislikeShow(adapter: TBCustomNativeAdAdapter, origin: Object): void;
  /**
   * dislike 弹窗取消
   */
  onDislikeCancel(adapter: TBCustomNativeAdAdapter, origin: Object): void;

  /**
   * dislike 弹窗条目被选中
   */
  onDislikeSelected(adapter: TBCustomNativeAdAdapter, origin: Object, dislike: TBDislikeInfo): void;
}

其它同自定义信息流相同

10、自定义广告配置客户端竞价

本章节主要介绍如何自定义Adapter实现Client Bidding

在收到广告加载完成时,通过回调协议中的onAdRequstSuccess方法,通知聚合SDK广告出价成功,该方法会携带一个ReportParameter参数,开发者可以该参数中配置价格price和货币类型currency

注意:尽量在可以获取到价格的最早时机通过onAdRequstSuccess告知聚合SDK广告出价成功,否则可能影响整体的出价时间

以穿山甲激励视频为例:

typescript
// 广告基础信息加载完成
  onAdLoaded(rewardAd: CSJRewardAd) {
    if (this.parameter?.isHeaderBidding) {
      let mediaExtraInfo = rewardAd.getMediaExtraInfo();
      let price =  mediaExtraInfo.get('price');
      let request_id = mediaExtraInfo.get('request_id');
      let extra: ReportParameter = {
        transId: `${request_id}`
      };
      if (price != undefined) {
        extra.price = `${price}`
      }
      this.bridge.onAdRequstSuccess(this, extra);
    }
  }