Skip to content

Android平台Admob广告接入和封装

Android平台Admob广告接入和封装

前言

关于Admob如何接入,官方文档已经写的很清楚,所以不是本文的重点。本文主要讲Admob的调用封装。因为作为开发者接入Admob之后,其实工作远没有结束,可能想做预加载,想做些封装让接口更加简洁友好,此外还想让业务代码尽可能不与SDK耦合,等等。其实这部分内容也是一个轮子,那我们就不要重复造轮子了。

Admob接入

1. 官方网站:https://developers.google.cn/admob/android/quick-start

官网文档有中英文版本,阅读上不是什么问题,实际接入难度不大。只是随着版本的更新,文档同步的不是很及时。

2. 官方开发论坛:https://groups.google.com/forum/#!forum/google-admob-ads-sdk

遇到一些问题可以到论坛搜索下。我在开发时遇到一个兼容性问题,某些手机上激励广告播放时会突然被强制关闭,后来就是在论坛上找到了解决方案:正在播放的激励广告需要有明确的引用持有,否则可能被系统回收导致广告关闭。

二次封装

完整代码可以查看本文后面的github项目地址。

AdmobManager

框架内唯一暴露给业务层的接口,是一个单例。业务层只需要跟它打交道就可以进行加载、获取、显示广告等操作。

NativeAdRepository

原生高级广告仓库,一个广告位id对应一个广告仓库。本质是一个广告池,可实现给定数量的广告预加载,并在广告被使用后自动进行个数的加载补足。

/**

* 一个id对应一个广告仓库,仓库会自动进行广告的预加载(个数preloadCount),并向外提供广告内容

 *

 * id默认是测试广告

 */

class NativeAdRepository constructor(private var id: String = “ca-app-pub-3940256099942544/2247696110”,

                                     private var preloadCount: Int = 1) {

    /**

     * 已加载的广告列表

     */

    var adList = LinkedList()

    /**

     * 是否正在进行广告加载

     */

    var isLoading = false

    /**

     * 正在加载的广告个数

     */

    var loadingCount = 0

    var loadListenerList = ArrayList()

    /**

     * 进行广告加载

     */

    fun loadAds(context: Context) {

        if (isLoading || adList.size >= preloadCount) {

            Log.w(AdmobManager.TAG, “$id NativeAd don’t 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)

    }

    /**

     * 一个广告加载完成时调用

     */

    private fun onAdLoaded() {

        //更新正在加载的广告个数

        loadingCount–

        //所有广告加载完成,状态更新成未在加载中

        if (loadingCount

            isLoading = false

            //一般广告加载成功,收到一次通知即可,所以将所有监听器在这里进行移除

            if(adList.size > 0) {

                loadListenerList.clear()

            }

        }

    }

    /**

     * 是否已经有广告加载完成

     */

    fun isReady(context: Context): Boolean {

        return adList.isNotEmpty()

    }

    /**

     * 获取加载好的原生广告

     */

    fun getAd(context: Context): UnifiedNativeAd? {

        var ad = adList.poll()

        //广告被取走后,需要重新加载广告,保证池子里面有一定数量的预加载广告

        loadAds(context)

        return ad

    }

    /**

     * 设置预加载个数

     */

    fun setPreloadCount(value: Int) {

        preloadCount = value

    }

    /**

     * 添加广告加载监听器。注意:监听器会在广告的一轮加载成功后被全部移除。

     */

    fun addLoadListener(listener: NativeAdLoadListener) {

        if (!loadListenerList.contains(listener)) {

            loadListenerList.add(listener)

        }

    }

    /**

     * 移除广告加载监听器

     */

    fun removeLoadListener(listener: NativeAdLoadListener) {

        loadListenerList.remove(listener)

    }

}

RewardAdRepository

激励广告仓库,一个广告位id对应一个广告参考,实现方式与原生高级广告基本一致。

class RewardAdRepository constructor(private var id: String = “ca-app-pub-3940256099942544/5224354917”,

                                     private var preloadCount: Int = 1) {

    /**

     * 是否正在加载

     */

    var isLoading = false

    var adList = ArrayList()

    /**

     * 正在加载的广告个数

     */

    var loadingCount = 0

    /**

     * 正在播放的广告需要有明确的引用持有,否则在有些系统里面广告会被强制回收关闭

     */

    var rewardedAdShowing: RewardedAd? = null

    var loadListenerList = ArrayList()

    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

            isLoading = false

            //一般广告加载成功,收到一次通知即可,所以将所有监听器在这里进行移除

            if(adList.size > 0) {

                loadListenerList.clear()

            }

        }

    }

    /**

     * 加载广告

     */

    fun loadAds(context: Context) {

        if (isLoading) {

            return

        }

        //用来放没有加载成功的广告

        var removeList = ArrayList()

        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

            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)

                    }

                })

            }

        }

    }

    /**

     * 设置预加载个数

     */

    fun setPreloadCount(value: Int) {

        preloadCount = value

    }

    /**

     * 添加广告加载监听器。注意:监听器会在广告的一轮加载成功后被全部移除。

     */

    fun addLoadListener(listener: RewardAdLoadListener) {

        if (!loadListenerList.contains(listener)) {

            loadListenerList.add(listener)

        }

    }

    /**

     * 移除广告加载监听器

     */

    fun removeLoadListener(listener: RewardAdLoadListener) {

        loadListenerList.remove(listener)

    }

}

Demo

项目地址:https://github.com/CoddZhang/AdmobDemo

包含:

1. 对SDK调用的封装代码

2. 使用测试id实现激励广告和原生高级广告。

写在最后

Admob其实是被Google收购的,并非土著的Google开发团队作品,所以SDK的设计水准感觉一般,友好性和自由度上做的不太好,不够赏心悦目。

相关推荐: 寄药品到国外最好用什么快递

很多人会问:国际快递怎么寄药品?药品快递到国外有什么要求,哪些药品可以快递到国外? 今天小编就和大家一起分享一下,关于国际快递怎么寄药品、要求以及哪些药品能寄国外的问题~ 国际快递哪些药品不能寄? 摇头丸、迷幻药、海洛因、吗啡 甲基苯丙胺、可卡因、美他沙酮、安…

    码刀科技(www.lekshop.cn)是国内知名企业级电商平台提供商,为企业级商家提供最佳的电商平台搭建(多种模式电商平台搭建:B2B/B2B2C/B2C/O2O/新零售/跨境等)、平台管理系统开发及互联网采购解决方案服务, 联系客服了解更多.

    电子商务网站建设的重要性和好处