美文网首页Android开发Android技术知识Android开发
Android实现后台返回前台再次显示广告

Android实现后台返回前台再次显示广告

作者: 蒲导 | 来源:发表于2017-12-26 22:27 被阅读332次

    Android实现后台返回前台再次显示广告

    市面上主流的APP都是在启动页做广告展示的,即通常都是叫SplashActivity的是APP的launcher页面,在manifest文件中配置, 2017年以来, 你会发现越来越多的APP在进入后台时隔一定时间后再次回到前台会再次显示广告界面, 3s自动播放, 或者手动点击跳过

    1461514126877_.pic.jpg

    比如网易云音乐, 淘宝, 京东商城啦, 似乎现在都是很主流的做法了,刚好最近项目中也有这样的需求, 我们也实现了一遍,所以写出来分享下,相互学习借鉴

    要实现后台返回前台显示广告的逻辑, 主要的点在于监听APP进入后台的时间点, 和APP从后台返回到前台的时间点

    我们是在Application子类中完成的, 定义三个常量记录当前APP状态

     // 正常状态
    public static final int STATE_NORMAL = 0;
    // 从后台回到前台
    public static final int STATE_BACK_TO_FRONT = 1;
    // 从前台进入后台
    public static final int STATE_FRONT_TO_BACK = 2;
    

    在Application中需要监听Activity的生命周期变化, registerActivityLifecycleCallbacks是application类已经提供好的一个方法, 它可以非常方便的监听整个项目中的所有activity的生命周期

    // Application类中的内部类接口
    public interface ActivityLifecycleCallbacks {
        void onActivityCreated(Activity activity, Bundle savedInstanceState);
        void onActivityStarted(Activity activity);
        void onActivityResumed(Activity activity);
        void onActivityPaused(Activity activity);
        void onActivityStopped(Activity activity);
        void onActivitySaveInstanceState(Activity activity, Bundle outState);
        void onActivityDestroyed(Activity activity);
    }
    

    可以很清晰的看到Activity的生命周期函数都会回调到ActivityLifecycleCallbacks接口来, 我们让Application实现此接口, 并在相应的回调方法中的完成具体的后台状态的监听

    定义几个需要用的变量记录相关状态和时间

    // APP状态
    private static int sAppState = STATE_NORMAL;
    // 标记程序是否已进入后台(依据onStop回调)
    private boolean flag;
    // 标记程序是否已进入后台(依据onTrimMemory回调)
    private boolean background;
    // 从前台进入后台的时间
    private static long frontToBackTime;
    // 从后台返回前台的时间
    private static long backToFrontTime;
    

    在onResume回调中监听回到前台的判断, 只要activity一旦获取焦点这个方法都会触发,并且会触发多次

    @Override
    public void onActivityResumed(@NonNull Activity activity) {
            if (background || flag) {
                background = false;
                flag = false;
                sAppState = STATE_BACK_TO_FRONT;
                backToFrontTime = System.currentTimeMillis();
                Log.e(TAG, "onResume: STATE_BACK_TO_FRONT");
                if (canShowAd()) {
                    ShowADActivity.show(activity);
                }
            } else {
                sAppState = STATE_NORMAL;
            }
    }
    

    在onStop回调中监听程序进入后台的判断

    @Override
    public void onActivityStopped(@NonNull Activity activity) {
            //判断当前activity是否处于前台
            if (!SystemUtils.isCurAppTop(activity)) {
                // 从前台进入后台
                sAppState = STATE_FRONT_TO_BACK;
                frontToBackTime = System.currentTimeMillis();
                flag = true;
                Log.e(TAG, "onStop: " + "STATE_FRONT_TO_BACK");
            } else {
                // 否则是正常状态
                sAppState = STATE_NORMAL;
            }
     }
    

    在onTrimMemory中监听应用程序的切换,这也是一种监听方式.因为有时候onStop的回调不一定会完全执行(尤其是切换最近使用APP列表时),所以这个方法也是必须的

    @Override
    public void onTrimMemory(int level) {
        super.onTrimMemory(level);
        // TRIM_MEMORY_UI_HIDDEN是UI不可见的回调, 通常程序进入后台后都会触发此回调,大部分手机多是回调这个参数
        // TRIM_MEMORY_BACKGROUND也是程序进入后台的回调, 不同厂商不太一样, 魅族手机就是回调这个参数
        if (level == Application.TRIM_MEMORY_UI_HIDDEN || level == TRIM_MEMORY_BACKGROUND) {
            background = true;
        } else if (level == Application.TRIM_MEMORY_COMPLETE) {
            background = !SystemUtils.isCurAppTop(this);
        }
        if (background) {
            frontToBackTime = System.currentTimeMillis();
            sAppState = STATE_FRONT_TO_BACK;
            logcat.e(TAG, "onTrimMemory: TRIM_MEMORY_UI_HIDDEN || TRIM_MEMORY_BACKGROUND");
        } else {
            sAppState = STATE_NORMAL;
        }
    
    }
    

    最后, 就可以得到当前APP的准确状态(sAppState)了, 是否可以再次显示广告

    /**
     * 进入后台间隔10分钟以后可以再次显示广告
     *
     * @return 是否能显示广告
     */
    public static boolean canShowAd() {
        return sAppState == STATE_BACK_TO_FRONT &&
                (backToFrontTime - frontToBackTime) > 10 * 60 * 1000;
    }
    

    测试过程中,发现大部分品牌的手机都是OK的, 但是也有意外的,OPPO R9在切换应用时,一个回调都没触发,一定是Color OS改动太大, 目前尚无法处理.OV手机适配起来就是费劲啊

    最后补充一个判断程序是否前台的API

    /**
     * 判断当前程序是否前台进程
     *
     * @param context
     * @return
     */
    public static boolean isCurAppTop(Context context) {
        if (context == null) {
            return false;
        }
        String curPackageName = context.getPackageName();
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<RunningTaskInfo> list = am.getRunningTasks(1);
        if (list != null && list.size() > 0) {
            RunningTaskInfo info = list.get(0);
            String topPackageName = info.topActivity.getPackageName();
            String basePackageName = info.baseActivity.getPackageName();
            if (topPackageName.equals(curPackageName) && basePackageName.equals(curPackageName)) {
                return true;
            }
        }
        return false;
    }
    

    各位大佬们如果有更好的实现,欢迎提供思路!

    相关文章

      网友评论

      • 03226f1021c2:大佬,当我调用系统相机/相册/调用第三方登录/支付等等时,该如何处理?
      • 仕明同学:可以的呃呃

      本文标题:Android实现后台返回前台再次显示广告

      本文链接:https://www.haomeiwen.com/subject/brkkgxtx.html