1:ActivityLifecycleCallbacks 是Application 内部的 一个接口,在Activity的每一个生命周期都对应ActivityLifecycleCallbacks接口中一个方法,比如 onActivityCreated 的回调是在 Activity的 onCreate方法中调用 getApplication().dispatchActivityCreated(this, savedInstanceState) 来完成对Activity生命周期的监听。
2:要使用这个接口,一般我们在自定义的Application(比如 MyApplication)的 onCreate()中 registerActivityLifecycleCallbacks()注册这个接口就可以使用了
3:ActivityLifecycleCallbacks接口函数回调源码分析
4:使用场景
使用场景一 :管理Activity栈
我们可以先定义一个变量Stack 然后在接口onActivityCreated() 函数中 将Activity 压入栈中Stack.push(activity) ,在 onActivityDestoryed()函数中 将Activity从栈中移除 Stack.pop(),也可以在应用程序退出时,清楚所有Activity
使用场景二 :判断 App前后台状态
判断应用是否在后台运行,针对前后台运行会做一些处理,比如提示用户应用运行在后台、以及应用前后台切换回调通知等。利用通过监听回调方法 onActivityStarted与onActivityStopped两个方法,结合Activity Stack 中Activity数量 来判断应用前后台。
使用场景三:应用新开进程假重启处理(低内存回收、修改权限)
应用在低内存的情况下退出重新启动,并不会执行正常的启动流程,而是创建新的进程,直接还原上一次的操作页面,这样会导致页面栈信息丢失,页面显示以及返回跳转异常。
比如:正常的启动流程时:SplashActivity ----loginActivity ----MainActivity
在低内存重新开进程情况下,会直接启动LoginActivity. 这样就会出现页面信息丢失,解决方案就是我们可以通过监听回调方法 onActivityCreated,判断应用启动的第一个 Activity 页面是否为 SplashActivity ,如果不是,则强制启动SplashActivity 来执行正常的启动流程。
使用场景四:获取当前运行页面
通过监听回调方法 onActivityResumed,设置当前 Activity 页面
使用场景五:保存恢复状态值 savedInstanceState
Activity 异常退出经常需要保存恢复一些数据,ActivityLifecycleCallbacks 实现数据保存恢复也是比较简单的。 通过监听回调方法onActivityCreated与onActivitySaveInstanceState保存恢复状态值
使用场景六:页面分析统计埋点,页面信息统计
使用场景七:给App设置指纹解锁或者手势密码解锁,例如,App切换至后台或者进程关闭,时间如果超过20sec,App再次切换至前台或者重新打开,要让用户验证指纹或者手势密码,验证通过的话才能进入home页,当然,具体的时间长短,后端可配
此场景最重要的就是 :记录App切换至后台或进程被杀死的时间点是解决问题的关键点一,假设这个时间点是T1;记录App再次切换至前台或者重新打开的时间点是解决问题的关键点二,假设这个时间点是T2。只要能准确的记录T1和T2,上述需求就迎刃而解(假设后端配置的时间间隔为timeSpan)。
思路:
监听T1和T2的基本思路
(1).写一个基类baseActivity,所有新创建的Activity全都继承基类;
(2).在基类中定义一个int变量activeNum,记录当前存活的Activity个数;
(3).回调基类的onResume()方法,activeNum就加1,回调基类的onStop()方法, activeNum就减1;
(4).当activeNum的值减到0,说明App进入后台或者被Kill,记录时间点T1并保存.因为App不同页面间切换都会走onResume(),所以在记录时间点T1的同时,保存一个标记checkTimeFlag, 置为true,这个标记用来判断下次调用onResume()时是否为T2时间点
(5).在基类的onResume()方法里获取并判断标记checkTimeFlag,true的话,获取App切换到前台或者重新打开的时间点T2,检查是否超时,超时的话,将标记checkTimeFlag置为false并验证用户指纹或者手势密码;
(6).配置的时间间隔timeSpan可以在启动页从后端获取,每次走启动页的时候刷新一次,当然个别场景会有些延迟,例如,用户从页面A进入后台,timeSpan修改了,但是用户切回前台,判断时使用的timeSpan还是上次的,不是修改后的,这种场景不走启动页刷新timeSpan,如果非要实时的话,其实可以把接口请求写在onResume()里,获取T2之后,请求接口获取timeSpan。



