Android平臺Admob廣告接入和封裝,android程序化廣告詳細流程Android平臺Admob廣告接入和封裝前言關(guān)于Admob如何接入,官方文檔已經(jīng)寫的很清楚,所以不是本文的重點。本文主要講Admob的調(diào)用封裝。因為作為開發(fā)者接入Admob之后,其實工作遠沒有結(jié)束,可能想做預(yù)加載,想做些封裝讓接口更加簡潔友好......
前言
關(guān)于Admob如何接入,官方文檔已經(jīng)寫的很清楚,所以不是本文的重點。本文主要講Admob的調(diào)用封裝。因為作為開發(fā)者接入Admob之后,其實工作遠沒有結(jié)束,可能想做預(yù)加載,想做些封裝讓接口更加簡潔友好,此外還想讓業(yè)務(wù)代碼盡可能不與SDK耦合,等等。其實這部分內(nèi)容也是一個輪子,那我們就不要重復(fù)造輪子了。
Admob接入
1. 官方網(wǎng)站:https://developers.google.cn/admob/android/quickstart
官網(wǎng)文檔有中英文版本,閱讀上不是什么問題,實際接入難度不大。只是隨著版本的更新,文檔同步的不是很及時。
2. 官方開發(fā)論壇:https://groups.google.com/forum/#!forum/googleadmobadssdk
遇到一些問題可以到論壇搜索下。我在開發(fā)時遇到一個兼容性問題,某些手機上激勵廣告播放時會突然被強制關(guān)閉,后來就是在論壇上找到了解決方案:正在播放的激勵廣告需要有明確的引用持有,否則可能被系統(tǒng)回收導(dǎo)致廣告關(guān)閉。
二次封裝
完整代碼可以查看本文后面的github項目地址。
AdmobManager
框架內(nèi)唯一暴露給業(yè)務(wù)層的接口,是一個單例。業(yè)務(wù)層只需要跟它打交道就可以進行加載、獲取、顯示廣告等操作。
NativeAdRepository
原生高級廣告?zhèn)}庫,一個廣告位id對應(yīng)一個廣告?zhèn)}庫。本質(zhì)是一個廣告池,可實現(xiàn)給定數(shù)量的廣告預(yù)加載,并在廣告被使用后自動進行個數(shù)的加載補足。
/**
* 一個id對應(yīng)一個廣告?zhèn)}庫,倉庫會自動進行廣告的預(yù)加載(個數(shù)preloadCount),并向外提供廣告內(nèi)容
*
* id默認(rèn)是測試廣告
*/
class NativeAdRepository constructor(private var id: String = caapppub3940256099942544/2247696110,
private var preloadCount: Int = 1) {
/**
* 已加載的廣告列表
*/
var adList = LinkedListUnifiedNativeAd()
/**
* 是否正在進行廣告加載
*/
var isLoading = false
/**
* 正在加載的廣告?zhèn)€數(shù)
*/
var loadingCount = 0
var loadListenerList = ArrayListNativeAdLoadListener()
/**
* 進行廣告加載
*/
fun loadAds(context: Context) {
if (isLoading adList.size = preloadCount) {
Log.w(AdmobManager.TAG, $id NativeAd dont need load)
return
}
isLoading = true //開始加載
val request = AdRequest.Builder().build()
val adLoader = AdLoader.Builder(context, id).forUnifiedNativeAd {//廣告加載完成
adList.offer(it)
for(listener in loadListenerList) {
listener.onLoaded()
}
onAdLoaded()
}.withAdListener(object : AdListener() {
override fun onAdFailedToLoad(errorCode: Int) {
onAdLoaded()
Log.w(AdmobManager.TAG, $id NativeAd load failed, errorCode = $errorCode)
}
}).build()
//開始加載
loadingCount = preloadCount adList.size
adLoader.loadAds(request, loadingCount)
}
/**
* 一個廣告加載完成時調(diào)用
*/
private fun onAdLoaded() {
//更新正在加載的廣告?zhèn)€數(shù)
loadingCount
//所有廣告加載完成,狀態(tài)更新成未在加載中
if (loadingCount = 0) {
isLoading = false
//一般廣告加載成功,收到一次通知即可,所以將所有監(jiān)聽器在這里進行移除
if(adList.size 0) {
loadListenerList.clear()
}
}
}
/**
* 是否已經(jīng)有廣告加載完成
*/
fun isReady(context: Context): Boolean {
return adList.isNotEmpty()
}
/**
* 獲取加載好的原生廣告
*/
fun getAd(context: Context): UnifiedNativeAd {
var ad = adList.poll()
//廣告被取走后,需要重新加載廣告,保證池子里面有一定數(shù)量的預(yù)加載廣告
loadAds(context)
return ad
}
/**
* 設(shè)置預(yù)加載個數(shù)
*/
fun setPreloadCount(value: Int) {
preloadCount = value
}
/**
* 添加廣告加載監(jiān)聽器。注意:監(jiān)聽器會在廣告的一輪加載成功后被全部移除。
*/
fun addLoadListener(listener: NativeAdLoadListener) {
if (!loadListenerList.contains(listener)) {
loadListenerList.add(listener)
}
}
/**
* 移除廣告加載監(jiān)聽器
*/
fun removeLoadListener(listener: NativeAdLoadListener) {
loadListenerList.remove(listener)
}
}
RewardAdRepository
激勵廣告?zhèn)}庫,一個廣告位id對應(yīng)一個廣告參考,實現(xiàn)方式與原生高級廣告基本一致。
class RewardAdRepository constructor(private var id: String = caapppub3940256099942544/5224354917,
private var preloadCount: Int = 1) {
/**
* 是否正在加載
*/
var isLoading = false
var adList = ArrayListRewardedAd()
/**
* 正在加載的廣告?zhèn)€數(shù)
*/
var loadingCount = 0
/**
* 正在播放的廣告需要有明確的引用持有,否則在有些系統(tǒng)里面廣告會被強制回收關(guān)閉
*/
var rewardedAdShowing: RewardedAd? = null
var loadListenerList = ArrayListRewardAdLoadListener()
val rewardAdLoaderCallback = object : RewardedAdLoadCallback() {
override fun onRewardedAdLoaded() {
Log.i(AdmobManager.TAG, $id Reward Ad loaded)
for(listener in loadListenerList) {
listener.onLoaded()
}
onAdLoaded()
}
override fun onRewardedAdFailedToLoad(var1: Int) {
Log.e(AdmobManager.TAG, $id Reward Ad load failed, errorCode = $var1)
onAdLoaded()
}
}
private fun onAdLoaded() {
loadingCount
if (loadingCount = 0) {
isLoading = false
//一般廣告加載成功,收到一次通知即可,所以將所有監(jiān)聽器在這里進行移除
if(adList.size 0) {
loadListenerList.clear()
}
}
}
/**
* 加載廣告
*/
fun loadAds(context: Context) {
if (isLoading) {
return
}
//用來放沒有加載成功的廣告
var removeList = ArrayListRewardedAd()
for (rewardAd in adList) {
//沒加載成功的廣告就丟到待刪除列表里
if (!rewardAd.isLoaded) {
removeList.add(rewardAd)
}
}
adList.removeAll(removeList)
loadingCount = preloadCount adList.size
val request = AdRequest.Builder().build()
while (adList.size preloadCount) {
var rewardedAd = RewardedAd(context, id)
adList.add(rewardedAd)
rewardedAd.loadAd(request, rewardAdLoaderCallback)
isLoading = true
Log.i(AdmobManager.TAG, $id Reward Ad loading)
}
}
/**
* 是否有加載完成的激勵廣告
*/
fun isReady(context: Context): Boolean {
for(rewardAd in adList) {
if (rewardAd.isLoaded) {
return true
}
}
return false
}
/**
* 顯示激勵廣告
*/
fun show(activity: Activity, listener: RewardAdShowListener?) {
for(rewardAd in adList) {
if (rewardAd.isLoaded) {
Log.i(AdmobManager.TAG, $id Reward Ad show)
rewardedAdShowing = rewardAd
rewardAd.show(activity, object : RewardedAdCallback() {
override fun onRewardedAdOpened() {
listener?.onShowed()
}
override fun onRewardedAdClosed() {
listener?.onClosed()
rewardedAdShowing = null
}
override fun onUserEarnedReward(@NonNull var1: RewardItem) {
listener?.onEarned()
}
override fun onRewardedAdFailedToShow(var1: Int) {
listener?.onShowFailed(var1)
}
})
}
}
}
/**
* 設(shè)置預(yù)加載個數(shù)
*/
fun setPreloadCount(value: Int) {
preloadCount = value
}
/**
* 添加廣告加載監(jiān)聽器。注意:監(jiān)聽器會在廣告的一輪加載成功后被全部移除。
*/
fun addLoadListener(listener: RewardAdLoadListener) {
if (!loadListenerList.contains(listener)) {
loadListenerList.add(listener)
}
}
/**
* 移除廣告加載監(jiān)聽器
*/
fun removeLoadListener(listener: RewardAdLoadListener) {
loadListenerList.remove(listener)
}
}
Demo
項目地址:https://github.com/CoddZhang/AdmobDemo
包含:
1. 對SDK調(diào)用的封裝代碼
2. 使用測試id實現(xiàn)激勵廣告和原生高級廣告。
寫在最后
Admob其實是被Google收購的,并非土著的Google開發(fā)團隊作品,所以SDK的設(shè)計水準(zhǔn)感覺一般,友好性和自由度上做的不太好,不夠賞心悅目。
特別聲明:以上文章內(nèi)容僅代表作者本人觀點,不代表ESG跨境電商觀點或立場。如有關(guān)于作品內(nèi)容、版權(quán)或其它問題請于作品發(fā)表后的30日內(nèi)與ESG跨境電商聯(lián)系。
二維碼加載中...
使用微信掃一掃登錄
使用賬號密碼登錄
平臺顧問
微信掃一掃
馬上聯(lián)系在線顧問
小程序
ESG跨境小程序
手機入駐更便捷
返回頂部