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

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 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;
}

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

你可能感兴趣的:(Android实现后台返回前台再次显示广告)