从后台切回来,你不想展示点广告吗?

4,810 阅读4分钟

版权声明:

本账号发布文章均来自公众号,承香墨影(cxmyDev),版权归承香墨影所有。

未经允许,不得转载。

一、前言

在使用一些携带广告的 App 的时候,经常会碰到,第二次启动的时候,会首先进入一个闪屏的广告页面,然后广告倒计时退出之后,才恢复到我们上次最后停留的页面上。

注意这样的功能,并非首次启动的时候,在启动页的出现的广告,而是在 App 内任意页面退出到后台,再次进入之后,出现一个广告页面,之后回退到最后停留的页面。

那么这样的功能,当然也不仅仅适用于广告,一些安全级别较高的 App 也会有要求退出后台一段时间再进入的时候,需要重新输入密码。那么它应该如何来实现呢?

二、思路和解决方案

实际上这样一个功能,唯一的难点是在什么时机去启动承载广告的页面。

1、方案一,利用ActivityLifecycleCallbacks

之前有过一个思路,就是利用 ActivityLifecycleCallbacks 中,通过管理各种 Activity 的生命周期,来判断 App 退出到后台又进入到前台了。

对 ActivityLifecycleCallbacks 的原理不那么了解的朋友,可以看看之前的文章《ActivityLifecycleCallbacks》。

其实现方式就是在 onActivityPaused() 方法的时候 postDelayed() 一个 Runnable,大概延迟 500 毫秒,然后在 onActivityResumed() 的时候,移除掉此 Runnable。

原理就是,如果正常的页面跳转,一个 Activity 走到了 onActivityPaused() ,应该马上就有另外一个 Activity 走到了 onActivityResume() ,这是一个正常的页面跳转,反之,则认为是退出到后台了。

关键代码如下:

2、方案二:ActivityLifecycleCallbacks + ComponentCallbacks2

其实方案一,单纯的使用 ActivityLifecycleCallbacks 来作为依据,判断当前 App 是退出到后台又再次进来,是完全足够的。

但是实际上,还有另外一种方法来辅助判断,当前 Activity 退出到后台了。

那就是 Application.onTrimMemory() 的回调中, level 参数为 TRIM_MEMORY_UI_HIDDEN 的时候,就是 App 退出到后台的时机。

当然,我们也可以通过 Application.registerComponentCallbacks() 方法,来注册一个回调对象,在其中处理 onTrimMemory() 的逻辑。

有关 onTrimMemory() ,不那么了解的朋友,也可以先看看之前的文章《omTrimMemory》

那么和方案一参考起来,唯一就是去掉了 Handler 去延迟判断,直接依赖 onTrimMemory() 方法来判断 App 退出到后台,然后下次有Activity 走到 onResume() 的时候,就认为是从后台再次启动,就可以去启动我们的广告页面了。

为了便于封装,我们可以单独写一个类 SplashAdWrapper ,然后分别实现 ActivityLifecycleCallbacks 和 ComponentCallbacks2 接口。

首先在 onTrimMemory() 中,监听 App 退出到后台,并增加标识位。

然后在 onActivityResumed() 的时候,判断标识位来确定是否是从后台进入的前台。

最后在 SplashAdWrapper 的构造方法中,通过 Application 对这两个接口进行注册。

然后就只需要在 Application.onCreate() 方法中,构造 SplashAdWrapper 即可。

最后运行看一下效果,各种后台前台切换,发现并没有什么问题。

3、方案的优缺点

这两种方案,方案一需要依赖一个 Handler 去延迟判断,而方案二,剔除了 Handler 的延迟判断,依赖 Android 自己的 Api 来做进入后台的判断,会更优雅一些。

还有一个问题就是,不管使用那种方案,依赖的 Api 都是 Android Level 14(Android 4.0) 以上,所以对于低于 4.0 一下的设备,可以考虑放弃掉这些设备广告的展现。如果必须使用的话,就只能使用方案一,并且构造一个 Activity 的父类,在其中将所有什么周期方法,统一管理来进行处理。

三、小结

前面也提到了,这种方案并不是只能使用在启动广告上,对于一些需要录入密码的,也可以计算退出到后台的时长,如果大于一个安全值,就需要重新输入密码,来保证安全。

实现方法在这里,怎么使用就看你自己了。