fix(bugcollect): 修复 fatal crash 不上报——startCrashCapture 从未被调用
根本原因链: 1. XuqmInitializerProvider 只调用 XuqmSDK.autoInitialize,从不调用 startCrashCapture 2. 即使调用,startCrashCapture 检查 bugCollectApiUrl == null 即提前返回; 而 bugCollectApiUrl 由远端配置下发,崩溃发生时往往尚未到达 3. UncaughtExceptionHandler 从未注册,崩溃文件没有写入,下次启动无数据可上报 修复: - XuqmSDK 新增 platformUrl 属性(同步可用,初始化即有值) - BugCollect.startCrashCapture 不再依赖 bugCollectApiUrl, 用 platformUrl + "/api/bugcollect/" 作为兜底 URL 写入崩溃文件 - LogQueue.uploadPendingCrashes 优先使用崩溃文件内保存的 logApiUrl - XuqmInitializerProvider 通过反射调用 BugCollect.startCrashCapture, 在 SDK 初始化后立即注册 UncaughtExceptionHandler Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
这个提交包含在:
父节点
e300cbdb83
当前提交
cc1557daf0
@ -131,11 +131,15 @@ object BugCollect {
|
||||
|
||||
fun startCrashCapture() {
|
||||
if (crashCaptureStarted) return
|
||||
val bugCollectApiUrl = XuqmSDK.bugCollectApiUrl ?: return
|
||||
if (!XuqmSDK.isInitialized()) return
|
||||
// bugCollectApiUrl 由远端配置下发,启动时可能尚未到达。
|
||||
// 用 platformUrl 推导兜底地址:崩溃文件里会保存此 URL,下次启动时用它上报。
|
||||
val logApiUrl = XuqmSDK.bugCollectApiUrl
|
||||
?: (XuqmSDK.platformUrl.trimEnd('/') + "/api/bugcollect/")
|
||||
crashCaptureStarted = true
|
||||
CrashCapture.start(
|
||||
appContext = XuqmSDK.appContext,
|
||||
logApiUrl = bugCollectApiUrl,
|
||||
logApiUrl = logApiUrl,
|
||||
appKey = XuqmSDK.appKey,
|
||||
getUserId = { XuqmSDK.getUserId() },
|
||||
)
|
||||
|
||||
@ -94,7 +94,9 @@ internal class LogQueue(
|
||||
userId = obj.optNullableString("userId"),
|
||||
user = IssueEvent.UserInfo(id = obj.optNullableString("userId")),
|
||||
)
|
||||
LogUploader.uploadIssue(logApiUrl, event)
|
||||
// 优先使用崩溃文件里保存的 URL(崩溃时可能远端配置未到达)
|
||||
val uploadUrl = obj.optString("logApiUrl").takeIf { it.isNotBlank() } ?: logApiUrl
|
||||
LogUploader.uploadIssue(uploadUrl, event)
|
||||
file.delete()
|
||||
}.onFailure { e ->
|
||||
Log.e(TAG, "Failed to upload crash: ${file.name}", e)
|
||||
|
||||
@ -40,6 +40,9 @@ object XuqmSDK {
|
||||
private var initialized = false
|
||||
@Volatile private var initializedAppKey: String? = null
|
||||
@Volatile private var resolvedPlatformUrl: String = DEFAULT_PLATFORM_URL
|
||||
|
||||
/** 初始化时使用的平台地址(同步可用,远端配置到达前即有值)。 */
|
||||
val platformUrl: String get() = resolvedPlatformUrl
|
||||
@Volatile private var loginSession: XuqmLoginSession? = null
|
||||
@Volatile private var userInfoValue: XuqmUserInfo? = null
|
||||
@Volatile var platformConfig: SdkPlatformConfig? = null
|
||||
|
||||
@ -19,12 +19,26 @@ class XuqmInitializerProvider : ContentProvider() {
|
||||
if (!XuqmSDK.isInitialized()) {
|
||||
XuqmSDK.autoInitialize(ctx)
|
||||
}
|
||||
// 在 SDK 初始化后立即启动崩溃捕获,确保任何后续崩溃都能被落盘。
|
||||
// startCrashCapture 内部使用 platformUrl 兜底,无需等远端配置到达。
|
||||
startCrashCaptureIfAvailable()
|
||||
}.onFailure { e ->
|
||||
Log.w("XuqmSDK", "Auto-initialization skipped: ${e.message}")
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
private fun startCrashCaptureIfAvailable() {
|
||||
runCatching {
|
||||
val bugCollect = Class.forName("com.xuqm.sdk.bugcollect.BugCollect")
|
||||
val companion = bugCollect.getField("INSTANCE").get(null)
|
||||
val method = bugCollect.getMethod("startCrashCapture")
|
||||
method.invoke(companion)
|
||||
}.onFailure {
|
||||
// sdk-bugcollect 未依赖时跳过,不影响其他功能
|
||||
}
|
||||
}
|
||||
|
||||
override fun query(uri: Uri, projection: Array<out String>?, selection: String?, selectionArgs: Array<out String>?, sortOrder: String?): Cursor? = null
|
||||
override fun getType(uri: Uri): String? = null
|
||||
override fun insert(uri: Uri, values: ContentValues?): Uri? = null
|
||||
|
||||
正在加载...
在新工单中引用
屏蔽一个用户