美文网首页ITiOS 开发 Android
App打造自定义的统计SDK, 是时候和友盟说分手了

App打造自定义的统计SDK, 是时候和友盟说分手了

作者: Tamic | 来源:发表于2016-07-04 22:12 被阅读10775次

简书 :Tamic
原文地址:
http://www.jianshu.com/p/cd83e81b78aa
授权文章 请访问版权印 http://www.banquanyin.com/u/101701130004540


42f293e51580443ade1e91772034aff6.jpg

前言

谈到移动APP开发的优化方案,开发者第一时间会想到关于GPU渲染和CPU优化问题,而这两大方案确实是优化app的两把尖刀,使APP提升用户量和体验度有较高的推动力。然而我们却会忽视一个比较简单而又难记住的方面,是对用户潜在行为的预估和把控,其实也属于APP业务优化范畴。
在无法预估的就是用户的实用操作欲望的情况下,针对已经发出去的版本,我们很难知道用户喜欢什么功能,和想要怎样的功能,包括用户卸载了,甚至安装不用的情况,并且对潜在线上崩溃的问题也想知道问题出在哪里等等 ,这些对于app的成长优化也有关键的导向作用,其实这也可以算是一种对app的优化方案。

对于上面存的问题,一般开发者所关心的是已发版的crash的问题,而产品更关心的是对一个用户行为体系的采集和预研,那么这种专门解决化方案出现了,第三方的统计化框架(SDK), 比如市场的友盟,小米,百度等提供的统计sdk, 对于一个小型的项目,我们可以采取第三方来实现,那么对于一个成熟包括万级日活的应用,那么属于自己的一个日志统计体系是刻不容缓的,掌握了市场动向和用户行为,就能拥有了主动权,拥有客户就是拥有了市场,那么怎样去设计实现一种优良的行为统计方案?

统计分类

PC端统计

以经典的pc上的web页面统计一般有PV.UV和IP之分,对于crash问题,本身web页面就存在远程的服务器端,日志将会保存在服务器的特定目录,所以一般web项目开发者无需考虑收集Log的case,那么我们更care的就是上面说的行为统计,下面说说这三种统计区别。

  • IP、PV和UV含义

IP,实际上也就是指独立IP,是独立IP数的意思。一天24h内相同IP地址只记录一次。即使你有多台PC,如果IP地址是一样的,那么也只能算是一个IP的访问,IP数据依然为1。当然多台pc的ip一般都不一样,除非你插上同一个网络端口然后换零一台连接,都是一样,同时连接多台,每台pc的IP就是不一样的。

PV, 指访问量,它的英文是PageView,具体是指网站的是页面总浏览量或者点击量,页面被刷新一次就计算一次。如果网站被刷新了10次,那么流量统计工具显示的PV就是10 。

UV,它是独立访客的意思,英文为Unique Visitor。具体指访问您网站的一个客户端(移动设备或者是电PC)为一个访客。00:00-24:00内相同的客户端(mac地址区分)只被计算一次。

IP、PV和UV关系?

  • IP和PV之间的关系

PV是和IP的数量是成正比的,因为页面被刷新一次那么PV就会被记录一次,所以IP越多,说明网站的PV数据也就随之增多。但是需要注意的是PV并不是网站的页面的访问者数量,而是网站被访问的页面数量。因为一个访问者可以多次刷新页面,增加PV数量。

  • IP和UV之间的关系:

在记录网站流量统计数据时,运维有时候发现这样一种情况:有时候网站的IP数据大于UV数据,有时候UV的数据也会大于IP数据。为什么会出现这种现象呢?我们可以用一个例子来说明。比如,用同一个IP去访问我们的某个网站,但是一个是用的台式的电脑,一个是用的笔记本,那么网站流量统计工具显示的数据就会是2个UV,1个IP。这时UV的数据就会大于IP的数据。但是,再比如,只是用一个台式电脑访问我们的网站,但是一会拨一个号换一个IP,那么这时候网站流量统计工具显示的数据的UV就为1,但是IP的数据就会高于UV的数据。因此,IP和UV之间的数据并不一定存在比例关系,两者之间的数据也不是此消彼长的关系。

IP和PV之间的关系

那么IP和PV的关系如何呢? 如果一个IP刷新了某个网站1000次,网站的PV就为100,所以从这点看二者之间没有多大关系。但是,我们可以通过IP和PV之间的数据差异,来更加深入的理解网站的流量数据。如果IP和PV的数据悬殊很大,比如,我们在查看网站流量数据时发现网站的PV是1000,IP为300,那么说明这个站点平均一个IP访问了网站内容10次,说明网站内容还是比较受欢迎的,所以访客才愿意在网站中停留那么久的时间,并浏览了那么多的网站页面内容。但是如果IP和PV的数据很接近,比如,网站的IP为100,PV为110,说明一个IP也就访问了网站内容大约1次,就说明网站内容的可读性太差,客户点击进去之后就离开了,没有有过多的停留。如果网站流量统计这样的数据过多的话,产品就需要对网站内容和功能进行深入思考了,以便更好的提高网站的流量。

  • 移动开发我们能从这边得到什么

鉴于已经很成熟的WEB统计方案,我们在移动设备上(这里只说Android)实现一个完美的用户数据和行为统计,崩溃日志的套装方案该怎样做?

stat.jpg

移动设备统计

一款App,我们在通过上面的情况又该做的哪些呢

  • 用户数据(日活)

首先我们的可以加入IP,PV和UV统计模式,这样我们可以成功的get到app的日活,以及整体使用情况,
列入App启动了多少次,访问了多少h5页面,有多少个ip(设备)访问过,但是我们无法得native页面的信息(一般都是Activity),服务端是无法获取的,除非我们本地的页面有加载服务端数据的接口的功能,在某个接口(API)中捞数据,这种情况下服务是可以监控到本页面的数据流量的,但是在断网情况下,服务端是无法及时获取日活数据的,那么怎么解决呢?。

  • 用户行为

获取到了APP整体流量后,怎么知道某个功能受欢迎,或者本地某个页面经常被用户使用,则针对这种需求,app实现具体行为统计是必须的, 目前一般由客户端和服务器端协商好一套自定义事件字典(也就是所谓的统计id)当用户使用某个功能时,我们将对应的功能id发送到后台。这样服务端就有统计用户行为的能力了,那么这种只是一种初次尝试的想法,那么断网,或者功能复杂的情况子下,我们又如何采集用户行为?

  • Log日志

那么对于线上的app版本,又是怎样收集carsh日志呢。常规做法在app崩溃的时候发送一条请求到服务端,是可以实现的,但没必要这样做,一般是将日志保存到本地,在某个时间或者case来触发数据上报行为

统计

综合方式

业界的统计策略不会采用单一的方式进行上报,大多采用组合的形式实现,服务器和客户端,有网和没网,实时和不定时,主动触发和被动接受之分

  • Server

客户端请求接口是统一包含特定的请求头,服务端的每个接口中可以去采集这些请求头 用来记录访问量 包括ip,PV,UV , 这样可以去捕获一定的用户数据。

web端也可以采用推送的形式,在需要数据的时候让客户端发送特定采集好的信息上报给服务器。

  • Client

移动端统计一般大部分体现在客户端,我们可以将一个整体的app分解成多个模块,每个模块还可能有多个功能,功能又分为用户主动使用和被动接受之分,开发者给每个域分配一定的ID,那么在用户使用某个功能时 我们动态记录这个ID(比如登陆和注册一般属于用户中心(用户中心的功能域001), 登陆和注册属于两种功能,则分别给03,04标记作为事件域,登陆属于用户主动操作,那么可以给 01,注册被动跳转给02), 最后写入数据保存本地,那么用户打开用户中心登陆整个流程产生的数据信息则为0010201 ,这样服务器能知道完整搜集此条用户操作,只要在某个时间点将文本数据上传即可,即使没网络情况下我们也不用担心,等设备有网的情况下 我们偷偷上报即可,也可以在用户启动APP的时侯就上传这些数据,这个策略视具体功而定。

一般一个APP统计有模块域 ,功能域,事件域,由大到小分配而来,也有按页面(Activity)区分的,具体看实际的需求场景而定

对于APP 的crash 开发者可以继承android自带的全局异常类(UncaughtExceptionHandler)来进行自我捕获异常,或者读取系统log和用户行为一起上报

同时也可单独加个意见反馈功能,采集用户的吐槽和建议。

介绍了上面一大堆策略问题,对于开发而言很可能觉得很无聊,但是事实上 至于统计其实没什么技术含量(用户设备的唯一标识符除外),无非就是采集数据写到文件中,请求发送数据而已,最重要的还是一种策略的定义。

  • 何时上报
    主流的多采用 时间戳,内存大小(日志积累到多大字节),次数(总计积累到多十条)等,

对于一款好的统计方案,我们可以检测网络,检测home建来触发我们的上报数据接口,也可以采用注册静态广播,用alarm 闹钟定时上报数据(客户端轮询),然后这些技术已经是被大家玩透的功能而已,没必要再这里给大家补脑,但是注意的是 ,鉴于设备多样化统计设备唯一标识符很难确定,
统计上报接口采用分布式,不然所有数据都请求同一个接口,那么日活大的情况下,服务器挂了 不仅不能收到统计数据,反而影响客户端其他功能的正常使用。

20160319155945072.png

接下来给大家带来一款自定义的统计SDK 天眼 :SkyMonitoring

SkyMonitoring

Android StaticFrameWork

自定义统计SDK, 完全放弃第三方平台,让app拥有自主的数据统计功能

支持页面统计
自定义事件统计
APP启动退出统计
不同渠道统计
多版本 多机型 多区域统计
多时段,多场景上报

客户端SDK功能概述

在使用统计服务前,开发者先要拿到本身APPID。其中AppId是客户端的身份标识,在客户端SDK初始化时使用。然后下载最新Library的SDK压缩包,其中包括了Android SDK和AndroidDemo。Android版SDK以Module形式提供, 你的APP只需要添加少量代码和配置,即可完成接入TcInterface统计服务。

统计服务Android

SDK所有的接口都封装在TcStatInterface抽象类的静态方法中,主要功能接口请参考GitHub ReadMe。应用在启动时,需要调用initialize方法来初始化统计服务,之后便可按照统计的业务需求,调用统计数据上报接口上报统计打点。
SDK提供了接口给开发者来设置向统计统计服务器上报统计数据的策略,开发者可以在任意时候调用修改策略。客户端SDK上报的数据包括默认事件统计、应用全局(AppAction)统计(用于统计app的唤醒、打开关闭频率、使用时长等)、页面访问统计(Page)和自定义事件(Event)统计。

统计SDK提供app的崩溃日志收集功能(统计SDK2.0 将会新增)。功能开启后,对于app在使用过程中的崩溃,SDK将自动采集崩溃日志,并上传到统计后台;统计后台会根据app版本,对崩溃进行聚合、展示。开发者可以根据app实际情况情况,将该崩溃标记成已处理或者忽略状态。

注意
由于是自我的统计服务,目前服务端代码需要开发者自我实现,数据结结构按客户端数据结构实现即可。

华丽的结尾

你的统计SDK你作主,是时候和第三方统计说再见了

Github:
https://github.com/Tamicer/SkyMonitoring

第一时间获取技术文章请关注的公众号!

开发者技术前线

相关文章

网友评论

  • 黑马有点白986:来一套无痕埋点技术,准确率高的那种。
  • 豆奶不好喝:请问这个appid怎么生成?还是随便自己定义?或者读取设备唯一id这种?
    Tamic:@豆奶不好喝 就是普通的字符串
  • Chauncey_Chen:讲了一大堆.....然后....作者没有开源代码...
    Tamic:@Chauncey_Chen 切分支不会吗?
    Chauncey_Chen:@1101o 我在公司,写了一个自主统计sdk , 目前已经上线到公司千万亿用户app 不久后我会开源, 到时候@你.
    1101o:对于这个作者,我真是醉了
  • 甜牛奶苦咖啡:private synchronized void onForegroundChanged(Context aContext, boolean aIsForeground) {
    // 更新前后台状态
    isForeground = aIsForeground;
    //前后台变换时访问report
    reportData(aContext);
    //记录前后台切换
    if (aIsForeground) {
    if (StaticsConfig.DEBUG) {
    Log.d(LOG_TAG, "onForeground true");
    }
    // app唤醒
    DataConstruct.storeAppAction("3");
    //切前台时开始计时
    scheduleStart();
    } else {
    //切后台
    if (StaticsConfig.DEBUG) {
    Log.d(LOG_TAG, "onForeground false");
    }
    //切后台时数据上传
    TcStatSdk.getInstance(aContext).send();
    // 切后台停止计时
    scheduleStop();

    }
    }

    上报前,没有看到不同上报策略的处理逻辑;这里直接调用reportData,而且如果aIsForeground为false。那数据不是send了两次吗?
    Tamic:@甜牛奶苦咖啡 你可以优化 下
  • 甜牛奶苦咖啡:@Override
    protected void onDestroy() {
    super.onDestroy();

    // APP退出
    TcStatInterface.recordAppEnd();
    }
    这个统计是什么意思?
    Tamic:@甜牛奶苦咖啡 可以的
    甜牛奶苦咖啡:@Tamic app退出统计写在BaseActivity#onDestroy方法里面不合适吧
    Tamic:@甜牛奶苦咖啡app退出统计
  • 程洛_1114:您好,最近正要自定义埋点操作,看了您的文章受益匪浅,从什么地方可以下载到Library呢?谢谢!
  • 850a124b870b:tamic 这个包没有开源?
    Tamic: @金诚123 github地址有的
    850a124b870b:@Tamic 麻烦给个开源地址呗? app依赖的那个库
    Tamic: @金诚123 有开源
  • 小六01:点击事件得自己实现 必须打点是么
    Tamic: @小六01 是的
  • 023fad626d53:demo,app安装会报错,INSTALL_PARSE_FAILED_MANIFEST_MALFORMED
    d0c54da72115:demo,app我也安装不了,注释掉tamic依赖才能安装。
    1b63208e9821:@Tamic 切到2.0还是报INSTALL_PARSE_FAILED_MANIFEST_MALFORMED
    Tamic:@爬树的pig 切到2.0
  • fae1bae788fc:安装来源统计我推荐openinstall
  • b359f169db1b:作者你好,我现在正在做这个功能,想用你这个作为参考,你有什么建议和完善的地方吗。注意事项等
  • sing_song:分析的很好。
  • d7b07845e0c4:感谢楼主的分享,好人一生平安!
    PS:有个小小的建议,我发现代码中有很多不好的编写习惯,比如for循环中条件直接用list.size,for外面定义的变量多余初始化,model中有几个像AppActionList等有点多余的class,命名规则的不统一,命名单词错误等,可能是多人开发的原因造成的,不过对于一个SDK来说最好还是做到代码高效统一,刚开始看,有点强迫症,勿怪 :joy:
    72e6288a5f4c:怎么看源码?我看github上是demo呢
    Tamic:@andy_wangys 是的 两三个人开发的
  • zhandroid:很棒,正在做日志这块
    Tamic:@zhandroid 恩 好的方式可以建议下
  • EMG:这种模式个人感觉与业务耦合度有点高而且统计的颗粒度不够,个人觉得可以考虑面向切面编程的思想。:yum:
    Tamic:@EminemGolden 耦合度可以用代理就可以解决 不管是页面统计,还是某个事件统计 无语待定的去做打点 只需前期的架构做层代理层即可
    68e8078b0c5d:@EminemGolden 满满的专业术语 不明觉厉

本文标题:App打造自定义的统计SDK, 是时候和友盟说分手了

本文链接:https://www.haomeiwen.com/subject/paqhjttx.html