Skip to content

Commit 2e6e165

Browse files
author
chenru
committed
Release 2.0.5
1 parent 40b8724 commit 2e6e165

File tree

15 files changed

+465
-478
lines changed

15 files changed

+465
-478
lines changed

README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,22 @@
33
[![License](https://img.shields.io/github/license/sensorsdata/sa-sdk-android.svg)](https://github.com/sensorsdata/sa-sdk-android/blob/master/LICENSE)
44
[![GitHub release](https://img.shields.io/github/tag/sensorsdata/sa-sdk-cpp.svg?label=release)](https://github.com/sensorsdata/sa-sdk-cpp/releases)
55
[![GitHub release date](https://img.shields.io/github/release-date/sensorsdata/sa-sdk-cpp.svg)](https://github.com/sensorsdata/sa-sdk-cpp/releases)
6+
67
## 神策简介
78

89
[**神策数据**](https://www.sensorsdata.cn/)
910
(Sensors Data),隶属于神策网络科技(北京)有限公司,是一家专业的大数据分析服务公司,大数据分析行业开拓者,为客户提供深度用户行为分析平台、以及专业的咨询服务和行业解决方案,致力于帮助客户实现数据驱动。神策数据立足大数据及用户行为分析的技术与实践前沿,业务现已覆盖以互联网、金融、零售快消、高科技、制造等为代表的十多个主要行业、并可支持企业多个职能部门。公司总部在北京,并在上海、深圳、合肥、武汉等地拥有本地化的服务团队,覆盖东区及南区市场;公司拥有专业的服务团队,为客户提供一对一的客户服务。公司在大数据领域积累的核心关键技术,包括在海量数据采集、存储、清洗、分析挖掘、可视化、智能应用、安全与隐私保护等领域。 [**More**](https://www.sensorsdata.cn/about/aboutus.html)
1011

12+
13+
## SDK 简介
14+
15+
SensorsAnalytics SDK 是国内第一家开源商用版用户行为采集 SDK,目前支持代码埋点、全埋点、App 点击图、可视化全埋点等。目前已累计有 1500 多家付费客户,2500+ 的 App 集成使用,作为 App 数据采集利器,致力于帮助客户挖掘更多的商业价值,为其精准运营和业务支撑提供了可靠的数据来源。其采集全面而灵活、性能良好,并一直保持稳定的迭代,经受住了时间和客户的考验。
16+
1117
## 基本要求
1218
App 元素点击事件要求 React Native 0.23 ~ 0.63;
1319
App 页面浏览事件要求 React Navigation ^2.0 ~ ^5.0;
14-
App 可视化全埋点要求 React Native 0.46 ~ 0.63。
20+
App 可视化全埋点要求 React Native 0.46 ~ 0.63;
21+
App 点击事件自定义属性要求 React Native 0.46 ~ 0.63。
1522

1623
## 集成方式
1724
### 安装 React Native 模块

RNSensorsAnalyticsModule.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
Pod::Spec.new do |s|
33
s.name = "RNSensorsAnalyticsModule"
4-
s.version = "2.0.4"
4+
s.version = "2.0.5"
55
s.summary = "The official React Native SDK of Sensors Analytics."
66
s.description = <<-DESC
77
神策分析 RN 组件

SensorsDataRNHook.js

Lines changed: 111 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -669,22 +669,83 @@ sensorsdataHookClickableRN = function (reset = false) {
669669
throw "can't inject clickable js";
670670
}
671671
var lastParentheses = content.lastIndexOf(')', match.index);
672-
var lastCommaIndex = content.lastIndexOf(',', lastParentheses);
673-
if (lastCommaIndex == -1)
674-
throw "can't inject clickable js,and lastCommaIndex is -1";
675672
var nextCommaIndex = content.indexOf(',', match.index);
676673
if (nextCommaIndex == -1)
677674
throw "can't inject clickable js, and nextCommaIndex is -1";
678-
var propsName = lastArgumentName(content, lastCommaIndex).trim();
679675
var tagName = lastArgumentName(content, nextCommaIndex).trim();
680-
var functionBody = `var clickable = false;
681-
if(${propsName}.onStartShouldSetResponder){
682-
clickable = true;
683-
}
684-
var ReactNative = require('react-native');
685-
var dataModule = ReactNative.NativeModules.RNSensorsDataModule;
686-
dataModule && dataModule.saveViewProperties && dataModule.saveViewProperties(${tagName}, clickable , null);
687-
`;
676+
var functionBody = `
677+
var saElement;
678+
if(typeof internalInstanceHandle !== 'undefined'){
679+
saElement = internalInstanceHandle;
680+
}else if(typeof workInProgress !== 'undefined'){
681+
saElement = workInProgress;
682+
}else if(typeof thatThis._currentElement !== 'undefined'){
683+
saElement = thatThis._currentElement;
684+
}
685+
var eachProgress = function (workInProgress){
686+
if(workInProgress == null){
687+
return;
688+
}
689+
var props;
690+
if(workInProgress.memoizedProps){
691+
props = workInProgress.memoizedProps;
692+
}else if(workInProgress.props){
693+
props = workInProgress.props;
694+
}
695+
if(props && props.sensorsdataparams){
696+
return props.sensorsdataparams;
697+
}else {
698+
if(!props ||
699+
!workInProgress.type ||
700+
workInProgress.type.displayName === 'TouchableOpacity' ||
701+
workInProgress.type.displayName === 'TouchableHighlight' ||
702+
workInProgress.type.displayName === 'TouchableWithoutFeedback'||
703+
workInProgress.type.displayName === 'TouchableNativeFeedback'||
704+
workInProgress.type.displayName === 'Pressable'||
705+
workInProgress.type.name === 'TouchableOpacity' ||
706+
workInProgress.type.name === 'TouchableHighlight' ||
707+
workInProgress.type.name === 'TouchableNativeFeedback'||
708+
workInProgress.type.name === 'TouchableWithoutFeedback'||
709+
workInProgress.type.displayName === undefined||
710+
workInProgress.type.name === undefined ||
711+
!props.onPress){
712+
if(workInProgress.return){
713+
return eachProgress(workInProgress.return);
714+
}else{
715+
if(workInProgress._owner && workInProgress._owner._currentElement){
716+
return eachProgress(workInProgress._owner._currentElement);
717+
}else{
718+
return eachProgress(workInProgress._owner);
719+
}
720+
}
721+
}
722+
}
723+
};
724+
var elementProps;
725+
if(saElement && saElement.memoizedProps){
726+
elementProps = saElement.memoizedProps;
727+
}else if(saElement && saElement.props){
728+
elementProps = saElement.props;
729+
}
730+
if(elementProps){
731+
// iOS 兼容 SegmentedControl 逻辑
732+
var isSegmentedControl = (saElement &&
733+
(saElement.type === 'RNCSegmentedControl' ||
734+
saElement.type === 'RCTSegmentedControl' ||
735+
saElement.type.name === 'RNCSegmentedControl' ||
736+
saElement.type.name === 'RCTSegmentedControl' ||
737+
saElement.type.displayName === 'RNCSegmentedControl' ||
738+
saElement.type.displayName === 'RCTSegmentedControl'));
739+
if(elementProps.onStartShouldSetResponder || isSegmentedControl) {
740+
var saProps = eachProgress(saElement);
741+
if(saProps){
742+
console.log(saProps);
743+
}
744+
var ReactNative = require('react-native');
745+
var dataModule = ReactNative.NativeModules.RNSensorsDataModule;
746+
dataModule && dataModule.saveViewProperties && dataModule.saveViewProperties(${tagName}, true , saProps);
747+
}
748+
}`;
688749
var call = addTryCatch(functionBody);
689750
var lastReturn = content.lastIndexOf('return', match.index);
690751
var splitIndex = match.index;
@@ -778,47 +839,46 @@ navigationString3 = function (
778839
}`;
779840

780841
if (actionName) {
781-
script = `${script}
782-
var type = ${actionName}.type;
783-
var iosOnPageShow = false;
784-
785-
if (require('react-native').Platform.OS === 'android') {
786-
if(type == 'Navigation/SET_PARAMS' || type == 'Navigation/COMPLETE_TRANSITION') {
787-
return;
788-
}
789-
} else if (require('react-native').Platform.OS === 'ios') {
790-
if(type == 'Navigation/BACK' && (${currentStateVarName} && !${currentStateVarName}.isTransitioning)) {
791-
iosOnPageShow = true;
792-
} else if (!(type == 'Navigation/SET_PARAMS' || type == 'Navigation/COMPLETE_TRANSITION')) {
793-
iosOnPageShow = true;
794-
}
795-
if (!iosOnPageShow) {
796-
return;
797-
}
798-
}
799-
842+
script = `
843+
${script}
844+
var type = ${actionName}.type;
845+
var iosOnPageShow = false;
800846
801-
`;
847+
if (require('react-native').Platform.OS === 'android') {
848+
if(type == 'Navigation/SET_PARAMS' || type == 'Navigation/COMPLETE_TRANSITION') {
849+
return;
850+
}
851+
} else if (require('react-native').Platform.OS === 'ios') {
852+
if(type == 'Navigation/BACK' && (${currentStateVarName} && !${currentStateVarName}.isTransitioning)) {
853+
iosOnPageShow = true;
854+
} else if (!(type == 'Navigation/SET_PARAMS' || type == 'Navigation/COMPLETE_TRANSITION')) {
855+
iosOnPageShow = true;
856+
}
857+
if (!iosOnPageShow) {
858+
return;
859+
}
860+
}`;
802861
}
803862

804-
script = `${script} var params = $$$getActivePageName$$$(${currentStateVarName});
805-
if (require('react-native').Platform.OS === 'android') {
806-
if (${prevStateVarName}){
807-
var prevParams = $$$getActivePageName$$$(${prevStateVarName});
808-
if (params.sensorsdataurl == prevParams.sensorsdataurl){
809-
return;
810-
}
811-
}
812-
var ReactNative = require('react-native');
813-
var dataModule = ReactNative.NativeModules.RNSensorsDataModule;
814-
dataModule && dataModule.trackViewScreen && dataModule.trackViewScreen(params);
815-
} else if (require('react-native').Platform.OS === 'ios') {
816-
if (!${actionName} || iosOnPageShow) {
817-
var ReactNative = require('react-native');
818-
var dataModule = ReactNative.NativeModules.RNSensorsDataModule;
819-
dataModule && dataModule.trackViewScreen && dataModule.trackViewScreen(params);
820-
}
821-
}`;
863+
script = `
864+
${script} var params = $$$getActivePageName$$$(${currentStateVarName});
865+
if (require('react-native').Platform.OS === 'android') {
866+
if (${prevStateVarName}){
867+
var prevParams = $$$getActivePageName$$$(${prevStateVarName});
868+
if (params.sensorsdataurl == prevParams.sensorsdataurl){
869+
return;
870+
}
871+
}
872+
var ReactNative = require('react-native');
873+
var dataModule = ReactNative.NativeModules.RNSensorsDataModule;
874+
dataModule && dataModule.trackViewScreen && dataModule.trackViewScreen(params);
875+
} else if (require('react-native').Platform.OS === 'ios') {
876+
if (!${actionName} || iosOnPageShow) {
877+
var ReactNative = require('react-native');
878+
var dataModule = ReactNative.NativeModules.RNSensorsDataModule;
879+
dataModule && dataModule.trackViewScreen && dataModule.trackViewScreen(params);
880+
}
881+
}`;
822882
return script;
823883
};
824884
navigationEventString = function () {
@@ -1089,6 +1149,7 @@ allSensorsdataHookRN = function () {
10891149
// 命令行
10901150
switch (process.argv[2]) {
10911151
case '-run':
1152+
resetAllSensorsdataHookRN();
10921153
allSensorsdataHookRN();
10931154
break;
10941155
case '-reset':

android/src/main/java/com/sensorsdata/analytics/RNAgent.java

Lines changed: 23 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,14 @@
77
import com.facebook.react.bridge.ReadableMap;
88
import com.sensorsdata.analytics.RNSensorsAnalyticsModule;
99
import com.sensorsdata.analytics.utils.RNViewUtils;
10-
import com.sensorsdata.analytics.data.ViewProperties;
10+
import com.sensorsdata.analytics.data.SAViewProperties;
1111

1212
import com.facebook.react.uimanager.JSTouchDispatcher;
1313
import com.facebook.react.uimanager.events.EventDispatcher;
1414
import com.sensorsdata.analytics.android.sdk.SALog;
1515
import com.sensorsdata.analytics.android.sdk.SensorsDataAPI;
1616
import com.sensorsdata.analytics.android.sdk.util.SensorsDataUtils;
1717
import com.sensorsdata.analytics.android.sdk.SensorsDataAutoTrackHelper;
18-
import com.sensorsdata.analytics.utils.RNTouchTargetHelper;
1918

2019
import java.lang.reflect.Field;
2120
import java.util.WeakHashMap;
@@ -25,38 +24,10 @@
2524

2625
public class RNAgent {
2726
private static final WeakHashMap jsTouchDispatcherViewGroupWeakHashMap = new WeakHashMap();
28-
private static SparseArray<ViewProperties> viewPropertiesArray = new SparseArray();
27+
private static SparseArray<SAViewProperties> viewPropertiesArray = new SparseArray();
2928

3029
public static void handleTouchEvent(
3130
JSTouchDispatcher jsTouchDispatcher, MotionEvent event, EventDispatcher eventDispatcher) {
32-
33-
if (event.getAction() == MotionEvent.ACTION_DOWN) { // ActionDown
34-
ViewGroup viewGroup = (ViewGroup)jsTouchDispatcherViewGroupWeakHashMap.get(jsTouchDispatcher);
35-
if (viewGroup == null) {
36-
try {
37-
Field viewGroupField = jsTouchDispatcher.getClass().getDeclaredField("mRootViewGroup");
38-
viewGroupField.setAccessible(true);
39-
viewGroup = (ViewGroup) viewGroupField.get(jsTouchDispatcher);
40-
jsTouchDispatcherViewGroupWeakHashMap.put(jsTouchDispatcher, viewGroup);
41-
} catch (Exception e) {
42-
SALog.printStackTrace(e);
43-
}
44-
}
45-
if (viewGroup != null) {
46-
View nativeTargetView =
47-
RNTouchTargetHelper.findTouchTargetView(
48-
new float[] {event.getX(), event.getY()}, viewGroup);
49-
if (nativeTargetView != null) {
50-
View reactTargetView = RNTouchTargetHelper.findClosestReactAncestor(nativeTargetView);
51-
if (reactTargetView != null) {
52-
nativeTargetView = reactTargetView;
53-
}
54-
}
55-
if (nativeTargetView != null) {
56-
RNViewUtils.setOnTouchView(nativeTargetView);
57-
}
58-
}
59-
}
6031
}
6132

6233
public static void trackViewScreen(String url, JSONObject properties, boolean isAuto){
@@ -95,6 +66,14 @@ public static void trackViewScreen(String url, JSONObject properties, boolean is
9566

9667
public static void trackViewClick(int viewId){
9768
try {
69+
//关闭 AutoTrack
70+
if (!SensorsDataAPI.sharedInstance().isAutoTrackEnabled()) {
71+
return;
72+
}
73+
//$AppClick 被过滤
74+
if (SensorsDataAPI.sharedInstance().isAutoTrackEventTypeIgnored(SensorsDataAPI.AutoTrackEventType.APP_CLICK)) {
75+
return;
76+
}
9877
View clickView = RNViewUtils.getTouchViewByTag(viewId);
9978
if (clickView != null) {
10079
JSONObject properties = new JSONObject();
@@ -104,7 +83,15 @@ public static void trackViewClick(int viewId){
10483
if(RNViewUtils.getScreenName() != null){
10584
properties.put("$screen_name",RNViewUtils.getScreenName());
10685
}
107-
SensorsDataAPI.sharedInstance().trackViewAppClick(clickView,properties);
86+
SAViewProperties viewProperties = viewPropertiesArray.get(viewId);
87+
if(viewProperties != null && viewProperties.properties != null && viewProperties.properties.length() > 0){
88+
if(viewProperties.properties.optBoolean("ignore", false)){
89+
return;
90+
}
91+
viewProperties.properties.remove("ignore");
92+
SensorsDataUtils.mergeJSONObject(viewProperties.properties, properties);
93+
}
94+
SensorsDataAPI.sharedInstance().trackViewAppClick(clickView, properties);
10895
}
10996
} catch (Exception e) {
11097
SALog.printStackTrace(e);
@@ -113,14 +100,14 @@ public static void trackViewClick(int viewId){
113100

114101
public static void saveViewProperties(int viewId, boolean clickable, ReadableMap viewProperties) {
115102
if(clickable){
116-
viewPropertiesArray.put(viewId, new ViewProperties(clickable,viewProperties));
103+
viewPropertiesArray.put(viewId, new SAViewProperties(clickable, viewProperties));
117104
}
118-
}
105+
}
119106

120107
public static void addView(View view,int index){
121-
ViewProperties properties = viewPropertiesArray.get(view.getId());
108+
SAViewProperties properties = viewPropertiesArray.get(view.getId());
122109
if(properties != null){
123-
properties.setViewProperty(view);
110+
properties.setViewClickable(view);
124111
}
125112
}
126113

android/src/main/java/com/sensorsdata/analytics/RNSensorsAnalyticsPackage.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*/
1616

1717
public class RNSensorsAnalyticsPackage implements ReactPackage {
18-
public static final String VERSION = "2.0.4";
18+
public static final String VERSION = "2.0.5";
1919
@Override
2020
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
2121
List<NativeModule> modules = new ArrayList<>();

android/src/main/java/com/sensorsdata/analytics/RNSensorsDataModule.java

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -18,28 +18,19 @@
1818
package com.sensorsdata.analytics;
1919

2020

21-
import android.text.TextUtils;
22-
import android.util.Log;
23-
24-
import com.facebook.react.bridge.Callback;
2521
import com.facebook.react.bridge.LifecycleEventListener;
26-
import com.facebook.react.bridge.Promise;
2722
import com.facebook.react.bridge.ReactApplicationContext;
23+
import com.facebook.react.bridge.ReactContext;
2824
import com.facebook.react.bridge.ReactContextBaseJavaModule;
2925
import com.facebook.react.bridge.ReactMethod;
30-
import com.facebook.react.bridge.ReadableArray;
3126
import com.facebook.react.bridge.ReadableMap;
32-
import com.facebook.react.bridge.ReadableNativeMap;
3327
import com.sensorsdata.analytics.android.sdk.SensorsDataAPI;
3428
import com.sensorsdata.analytics.android.sdk.SALog;
35-
import com.sensorsdata.analytics.RNAgent;
3629
import com.sensorsdata.analytics.utils.RNUtils;
3730
import com.sensorsdata.analytics.utils.RNViewUtils;
3831

3932
import org.json.JSONObject;
4033

41-
import java.util.HashSet;
42-
4334

4435
/**
4536
* Created by yang on 2017/4/5
@@ -80,15 +71,6 @@ public String getName() {
8071

8172
@ReactMethod
8273
public void trackViewClick(int viewId) {
83-
//关闭 AutoTrack
84-
if (!SensorsDataAPI.sharedInstance().isAutoTrackEnabled()) {
85-
return;
86-
}
87-
//$AppClick 被过滤
88-
if (SensorsDataAPI.sharedInstance().isAutoTrackEventTypeIgnored(SensorsDataAPI.AutoTrackEventType.APP_CLICK)) {
89-
return;
90-
}
91-
9274
RNAgent.trackViewClick(viewId);
9375
}
9476

@@ -123,10 +105,12 @@ public void saveViewProperties(int viewId, boolean clickable, ReadableMap viewPr
123105
class SensorsDataLifecycleListener implements LifecycleEventListener {
124106
public void onHostResume() {
125107
RNViewUtils.setScreenVisiable(true);
108+
RNViewUtils.setCurrentActivity(getCurrentActivity());
126109
}
127110

128111
public void onHostPause() {
129112
RNViewUtils.setScreenVisiable(false);
113+
RNViewUtils.clearCurrentActivityReference();
130114
}
131115

132116
public void onHostDestroy() {

0 commit comments

Comments
 (0)