主题
横幅 —— NovvyBannerAd
固定位置、固定尺寸、常驻在宿主页面上的横幅位,由 SDK 自动定时轮换素材(素材类型为图片)。
与其它广告位最大的不同:没有 load() → attach() 两段式。构造函数就在你给的容器里建好广告位,load() 启动一个自驱动的循环(请求 → 预取 → 到点替换 → 请求下一张),直到 destroy()。
对接流程
NovvyBannerAd(adUnitId, size, adContainer) // 构造即建位,立刻占好版面
↓
load(listener) // 起轮换
↓
onAdLoaded → onAdShown // 首张
↓ (每 refreshIntervalSeconds 秒重复一次)
onAdLoaded → onAdShown → …
↓
destroy() // 宿主 onDestroy 中调用1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
创建
kotlin
class MainActivity : AppCompatActivity() {
private lateinit var banner: NovvyBannerAd
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
banner = NovvyBannerAd(
adUnitId = "your_ad_unit_id",
size = NovvyBannerSize.STANDARD,
adContainer = findViewById(R.id.ad_container),
refreshIntervalSeconds = 60, // 可省略,默认 60
)
banner.load(object : NovvyBannerAdListener {
override fun onAdShown(ad: NovvyBannerAd) { /* 每轮触发一次 */ }
override fun onAdClicked(ad: NovvyBannerAd) { /* 用户点击,正在打开落地页 */ }
})
}
override fun onDestroy() {
banner.destroy()
super.onDestroy()
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
构造参数
| 参数 | 说明 |
|---|---|
adUnitId | banner 类型的广告位标识 |
size | NovvyBannerSize 档位,见下表 |
adContainer | 宿主容器。SDK 会在其中新建一个自己的固定尺寸子 view,不会动容器里已有的任何子 view |
refreshIntervalSeconds | 轮换间隔秒数,默认 60,钳制到 [30, 120];传 <= 0 关闭轮换(只加载一张) |
尺寸档位
请给 adContainer 预留不小于所声明档位的宽高。容器比声明尺寸小时素材会被裁切,而裁切后的素材达不到「自身面积 50% 连续可见 1 秒」的曝光判据,因此不会产生曝光、不会有收入。SDK 会打一条 warning 写明所需 dp,但不会缩放素材(那等于投一个服务端没有竞价过的尺寸)。
| 档位 | 尺寸 | 说明 |
|---|---|---|
NovvyBannerSize.STANDARD | 320 × 50 dp | 默认档位,最通用 |
NovvyBannerSize.LARGE | 320 × 100 dp | 手机上的大横幅 |
NovvyBannerSize.MEDIUM_RECTANGLE | 300 × 250 dp | 中矩形,适合内容中插位 |
NovvyBannerSize.FULL_BANNER | 468 × 60 dp | 平板 |
NovvyBannerSize.LEADERBOARD | 728 × 90 dp | 平板 / 横屏 |
占位与居中
- SDK 在容器里自建的槽位从构造那一刻起恒定占位,首张填充之前也占(空着、透明)。素材到达与每次轮换都只换内容、不改尺寸,宿主页面全程零跳动。
- 如果确实要在无填充时收起横幅,用
onAdLoaded/onAdFailedToLoad自己控制adContainer的可见性 —— 但注意onAdFailedToLoad会随退避重试反复触发,不要在它里面隐藏容器(会随重试闪烁)。 - SDK 用容器自身的
LayoutParams类型表达居中:FrameLayout/RelativeLayout/LinearLayout下可以真正居中;其它容器类型下尺寸仍生效,但落点由该容器自己的规则决定(SDK 会打 warning,建议外面套一层FrameLayout)。
轮换与失败重试
- 预取式轮换:新素材在上一张刚上屏时就开始请求,「满间隔且素材就绪」才替换(两个条件谁后到谁触发),替换是瞬时的,不会出现空窗。
- 预取失败不下屏:当前素材继续展示,SDK 在其下退避重试(最长 5 分钟一次)。
onAdFailedToLoad会随之反复触发,这是正常的,不要在回调里重新load(),更不要据此隐藏容器。 - 后台不轮换:宿主进入后台、或槽位所在的 view 离开 window(如
RecyclerView回收了它所在的行)时,计时与请求都暂停,回到前台恢复。 load()只需调用一次(重复调用无副作用)。destroy()停止轮换、撤下素材并把槽位从容器移除,请在宿主onDestroy中调用;宿主 Activity 被销毁时 SDK 也会自行清理。
事件回调
NovvyBannerAdListener 方法均有空实现默认值,按需重写;回调统一在主线程触发。
| 回调 | 触发时机 |
|---|---|
onAdLoaded(ad) | 一支创意预取就绪。此时还没上屏 —— 轮换是「先取好再换」,素材到手与上屏之间通常隔着剩下的那段间隔(首张几乎同时) |
onAdFailedToLoad(ad, error) | 一次填充失败。屏上那支不动,SDK 自行退避重试,因此本回调会随重试反复触发;error 取值见错误类型 |
onAdShown(ad) | 一支创意上屏、曝光上报完成。轮换开着时每轮一次 |
onAdClicked(ad) | 用户点击、落地页正在打开。横幅是全 SDK 唯一有点击回调的类型(其余类型的点击紧跟着浏览器跳转,宿主自己观察得到;常驻槽位给不了这个信号) |
onAdHidden(ad) | 槽位空了 —— destroy(),或屏上那支渲染失败被撤下。轮换换屏是「换」不是「空」,不触发本回调 |