From ba6de0a5fd58961ea700e408f462952b51f8bbcc Mon Sep 17 00:00:00 2001 From: XuqmGroup Date: Thu, 18 Jun 2026 14:53:34 +0800 Subject: [PATCH] =?UTF-8?q?perf(sdk):=20ContentProvider=20=E5=BC=82?= =?UTF-8?q?=E6=AD=A5=E5=88=9D=E5=A7=8B=E5=8C=96=EF=BC=8C=E5=87=8F=E5=B0=91?= =?UTF-8?q?=E5=86=B7=E5=90=AF=E5=8A=A8=E9=98=BB=E5=A1=9E=E6=97=B6=E9=97=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - XuqmInitializerProvider 改用 autoInitializeAsync(),TokenStore/DeviceId/ApiClient 移到 IO 线程 - XuqmSDK 新增 readAppKey() 公开方法,仅读取 config 不做初始化 - BugCollectInitProvider 适配异步初始化,直接读取 appKey 注册崩溃拦截器 - 同步阶段只做 config 文件读取(~5ms),主线程不再阻塞 --- .../internal/BugCollectInitProvider.kt | 15 +++++--- .../src/main/java/com/xuqm/sdk/XuqmSDK.kt | 35 +++++++++++++++++++ .../sdk/internal/XuqmInitializerProvider.kt | 4 ++- 3 files changed, 49 insertions(+), 5 deletions(-) diff --git a/sdk-bugcollect/src/main/java/com/xuqm/sdk/bugcollect/internal/BugCollectInitProvider.kt b/sdk-bugcollect/src/main/java/com/xuqm/sdk/bugcollect/internal/BugCollectInitProvider.kt index 005a10e..f320718 100644 --- a/sdk-bugcollect/src/main/java/com/xuqm/sdk/bugcollect/internal/BugCollectInitProvider.kt +++ b/sdk-bugcollect/src/main/java/com/xuqm/sdk/bugcollect/internal/BugCollectInitProvider.kt @@ -31,15 +31,22 @@ internal class BugCollectInitProvider : ContentProvider() { override fun onCreate(): Boolean { val ctx = context?.applicationContext ?: return true - if (!XuqmSDK.isInitialized()) { - Log.w("BugCollect", "BugCollectInitProvider: XuqmSDK not initialized, skipping") + // ── Phase 1:注册崩溃拦截器(只需 appKey,无需 SDK 完全初始化)────────── + // SDK 可能正在后台初始化中,直接读取 config 文件获取 appKey + val appKey = if (XuqmSDK.isInitialized()) { + XuqmSDK.appKey + } else { + XuqmSDK.readAppKey(ctx) + } + + if (appKey.isNullOrBlank()) { + Log.w("BugCollect", "BugCollectInitProvider: no appKey available, skipping") return true } - // ── Phase 1:立即注册拦截器,只需 appKey,无需 URL ────────────────────── CrashCapture.start( appContext = ctx, - appKey = XuqmSDK.appKey, + appKey = appKey, getUserId = { XuqmSDK.getUserId() ?: XuqmSDK.deviceId }, ) diff --git a/sdk-core/src/main/java/com/xuqm/sdk/XuqmSDK.kt b/sdk-core/src/main/java/com/xuqm/sdk/XuqmSDK.kt index 308b5a3..1844e8d 100644 --- a/sdk-core/src/main/java/com/xuqm/sdk/XuqmSDK.kt +++ b/sdk-core/src/main/java/com/xuqm/sdk/XuqmSDK.kt @@ -78,6 +78,14 @@ object XuqmSDK { * 配置文件包含 `appKey` 和可选的 `serverUrl`(私有化部署平台地址)。 * App 无需调用任何初始化代码。 */ + /** + * 仅读取 config 文件中的 appKey,不做任何初始化。 + * 用于 ContentProvider 等需要快速获取 appKey 的场景。 + */ + fun readAppKey(context: Context): String? { + return runCatching { ConfigFileReader.read(context.applicationContext)?.appKey }.getOrNull() + } + fun autoInitialize(context: Context, logLevel: LogLevel = LogLevel.WARN) { val configFile = ConfigFileReader.read(context) ?: throw IllegalStateException( @@ -94,6 +102,33 @@ object XuqmSDK { initialize(context, configFile.appKey, configFile.serverUrl, logLevel) } + /** + * 异步自动初始化 — ContentProvider 调用,不阻塞主线程。 + * 同步阶段只读取 config 文件(~5ms),TokenStore / DeviceId / ApiClient 等重活移到 IO 线程。 + */ + fun autoInitializeAsync(context: Context, logLevel: LogLevel = LogLevel.WARN) { + val ctx = context.applicationContext + // 同步:读取 config(快,<10ms) + val configFile = ConfigFileReader.read(ctx) + if (configFile == null) { + Log.w("XuqmSDK", "autoInitializeAsync: no config file, skipping") + return + } + val configPackageName = configFile.packageName + if (!configPackageName.isNullOrBlank() && configPackageName != ctx.packageName) { + Log.w("XuqmSDK", "autoInitializeAsync: package name mismatch, skipping") + return + } + // 异步:TokenStore / DeviceId / ApiClient / 远端配置 + kotlinx.coroutines.CoroutineScope(kotlinx.coroutines.Dispatchers.IO + kotlinx.coroutines.SupervisorJob()).launch { + runCatching { + initialize(ctx, configFile.appKey, configFile.serverUrl, logLevel) + }.onFailure { e -> + Log.w("XuqmSDK", "autoInitializeAsync background init failed: ${e.message}") + } + } + } + /** * 方式 B:手动初始化。 * diff --git a/sdk-core/src/main/java/com/xuqm/sdk/internal/XuqmInitializerProvider.kt b/sdk-core/src/main/java/com/xuqm/sdk/internal/XuqmInitializerProvider.kt index 819af2d..e0fc111 100644 --- a/sdk-core/src/main/java/com/xuqm/sdk/internal/XuqmInitializerProvider.kt +++ b/sdk-core/src/main/java/com/xuqm/sdk/internal/XuqmInitializerProvider.kt @@ -15,9 +15,11 @@ import com.xuqm.sdk.XuqmSDK class XuqmInitializerProvider : ContentProvider() { override fun onCreate(): Boolean { val ctx = context?.applicationContext ?: return true + // 同步阶段只做最小工作:读取 config 文件设置 appKey(约 5ms) + // TokenStore / DeviceId / ApiClient 等重初始化移到后台线程 runCatching { if (!XuqmSDK.isInitialized()) { - XuqmSDK.autoInitialize(ctx) + XuqmSDK.autoInitializeAsync(ctx) } }.onFailure { e -> Log.w("XuqmSDK", "Auto-initialization skipped: ${e.message}")