零蚀
全埋点的认识
-
全埋点的理解
全埋点是指工程师只需要使用少量代码,或者不使用代码就可以对用户的所有的行为数据进行搜集,并根据业务要求在行为数据中筛选出自己想要的数据。
- $AppStart事件: 指应用的启动事件,同时包括冷启动和热启动,热启动是指应用程序从后台回复的情况。
- $AppEnd事件: 指应用退出的情况,包括正常退出,按home键退出,应用被强杀,应用崩溃的等情况。
- $AppViewScreen事件: 指应用程序的页面浏览,对于 Android应用程序来说就是切换activity和fragment。
- AppClick事件: 应用的触控点击事件。通过自动找到点击事件的原处理逻辑,并在原处理逻辑的前后插入相应的埋点代码,进行事件的消息的“拦截”。
AppViewScreen全埋点方案
-
原理概述
$AppViewScreen 事件即是页面浏览事件,在Android事件中,是指activity或者fragment的切换事件。以activity为例,当一个activity执行到onResume方法时也就表示这个activity显示出来了。即在onResume埋点
Application.ActivityLifecycleCallbacks是application的一个内部借口。从Android4.0开始使用,此接口提供了一系列的回调方法,让用户对activity的声明周期时间进行全面的管理。一个application可以注册多个callback方法,其内部定义了一个list用来用来保存所有的activityLifecycleCallBacks.
如果我们的应用包含了三方库,且这个三方库的内部也包含activity的话,我们也是可以用Application.ActivityLifecyclerCallback.
-
监听实现(简化版)
创建Android lib(“sdk”)并且让module对其进行依赖。
Application中实例化的监听对象
public class SensorAPI { private static final Object key_lock=new Object(); private static SensorAPI INSTANCE; /** * 设置单例模式 * @param application */ private SensorAPI(Application application){ SensorPrivate.registerActivityLifeCallback(application); } public static SensorAPI init(Application application){ synchronized (key_lock){ if (null==INSTANCE){ INSTANCE=new SensorAPI(application); } } return INSTANCE; } // 获取对象 public static SensorAPI getInstance(){ return INSTANCE; } // 最终监控的AppViewScreen(所有的activity对象)并且打印出他们的信息 public void track(String $AppViewScreen, JSONObject propertise) { Log.e("zero",propertise.toString()); } }
监听的实现方法
public class SensorPrivate { // 记录所有的打开的activity类的列表 private static List<Integer> list=new ArrayList<>(); public static void trackAppViewScreen(Activity activity){ try { // 判断hashcode,然后进行防止重复记录(看需求) if (null!=activity&&!list.contains(activity.getClass().hashCode())){ JSONObject propertise=new JSONObject(); propertise.put("$activity",activity.getClass().getCanonicalName()); SensorAPI.getInstance().track("$AppViewScreen",propertise); } } catch (Exception e) { e.printStackTrace(); } } // 注册监听回调 public static void registerActivityLifeCallback(Application application){ application.registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() { @Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) { } @Override public void onActivityStarted(Activity activity) { } @Override public void onActivityResumed(Activity activity) { trackAppViewScreen(activity); } @Override public void onActivityPaused(Activity activity) { } @Override public void onActivityStopped(Activity activity) { } @Override public void onActivitySaveInstanceState(Activity activity, Bundle outState) { } @Override public void onActivityDestroyed(Activity activity) { } }); } }
module中的运用
//MyApplication SensorAPI.init(this); // MainActivity 添加跳转按钮 public void IntentClick(View view) { startActivity(new Intent(this,SecondActivity.class)); }
print logcat
E/zero: {"$activity":"com.example.trackapplication.MainActivity"} E/zero: {"$activity":"com.example.trackapplication.SecondActivity"}
-
监听和权限冲突
在我们申请权限的时候,我们在允许/禁止的时候系统会自行调用onRequestPermissionResult方法,然后再次调用当前Activity的onResume方法,会导致我们埋点的SDK重新走一次track方法,导致埋点的数据不准确。
为此,我们可以用一个容器例如list来记录这个埋点的过程从而使得,在申请权限的时候我们可以通过扫描忽略的activity来甄别是否要打印出相关信息
$AppStart(AppEnd)全埋点方案
-
简介
这两个事件主要是判断应用所处的状态,是前台还是后台。而Android自身并没有给出相对应的接口。
-
解决方案
原书在判断应用是否是APpEnd的情况下,运用的是记录当前的activity的onStart和上一个activity的onPause是否中间相隔>30s未启动,从而判断是否是当前的app出现了退出/卸载等情况。(但是记载时间戳的这种方法只存于不依赖任何外界情况的条件下,所以这种方案的局限性很大,并且用户卸载,或者崩溃,瘫痪等情况导致用户不在打开应用,也会导致$AppEnd事件丢失)
文章内容为《Android 全埋点解决方案》学习笔记
🔗 前言
🔗 Android 专题列表
🔗 Android 全埋点 专题列表
🔗 NO.2 Android OnClick全埋点-1
🔗 NO.3 Android OnClick全埋点-2