V1.0.0 功能列表 | 是否支持 |
接口自定义 |
支持 |
缓存策略 |
支持 |
外部cookie注入 |
支持 |
推送周期设定 |
支持 |
强制推送 |
支持 |
自定义埋点事件 |
支持 |
独立运行 |
支持 |
多线程写入 |
支持 |
后台线程服务 |
支持 |
注:代码已经经过线上项目验证, 横向Google统计对比,统计数据无丢失,性能稳定.
10年积累的网站建设、成都网站建设经验,可以快速应对客户对网站的新想法和需求。提供各种问题对应的解决方案。让选择我们的客户得到更好、更有力的网络服务。我虽然不认识你,你也不认识我。但先网站制作后付款的网站建设流程,更有如东免费网站建设让你可以放心的选择与我们合作。

项目背景
统计数据 是BI做大数据,智能推荐,千人千面,机器学习的 数据源和依据.
在这个app都是千人千面,智能推荐,ab流量测试的时代, 一个可以根据BI部门的需求, 可以自有定制的 数据统计上报, 就显得非常重要.
目前, 市面上 做统计的第三方平台有很多, 比如最出名的Google的GTM统计,友盟统计等等.
但是 这些统计, 第一点,就是上传的频率,比较固定, 难以满足要求不同的频次需求. 第二点,需要统计到的字段和规则都是死板的,无法定制.
目前GitHub上, 没有一个 自定义的 统计SDK 思路和源码.
我想,在这里分享下,我的思路和代码.
这里有几个要点
- 统计分类:统计分为屏幕值,事件两种,后续可能扩展.
- 统计规则: 支持简单Google统计方式,支持自定义字段.
- 推送方式:每两分钟上传到服务器,
- 作为sdk,可以单独集成,独立运行.
这是一个什么样的统计SDK?
做统计SDK的方式有这两种
1.用AOP的处理方式, 在方法内,插入统计代码. 这种方式虽然在.java
文件里 没有代码侵入,但是可定制行不高,只适合简单的 统计需求.
2.用普通的方法样式,使用GTM.event(xxx)
方式,代码侵入极高, 但是可以实现高度自定义.
现阶段, 我会采用第二种方式,为了数据的精确要求,采用侵入式.
后续, 我会继续思考,更好的实现方式. 也请大家一起分享自己的思路.
因为统计规则业务定制性很强,无法对传送数据进行统一的抽象管理, 该项目就不单独发布到jcenter,
如果需要,可以参考源码思路, 自己修改源码,修改数据载体,实现需求即可.
JJEvent设计初衷为:一个统计SDK, 可以单独发布到仓库,单独被项目依赖而不产生冲突,拥有自己的数据存储,网络请求.
1.上传规则
这些都是可以自定义的,修改源码即可
固定周期进行上传: 比如每2分钟,进行一次数据上传.数据为 触发推送的时间节点 之前的数据.用于大部分统计.
固定条数进行上传: 比如每100条,进行一次数据上传.数据为 触发 触发100条推送开始 之前的数据.用于大部分统计.
- 实时上传:每次点击就进行push操作.数据为 触发推送的时间节点 之前的数据.用于特定统计.
2.统计分类
这里, 可以根据BI的业务需求而定, 大家可以在此基础上修改.
1.PV(PageView) 屏幕事件
- sn(screen) 屏幕名称遵循旧策略(Android/好价/好价详情页/title).
- ltp 屏幕加载方式下拉刷新=1、翻页=2、标签切换=3、局部弹屏4、筛选刷新=5.
- ecp 自定义事件,json map存储.
2.Event点击事件
- ec(event category) 事件类别
- ea(event action) 事件操作
- el(event lable) 事件标签
- ecp 自定义事件,json map存储.
3.expose曝光事件
- url曝光url
- ecp 自定义事件,json map存储.
4. 其他事件
支持自定义扩展
SDK抽象过程
面向对象语言的特点: 就是要面向对象编程,面向接口编程.当你在抽象的过程中,只关注某个对象是什么,然后他拥有什么属性,什么功能即可.不需要考虑其中的实现.这也就是Java乃至面向对象语言,为啥这么多类的原因,这其中有单一职责原则,接口分隔原则.
模块之间的依赖,应该最大程度的依赖抽象.
要想完整的把整个过程抽象清楚,需要对整个流程有个最大的认知.
判断逻辑,技术选型
思考:肯定会想到这些东西,只不过想到的过程可能不同,而且每个设计者,想法都不会一样,实现过程也不一样.
首先需要一个配置类Constant
,对常量,开关进行管理.
一个sdk有事件统计,那么必须要有一个Event
类来进行屏幕值,事件
两种统计动作.
统计事件发生后, 需要一个持久化过程DbHelper
,即需要一个数据库支持存取.
如何推送呢? 需要建立一个后台服务JJService
,对数据进行推送.
用什么推送呢?肯定需要网络啊, 需要一个网络模块NetHelper
从数据库中拿数据,进行推送.
推送的是什么呢? 需要建一个任务Task
,让task承载推送的过程.
如何将模块进行连接,统一管理?
SDK整体架构
1.统计客户端SDK架构图

2.服务端数据收集采用的是
- openresty实现客户端日志上报接口
- flume实现日志采集发送kafka
- 最终落地到硬盘
3. 大数据端
经过抓取数据库数据快照 ,进行数据清洗,然后提供给机器学习,或者千人千面.
模块建设
这里如果有兴趣,请配合源代码.
1.JJEventManager
管理模块
首先,sdk的生命周期是整个application的周期,所以我让sdk 持有application 上下文,不会存在内存泄漏.所以,我考虑将全局上下文放在这里管理.当其他位置需要的时候到JJEventManager .getContext()
取值.
作为管理类,需要拥有控制sdk完整生命周期的功能.即init()
,cancelPush()
,destroy()
等方法.让各个模块的生命周期在这里管理.
然后考虑到,让用户可以动态配置各种参数,比如周期,是否是debug模式,主动推送周期等等.所以在内部使用buider模式,进行动态构建.
JJEventManager.Builder builder =new JJEventManager.Builder(this);
builder.setHostCookie("s test=cookie String;")//cookie
.setDebug(false)//是否是debug
.setSidPeriodMinutes(15)//sid改变周期
.setPushLimitMinutes(0.10)//多少分钟 push一次
.setPushLimitNum(100)//多少条 就主动进行push
.start();//开始
}
2.Event
动作模块
动作类,统计只有两个动作,即两个方法screen ()
,event()
,以及一些重载方法.
因为是公开类,所以要做到简洁,注释要到位..(导入项目中的jar包,没有Java document..因为doc生成在本地..云端没有)
由于是数据入口类,所有坚决不能存在崩溃的情况发生.
所以在相应的地方加上了try catch
处理.
/**
* 统计入口
* Created by chenchangjun on 18/2/8.
*/
public final class JJEvent {
/**
* pageview 屏幕值
* @param sn screen 屏幕值,例`Android/主页/推荐`
* @param ltp 屏幕加载方式
*/
public static void screen(String sn, LTPType ltp) {
screen(sn, ltp, null);
}
/**
* pageview 屏幕值
* @param sn screen 屏幕值,例`Android/主页/推荐`
* @param ltp 屏幕加载方式
* @param ecp event custom Parameters 自定义参数Map
*/
public static void screen(String sn, LTPType ltp, Map ecp) {
try {
ScreenTask screenTask =new ScreenTask(sn,ltp,ecp);
JJPoolExecutor.getInstance().execute(new FutureTask