RN 层只暴露一个统一的埋点方法,例如 trackEvent(eventName, params)
,内部通过 NativeModule 调用 Android/iOS 的原生埋点 SDK。这样 RN 层不用关心具体实现。
写一个通用的示例:
1. RN 层封装统一接口(JS 代码)
javascript
// analytics.js
import { NativeModules, Platform } from 'react-native';
const { AnalyticsModule } = NativeModules;
const Analytics = {
trackEvent(eventName, params = {}) {
if (!AnalyticsModule) {
console.warn("AnalyticsModule not linked");
return;
}
AnalyticsModule.trackEvent(eventName, params);
}
};
export default Analytics;
RN 业务里用法:
javascript
import Analytics from './analytics';
Analytics.trackEvent('button_click', { page: 'home', userId: '12345' });
2. Android 端原生模块
在 android/app/src/main/java/com/yourapp/analytics/AnalyticsModule.java
:
javascript
package com.yourapp.analytics;
import android.util.Log;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;
import java.util.HashMap;
import java.util.Map;
public class AnalyticsModule extends ReactContextBaseJavaModule {
public AnalyticsModule(ReactApplicationContext reactContext) {
super(reactContext);
}
@Override
public String getName() {
return "AnalyticsModule"; // RN 里调用的名字
}
@ReactMethod
public void trackEvent(String eventName, ReadableMap params) {
Map<String, Object> map = params.toHashMap();
// TODO: 这里替换成你们实际的埋点 SDK 调用
Log.d("Analytics", "TrackEvent: " + eventName + " params: " + map.toString());
}
}
注册模块 AnalyticsPackage.java
:
java
package com.yourapp.analytics;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.uimanager.ViewManager;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class AnalyticsPackage implements ReactPackage {
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new AnalyticsModule(reactContext));
return modules;
}
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}
在 MainApplication.java
里注册:
java
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new AnalyticsPackage() // 注册
);
}
3. iOS 端原生模块
在 ios/AnalyticsModule.m
:
Swift
#import <React/RCTBridgeModule.h>
@interface RCT_EXTERN_MODULE(AnalyticsModule, NSObject)
RCT_EXTERN_METHOD(trackEvent:(NSString *)eventName params:(NSDictionary *)params)
@end
在 ios/AnalyticsModule.swift
(或 .m
,我用 Swift 例子):
Swift
import Foundation
@objc(AnalyticsModule)
class AnalyticsModule: NSObject {
@objc
func trackEvent(_ eventName: String, params: [String: Any]) {
// TODO: 替换为 iOS 的埋点 SDK 调用
print("TrackEvent: \(eventName), params: \(params)")
}
}
✅ 最终效果:
RN 调用 Analytics.trackEvent("xxx", {...})
👉 Android / iOS 走各自原生埋点 SDK。
这样就实现了 RN 与原生端通用的埋点接口。