Android 全埋点解决方案(1)

简介: Android 全埋点解决方案

本文参考《Android全埋点解决方案》一书,并在实操中查漏补缺。

前言

为什么选择全埋点呢,因为传统的手动埋点虽然简单、扩展性强,但弊端也很明显:

  • 开发时间成本较高
  • 改动的时间成本也较高
  • 容易出现漏埋、埋错的情况
  • 代码侵入性强

但也不是说全埋点就一定没有弊端,比如扩展性较差。

经过调研,实际上都是以全埋点为主手动埋点为辅的情况,从而达到比较理想的埋点效果。

本文内容可能稍微有点长,但是很简单,别太长不看啊,最后有demo源码

页面

一般来说我们需要的数据就是,用户在哪个页面干了什么,也就是页面和事件,现在来说页面。

原理

通过生命周期可以计算出时长数据,以及页面对象。

Activity

页面有两个核心的需求数据:

  • 浏览时长
  • 页面唯一标示

这两个数据都挺好拿的,Application有一个registerActivityLifecycleCallbacks接口可以监测到activity的生命周期

有了生命周期,我们在onActivityResumed里面记录一下开始时间,然后在onActivityPaused中获取当前时间,就是整个页面的浏览时间

在生命周期方法中是有activity对象的,这样也可以拿到全路径作为唯一标示;

示例:

public static void registerActivityLifecycleCallbacks(Application application) {
        application.registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() {
            @Override
            public void onActivityCreated(Activity activity, Bundle bundle) {
            }
            @Override
            public void onActivityStarted(Activity activity) {
            }
            @Override
            public void onActivityResumed(Activity activity) {
                mBeginTime = System.currentTimeMillis();
            }
            @Override
            public void onActivityPaused(Activity activity) {
                trackAppViewScreen(activity);
            }
            @Override
            public void onActivityStopped(Activity activity) {
            }
            @Override
            public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
            }
            @Override
            public void onActivityDestroyed(Activity activity) {
            }
        });
    }

onActivityPaused的时候我们调用了一下trackAppViewScreen方法,并传入当前activity,来看看trackAppViewScreen方法。

private static void trackAppViewScreen(Activity activity) {
        try {
            if (activity == null) {
                return;
            }
            if (mIgnoredActivities.contains(activity.getClass().getCanonicalName())) {
                return;
            }
            JSONObject properties = new JSONObject();
            //获取页面的参数
            if (activity.toString().contains("SecondActivity")) {
                String userId = activity.getIntent().getStringExtra("userId");
                properties.put("userId", userId);
            }
            properties.put("activity", activity.getClass().getCanonicalName());
            SensorsDataAPI.getInstance().track("$AppViewScreen", properties, mBeginTime);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

我们在trackAppViewScreen方法中创建了JSONObject对象properties,用来添加我们需要埋点的数据,比如页面的唯一标示key我们用activity表示,并取全路径作为value。


这里有一点需要注意的,我们除了可以收集一些固定参数之外,activity中intent的参数也是可以获取的,比如其他页面跳转到这个页面传的参数,我们同样可以获取到并作为埋点的参数使用的。


就像上面的SecondActivity,当MainActivity跳转到SecondActivity时传的userId是可以通过getIntent获取到的。


最后调用了SensorsDataAPI类的track方法,继续看

    public void track(@NonNull String eventName, @Nullable JSONObject properties, long beginTime) {
        try {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("event", eventName);
//            jsonObject.put("device_id", mDeviceId);
            JSONObject sendProperties = new JSONObject(mDeviceInfo);
            if (properties != null) {
                SensorsDataPrivate.mergeJSONObject(properties, sendProperties);
            }
            jsonObject.put("extras", sendProperties);
            jsonObject.put("beginTime", beginTime);
            jsonObject.put("endTime", System.currentTimeMillis());
            jsonObject.put("pageId", SensorsDataPrivate.getCurrentActivity().getClass().getCanonicalName());
            jsonObject.put("sessionId", UUID.randomUUID().toString().replace("-", ""));
            Log.i(TAG, SensorsDataPrivate.formatJson(jsonObject.toString()));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

这里也很简单,先后创建了两个JSONObject,一个是最外层的jsonObject ,一个是作为参数使用的sendProperties,然后又把传过来的参数合并到sendProperties中,然后sendProperties作为extras的value使用。


endTime结束时间就取当前时间。


sessionId表示是这个埋点的唯一标示,看自己需求,非必须。


最后调用了Log打印出来,来看一下最后完整的数据:


{
  "event": "$AppViewScreen",
  "extras": {
    "app_name": "TrackDemo",
    "screen_width": 1440,
    "screen_height": 2621,
    "app_version": "1.0",
    "os_version": "10",
    "model": "Android SDK built for x86",
    "manufacturer": "Google",
    "activity": "com.yechaoa.trackdemo.ui.MainActivity"
  },
  "beginTime": 1603279291751,
  "endTime": 1603279293759,
  "pageId": "com.yechaoa.trackdemo.ui.MainActivity",
  "sessionId": "5dbb96807e634b6498f897784972ade3"
}


可以看到除了我们必要的参数之外,还有一些附加参数,比如手机型号、系统版本等等。

目录
相关文章
|
6月前
|
XML Android开发 数据格式
android点击FrameLayout、LinearLayout等父布局没响应的原因以及解决方案
android点击FrameLayout、LinearLayout等父布局没响应的原因以及解决方案
172 2
|
6月前
|
安全 Shell Android开发
Android系统 init.rc sys/class系统节点写不进解决方案和原理分析
Android系统 init.rc sys/class系统节点写不进解决方案和原理分析
347 0
|
6天前
|
安全 搜索推荐 程序员
深入探索Android系统的碎片化问题及其解决方案
在移动操作系统的世界中,Android以其开放性和灵活性赢得了广泛的市场份额。然而,这种开放性也带来了一个众所周知的问题——系统碎片化。本文旨在探讨Android系统碎片化的现状、成因以及可能的解决方案,为开发者和用户提供一种全新的视角来理解这一现象。通过分析不同版本的Android系统分布、硬件多样性以及更新机制的影响,我们提出了一系列针对性的策略,旨在减少碎片化带来的影响,提升用户体验。
|
1月前
|
开发框架 移动开发 Android开发
安卓与iOS开发中的跨平台解决方案:Flutter入门
【9月更文挑战第30天】在移动应用开发的广阔舞台上,安卓和iOS两大操作系统各自占据半壁江山。开发者们常常面临着选择:是专注于单一平台深耕细作,还是寻找一种能够横跨两大系统的开发方案?Flutter,作为一种新兴的跨平台UI工具包,正以其现代、响应式的特点赢得开发者的青睐。本文将带你一探究竟,从Flutter的基础概念到实战应用,深入浅出地介绍这一技术的魅力所在。
72 7
|
2月前
|
开发框架 前端开发 Android开发
安卓与iOS开发中的跨平台解决方案
【9月更文挑战第27天】在移动应用开发的广阔天地中,安卓和iOS两大操作系统如同双子星座般耀眼。开发者们在这两大平台上追逐着创新的梦想,却也面临着选择的难题。如何在保持高效的同时,实现跨平台的开发?本文将带你探索跨平台开发的魅力所在,揭示其背后的技术原理,并通过实际案例展示其应用场景。无论你是安卓的忠实拥趸,还是iOS的狂热粉丝,这篇文章都将为你打开一扇通往跨平台开发新世界的大门。
|
28天前
|
Android开发
Android开发显示头部Bar的需求解决方案--Android应用实战
Android开发显示头部Bar的需求解决方案--Android应用实战
19 0
|
3月前
|
前端开发 开发工具 Android开发
探索安卓与iOS应用开发:跨平台解决方案的崛起
【8月更文挑战第27天】在移动设备日益普及的今天,安卓和iOS系统占据了市场的主导地位。开发者们面临着一个重要问题:是选择专注于单一平台,还是寻找一种能够同时覆盖两大系统的解决方案?本文将探讨跨平台开发工具的优势,分析它们如何改变了移动应用的开发格局,并分享一些实用的开发技巧。无论你是新手还是资深开发者,这篇文章都将为你提供有价值的见解和建议。
|
3月前
|
Android开发
Android编译出现Warning: Mapping new ns to old ns的解决方案
Android编译出现Warning: Mapping new ns to old ns的解决方案
303 3
|
3月前
|
前端开发 JavaScript Android开发
探索Android和iOS开发中的跨平台解决方案
【8月更文挑战第1天】随着移动应用市场的不断扩张,开发者面临一个共同的挑战——如何高效地为多个平台创建和维护应用程序。本文将深入探讨跨平台开发工具,特别是Flutter和React Native,通过比较它们的优势和限制,并辅以实际代码示例,揭示这些工具如何帮助开发者在保持高性能的同时,实现代码的最大化重用。
|
3月前
|
前端开发 JavaScript Android开发
安卓与iOS开发中的跨平台解决方案
【8月更文挑战第24天】在移动应用开发领域,安卓和iOS两大平台占据了主导地位。然而,为这两个平台分别开发和维护应用会带来额外的时间和成本。本文将探讨跨平台开发的概念、优势以及流行的跨平台框架,如React Native和Flutter,并分析它们如何解决多平台开发的挑战。