Android埋点技术分析
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埋点技术分析的更多相关文章
- Android埋点技术概览
注:本文同步发布于微信公众号:stringwu的互联网杂谈Android无埋点技术概览 本文是Android无埋点系列的开篇---埋点技术概览 1 背景 埋点是数据产品经理(分析师)基于业务需求,对用 ...
- Android“寄生兽”漏洞技术分析
一.关于app的缓存代码 安卓的应用程序apk文件是zip压缩格式的文件,apk文件中包含的classes.dex文件相当于app的可执行文件,当app运行后系统会对classes.dex进行优化,生 ...
- Android插件化技术——原理篇
<Android插件化技术——原理篇> 转载:https://mp.weixin.qq.com/s/Uwr6Rimc7Gpnq4wMFZSAag?utm_source=androi ...
- 基于日志服务的GrowthHacking(1):数据埋点和采集(APP、Web、邮件、短信、二维码埋点技术)
数据质量决定运营分析的质量 在上文中,我们介绍了GrowthHacking的整体架构,其中数据采集是整个数据分析的基础,只有有了数据,才能进行有价值的分析:只有高质量的数据,才能驱动高质量的运营分析. ...
- Android 热修复技术(1)---原理
热修复技术分为几部分: 原理介绍 Android HotFix源码分析 自定义框架 1.Android分包MultiDex原理 首先Dex是什么东西? Dex就是Window里面的exe文件 也就是可 ...
- 【转】Android 防破解技术简介
http://www.cnblogs.com/likeandroid/p/4888808.html Android 防破解技术简介 这几年随着互联网的不断发展,Android App 也越来越多!但是 ...
- 《Android系统源代码情景分析》连载回忆录:灵感之源
上个月,在花了一年半时间之后,写了55篇文章,分析完成了Chromium在Android上的实现,以及Android基于Chromium实现的WebView.学到了很多东西,不过也挺累的,平均不到两个 ...
- 全面了解Android热修复技术
WeTest 导读 本文探讨了Android热修复技术的发展脉络,现状及其未来. 热修复技术概述 热修复技术在近年来飞速发展,尤其是在InstantRun方案推出之后,各种热修复技术竞相涌现.国内大部 ...
- Android 中图片压缩分析(上)
作者: shawnzhao,QQ音乐技术团队一员 一.前言 在 Android 中进行图片压缩是非常常见的开发场景,主要的压缩方法有两种:其一是质量压缩,其二是下采样压缩. 前者是在不改变图片尺寸的情 ...
随机推荐
- POJ 1101
#include <iostream> #include <string> #define MAXN 78 #define min _min #define inf 12345 ...
- dubbo学习(1)--简单的入门搭建实例
转载请注明源文出处:http://www.cnblogs.com/lighten/p/6828026.html 1 简介 dubbo是一个分布式服务框架,由阿里巴巴的工程师开发,致力于提供高性能和透明 ...
- 暴力攻击 PHP 脚本 初探
考虑下面的HTML表单: CODE: <form action="http://example.org/login.php" method="POST"& ...
- css 边框颜色渐变的半圆
1.需求有这么个东西,个人不习惯背景图片来解决,开始了css尝试. <!DOCTYPE html> <html> <head> <meta charset=& ...
- 解决linux安装软件依赖的曲线救国方案
相信大家在一台无法连接外网的linux上安装软件时,对于软件依赖的安装,都会特别头疼,因为软件依赖的安装,不论是其数量,还是安装的复杂度都比软件本身要高出一个维度! 今天就和大家分享一个,解决linu ...
- golang channel的使用
channel常常结合go程使用,作为通信消息队列 var testChan chan int fmt.Println(testChan) // nil 未初始化,没地址 testChan ) fmt ...
- google glog 使用方法
#include <glog/logging.h> int main(int argc,char* argv[]) { google::ParseCommandLineFlags(& ...
- window.location.replace
有3个页面 a,b,c 如果当前页面是c页面,并且c页面是这样跳转过来的:a->b->c 1:b->c 是通过window.location.replace("..xx/c ...
- form表单select的选项值选择
html: <form action=""> <p>选择城市</p> <p> <select name="" ...
- java linux ssh jar
Ganymed SSH-2 for Java http://www.ganymed.ethz.ch/ssh2/ Ganymed SSH-2 for Java is a library which im ...