微信小程式的廣告使用踩坑
微信小程式廣告接入,相關的文件說的已經很清晰了,下面主要總結了我遇到的一些問題。
相關文件
廣告相關事件重複註冊
- 問題程式碼
```js useEffect(() => { // 拉取插屏廣告 if (wx.createInterstitialAd) { interstitialAd.current = wx.createInterstitialAd({ adUnitId: 'adunit-xxxx' })
// 廣告載入除錯可開啟以下注釋程式碼
const handleOnLoad = () => {
console.log('插屏廣告拉取成功~~')
}
interstitialAd.current.onLoad(handleOnLoad)
const handleOnError = (err) => {
console.warn('wx.createInterstitialAd error: ', err)
}
interstitialAd.current.onError(handleOnError)
const handleOnClose = () => {
// 關閉插屏廣告後,播放領取動畫
handleShowDrawDownTips()
}
interstitialAd.current.onClose(handleOnClose)
}
}, [handleShowDrawDownTips])
``
上述程式碼中的副作用因為依賴了外部傳入的方法
handleShowDrawDownTips`,當此方法發生變更時,上述副作用會被觸發,導致廣告被重複註冊,相關事件被重複註冊。
改進:廣告註冊邏輯與事件註冊分離開,事件註冊前先進行銷燬(這個操作在微信的文件-廣告指南中有提到,但具體方法沒有寫明,後來谷歌後,在對應的 API 文件中找到了相關方法)
- 問題處理後
```js useEffect(() => { // 拉取插屏廣告 if (wx.createInterstitialAd) { interstitialAd.current = wx.createInterstitialAd({ adUnitId: 'adunit-xxxx' }) } }, [])
useEffect(() => { // 插屏廣告新增監聽事件 if (interstitialAd.current) { // 廣告載入除錯可開啟以下注釋程式碼 const handleOnLoad = () => { console.log('插屏廣告拉取成功~~') } interstitialAd.current.onLoad(handleOnLoad)
const handleOnError = (err) => {
console.warn('wx.createInterstitialAd error: ', err)
}
interstitialAd.current.onError(handleOnError)
const handleOnClose = () => {
// 關閉插屏廣告後,播放領取動畫
handleShowDrawDownTips()
}
interstitialAd.current.onClose(handleOnClose)
// 此處取消監聽事件
return () => {
interstitialAd.current.offLoad(handleOnLoad)
interstitialAd.current.offError(handleOnError)
interstitialAd.current.offClose(handleOnClose)
}
}, [handleShowDrawDownTips])
```
其它需要注意的點
- 多個可控制播放的廣告(激勵式視訊廣告,插屏廣告)展示之間需要一定的間隔時間,若間隔時間太短,下一個廣告將不會播放
- 廣告可能拉取不到,需要處理好沒拉取到廣告的相關互動和展示邏輯
- 某些情況,如觸發了頻次限制,插屏廣告即使載入成功了,呼叫
interstitialAd.current.show()
時也不會展示,甚至官方所說的在 catch 也不會執行 ```js if (interstitialAd.current) { interstitialAd.current.show().catch((err) => { 某些情況,如觸發了頻次限制,插屏廣告不展示也不報錯,所以不會執行一下邏輯 handleShowDrawDownTips() console.warn('「插屏廣告展示出錯」error', error) ) }
// 可嘗試以下方法做好業務的兜底 if (interstitialAd.current) { // 防止廣告因為觸發頻率限制不展示,導致後續邏輯沒有正常執行 const timer = setTimeout(() => { handleShowDrawDownTips() }, 1000)
try {
await interstitialAd.current.show()
clearTimeout(timer)
} catch (error) {
clearTimeout(timer)
handleShowDrawDownTips()
console.warn('「插屏廣告展示出錯」error', error)
}
} ```