Android 自定义优质精准的用户行为和日志打捞方案

Tamic csdn博客 :http://blog.csdn.net/sk719887916/article/details/51398416

说到app优化方案,大家很可能第一想到关于GPU和CPU渲染问题,而这两大方案确实是优化app的两把尖刀,让一个app提升用户量和体验度有较高的推动力。然后在我们无法预估的就是用户的实用操作欲望下,也就是已经发出去的版本,我们很难知道用户喜欢什么功能,和想要怎样的功能,包括用户卸载了,安装不用的情况,并且对潜在线上崩溃的问题也想知道问题出在哪里,等等这些对于app的成长也有关键的导向作用,其实这也可以算是一种对app的优化方案。

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

一 统计分类

1. 1 PC端统计

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

2. 2、IP、PV和UV分别是什么意思?

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

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

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

3 . 3 IP、PV和UV之间的关系是什么?

1.3.1.IP和PV之间的关系

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

1.3.2 .IP和UV之间的关系:

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

1.3.3.IP和PV之间的关系:

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

1.4 我们能从这边得到什么

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

2 移动设备统计

那么我们的一个App,我们能做的那些方面呢

2.1 .1 用户数据(日活)

首先我们的可以加入ip,PV和UV统计模式,这样我们可以成功的get到app的日活,以及整体使用情况,

比如App启动了多少次,访问了多少h5页面,有多少个ip(设备)访问过,但是我们无法得native页面的信息(也就是Activity)服务端是是无法获取的,除非我们本地的页面有加载服务端数据的接口的功能,这种情况下服务是可以监控到本页面的数据流量的,但是在断网情况下,服务端是无法及时获取日活数据的,那么怎么解决呢,这里先不说,先看下个要解决的问题。

2.1.2 用户行为

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

2.1.3 Log日志

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

三 综合方式。

一般统计策略不会采用单一的方式进行上报,多采用组合的形式实现,服务器和客户端,有网和没网,实时和不定时。主动和被动的策略。

1 服务端

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

服户端也可以采用推送的形式,让客户端去发送特定的采集好信息上报给服务器。

2 客户端

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

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

对于我们的app crash 我们可以继承android自带的全局异常类(UncaughtExceptionHandler),来进行自我捕获异常,和用户行为一起上报,具体见 《Android全局异常处理(可以做强制退出和carsh日志抓取)》一文,

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

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

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

对于好的统计,我们可以检测网络,检测home建来触发我们的上报数据接口,也可以采用注册静态广播,用alarm 闹钟定时上报数据(客户端轮询见 《Android 最优轮循(心跳策略)探究实践》),然后这些技术也就是被大家玩透的功能而已,没必要再这里给大家补脑,但是注意的是

  1. 统计设备唯一标识符的确定, 这个以后再去分析.
  2. 统计上报接口采用分布式,不然所有数据都请求同一个接口,那么日活大的情况下,服务器挂了 不仅无法收到数据,反而影响客户端其他正常的功能

Android 优质精准的用户行为统计和日志打捞方案的更多相关文章

  1. 【Android】ADB常用指令与logcat日志(转)

    ADB命令简介 ADB是一个功能强大的命令行工具.通过它可以直接和模拟器或真机进行交互.它是一个具有客户端和服务器端的程序. 它主要由三个部分组成: 客户端,它运行在你的开发机上,你可以通过执行adb ...

  2. 【Android】ADB常用指令与logcat日志

    ADB命令简介 ADB是一个功能强大的命令行工具.通过它可以直接和模拟器或真机进行交互.它是一个具有客户端和服务器端的程序. 它主要由三个部分组成: 客户端,它运行在你的开发机上,你可以通过执行adb ...

  3. 网易七鱼 Android 高性能日志写入方案

    本文来自网易云社区 作者:网易七鱼 Android 开发团队 前言 网易七鱼作为一款企业级智能客服系统,对于系统稳定性要求很高,不过难保用户在使用中不会出现问题,而 Android SDK 安装在用户 ...

  4. Android APP压力测试(三)之Monkey日志自动分析脚本

    Android APP压力测试(三) 之Monkey日志自动分析脚本 前言 上次说要分享Monkey日志的分析脚本,这次贴出来分享一下,废话不多说,请看正文. [目录] 1.Monkey日志分析脚本 ...

  5. Android Permissions管理之用户拒绝授权

    Android Permissions管理之用户拒绝授权,在Marshmallow之前的安卓版本,应用的权限只需要注册一下,应用就会获取到,在Marshmallow之后,为了安全,全新的权限模型出现, ...

  6. Android开发周报:Android L默认加密用户数据

    Android开发周报:Android L默认加密用户数据 新闻 <iCloud前车之鉴,Android L默认开启加密功能>:iCloud 艳照风波再起,第二波女星照片流出,大量女星的裸 ...

  7. Android开发华为手机无法看log日志解决方法

    Android开发华为手机无法看log日志解决方法 上班的时候,由于开发工具由Eclipse改成Android Studio后,原本的华为手机突然无法查看崩溃日志了,大家都知道,若是无法查看日志要它毛 ...

  8. iOS获取用户设备崩溃日志并分析

    项目最近发布,部分用户在内侧使用,正好遇到一些问题,由于用户在其他城市,所以对于用户设备产生的崩溃日志,不好直接拿设备连接电脑. 对于这种情况,我们可以这样: 1.引导用户开启iOS设备设置-> ...

  9. Android超精准计步器开发-Dylan计步

    转载请注明出处:http://blog.csdn.net/linglongxin24/article/details/52868803 本文出自[DylanAndroid的博客] Android超精准 ...

随机推荐

  1. Calendar 时间日历简单例子

    直接上代码: 运行结果:

  2. UDA机器学习基础—评估指标

    这里举例说明 混淆矩阵  精确率 召回率  F1

  3. 《Java技术》的第二次作业

    (一)学习总结 1.什么是构造方法?什么是构造方法的重载?下面的程序是否可以通过编译?为什么? (1) 构造方法用于在创建对象时对其进行初始化,且方法名与类名相同,方法名前面没有返回值类型的声明,不能 ...

  4. IOS UITextView支持输入、复制、粘贴、剪切自定义表情

    UITextView是ios的富文本编辑控件,除了文字还可以插入图片等.今天主要介绍一下UITextView对自定义表情的处理. 1.首先识别出文本中的表情文本,然后在对应的位置插入NSTextAtt ...

  5. Java Web -【分页功能】详解

    分页简介 分页功能在网页中是非常常见的一个功能,其作用也就是将数据分割成多个页面来进行显示. 使用场景: 当取到的数据量达到一定的时候,就需要使用分页来进行数据分割. 当我们不使用分页功能的时候,会面 ...

  6. 反射获取 Class

    原文链接:https://www.codemore.top/cates/Backend/post/2018-04-26/reflect-class 类 Java中每个类型要么是引用类型,要么是原生类型 ...

  7. ubuntu + 不识别无线网卡简易处理方式 + 需有线联网

    进入ubuntu, 连接有线网; 系统设置 -> 软件和更新 -> 附加驱动 -> 找到无线网卡驱动并更新 若无候选的无线网卡驱动,我就没招了.

  8. if-case-循环语句

    IF语句 drop procedure if exists p_hello_world; create procedure p_hello_world(in v_id int) begin ) the ...

  9. webpack4新建一个项目

    Create a new directory mkdir webpack-4-quickstart Initialize a package.json by running: npm init -y ...

  10. JavaScript Date(日期)对象

    返回当日的日期和时间 如何使用 Date() 方法获得当日的日期. getFullYear() 使用 getFullYear() 获取年份. getTime() getTime() 返回从 1970 ...