Android可视化埋点集成文档

版本支持

可视化埋点SDK仅支持 android 4.0 及之上(api level >= 14)系统版本。在Android 4.0以下设备上,可视化埋点功能无效。

SDK依赖

可视化埋点SDK必须与私有化统计SDK、私有化SPM插件SDK配合使用。

请先参考私有化统计SDK 和私有化SPM插件将对应SDK集成到您的应用中。

控件支持列表

当前版本可视化埋点SDK仅支持如下列表中控件。未在列表中列出的控件,尚未完成兼容性测试,目前尚无法保证其有效性和准确性,对列表以外控件类型进行埋点不保证相关数据能成功上报。

控件

支持条件

备注

android.widget.TextView

控件clickable属性为true时,才支持埋点以及日志上报

android.widget.Button

android.widget.ImageButton

android.widget.CheckBox

android.widget.RadioButton

android.widget.ToggleButton

android.widget.Switch

android.view.View

支持埋点。但仅在控件clickable属性为true时,才支持日志上报

android.widget.ImageView

控件clickable属性为true时,才支持埋点以及日志上报

android.widget.ListView

支持ListView控件Item埋点,包括Item为Layout子布局的场景,当Item包含子布局时,支持对子布局中单个控件的埋点。

android.support.v7.widget.RecyclerView

支持RecyclerView控件Item埋点,包括Item为Layout子布局的场景,当Item包含子布局时,支持对子布局中单个控件的埋点。

SDK集成

SDK下载

SDK下载地址:Android SDK

SDK集成

将下载后的release.zip解压,将解压得到的两个aar包,拷贝到宿主App目录下libs目录中(如果您的工程没有此目录则需要自己创建)。

Android Studio工程配置

宿主应用对应Module编译脚本 build.gradle 的 android 配置段中,需要添加如下配置:

repositories {
        flatDir {
            dirs 'libs'
        }
    }

宿主应用对应Module编译脚本 build.gradle 的 dependencies 配置段中,需要添加对应依赖:

可视化SDK必须搭配私有化统计SDK和SPM插件才可使用,如您在可视化SDK包中未找到统计SDK和SPM插件,请务必查看AndroidSDK 引入&配置文档,完成相关包的引入。

         // 导入私有化统计SDK和SPM插件
    implementation files('libs/umeng-common-1.2.0.P.jar')
    implementation files('libs/umeng-spm-1.2.0.jar')

    // 导入可视化埋点SDK
    // tracker-config包仅在埋点配置模式导入,线上模式请切勿导入此包!
    implementation files('libs/tracker-config-1.1.2.P.aar')
    implementation files('libs/tracker-release-1.1.2.P.aar')
  • tracker-release是使用可视化埋点功能必须导入的包,必须引入。

  • tracker-config包仅在埋点配置模式依赖,线上正式发版App请切勿导入此包!

权限配置

需要在宿主App清单文件AndroidManifest.xml中增加以下权限声明:

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>

混淆配置

如果您的应用使用了代码混淆,请添加如下配置,以避免可视化埋点SDK被二次混淆导致SDK不可用。

# SDK混淆配置(重要:启用代码混淆必须设置)

-keep class com.umeng.** {*;}

-keepclassmembers class * {
   public <init> (org.json.JSONObject);
}
-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

SDK初始化

可视化埋点SDK无需额外初始化(统计SDK初始化函数UMConfigure.init内部会检查宿主App是否已经导入可视化埋点SDK,如果宿主App已经集成,会自动反射调用可视化埋点SDK初始化函数),按照私有化统计SDK初始化要求进行初始化即可。

统计SDK预初始化函数必须在宿主App的Application.onCreate函数主线程中执行:

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();

                // 设置收数域名,注意:需要设置贵司自己的收数域名
                UMConfigure.setCustomDomain("https://log-api.aplus.emas-poc.com", null);
        
        UMConfigure.setLogEnabled(true);
        // 预初始化, appkey和channel参数请修改为贵司App对应值
        final String useAppkey = "91547686";
        final String useChannel = "test_channel";

        // preInit预初始化函数必须在Application.onCreate函数主线程中执行。
        UMConfigure.preInit(this, useAppkey, useChannel);
        
        /**
         * 统计SDK初始化,注意:init初始化函数需要在客户同意隐私授权协议之后调用
         */
        final Context appContext = this.getApplicationContext();
        final ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1);
        executor.schedule(new Runnable() {
            @Override
            public void run() {
                Log.i(TAG, "--->>> 延迟5秒调用初始化接口:UMConfigure.init() ");
                UMConfigure.init(appContext, useAppkey, useChannel, UMConfigure.DEVICE_TYPE_PHONE, null);
            }
        }, 5, TimeUnit.SECONDS);
    }
}

控件唯一性ID设置

对于APP中的每个所需上报日志的控件而言,都需要有一个可以唯一性识别该控件的ID,便于在遍历组件树时能够精准定位该控件。设置控件唯一性ID设置方法调用:

ViewTools.setViewId(View view, String id)
  • 【重要】对于ListView,RecycleView等这类具有“瀑布流”特征的控件,为了减少业务方在可视化界面上的埋点配置,对于控件中的各个组件设置统一ID,通过其位置信息或者子控件名称进行区分,强烈推荐调用如下接口:

SDK提供以下两个接口进行子ID设置

A. 通过position区分控件

ViewTools.setViewId(View view, String id, int position)

如:RecycleView中的每个item项设置唯一ID。

B. 通过自定义子控件名区分控件

ViewTools.setViewId(View view, String id, String subViewId)

调试日志

可视化埋点SDK模块完成初始化后,会打印相关日志,日志tag为"VTTracker"。日志内容包含当前SDK工作模式。

  • Config Mode说明当前SDK工作在可视化埋点配置模式。此模式可以配合前端页面埋点。

com.umeng.abtest I/VTTracker: Config Mode: SDK Init complete.
  • Release Mode说明当前SDK工作在可视化埋点线上模式。此模式下SDK拉取可视化埋点配置,可以在对应事件被触发时发送统计日志。

com.umeng.abtest I/VTTracker: Release Mode: SDK Init complete.

SDK集成Demo

Demo工程源码:Android可视化埋点Demo

常见问题

1.在Activity或者Fragment页面中如何埋点才能让当前页面支持可视化埋点功能?

只有在预先完成了手动PV埋点和SPM编码埋点的Activity或者Fragment页面中,才能支持本页面的可视化埋点功能。

手动PV埋点和SPM编码埋点示例代码:

@Override
    protected void onResume() {

        super.onResume();
        MobclickAgent.onPageStart("MainPage"); // 页面手动PV埋点
        SpmAgent.updateCurSpm(this, "MainPage"); // SPM编码设置

    }

@Override
    protected void onPause() {
    
        super.onPause();
        MobclickAgent.onPageEnd("MainPage"); // 页面手动PV埋点
        
    }

没有完成页面手动PV埋点的页面(调用MobclickAgent.onPageStart/onPageEnd完成手动PV埋点),如果试图做可视化埋点,前端埋点页面会提示页面不匹配。

2.如何在正式发版前更好地去除配置版SDK?

应用在build.gradle文件中经常会进行应用环境隔离配置,因此,建议在debug配置中引入tracker-configb包依赖,而在正式release配置中不引入该依赖即可。

3.是否支持ListView,RecycleView, Fragment等相对复杂的自定义控件?

支持。需要注意的是,对于这些控件在设置唯一性ID时,需要对子项中的某个具体控件进行ID设置,而不是简单的对整个控件设置ID,如ViewToos.setViewId(listView, "listViewId")。

正确示例

ListView示例:

在自定义的ArrayAdapter的getView方法中设置ID,如:

@Override
    public View getView(int position, View convertView, ViewGroup parent) {
        //子view复用机制逻辑
        View view = convertView;
        if(view == null) {
            LayoutInflater inflater = LayoutInflater.from(mContext);
            View newView = inflater.inflate(R.layout.arrayadapter_item, parent, false);
            view = newView.findViewById(R.id.arrayadapter_text);
        }
        //更新子view内容
        ((TextView)view).setText(data[position]);
        //设置唯一id,可设置有业务含义的id name,本示例直接使用文本内容
        ViewTools.setViewId(view, "统一id值", position);

        return view;
    }

RecycleView示例:

自定义RecycleView.Adapter的ViewHolder,在onBindViewHolder方法中进行唯一性ID设置,如:

@Override
public void onBindViewHolder(final InfoViewHolder holder, int position) {
    if (getItemViewType(position)==TYPE_HEADER) {
        return;
    }
    final int pos=getRealPosition(holder);
    //mData缓存网络数据
    String title = mData.get(pos).getTitle();
    //更新标题,holder.title为TextView
    holder.title.setText(title);
    //对hodler.title设置id
    ViewTools.setViewId(holder.title, "统一id值", position);
    
}

自定义VideoPlayer:

找到需要设置监听的控件,如播放按钮,或播放窗口,设置ID

//jzvdStd为自定义的视频播放控件
//对开始按钮设置id,id为url
ViewTools.setViewId(jzvdStd.startButton,"play_"+mData.get(pos).getVideoUrl());
//对播放窗口设置id
ViewTools.setViewId(jzvdStd.thumbImageView,"window_"+mData.get(pos).getVideoUrl());

4.如何记录页面PV?

可视化埋点SDK目前支持控件的点击 & 曝光事件采集,暂未开放PV采集功能,主要原因在于业务APP的页面跳转逻辑相对复杂,容易引发页面pv记录出错问题。因此,对于页面pv,建议业务方沿用已有的代码pv埋点。

5.曝光默认规则是?

默认曝光条件为:

  • 曝光面积超过/等于控件面积的50%

  • 曝光时长超过/等于500ms

  • 曝光日志合并发送

  • 在一个页面中,如果已经发生曝光,则不再重复曝光,直到发生以下操作:

  • 页面切换

  • 关闭App,重新进入App

  • 退至后台,重新进入App

[重点注意] 如何定义一个页面?

在Android开发中,习惯性会以Activity定义一个页面,可视化埋点SDK默认同样采用Activity定义一个页面。但实际情况中一个Activity中往往会有子页面存在,如TabHost,Fragment等的使用,SDK默认只会发送一次曝光记录。因此,如果业务方要求在一个Activity下的子页中来回切换,曝光需要重新上报,可在子页退出时,调用曝光数据刷新接口进行重复曝光。

6.是否可以修改曝光规则中的曝光时长和曝光面积基线?

暂未提供该服务

7.如何验证埋点是否正常,日志上报是否正确?

在埋点配置阶段,集成配置版SDK后,可在可视化页面中点击“查看埋点验证日志”,即可实时查看埋点及日志上报情况。

8.可视化配置没问题,但在发布APP中发现无法上报点击日志?(或瀑布流中list的item项无法上报日志或list套list,里层list的item项无法上报日志)

主要原因在于唯一性ID设置的对象异常。检查控件点击事件监听逻辑,确认绑定了ID的控件是否直接响应点击,如果不是,需要将唯一性ID绑定在响应点击事件的对象上。

例如,常见的listview中的item的布局为

<relativeLayout clickable="true">
<textview>
</textview>
</relativeLayout>

此时,layout对象处理了针对该item的点击行为,并且该点击事件并不会下传到 textview 对象上,因此,如果将ID绑在textview上,则无法捕获点击行为,应相应的将ID绑定到 textview 对应的 layout 对象上。

再例如:TextView控件需要设置android:clickable="true"属性,否则默认情况下TextView可以支持可视化埋点,但是因为无法响应系统点击事件,导致发布版本App中无法正常上报点击日志。