前言
最近有一个需求,就是将AF之类的打点集成至我们主SDK内,但由于之前已有部分游戏接入过主SDK和AF,如果直接集成会导致下次CP更新SDK必须得先将之前他们自己接入的AF删除,造成很多不必要的开发量,这时,SDK组件化就显得很有必要了。
但是目前成熟的组件化方案大多是针对APP的,我感觉对于SDK来说有点繁琐了,只能走点歪门邪道了。AF是有初始化接口的,单独让CP调用初始化接口显得有点繁琐且违背了组件化的初衷,用反射来调用SDK初始化就能很好的解决问题了,如果没有打点模块反射报错直接捕获异常啦。理论支持下面就让我们实践走一走。
准备工作
1. 什么是反射?
对于java而言,其数据类型等在编译期间就已经确定,也无法在运行的时候使用诸如动态的增加代码、扩展对象等操作,所以认为其是静态语言,而反射的出现改变了这种情况。
反射机制可以让java具备在运行时动态获取类信息的能力,包括一些类型元数据信息、泛型信息等,同时可以动态的修改这些编码信息,诸如此类的,所以说反射机制使java具备了动态语言的特性。
Kotlin反射原理和Java基本一样,只是写法有所不同,后面会提供详细代码。
2. 反射初始化接口后怎么调用AF接口?
想了想,感觉接口回调的方式比较适合:在主SDK中定义一个打点接口,接口定义的参数就是AF打点所需的参数,主SDK反射调用打点模块初始化后,打点模块再实例化打点接口监听打点回调,收到回调就调用AF打点接口进行打点。理论又实现了,下面就让我们没病走两步~~
实践开始
1. 反射调用打点模块接口
和Java不同,Kotlin使用反射要先添加依赖:
//kotlin 反射库
implementation "org.jetbrains.kotlin:kotlin-reflect:1.5.21"
反射调用接口代码:
try {
val trackClass = Class.forName("打点类名,比如:com.track.classname").kotlin
val obj = trackClass.createInstance()
for(f in trackClass.declaredFunctions) {
if (f.name == "初始化方法名,比如:trackInit") {
f.call(obj, activity, afKey)
}
}
} catch (e: Exception) {
print(e.message)
}
这时我们就能够初始化打点模块了。
2. 新建打点回调
打点接口回调代码:
interface TrackListener {
fun callLogEvent(activity: Activity, map: HashMap<String, Any>?, eventType: String)
}
主SDK初始化打点接口代码:
internal lateinit var trackListener: TrackListener
internal fun isTrackInit(): Boolean {
return this::gcTrackListener.isInitialized
}
fun trackEvent(trackListener: TrackListener, afId: String?) {
this.trackListener = trackListener
if (!afId.isNullOrEmpty()) {
this.afId = afId
}
}
打点模块实现回调代码:
private val trackListener: TrackListener = object : TrackListener {
override fun callLogEvent(
activity: Activity,
map: HashMap<String, Any>?,
eventType: String
) {
}
}
fun trackInit(activity: Activity, initKey: String) {
this.activity = activity
AppsFlyerLib.getInstance().init(initKey, conversionDataListener, activity)
AppsFlyerLib.getInstance().start(activity)
SDK.trackEvent(trackListener, AppsFlyerLib.getInstance().getAppsFlyerUID(activity))
}
到这儿就能正常监听到主SDK的打点回调了,剩下就差一个调用打点的方法了。
3. 主SDK调用打点接口方法
so easy ,上代码:
internal fun logEvent(activity: Activity, map: HashMap<String, Any>?, eventType: String) {
if (isTrackInit()) {
trackListener.callLogEvent(activity, map, eventType)
}
}
后面,CP如果需要打点直接调用logEvent()方法就可以啦,AF相关接入我就不赘述了,官方文档写的很清楚。
|