穿山甲和广点通激励视频广告打开失败的异常处理

  • Post author:
  • Post category:其他


由于项目里接入了广告,包括但不限于穿山甲sdk和广点通sdk,视频广告是收益比较高的广告,项目里面出现的地方比较多。流程一般都是UI上有个按钮,点击按钮,请求到激励视频广告,然后直接打开该广告,也就是跳转到广告视频页面,等广告播放结束后,会有关闭按钮,点击关闭按钮,广告sdk会触发暴露出来的回调;如果请求广告失败,我们自己也会处理;这两种情况我们都是可以掌控的,也就是说这两种情况,我们都会有方法接收到事件,我们可以根据相应的事件,做出下一步的处理,比如给用户发奖励,或者重新请求广告。

打开广告激励视频的方法如下

穿山甲 :   nativeAd.showRewardVideoAd(activity);   // nativeAd 是 TTRewardVideoAd 类型

广点通 :   rewardVideoAD.showAD();  //  rewardVideoAD 是 RewardVideoAD 类型

上面方法都是 sdk 提供的方法,我们直接调用即可。但问题也来了,如果广告获取到了,同时也调用了该方法,如果广告页面没打开怎么办?上面两个方法都是 void 类型,如果说广告页面打开失败,但是没有回调事件,那么我们的UI界面由于没有接到下一步的指示,可能会一直固定在当前页面,甚至给人一种卡死的感觉,这种体验无意是很差的。

怎么办?sdk没提供方法,这就需要我们自己额外用些方法来检查了,加些防护。


这种场景比较好复现,比如说我们请求了广告,此时把app切到后台,比如说回到桌面,1秒后广告接口有广告返回,此时触发了 showRewardVideoAd(activity) 或 showAD() 方法,注意这时候app还在后台,不可见的状态,有些手机比如 oppp ,此时就不会跳转到广告页面,即使此时重新计入app,也不行。我们怎么处理呢?最简单的方式,用 Handler 延迟方法,我们在调用广告打开的方法的同时,用 Handler 延迟3秒执行段代码,检测app此时打开的Activity中,是否有当前打开的广告页面,比如 广点通的 Activity : PortraitADActivity,穿山甲的 Activity:TTRewardVideoActivity 或 TTRewardExpressVideoActivity。 老样子,

Application 的 registerActivityLifecycleCallbacks() 方法再次被用到,根据它的回调方法,来储存当前所有的 Activity, 方法如下

public class GlobalActivityLifecycle implements Application.ActivityLifecycleCallbacks {

    private static GlobalActivityLifecycle sInstance;

    public static void register(Application app) {
        if (sInstance == null) {
            synchronized (GlobalActivityLifecycle.class) {
                if (sInstance == null) {
                    sInstance = new GlobalActivityLifecycle();
                    app.registerActivityLifecycleCallbacks(sInstance);
                }
            }
        }
    }
    
    private static HashSet<String> mActivityNameSet = new HashSet<>();

    @Override
    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
        mActivityNameSet.add(activity.getClass().getSimpleName());
    }

    @Override
    public void onActivityStarted(Activity activity) {
         
    }

    @Override
    public void onActivityResumed(Activity activity) {

    }

    @Override
    public void onActivityPaused(Activity activity) {

    }

    @Override
    public void onActivityStopped(Activity activity) {
         
    }

    @Override
    public void onActivitySaveInstanceState(Activity activity, Bundle outState) {

    }

    @Override
    public void onActivityDestroyed(Activity activity) {
        mActivityNameSet.remove(activity.getClass().getSimpleName());
    }

    public static boolean isContainActivity(String activitySimpleName){
        return mActivityNameSet.contains(activitySimpleName);
    }

    public static boolean isContainActivity(String ... names){
        for(String name : names){
            if(mActivityNameSet.contains(name)){
                return true;
            }
        }
        return false;
    }
    
}


上面是工具类,下面是调用方法

    Handler mHandler = new Handler(Looper.getMainLooper());

    /**
     * 穿山甲
     */
    public void showRewardVideoAd(Activity activity, TTRewardVideoAd nativeAd) {
        nativeAd.showRewardVideoAd(activity);
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                if(!GlobalActivityLifecycle.isContainActivity("TTRewardVideoActivity", "TTRewardExpressVideoActivity")){
                    // TODO: 在 这个里面做一些告知UI的操作,意思是界面打开失败了
                }
            }
        }, 3000);
    }

    /**
     * 广点通
     */
    public void tryShowRewardVideo(RewardVideoAD rewardVideoAD) {
        rewardVideoAD.showAD();
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                if(!GlobalActivityLifecycle.isContainActivity("PortraitADActivity")){
                    // TODO: 在 这个里面做一些告知UI的操作,意思是界面打开失败了
                }
            }
        }, 3000);
    }

以上是思路,具体的大家可以通过扩展方法的形参,添加回调,或者使用观察者模式发送通知,总之符合自己项目的业务逻辑即可。上面的方法是通过集合来检查 Activity 的名字,可能有人会问,为什么不直接用 App里最 top 的Activity 来检测?假如说我们成功的打开了激励视频页面,这时候我们切入了后台,或者点击了视频广告,又打开了一个新的广告页面,这样最顶端的Activity就不是激励视频广告页面了,这样就误判了。

以上只是提供一个思路,希望起到抛砖引玉的作用。



版权声明:本文为Deaht_Huimie原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。