美呗埋点解决方案
前言
接到上级需求需要开发一个公司内部使用的埋点SDK,参考了部分文档,感觉满足不了我们的需求,所以自己按照自己的思路撸了一个。没有用到AspectJ ,有需要的可以去学习一下挺强大的。AspectJ可以看着个:http://zhuhf.tech/2017/01/22/AspectJ/
产品需求:
1.行为轨迹(记录用户使用app的页面路径,埋点后台给每一个页面分配一个页面id,上传时需要把页面id带上)
2.事件(记录用户的点击事件等,埋点后台给每一个事件分配一个事件id,上传时需要把事件id带上)
思路:
行为轨迹(页面可见就记录事件)
1.activity我们可以在监听onResume,我用的是application的registerActivityLifecycleCallbacks()回调监听onActivityResumed(Activity activity),此时代表此activity可见
2.fragment不能监听onResume,会出现如下场景
场景一:
首页一个Activity承载多个Fragment的情况,此时tab间切换并不会触发Fragment的onResume/onPause.触发的回调函数是onHiddenChanged(boolean hidden)
场景二:
一个ViewPager承载多个页面的Fragment时
a.当第一个Fragment1显示时,虽然第二个Fragment2此时尚未显示,但是Fragment2的OnResume却以及执行,处于resumed的状态.
b.ViewPager页面切换OnResume/OnPause/onHiddenChanged均未触发,触发的回调是setUserVisibleHint
我的解决方案是写一个BaseFragment,通过onHiddenChanged、setUserVisibleHint、OnResume组合判断页面是否可见,代码如下(打印日志的地方就代表fragment真正可见):
public class BaseTrackFragment extends Fragment {
private boolean isOnHiddenChanged;
private boolean isSetUserVisibleHint;
private int type;
@Override
public void onHiddenChanged(boolean hidden) {
super.onHiddenChanged(hidden);
if (!hidden) {
addTrace();
System.out.println("------------->onHiddenChanged:可见" + getClass().getSimpleName());
}
isOnHiddenChanged = true;
type = 1;
}
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
addTrace();
System.out.println("------------->setUserVisibleHint:可见" + getClass().getSimpleName());
}
isSetUserVisibleHint = true;
type = 2;
}
@Override
public void onResume() {
super.onResume();
if (type == 1) {
if (!isOnHiddenChanged && !isHidden()) {
addTrace();
System.out.println("------------>onResume:可见1" + getClass().getSimpleName());
}
} else if (type == 2) {
if (!isSetUserVisibleHint && getUserVisibleHint()) {
addTrace();
System.out.println("------------>onResume:可见2" + getClass().getSimpleName());
}
} else {
if (!isOnHiddenChanged && !isHidden()) {
addTrace();
System.out.println("------------->onResume:可见0" + getClass().getSimpleName());
}
}
}
@Override
public void onPause() {
super.onPause();
isSetUserVisibleHint = false;
isOnHiddenChanged = false;
}
private void addTrace() {
//上传事件
}
}
3.页面id,SDK如何获取到?
我的解决方案是在页面上添加一个注解,然后通过getClass().getAnnotation()去获取注解信息
or
可以写一个配置文件通过 getClass().getName()去对比配置获取id
事件
1.集成端直接调用sdk提供的方法传递事件id
总结:
埋点这个需要根据每个公司需求来订,适合自己的就是最好的!