From 13ee0de952edf2c6f39fd3a9d0dec81ea9a6ee4b Mon Sep 17 00:00:00 2001 From: Lindong Date: Mon, 26 Jan 2026 16:24:45 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90=E5=9F=8B=E7=82=B9=E3=80=91Loading=5FS?= =?UTF-8?q?tart=20=E5=A2=9E=E5=8A=A0=E6=95=B0=E6=95=B0=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=E4=B8=8A=E6=8A=A5=E7=BC=93=E5=AD=98=E5=A4=84=E7=90=86,?= =?UTF-8?q?=E6=95=B0=E6=95=B0=E5=88=9D=E5=A7=8B=E5=8C=96=E5=89=8D=E7=BC=93?= =?UTF-8?q?=E5=AD=98=E4=BA=8B=E4=BB=B6,=E9=98=B2=E6=AD=A2=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6=E4=B8=A2=E5=A4=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../statisticreporter/StatisticUtil.kt | 14 ++- .../statisticreporter/shushu/ShushuManager.kt | 103 +++++++++++++++--- app/build.gradle | 7 +- 3 files changed, 105 insertions(+), 19 deletions(-) diff --git a/StatisticReporter/src/main/java/com/gamedog/statisticreporter/StatisticUtil.kt b/StatisticReporter/src/main/java/com/gamedog/statisticreporter/StatisticUtil.kt index 1510d2b..22bb453 100644 --- a/StatisticReporter/src/main/java/com/gamedog/statisticreporter/StatisticUtil.kt +++ b/StatisticReporter/src/main/java/com/gamedog/statisticreporter/StatisticUtil.kt @@ -70,10 +70,12 @@ object StatisticUtil { "adid" to AdjustManager.instance().getAaId() ) FireBaseManager.instance().reportEvent(eventKey, eventData, superPropertiesMap) - ShushuManager.instance().reportEvent(eventKey, eventData, superPropertiesMap) + val shushuManager = ShushuManager.instance() + shushuManager.reportEvent(eventKey, eventData, superPropertiesMap) + StatisticLogger.d("[reportEvents] shushuReady=${shushuManager.isSdkReady()} eventKey=$eventKey") if (BuildConfig.DEBUG) { - StatisticLogger.d("Events reported to shushu&Firebase: type=$eventKey") + StatisticLogger.d("[reportEvents] Events reported to shushu&Firebase: type=$eventKey") } } } @@ -95,6 +97,14 @@ object StatisticUtil { data: Map ) { reportEvents(eventName, data) + val dataStr = try { + data.entries + .sortedBy { it.key } + .joinToString(prefix = "{", postfix = "}") { (k, v) -> "$k=$v" } + } catch (t: Throwable) { + "format_failed:${t.javaClass.simpleName}" + } + StatisticLogger.d("[DataReporter] eventName: $eventName data=$dataStr") } override fun setCommonParams(params: Map) { diff --git a/StatisticReporter/src/main/java/com/gamedog/statisticreporter/shushu/ShushuManager.kt b/StatisticReporter/src/main/java/com/gamedog/statisticreporter/shushu/ShushuManager.kt index 948197f..1e1a4e1 100644 --- a/StatisticReporter/src/main/java/com/gamedog/statisticreporter/shushu/ShushuManager.kt +++ b/StatisticReporter/src/main/java/com/gamedog/statisticreporter/shushu/ShushuManager.kt @@ -8,6 +8,8 @@ import cn.thinkingdata.analytics.ThinkingAnalyticsSDK import com.ama.core.architecture.BaseApp import com.ama.core.architecture.util.AndroidUtil.Companion.gson import com.gamedog.statisticreporter.StatisticLogger +import java.util.ArrayDeque +import java.util.concurrent.atomic.AtomicBoolean import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob @@ -33,19 +35,43 @@ class ShushuManager private constructor() { private val mAppContext = BaseApp.appContext() private val mBgScope = CoroutineScope(SupervisorJob() + Dispatchers.Default) private val mMainScope = CoroutineScope(SupervisorJob() + Dispatchers.Main) - private lateinit var mShushuSdk: ThinkingAnalyticsSDK + lateinit var mShushuSdk: ThinkingAnalyticsSDK + + private data class PendingEvent( + val eventKey: String, + val params: Map?, + val superProperties: Map + ) + + private val initStarted = AtomicBoolean(false) + @Volatile + private var sdkReady: Boolean = false + + private val pendingEventsLock = Any() + private val pendingEvents = ArrayDeque() + private val trackLock = Any() + private val maxPendingEvents = 200 fun initShushu(shushuAppId: String, shushuServerUrl: String) { + if (sdkReady) return + if (!initStarted.compareAndSet(false, true)) return mMainScope.launch { - TDAnalytics.init(mAppContext, shushuAppId, shushuServerUrl) + try { + TDAnalytics.init(mAppContext, shushuAppId, shushuServerUrl) - val config = TDConfig.getInstance(mAppContext, shushuAppId, shushuServerUrl) - config.setMode(/*if (BuildConfig.DEBUG) TDConfig.ModeEnum.DEBUG else*/ TDConfig.ModeEnum.NORMAL) - mShushuSdk = ThinkingAnalyticsSDK.sharedInstance(config) - - configAutoTrack() + val config = TDConfig.getInstance(mAppContext, shushuAppId, shushuServerUrl) + config.setMode(/*if (BuildConfig.DEBUG) TDConfig.ModeEnum.DEBUG else*/ TDConfig.ModeEnum.DEBUG) +// config.setMode(/*if (BuildConfig.DEBUG) TDConfig.ModeEnum.DEBUG else*/ TDConfig.ModeEnum.NORMAL) + mShushuSdk = ThinkingAnalyticsSDK.sharedInstance(config) + configAutoTrack() + sdkReady = true + flushPendingEventsAsync() + } catch (e: Exception) { + initStarted.set(false) + StatisticLogger.e("数数SDK初始化失败", e) + } } } @@ -54,16 +80,12 @@ class ShushuManager private constructor() { * 用户点击按钮、浏览页面、完成购买等。 */ fun reportEvent(eventKey: String, params: Map?, superProperties: Map) { - try { - TDAnalytics.setSuperProperties(JSONObject(superProperties)) - val jsonObj = params?.let { - JSONObject(params) - } - TDAnalytics.track(eventKey, jsonObj) - - } catch (e: Exception) { - e.printStackTrace() + if (!sdkReady) { + enqueuePendingEvent(eventKey, params, superProperties) + if (sdkReady) flushPendingEventsAsync() + return } + reportEventInternal(eventKey, params, superProperties) } @@ -157,6 +179,55 @@ class ShushuManager private constructor() { } } + fun isSdkReady(): Boolean { + return sdkReady && this::mShushuSdk.isInitialized + } + + private fun enqueuePendingEvent(eventKey: String, params: Map?, superProperties: Map) { + val safeParams = params?.toMap() + val safeSuper = superProperties.toMap() + synchronized(pendingEventsLock) { + if (pendingEvents.size >= maxPendingEvents) { + if (pendingEvents.isNotEmpty()) { + pendingEvents.removeFirst() + } + } + pendingEvents.addLast(PendingEvent(eventKey, safeParams, safeSuper)) + } + } + + private fun flushPendingEventsAsync() { + mBgScope.launch { + flushPendingEvents() + } + } + + private fun flushPendingEvents() { + if (!sdkReady) return + val batch = ArrayList() + synchronized(pendingEventsLock) { + while (pendingEvents.isNotEmpty()) { + batch.add(pendingEvents.removeFirst()) + } + } + if (batch.isEmpty()) return + batch.forEach { pending -> + reportEventInternal(pending.eventKey, pending.params, pending.superProperties) + } + } + + private fun reportEventInternal(eventKey: String, params: Map?, superProperties: Map) { + try { + synchronized(trackLock) { + TDAnalytics.setSuperProperties(JSONObject(superProperties)) + val jsonObj = params?.let { JSONObject(it) } + TDAnalytics.track(eventKey, jsonObj) + StatisticLogger.d("数数SDK事件上报: $eventKey $jsonObj") + } + } catch (e: Exception) { + StatisticLogger.e("数数SDK事件上报失败: $eventKey", e) + } + } } diff --git a/app/build.gradle b/app/build.gradle index 4702578..17f5c75 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -8,7 +8,7 @@ plugins { id("com.google.gms.google-services") id("com.google.firebase.crashlytics") } - +def buildTime = new Date().format('yyyyMMdd_HHmmss') android { namespace = "com.viddin.videos.free" compileSdk libs.versions.compileSdk.get().toInteger() @@ -23,6 +23,11 @@ android { testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } + applicationVariants.configureEach { variant -> + variant.outputs.configureEach { + outputFileName = "${variant.applicationId}_${variant.versionName}_${variant.versionCode}_${variant.buildType.name}_${buildTime}.apk" + } + } buildTypes { debug { minifyEnabled false