如您的产品中有账户体系,请在用户登录后立即设置 uuid,以保证用户登录前后口径一致性。 6.13.0+ 版本支持在初始化 AppLog 之前调用,用于设置已登录的用户 uuid。
// 设置您账号体系的 ID, 并保证其唯一性 // 6.13.0+ 版本支持此方法在初始化 AppLog 前调用 AppLog.setUserUniqueID("your_USER_UNIQUE_ID"); // 如果使用多实例,可以使用对应实例设置 IAppLogInstance other = Applog.newInstance(); other.setUserUniqueID("{{USER_UNIQUE_ID}}");
(6.13.0+ 版本不推荐使用)通过该方法设置 uuid,仅在首次冷启动时设置生效。由于 AppLog.setUserUniqueID 在 6.13.0+ 已支持在初始化之前调用,所以不再推荐使用该方法设置 uuid,建议统一使用 AppLog.setUserUniqueID。
// 初始化时设置uuid // 6.13.0+版本请勿使用此方法 config.setUserUniqueId("your_USER_UNIQUE_ID");
在账户登出时调用。
// 登出时设置uuid为null AppLog.setUserUniqueID(null); // 多实例同 7.1.1
请注意,不要误写成("null")
或 ("")
,否则会影响数据和用户的绑定关系。
设置用户属性,存在则覆盖,不存在则创建。
// 示例:设置用户属性,属性名为key,属性值为value JSONObject paramsObj = new JSONObject(); try { paramsObj.put("key", "value"); } catch (JSONException e) { e.printStackTrace(); } AppLog.profileSet(paramsObj);
设置用户属性,存在则不设置,不存在则创建,适合首次相关的用户属性,比如首次访问时间等。
// 示例:设置用户属性,属性名为key_once,属性值为value_once JSONObject paramsObj = new JSONObject(); try { paramsObj.put("key_once", "value_once"); } catch (JSONException e) { e.printStackTrace(); } AppLog.profileSetOnce(paramsObj);
设置数值类型的属性,可进行累加。
// 示例:设置用户属性,属性名为key,属性值为1 JSONObject paramsObj = new JSONObject(); try { paramsObj.put("key", 1); } catch (JSONException e) { e.printStackTrace(); } AppLog.profileIncrement(paramsObj);
设置List类型的用户属性,可持续向List内添加。
// 示例:设置用户属性,属性名为key,原本已有属性值,现添加属性值为value_append JSONObject paramsObj = new JSONObject(); try { paramsObj.put("key", "value_append"); } catch (JSONException e) { e.printStackTrace(); } AppLog.profileAppend(paramsObj);
删除用户的属性。
// 示例:删除用户属性,属性名为key AppLog.profileUnset("key");
通常在SDK 初始化后会向分流服务发送一个分流请求(request),在获取到分流服务的响应(response)后,客户端开发可以根据分流的结果参数完成代码分支。
AppLog.addDataObserver(new com.bytedance.applog.IDataObserver() { /** * 本地的id数据加载结果通知 * @param did device id * @param iid install id * @param ssid ssid */ @Override public void onIdLoaded(@NonNull String did, @NonNull String iid, @NonNull String ssid) { } /** * 通知注册结果,以及id变化情况 * 仅主进程会被调用 * @param changed 是否和本地缓存有所不同 * @param oldDid 原device id * @param newDid server返回新的device id * @param oldIid 原install id * @param newIid server返回新install id * @param oldSsid 原ssid * @param newSsid server返回新ssid */ @Override public void onRemoteIdGet(boolean changed, @Nullable String oldDid, @NonNull String newDid,@NonNull String oldIid, @NonNull String newIid, @NonNull String oldSsid, @NonNull String newSsid) { } /** * Config拉取数据,和本地数据对比有变化的通知 * 仅主进程会被调用 * @param changed 是否和本地缓存有所不同 * @param config server返回新config内容 */ @Override public void onRemoteConfigGet(boolean changed, @Nullable JSONObject jsonObject) { } /** * server拉取AbConfig数据,和本地数据对比有变化的通知 * 仅主进程会被调用 * @param changed 是否和本地缓存有所不同 * @param abConfig server返回新abConfig内容 */ @Override public void onRemoteAbConfigGet(boolean changed, @NonNull JSONObject jsonObject) { // 比如配置的ab实验参数名称是 "MyTest", 参数类型是 string,对照组参数值 "groupA", 实验组参数值 "groupB"// 通过applog接口获取实验分流结果// 第一个参数是实验名称,第二个参数是获取实验分流结果失败时的默认参数值,如默认为对照组参数值或null// 返回值是获取的ab实验分流结果,即实验参数值 String group = AppLog.getAbConfig("MyTest", null); if ("groupA".equals(group)) { // 执行对照组逻辑 } else if ("groupB".equals(group)) { // 执行实验组逻辑 } else { // 其它 } } /** * Vid变化通知 */ @Override public void onAbVidsChange(@NonNull String vids, @NonNull String extVids) { } });
如果想实时拉取实验分流结果,可以通过 pullABTestConfigs 方法手动触发实验配置更新 (10秒内多次调用只会触发一次请求)
AppLog.pullAbTestConfigs();//此功能需要6.7.0以上版本 // 执行该接口后,如果拉取到实验数据,会触发 IDataObserver.onRemoteAbConfigGet 回调。
用户行为日志采用事件event+属性params的形式,事件一般对应多个属性,也可以仅有事件没有属性。代码埋点方案一般由数据分析师或产品运营设计。
仅上报事件的代码埋点,示例如下:
// 示例:上报事件event,该事件不包含属性 // 置于业务逻辑对应位置 AppLog.onEventV3("event");
上报事件和对应属性的代码埋点,示例如下:
// 示例:上报事件event,该事件包含两个属性 // 一个string类型的属性,属性名为key_string,属性值为value_string // 一个int类型的属性,属性名为key_int,属性值为10 // 置于业务逻辑对应位置 JSONObject paramsObj = new JSONObject(); try { paramsObj.put("key_string", "value_string"); paramsObj.put("key_int", 10); } catch (JSONException e) { e.printStackTrace(); } AppLog.onEventV3("event", paramsObj);
如需在每个事件中都包括某属性,可通过公共属性设置,无需在每个事件中重复设置。公共属性只需设置一次,即可包括在所有代码埋点事件、预置事件和全埋点事件中。
/* * 示例:设置自定义的公共属性,属性名为key_public,属性值为value_public * 关于自定义 “公共属性” 请注意: * 1. 上报机制是随着每一次日志发送进行提交,默认的日志发送频率是1分钟, * 所以如果在一分钟内连续修改自定义公共属性,按照日志发送前的最后一次修改为准; * 2. 不推荐高频次修改,如每秒修改一次。 */ Map<String,Object> headerMap = new HashMap<String, Object>(); headerMap.put("key_public", "value_public"); AppLog.setHeaderInfo((HashMap<String, Object>)headerMap);
// 示例:移除属性名为 key_public 的公共属性 AppLog.removeHeaderInfo("key_public"); // 通过传入 null 移除所有设置过的公共属性 AppLog.setHeaderInfo(null);
// 请在初始化完成的3秒后开始获取,否则可能返回为空 String ssid = AppLog.getSsid(); // 获取SSID String did = AppLog.getDid(); // 获取设备bddid
// SDK版本号格式为X.X.X String sdk_version = AppLog.getSdkVersion();
注意
开展AB实验必须调用获取实验参数的api(详情请参见 获取实验参数 章节)。如需获取用户所有曝光或命中实验的版本ID(vid)时,可使用此API,此API不会上报abtest_exposure曝光事件。
AppLog.getAbSdkVersion();
切换账号时,同时切换数据发送方式
AppLog.setPrivacyMode(true); //默认是false,设置后true,不采集不上报
SDK提供addDataObserver方法,用以获取各类通知,建议放在 Application 中。
public static void addDataObserver(IDataObserver listener)
设置iid、ssid、did、abconfig从本地加载和server加载成功的回调。
IDataObserver接口方法的参数说明如下:
// step1:添加数据集观察回调,this 指代实现了 IDataObserver 的类 AppLog.addDataObserver(this); // step2:通过 IDataObserver 的 onIdLoaded 或 onRemoteIdGet 到数据后使用或者使用以下方式获取: 默认实例:Applog.getDid() / 使用多实例:IAppLogInstance.getDid() // IDataObserver 主要功能介绍与参数介绍: // - did、iid、ssid 获取都可以通过该回调获取 // - 服务端配置获取 // - ab 实验配置获取 public interface IDataObserver { /** * 本地的id数据加载结果通知 * @param did device id * @param iid install id * @param ssid 数说id */ void onIdLoaded(@NonNull String did, @NonNull String iid, @NonNull String ssid); /** * 通知注册结果,以及id变化情况 * 仅主进程会被调用 * @param changed 是否和本地缓存有所不同 * @param oldDid 本地老的 oldDid,可能为空 * @param newDid server返回新的 device id * @param newIid server返回新 install id * @param newSsid server返回新数说 id */ void onRemoteIdGet(boolean changed, @Nullable String oldDid, @NonNull String newDid, @NonNull String oldIid, @NonNull String newIid, @NonNull String oldSsid, @NonNull String newSsid); /** * Config拉取数据,和本地数据对比有变化的通知 * 仅主进程会被调用 * @param changed 是否和本地缓存有所不同 * @param config server返回新config内容 */ void onRemoteConfigGet(boolean changed, @Nullable JSONObject config); /** * server拉取AbConfig数据,和本地数据对比有变化的通知 * 仅主进程会被调用 * @param changed 是否和本地缓存有所不同 * @param abConfig server返回新abConfig内容 */ void onRemoteAbConfigGet(boolean changed, @NonNull JSONObject abConfig); /** * 客户端ab实验曝光vid集合发生变化的通知 * @param vids 客户端ab实验曝光vid集合 * @param extVids 外部设置的external vid集合 */ void onAbVidsChange(@NonNull String vids, @NonNull String extVids); }
SDK 默认采集以下信息,并作为用户公共属性,可在增长分析(DataFinder)中分组和筛选。
字段名称 | 字段类型 | 参数名称 |
---|---|---|
os | string | 设备系统,对应产品内属性为 os_name。 |
os_version | string | 操作系统版本 |
app_version | string | App 版本 |
app_version_minor | string | 次版本号,App四位版本号,需要初始化调用如: config.setVersionMinor( 1.2.3.r6 ) |
channel | string | 下载渠道(设置后可覆盖),对应产品内属性为 app_channel。 |
device_model | string | 设备机型 |
region | string | 操作系统地区 |
language | string | 系统语言 |
sdk_version | string | SDK版本 |
timezone | int | 时区 |
timezone_offset | int | 时区偏移量,对应产品内属性为 tz_offset。 |
timezone_name | string | 时区名称 |
sim_region | string | SIM卡地域 |
carrier | string | 运营商 |
resolution | string | 分辨率 |
device_brand | string | 设备品牌 |
access | string | 网络类型 |
本功能在 6.10.1+ 后开始支持,使用曝光建议及早初始化 SDK,比如在 Application 中先初始化。
用户需要手动标记监听某个 View 的曝光事件。当这个 View 出现在屏幕可视范围内时,会自动触发一个曝光事件。
说明
6.16.0 以下版本,进入页面后只会触发一次曝光事件,6.16.0 及以上页面内的 View 会根据不同行为多次触发曝光。
可以根据曝光事件内部的 $exposure_type 属性区分:
$exposure_type:0 首次曝光
$exposure_type:3 重复曝光
$exposure_type:6 从其他页面返回的曝光
$exposure_type:7 后台返回曝光
如果想在 6.16.0 以后版本实现之前只曝光一次的效果,可以在新版曝光回调中通过 $exposure_type == 0 进行首次曝光过滤。
在初始化配置中可开启曝光配置开关,开启方法:
config.setExposureEnabled(true);
开启配置后,在需要曝光的 View 上增加曝光监听,示例代码:
View banner = findViewById(R.id.banner); // Optional,自定义曝光事件属性 JSONObject properties = new JSONObject(); properties.put("custom_key", "custom_value"); // Optional,默认为 "$bav2b_exposure" String eventName = "custom_exposure"; // 6.16.2 后:曝光支持按面积+时间检测,并提供了曝光回调进行事件处理 // Optional, 曝光配置,有效曝光面积、可视化调试开关、有效曝光时间和曝光事件回调 // 有效曝光面积: 有效曝光的 View 显示面积的比例,默认是 0,取值 0-1 // 可视化调试开关: 默认 false,线上不要开启,开启后曝光的 View 会增加 background 红色边框,用于调试 // 有效曝光时间: 有效曝光的 View 时间,默认是 0,单位 ms // 曝光事件回调: 触发曝光事件时回调,会携带当前曝光事件相关属性,可以进行自定义追加以及支持过滤 ViewExposureConfig config = new ViewExposureConfig(0.5F, false, 200, viewExposureParam -> { try { // 在回调中添加自定义属性 viewExposureParam.getExposureParam().put("key", "value"); // 打印曝光类型 Log.d("Exposure", "ExposureType: " + viewExposureParam.getExposureParam().get("$exposure_type")); } catch (JSONException e) { // 在发生异常时过滤当前曝光事件 return false; } // true 保留曝光事件 return true; }); ViewExposureData<ViewExposureConfig> callbackData = new ViewExposureData<>(eventName, null, config); // 开始监听 View 曝光事件 viewExposureManager.observeViewExposure(banner, data); // 取消监听 viewExposureManager.disposeViewExposure(banner);
// 6.16.2 后:曝光支持按面积+时间检测,并提供了曝光回调进行事件处理 // Optional, 曝光配置,有效曝光面积、可视化调试开关、有效曝光时间和曝光事件回调 // 有效曝光面积: 有效曝光的 View 显示面积的比例,默认是 0,取值 0-1 // 可视化调试开关: 默认 false,线上不要开启,开启后曝光的 View 会增加 background 红色边框,用于调试 // 有效曝光时间: 有效曝光的 View 时间,默认是 0,单位 ms // 曝光事件回调: 触发曝光事件时回调,会携带当前曝光事件相关属性,可以进行自定义追加以及支持过滤 ViewExposureConfig config = new ViewExposureConfig(0.5F, false, 200, viewExposureParam -> { try { // 在回调中添加自定义属性 viewExposureParam.getExposureParam().put("key", "value"); // 打印曝光类型 Log.d("Exposure", "ExposureType: " + viewExposureParam.getExposureParam().get("$exposure_type")); } catch (JSONException e) { // 在发生异常时过滤当前曝光事件 return false; } // true 保留曝光事件 return true; });
// 6.15.2 后调整至 ViewExposureManager 中,用以代替之前 InitConfig.setViewExposureConfig 的方法 // 请在 SDK init 之后调用 AppLog.getViewExposureManager().updateViewExposureConfig(config);
在部分特殊场景下可能会由于页面不断重绘导致一直无法触发曝光,目前新增了两种曝光检测策略以供选择,可动态调整:
// 6.16.2 新增 // 默认检测策略 如果有多次频繁触发 会在最后一次触发的 100ms 后触发曝光检测 AppLog.getViewExposureManager().updateExposureCheckStrategy(ExposureCheckType.DEBOUNCE); // 新增检测策略 如果有多次频繁触发 会在每隔 500ms 触发一次曝光检测 AppLog.getViewExposureManager().updateExposureCheckStrategy(ExposureCheckType.THROTTLE);
本小节功能在 6.9.0+ 后开始支持。
开启全埋点事件采集开关后,会默认采集页面事件和 View 点击事件等。
有 2 种自定义配置页面事件($bav2b_page)的属性:@PageMeta 注解和实现 IPageMeta 接口。
@PageMeta
注解支持自定义标题和路径,在 Activity 或 Fragment 上添加该注解和配置参数,例如:
@PageMeta(path = "/mypath", title = "自定义页面") public class MyActivity extends Activity { }
IPageMeta
接口类支持自定义标题、路径和属性,优先级高于@PageMeta
。在 Activity 或 Fragment 上实现该接口和对应的函数,例如:
public class MyActivity extends Activity implements IPageMeta { @Override public String title() { return "自定义页面"; } @Override public String path() { return "/mypath"; } @Override public JSONObject pageProperties() { JSONObject params = new JSONObject(); try { params.put("key", "value"); } catch (JSONException e) { } return params; } }
支持对指定的 View 对象设置一个元素 ID,字符串即可,示例:
AppLog.setViewId(view, "myElementId");
支持对指定的 View 对象设置属性值,示例:
JSONObject props = new JSONObject(); try { props.put("key", "value"); } catch (Exception e) { } AppLog.setViewProperties(view, props);
支持忽略特定的 Activity 或 Fragment 的全埋点事件,示例:
AppLog.ignoreAutoTrackPage(MyActivity.class, MyFragment.class);
忽略指定 View 对象的点击事件,示例:
AppLog.ignoreAutoTrackClick(findViewById(R.id.button1));
忽略指定 View 类型的点击事件,示例:
// 忽略所有 Switch 组件的点击事件 AppLog.ignoreAutoTrackClickByViewType(Switch.class);
支持手动采集特定的 Activity 和 Fragment 对象的页面事件以及属性,示例:
JSONObject params = new JSONObject(); try { params.put("param1", "test"); } catch (JSONException e) { } AppLog.trackPage(MyActivity.this, params);
支持手动采集特定 View 的点击事件以及属性,示例:
JSONObject params = new JSONObject(); try { params.put("param1", "test"); } catch (JSONException e) { } AppLog.trackClick(myView, params);
本小节功能在 6.10.1+ 后开始支持。
带有时间属性的事件可以使用时长事件采集接口,例如采集视频播放时长事件等。示例:
// 在视频开始播放时调用 AppLog.startDurationEvent("play"); // 在视频暂停播放时调用 AppLog.pauseDurationEvent("play"); // 在视频继续播放时调用 AppLog.resumeDurationEvent("play"); // 在结束播放时调用,此时会上报一个 play 事件,且带有 $event_duration 属性(记录了播放时长,单位毫秒) JsonObject params = new JsonObject() // 可以在 params 填入自己的自定义参数 AppLog.stopDurationEvent("play", params); // 6.16.10 后自持自定义时长事件事件名,默认情况事件名为方法第一个参数 AppLog.stopDurationEvent("play", params, "custom_play");