1.现有的几种埋点技术的实现原理和优劣分析


(1)代码埋点:将收集数据的代码直接写在需要的地方,当用户点击某个控件或者打开某个页面时调用到该部分代码完成数据的收集。 
优势:准确性高,收集数据和发送数据都能精确控制,同时能方便的设置自定义属性,自定义控件,自定义View等。 
劣势:埋点工作量大,更新代价大。 
(2)可视化埋点:根据配置文件收集用户行为,从而获取数据进行分析。 
优势:无须手动埋点,配置文件可动态更新。 
劣势:配置文件的配置比较耗时,弹出框,隐藏控件等行为不能收集。收集的数据比较简单,只能收集用户行为,不能收集到与行为相关的具体数据。 
(3)无埋点:与可视化埋点基本一致。不同点在于可视化埋点是根据配置文件收集数据,无埋点是预先收集所有的用户行为,然后根据配置文件来提取数据。无埋点可以通过修改配置文件追溯之前的用户行为数据。 
(4)后端埋点:Sensors Analytics 这个平台有解决方案,优点是能收集到详细的与行为相关的数据,适用于电商等大平台。比如用户选择了一件商品,点击了加入购物车,那么可以收集到用户信息,商品信息,商品价格,商品库存,卖家等诸多信息。

埋点技术的选择

(1)代码埋点:既可以自己与后台定义接口,也可以使用第三方,常用的有友盟,百度统计等。 
(2)可视化埋点和无埋点:移动端可以自己实现数据采集(下面有Android端的实现原理和demo)。第三方有诸葛IO,GrowingIO 。在知乎上查了关于这两个平台的信息,GrowingIO隐藏收费,官网并没有说到收费,但是使用15天后发邮件通知收费并停止数据采集和分析。诸葛IO免费模式的数据量是每月200万条,还有其他收费模式。 
(3)后端埋点:Sensors Analytics

总结:根据当前公司产品特点和对埋点的要求,建议用可视化埋点;虽然诸葛IO的免费数据量对目前公司App使用规模来说够用,但是一方面以后数据量会越来越大,另一方面用户数据会被第三方掌握;同时在实现上面没有技术难点,所以,建议自己实现。

附录:Android实现可视化埋点技术

原理解析: 
(1)页面跳转:Activity的生命周期,创建BaseActivity基类,实现对Activity生命周期的监听。 
(2)控件的点击:根据UI布局的特性和Android点击事件传递机制实现。让创建的BaseActivity基类重写Activity的dispatchTouchEvent方法,当touch button时,可以获取到按下(DOWN)和抬起(UP)时产生的MotionEvent对象。这个MotionEvent对象有两个方 法,getRawX()和getRawY(),通过这两个方法我们可以获取到“点击位置”在界面中的坐标。然后搜索所有的子View或者控件的布局区域是否包含“点击位置”,从而来判断哪个View或控件被点击。 
难点:如何标识点击的控件,这里我们用该控件实例化所在的类名和该控件的UI路径来做唯一标识。

下面实现一个具体Demo:

(1)先写一个简单的登陆界面:有两个EditText分别输入用户名和密码,一个登陆Button,一个去注册的TextView。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/top"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context="com.wangliang160818.traking.MainActivity"> <EditText
android:id="@+id/activity_main_user"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="输入用户名 "/>
<EditText
android:id="@+id/activity_main_pwd"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="输入密码 "/>
<TextView
android:id="@+id/login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="登陆"
android:layout_marginTop="12dp"
android:background="@color/colorPrimary"
android:padding="10dp"
android:textColor="@android:color/white"
android:textSize="22sp"/>
<TextView
android:id="@+id/register"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="去注册"
android:layout_marginTop="12dp"
android:background="@color/colorAccent"
android:padding="10dp"
android:textColor="@android:color/white"
android:textSize="16sp"/>
</LinearLayout>

(2)然后模拟埋点数据,实际中就是我们放在服务器的埋点文件,通过动态修改这个文件实现动态埋点的效果。

@Override
public void onWindowFocusChanged (boolean hasFocus){
super.onWindowFocusChanged(hasFocus); if(allView != null)
allView.clear();
allView = getView((ViewGroup) rootView);
for(int i=;i<allView.size();i++) {
Log.v("out", allView.get(i).toString());
viewPath.add(mClassName+"."+allView.get(i).toString().split("\\{")[]);
}
Log.v("out" , allView.size()+"");
Rect outRect = new Rect();
this.getWindow().getDecorView().getWindowVisibleDisplayFrame(outRect);
statusBarHeight = outRect.top; }

遍历布局文件

 /*获取所有View和没有子View的ViewGroup*/
public ArrayList<View> getView(ViewGroup viewGroup){
if(views == null)
views = new ArrayList<View>();
if(viewGroup == null) return null;
//views.add(viewGroup);
int count = viewGroup.getChildCount();
for(int i=;i<count;i++){
if(!(viewGroup.getChildAt(i) instanceof ViewGroup)){
views.add(viewGroup.getChildAt(i));
}else this.getView(viewGroup);
}
return views;
}

点击时的处理

/*重写dispatchTouchEvent*/
public boolean dispatchTouchEvent(MotionEvent ev) {
if(ev.getAction() == MotionEvent.ACTION_UP){
/*获取当前点击位置,遍历布局,获取当前点击位置对应的view,根据view映射路径,与json文件中的对比*/
double x = ev.getRawX();
double y = ev.getRawY() - statusBarHeight;
if(allView2 != null)
allView2.clear();
allView2 = getView((ViewGroup) rootView);
for(int i=;i<allView2.size();i++) {
/*获取点击位置的view*/
int left = allView2.get(i).getLeft();
int right = allView2.get(i).getRight();
int top = allView2.get(i).getTop();
int bottom = allView2.get(i).getBottom();
if(x > left && x < right &&
y > top && y < bottom){
/*判断这个view是否是我们要埋点的*/
String s = mClassName+"."+allView2.get(i).toString().split("\\{")[];
if(viewPath.contains(s)){
Log.v("out" , "这是我们的埋点:"+s);
}
}
}
}
return super.dispatchTouchEvent(ev);
}

总结:根据无埋点原理初步实现了,目前还有几个问题: 
(1)每个View都必须有唯一标识,当前采用的是用view的路径,但是这样当布局文件层级比较复杂的时候,获取路径还有问题。 
(2)其二,当布局有margin,标题栏等情况时需要额外考虑。 
将以上两个问题完善后可以在实际应用中使用,后续做这部分工作。

第三方友盟:http://dev.umeng.com/analytics/reports/usage#2

Android埋点技术分析的更多相关文章

  1. Android埋点技术概览

    注:本文同步发布于微信公众号:stringwu的互联网杂谈Android无埋点技术概览 本文是Android无埋点系列的开篇---埋点技术概览 1 背景 埋点是数据产品经理(分析师)基于业务需求,对用 ...

  2. Android“寄生兽”漏洞技术分析

    一.关于app的缓存代码 安卓的应用程序apk文件是zip压缩格式的文件,apk文件中包含的classes.dex文件相当于app的可执行文件,当app运行后系统会对classes.dex进行优化,生 ...

  3. Android插件化技术——原理篇

    <Android插件化技术——原理篇>     转载:https://mp.weixin.qq.com/s/Uwr6Rimc7Gpnq4wMFZSAag?utm_source=androi ...

  4. 基于日志服务的GrowthHacking(1):数据埋点和采集(APP、Web、邮件、短信、二维码埋点技术)

    数据质量决定运营分析的质量 在上文中,我们介绍了GrowthHacking的整体架构,其中数据采集是整个数据分析的基础,只有有了数据,才能进行有价值的分析:只有高质量的数据,才能驱动高质量的运营分析. ...

  5. Android 热修复技术(1)---原理

    热修复技术分为几部分: 原理介绍 Android HotFix源码分析 自定义框架 1.Android分包MultiDex原理 首先Dex是什么东西? Dex就是Window里面的exe文件 也就是可 ...

  6. 【转】Android 防破解技术简介

    http://www.cnblogs.com/likeandroid/p/4888808.html Android 防破解技术简介 这几年随着互联网的不断发展,Android App 也越来越多!但是 ...

  7. 《Android系统源代码情景分析》连载回忆录:灵感之源

    上个月,在花了一年半时间之后,写了55篇文章,分析完成了Chromium在Android上的实现,以及Android基于Chromium实现的WebView.学到了很多东西,不过也挺累的,平均不到两个 ...

  8. 全面了解Android热修复技术

    WeTest 导读 本文探讨了Android热修复技术的发展脉络,现状及其未来. 热修复技术概述 热修复技术在近年来飞速发展,尤其是在InstantRun方案推出之后,各种热修复技术竞相涌现.国内大部 ...

  9. Android 中图片压缩分析(上)

    作者: shawnzhao,QQ音乐技术团队一员 一.前言 在 Android 中进行图片压缩是非常常见的开发场景,主要的压缩方法有两种:其一是质量压缩,其二是下采样压缩. 前者是在不改变图片尺寸的情 ...

随机推荐

  1. POJ 2301

    #include<iostream> #include<stdio.h> using namespace std; int main() { //freopen("a ...

  2. php生成markdown格式的数据库字典

    <?php /** * 生成mysql数据字典 */ //数据库配置 $config = [ 'host' => '192.168.43.134', 'user' => 'root' ...

  3. PHP CURL 抓取失败 自己调试

    蛋疼的一下午,物理机win7旗舰版+APACHE2 ,CURL抓取一直成功. 虚拟机ubuntu+apache2一直抓取失败. 晚上,问个仁兄才知道,CURL可以调试: 参考这位兄台: 地址 curl ...

  4. 《Mysql技术内幕,Innodb存储引擎》——文件、表

    文件 日志 错误日志 对Mysql启动.运行和关闭过程进行记录,通过SHOW VARIABLES LIKE 'log_error'查看日志文件位置. 慢查询日志 Mysql启动时设置一个阈值,运行时间 ...

  5. lintcode-->翻转字符串

    给定一个字符串,逐个翻转字符串中的每个单词. 您在真实的面试中是否遇到过这个题? Yes 说明 单词的构成:无空格字母构成一个单词 输入字符串是否包括前导或者尾随空格?可以包括,但是反转后的字符不能包 ...

  6. Nginx 为 Golang 配置 web 服务

    server { charset utf-; client_max_body_size 128M; #listen ; ## 监听 ipv4 上的 端口 #listen [::]: default_s ...

  7. linux svn 自启动

    .svn服务自启动脚本 把脚本放在/etc/init.d/下 vi /etc/rc.d/init.d/svn svn脚本内容: #!/bin/bash # chkconfig: - # descrip ...

  8. java将list转为树形结构的方法

    目录 1.通过转化成json封装数据 2.通过java8 stream转换 1.通过转化成json封装数据 原始数据如下 [ { "name":"甘肃省", & ...

  9. ARM的体系结构与编程系列博客——ARM处理器系列介绍

    ARM处理器系列介绍 现在到了3月,过年过得过于舒服了.系列博客也停更了近半月,我果然是个慢(lan)性(gui)子,那么趁着到校的第一天晚上,就写一篇博客来继续我的系列博客了!众所周知,ARM处理器 ...

  10. Linux下svn服务器搭建

    初次在linux上搭建svn服务器,本来以为很繁琐,其实很简单,主要分为以下几个步骤: 1.  首先安装subversion,命令:yum install subversion 2.  创建svn仓库 ...