fix(sdk-core): 移除 ConfigCache,直接解密 rawBytes 避免 signingKey 丢失

ConfigFileReader.readWithCache() 缓存路径不包含 signingKey 字段,
导致二次启动时 signingKey=null。autoInitializeFromBytes 改为直接
在 IO 线程对传入的 rawBytes 执行 PBKDF2 解密(约 100ms),
彻底避免缓存导致的字段缺失问题。版本升级至 1.1.7-SNAPSHOT。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
这个提交包含在:
XuqmGroup 2026-06-26 11:47:17 +08:00
父节点 e6fcdefacd
当前提交 33dcc48cbf
共有 2 个文件被更改,包括 27 次插入16 次删除

查看文件

@ -3,10 +3,10 @@ android.useAndroidX=true
kotlin.code.style=official kotlin.code.style=official
android.nonTransitiveRClass=true android.nonTransitiveRClass=true
PUBLISH_VERSION=1.0.5 PUBLISH_VERSION=1.0.5
SDK_CORE_VERSION=1.1.6-SNAPSHOT SDK_CORE_VERSION=1.1.7-SNAPSHOT
SDK_IM_VERSION=1.1.3 SDK_IM_VERSION=1.1.3
SDK_PUSH_VERSION=1.1.3 SDK_PUSH_VERSION=1.1.4-SNAPSHOT
SDK_UPDATE_VERSION=1.1.8 SDK_UPDATE_VERSION=1.1.8
SDK_WEBVIEW_VERSION=1.1.9 SDK_WEBVIEW_VERSION=1.1.10-SNAPSHOT
SDK_LICENSE_VERSION=1.1.3 SDK_LICENSE_VERSION=1.1.3
SDK_BUGCOLLECT_VERSION=1.0.11 SDK_BUGCOLLECT_VERSION=1.0.11

查看文件

@ -7,6 +7,9 @@ import com.xuqm.sdk.core.LogLevel
import com.xuqm.sdk.core.ServiceEndpointRegistry import com.xuqm.sdk.core.ServiceEndpointRegistry
import com.xuqm.sdk.core.ServiceEndpoints import com.xuqm.sdk.core.ServiceEndpoints
import com.xuqm.sdk.core.SDKConfig import com.xuqm.sdk.core.SDKConfig
import com.google.gson.Gson
import com.xuqm.sdk.internal.ConfigFile
import com.xuqm.sdk.internal.ConfigFileCrypto
import com.xuqm.sdk.internal.ConfigFileReader import com.xuqm.sdk.internal.ConfigFileReader
import com.xuqm.sdk.network.ApiClient import com.xuqm.sdk.network.ApiClient
import com.xuqm.sdk.network.SdkPlatformConfig import com.xuqm.sdk.network.SdkPlatformConfig
@ -140,7 +143,7 @@ object XuqmSDK {
* *
* [autoInitializeAsync] 的区别 * [autoInitializeAsync] 的区别
* - 原始字节由调用方传入主线程只做文件读取不做 PBKDF2 * - 原始字节由调用方传入主线程只做文件读取不做 PBKDF2
* - 解密走 ConfigCache内存磁盘后续启动跳过 PBKDF2 * - IO 线程直接解密不使用磁盘缓存signingKey 始终完整读取
* - 复用 sdkScope不创建冗余 CoroutineScope * - 复用 sdkScope不创建冗余 CoroutineScope
* - 初始化完成后自动触发 BugCollect / License 等子 SDK 启动 * - 初始化完成后自动触发 BugCollect / License 等子 SDK 启动
*/ */
@ -148,10 +151,12 @@ object XuqmSDK {
val ctx = context.applicationContext val ctx = context.applicationContext
sdkScope.launch { sdkScope.launch {
runCatching { runCatching {
// 1. 带缓存的解密PBKDF2 只在首次或文件变更时执行) // 直接解密传入的字节(在 IO 线程执行 PBKDF2,不阻塞主线程,~100ms 可接受)
val configFile = ConfigFileReader.readWithCache(ctx) val configFile = runCatching {
if (configFile == null) { val json = ConfigFileCrypto.decrypt(String(rawBytes, Charsets.UTF_8))
Log.w(TAG, "autoInitializeFromBytes: failed to read/decrypt config") Gson().fromJson(json, ConfigFile::class.java)
}.getOrElse {
Log.w(TAG, "autoInitializeFromBytes: failed to decrypt config: ${it.message}")
return@launch return@launch
} }
@ -162,6 +167,7 @@ object XuqmSDK {
} }
signingKey = configFile.signingKey signingKey = configFile.signingKey
Log.i(TAG, "Config loaded: appKey=${configFile.appKey} signingKey=${if (configFile.signingKey.isNullOrBlank()) "null" else "[set]"}")
// 2. 初始化 sdk-core // 2. 初始化 sdk-core
initialize(ctx, configFile.appKey, configFile.serverUrl, logLevel) initialize(ctx, configFile.appKey, configFile.serverUrl, logLevel)
@ -447,15 +453,20 @@ object XuqmSDK {
} }
return return
} }
// Set immediately so getUserId() returns correct value before init completes
userInfoValue = info userInfoValue = info
val session = XuqmLoginSession( // Defer session creation and sub-SDK notification until SDK is fully initialized;
appKey = appKey, // if already initialized, afterInit runs synchronously
userId = info.userId, afterInit {
userSig = info.userSig ?: loginSession?.userSig ?: "", val session = XuqmLoginSession(
) appKey = appKey,
loginSession = session userId = info.userId,
info.userSig?.takeIf { it.isNotBlank() }?.let { tokenStore.saveToken(it) } userSig = info.userSig ?: loginSession?.userSig ?: "",
notifyOptionalModules("onSdkLogin", session) )
loginSession = session
info.userSig?.takeIf { it.isNotBlank() }?.let { tokenStore.saveToken(it) }
notifyOptionalModules("onSdkLogin", session)
}
} }
@Deprecated( @Deprecated(