ActivityLifecycleCallbacks是4.0新增的一个接口,它管理着整个app的所有Activity的生命周期,也就是任何一个Activity只要走了生命周期就会回调这个接口中相应的方法,我们利用它可以做很多事情。
最新有个产品需求就是记录App进程从后台进入前台的情况,然后记录埋点,ok先奉上实现代码。
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
@Override
public void onActivityStopped(Activity activity) {
activityResumeCount--;
if (activityResumeCount == 0) {
isForground=false;
}
Log.e("wwww","onActivityStopped:"+activityResumeCount+"activity:"+activity+"isForground:"+isForground);
}
@Override
public void onActivityStarted(Activity activity) {
activityResumeCount++;
if(activityResumeCount==1){
isForground=true;
}else{
isForground=false;
}
Log.e("wwww","onActivityStarted:"+activityResumeCount+"activity:"+activity+"isForground:"+isForground);
}
@Override
public void onActivitySaveInstanceState(Activity activity,
Bundle outState) {
}
@Override
public void onActivityResumed(Activity activity) {
Log.e("wwww","onActivityResumed:"+activityResumeCount+"activity:"+activity+"isForground:"+isForground);
if(isForground){
Api.getApi().lvqClick(getApplicationContext(),"lv02459","访问","");
}
}
@Override
public void onActivityPaused(Activity activity) {
Log.e("wwww","onActivityPaused:"+activityResumeCount+"activity:"+activity+"isForground:"+isForground);
}
@Override
public void onActivityDestroyed(Activity activity) {
Log.e("wwww","onActivityDestroyed:"+activityResumeCount+"activity:"+activity+"isForground:"+isForground);
}
@Override
public void onActivityCreated(Activity activity,
Bundle savedInstanceState) {
Log.e("wwww","onActivityCreated:"+activityResumeCount+"activity:"+activity+"isForground:"+isForground);
}
});
假如我开始进入界面 A,然后进入界面B,接着进入界面C,那么ActivityLifecycleCallbacks中的生命周期执行次序是:
A -> onCreate()
A ->onStart()
A ->onResume()
A ->onPause()
B -> onCreate()
B -> onStart()
B -> onResume()
A -> onStop() (如果finish()掉的话还会走onDestroy())
B -> onPause()
C -> onCreate()
C -> onStart()
C -> onResume()
B -> onStop() (如果finish()掉的话还会走onDestroy())
可以看到不论我们跳转多少个Activity,最后一个Activity的之前所有Activity都会走onStop()方法,
所以我们在onActivityStarted(Activity activity) 中对变量自增++,在onActivityStopped(Activity activity)中对变量自减--,当然自增也可以放在onActivityResumed(Activity activity)中因为onActivityStarted之后onActivityResumed也会走,那么在最后一个Activity可见时这个变量值一定是1,当我们按了Home键切换到后台时这个值一定是0,。
根据这个值我们就可以在onResume()判断进程是在前台或者后台,只做这些就够了吗,当然不,我们分析另一种情况。
还是前面例子,假设我连续跳转2个Activity此时界面位于Activity C,这个时候变量activityResumeCount的值是等于1的,这没毛病,此时我按Back键返回到Activity B
那么接口回调的次序是
C -> onPause()
B -> onStart()
B -> onResume()
C -> onStop()
C -> onDestroy()
按照这种次序,C界面的onStop是执行在B界面的onStart和onResumed之后的,那么此时我们在B界面的onResumed()生命周期时,activityResumeCount的值是2,如果我们在onActivityStarted()中根据activityResumeCount>0就是后台切前台,activityResumeCount==0就是前台切后台的话,那么此时只是一次页面切换而已却记录成了一次后台切前台进程行为,我们就填坑啦!这次数据埋点就是错误的记录,那么应该怎么办呢,前面代码中在onActivityStarted中多加个判断,当前界面走onActivityStarted()时只有变量activityResumeCount的值为1时才符合我们之前跳转到最后一个Activity或者按了Home键在切回来这种情况,而当按Back键返回时,此时activityResumeCount值是大于1的不满足条件,这样就可以判断是否是后台切换前台进程啦.
这个实现方式经过我测试是没有什么问题的,可以完全记录前后台进程的切换行为。