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. 前后端分离最佳实现,使用Nuxt.js快速搭建单页SSR应用

    通常我们搭建ssr应用需要自己选择多个组件集成到一起 webpack babel loaders router server-render 各种入口配置等 如果是基于vue+vuex+vue-rout ...

  2. Java之集合(八)HashMap

    转载请注明源出处:http://www.cnblogs.com/lighten/p/7338372.html 1.前言 本章介绍Java中最常用的一个集合类HashMap,此类在不同的JDK版本有不同 ...

  3. Eclipse删除switch workspace下多余的workspace

    第一步:修改org.eclipse.ui.ide.prefs 文件 打开Eclipse目录的\configuration\.settings目录,找到org.eclipse.ui.ide.prefs ...

  4. Http编程(二)使用Apache 的API实现

    要下载jar包 import java.io.FileOutputStream; import java.io.IOException; import org.apache.http.HttpEnti ...

  5. 代码查看php是否已开启rewrite功能模块

    通过php代码来查询,是否把rewrite模块打开了 <?php $result = apache_get_modules(); if(in_array('mod_rewrite', $resu ...

  6. C++调用C代码的两种方式

    由于C++支持函数重载,在编译函数代码的时候会加上参数类型的信息,而C编译只有函数名信息,导致C++直接调用C代码在链接的时候会出现函数未定义的问题.解决这种问题有两种方法.方法一:在写C代码的时候考 ...

  7. Java 和 JSP 实现网站访问量统计 (刷新过滤)

    java 和 JSP 实现的统计网站访问量,不需要数据库,将数据存储在 指定位置的 txt 文件中,代码块分为两部分 首先, java 部分: import java.io.File; import ...

  8. git移除文件夹的版本控制

    案例背景:git提交的时候把bin文件下的各种.dll提交上去了,然后每次提交都得提交好多文件,很容易忽略你真正修改的东西,故对这些不必要的东西忽略掉 解决方案:git rm 命令参数 具体实施: 1 ...

  9. c#基础学习(0628)之使用进程打开指定的文件、模拟磁盘打开文件

    使用进程打开指定的文件 模拟磁盘打开文件 class Program { static void Main(string[] args) { while(true) { Console.WriteLi ...

  10. Angular待办事项应用4——模拟web服务

    内存服务器 angular提供了一个快速建立测试用的web服务方法,内存服务器(in-memory),让我们不用等待后端开发的进度 安装npm包 npm install --save angular- ...