XuqmGroup
50effbb274
fix(bugcollect-plugin): always inject xuqmBuildId manifest placeholder for all variants
...
The placeholder was only set when minifyEnabled=true, causing debug builds
to fail with "no value for <xuqmBuildId> is provided". Moved buildId
injection before the minify guard; mapping upload task registration stays
after it.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 11:12:49 +08:00
Jenkins CI
3554cbdf31
ci: bump module versions [sdk-bugcollect,sdk-bugcollect-plugin]
2026-06-23 11:08:19 +08:00
XuqmGroup
9d4de920a4
fix(bugcollect): 使用 manifest meta-data 传递 buildId,修复 namespace/applicationId 不一致导致反射失败
...
BuildConfig 反射方案在 applicationId 与 namespace 不同时(如 shijiaobao flavor)会抛出
ClassNotFoundException 导致 buildId=null。改为通过 manifestPlaceholders 注入 xuqmBuildId,
SDK 从 PackageManager.getApplicationInfo(GET_META_DATA) 读取,彻底绕开包名歧义。
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 17:50:16 +08:00
XuqmGroup
06f7b9d44d
feat(bugcollect): 为每次打包生成独立 buildId,支持相同版本多包溯源
...
- Gradle 插件在配置阶段生成 yyyyMMddHHmmss 格式的 buildId,通过
BuildConfig.XUQM_BUILD_ID 注入 APK,并作为 buildId 字段上传 sourcemap
- SDK 通过反射读取 BuildConfig.XUQM_BUILD_ID,在所有事件
(captureError/captureCrash/warn) 的 IssueEvent 中携带 buildId
- LogUploader 序列化时将 buildId 写入上报 JSON
- IssueEvent 新增 buildId 可选字段
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 16:46:41 +08:00
XuqmGroup
8e0193ceec
fix: BugCollect.buildDeviceInfo 和 appVersion 在 SDK 未初始化时安全降级
...
Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-19 02:17:26 +08:00
XuqmGroup
04eb0d13d3
fix: BugCollect.captureError 在 SDK 未初始化时不再崩溃
...
- captureError 检查 XuqmSDK.isInitialized() 再访问 appKey
- SDK 未初始化时将错误加入待处理队列,初始化后自动 flush
- captureCrash 也添加 isInitialized 检查
Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-19 02:05:06 +08:00
XuqmGroup
79463a5808
feat(core): 添加请求签名功能并扩展更新接口
...
- 在 SDKConfig 中新增 signingKey 配置项
- 在 ConfigFile 中添加 signingKey 序列化支持
- 实现 API 客户端请求签名拦截器,支持 HMAC-SHA256 签名
- 在 XuqmSDK 中管理 signingKey 的存储和读取
- 扩展 UpdateApi 接口增加 currentVersionName 参数
- 在 UpdateSDK 中集成设备信息和版本号上报功能
- 为 RN SDK 添加签名密钥管理和 HTTP 请求签名注入
- 实现跨平台的 HMAC-SHA256 签名算法支持
2026-06-19 01:27:56 +08:00
XuqmGroup
e3d03c0ea7
feat: 统一 deviceId 来源,所有 SDK 模块使用 XuqmSDK.deviceId
...
- DeviceUtils.getDeviceId() 统一委托 XuqmSDK.deviceId
- sdk-license: DeviceInfoProvider 改用 DeviceUtils
- sdk-push: 所有 getDeviceId(context) 改为 getDeviceId()
- sdk-update: checkUpdate 增加 deviceId/model/osVersion/vendor 参数
- DeviceUtils 新增 getDeviceInfo() 返回完整设备信息 Map
2026-06-18 23:37:59 +08:00
XuqmGroup
fd37f57fbf
feat(sdk-core): deviceId 优先使用 ANDROID_ID,卸载重装后仍可识别设备
...
- 优先读取 Settings.Secure.ANDROID_ID(绑定设备,非应用)
- 过滤已知无效值(9774d56d682e549c 等)
- ANDROID_ID 前缀 aid_ 区分来源
- 回退到随机 UUID(恢复出厂设置等场景)
2026-06-18 22:00:26 +08:00
Jenkins CI
5d1b07b997
ci: bump module versions [sdk-core,sdk-webview,sdk-bugcollect,sdk-bugcollect-plugin]
2026-06-18 21:22:59 +08:00
XuqmGroup
ffafd94a1e
chore(bugcollect): 清理调试日志,准备发布正式版本
2026-06-18 21:15:55 +08:00
XuqmGroup
84c9eb5e7a
fix(bugcollect): 修复上传流程 - pendingErrors 队列、动态 URL、相对路径补全
2026-06-18 20:12:00 +08:00
XuqmGroup
8d0dd0a41d
debug: uploadIssues 日志改为 Log.w
2026-06-18 19:45:14 +08:00
XuqmGroup
35bf96f89f
debug(bugcollect): 添加 uploadIssues 日志
2026-06-18 19:40:29 +08:00
XuqmGroup
64580b4b9e
debug(bugcollect): 添加 flush 日志排查上传流程
2026-06-18 19:36:17 +08:00
XuqmGroup
3f03f5c1de
fix(bugcollect): 平台配置下发后延迟重试 flush,修复事件丢失
...
- startCrashCapture 后延迟检查 bugCollectApiUrl,就绪后再次 flush
- 添加调试日志帮助排查上传流程
2026-06-18 19:29:18 +08:00
XuqmGroup
ceaaeca1fe
fix(bugcollect): LogQueue 动态获取 bugCollectApiUrl,修复上传 URL 为空问题
...
- LogQueue.logApiUrl 改为动态 getter,每次上传取最新 URL
- flush() 在 URL 为空时跳过,等下次定时 flush
- LogUploader.resolveUrl 自动补全相对路径
2026-06-18 19:16:02 +08:00
XuqmGroup
d742317c4d
fix(bugcollect): LogUploader 自动将相对路径补全为绝对 URL
...
- bugCollectApiUrl 为相对路径时,基于 XuqmSDK.platformUrl 拼接完整地址
- 修复 'Expected URL scheme http or https' 异常
2026-06-18 19:06:03 +08:00
XuqmGroup
3ded960383
fix(bugcollect): captureError 在 SDK 未就绪时暂存事件,就绪后自动 flush
...
- 添加 pendingErrors 队列,SDK 未初始化时 captureError 不再丢弃事件
- startCrashCapture 完成后自动 flush 暂存事件到上传队列
2026-06-18 18:56:37 +08:00
XuqmGroup
d5ce5ffabb
refactor(bugcollect): 移除 BugCollectInitProvider 减少框架开销
...
- 移除了 BugCollectInitProvider ContentProvider
- 改为通过 XuqmSDK afterInit 回调注册崩溃拦截器
- 消除了约 380ms 的 ContentProvider 框架启动开销
- 确保在 SDK 初始化完成后注册 UncaughtExceptionHandler
2026-06-18 17:07:12 +08:00
XuqmGroup
2b1857a8ff
fix(sdk-core): initBugCollect 反射调用 Kotlin object 需传单例实例
2026-06-18 17:01:21 +08:00
XuqmGroup
e180003386
fix(sdk-bugcollect): BugCollectInitProvider 添加 CrashCapture import
...
Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-18 16:25:35 +08:00
XuqmGroup
2c610b777d
fix(sdk-core): 修复编译错误 — KDoc 转义 + MasterKeys API
...
- ConfigFileReader: KDoc 中 *.xuqmconfig 改为 \*.xuqmconfig(避免 */ 被解析为注释结束)
- ConfigCache: MasterKey → MasterKeys(兼容当前 security-crypto 版本)
Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-18 16:04:57 +08:00
XuqmGroup
b7c7a2c385
perf(sdk-core): 合并 ContentProvider + PBKDF2 缓存,冷启动从 ~350ms 降到 ~7ms
...
优化内容:
- 新增 XuqmMergedProvider:合并 3 个 Provider 为 1 个,主线程只读文件字节
- 新增 ConfigCache:EncryptedSharedPreferences 持久化缓存解密结果
- ConfigFileReader 新增 readRawBytes() / readWithCache(),单例内存缓存
- XuqmSDK 新增 autoInitializeFromBytes():IO 线程完成解密+初始化
- BugCollectInitProvider 改为兼容 fallback,检查 isInitialized() 跳过
- XuqmInitializerProvider 标记 @Deprecated
性能对比:
优化前:主线程 ~350ms(PBKDF2 + 文件扫描 + 3 个 Provider 实例化)
优化后:主线程 ~7ms(文件发现 + 读字节),后续启动 ~3ms(读缓存)
Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-18 15:58:53 +08:00
XuqmGroup
1f1c0b4018
docs(readme): 更新文档说明新增日志监控模块
...
- 添加 sdk-bugcollect 模块说明及其功能描述
- 增加日志监控模块的依赖配置示例
- 更新初始化说明,区分自动初始化和手动初始化两种方式
- 添加推荐的配置文件自动初始化方式说明
2026-06-18 15:41:09 +08:00
XuqmGroup
6a5bfd1c10
fix(sdk-core): ConfigFileReader KDoc 注释中 */ 导致编译失败,转义为 \*
2026-06-18 15:30:09 +08:00
XuqmGroup
75c1d77965
feat(sdk-core): ConfigFileReader 新增 assets/config/ 目录支持
...
对齐 RN SDK 的 src/assets/config/ 目录约定:
搜索顺序:config/config.xuqmconfig → config/*.xuqmconfig → xuqm/config.xuqm → xuqm/*.xuqmconfig
旧路径 assets/xuqm/ 保持兼容。
Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-18 15:06:40 +08:00
XuqmGroup
ba6de0a5fd
perf(sdk): ContentProvider 异步初始化,减少冷启动阻塞时间
...
- XuqmInitializerProvider 改用 autoInitializeAsync(),TokenStore/DeviceId/ApiClient 移到 IO 线程
- XuqmSDK 新增 readAppKey() 公开方法,仅读取 config 不做初始化
- BugCollectInitProvider 适配异步初始化,直接读取 appKey 注册崩溃拦截器
- 同步阶段只做 config 文件读取(~5ms),主线程不再阻塞
2026-06-18 14:53:34 +08:00
XuqmGroup
0ec173677d
feat(webview): 添加 onProgressChanged 回调,支持页面加载进度监听
2026-06-18 14:05:43 +08:00
XuqmGroup
30ce89afcc
fix(file): 公共 Downloads 使用 MediaStore 写入,兼容华为设备
...
- Android 10+ 公共目录通过 MediaStore ContentResolver 写入
- 同时写入缓存文件供 openFile 使用
- 避免华为设备 mkdirs()/writeBytes() ENOENT 问题
2026-06-18 13:56:35 +08:00
XuqmGroup
d2873eda66
refactor(file): download 方法复用 resolveBaseDir,统一目录创建逻辑
2026-06-18 13:50:48 +08:00
XuqmGroup
a6b1905a66
fix(file): resolveBaseDir 多重尝试创建目录,兼容华为/小米设备
...
- mkdirs() 静默失败时,尝试 Runtime.exec('mkdir -p')
- 仍失败则回退到 Sandbox 目录,避免 ENOENT 崩溃
2026-06-18 13:50:14 +08:00
XuqmGroup
aeeba4fac8
feat(webview): 添加 onPageError 回调,支持页面加载失败检测
...
- XWebViewConfig 新增 onPageError(errorCode, description, failingUrl) 回调
- WebViewClient.onReceivedError 捕获主框架加载错误并回调
- App 层可据此显示重试 UI
2026-06-18 13:43:56 +08:00
XuqmGroup
d015fd7d40
fix(ci): 版本信息用逗号分隔,避免 Windows 管道符冲突
2026-06-18 12:59:05 +08:00
XuqmGroup
f797ec48d3
fix(ci): post 块中用 script 包裹 Groovy 变量声明
2026-06-18 12:48:30 +08:00
XuqmGroup
3e788e1c4e
fix(ci): 转义 PUBLISHED_VERSIONS 换行符,避免 Windows bat 解析多命令
2026-06-18 12:37:42 +08:00
XuqmGroup
6f216bc4c2
fix(ci): SNAPSHOT 版本基于下一版本号,避免与已发布的 release 冲突
...
- SNAPSHOT 模式:bumpVersion(baseVer) + '-SNAPSHOT',确保高于当前 release
- 解决 Gradle 解析 SNAPSHOT 时优先使用同版本号 release 的问题
2026-06-18 12:23:51 +08:00
XuqmGroup
f0276bb440
feat(webview): 添加blob下载功能并完善存储权限处理
...
- 添加pendingBlobDownload状态管理blob下载请求
- 实现API 30+系统上MANAGE_EXTERNAL_STORAGE权限检查
- 添加blob数据解码和文件保存功能
- 集成下载完成事件分发机制
- 完善存储权限对话框中的状态清理逻辑
- 实现blob下载成功后的相册保存或文件打开操作
2026-06-18 11:52:02 +08:00
XuqmGroup
aca0d009a8
feat(bugcollect): 使用 deviceId 作为 userId 兜底,保障影响设备数统计
...
- XuqmSDK 新增 deviceId 属性:首次生成 UUID 存入 SharedPreferences,后续不变
- BugCollect 上报事件时 userId 改为 getUserId() ?: deviceId,未登录也能统计影响设备数
- BugCollectInitProvider 崩溃拦截同步使用 deviceId 兜底
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 10:47:38 +08:00
XuqmGroup
77fef3a38b
refactor(bugcollect): 注册与 URL 完全解耦
...
注册 UncaughtExceptionHandler 不需要 URL:
- CrashCapture.start 移除 logApiUrl 参数,只需 appContext + appKey
- LogStorage.saveCrash 移除 logApiUrl,崩溃文件不再存储 URL
- LogQueue.uploadPendingCrashes 上传时直接取 XuqmSDK.bugCollectApiUrl,
URL 为 null 则跳过(下次启动重试),不依赖崩溃文件里的历史 URL
- BugCollect.startCrashCapture 移除 URL 构造逻辑
- BugCollectInitProvider Phase 1 纯粹只注册,彻底消除对 platformUrl 的依赖,
版本兼容问题从根本上消失
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 10:18:08 +08:00
XuqmGroup
be8eeba9e1
fix(bugcollect): BugCollectInitProvider 对旧版 sdk-core 防御降级
...
platformUrl 是新增属性,旧版 sdk-core 没有对应的 getPlatformUrl()。
改用 runCatching 包住调用,NoSuchMethodError 时记录警告、跳过崩溃拦截,
不再因版本不一致导致 app 启动崩溃。
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 10:16:05 +08:00
XuqmGroup
54b3163f53
refactor(bugcollect): 崩溃收集与上传分离,sdk-core 保持独立
...
设计问题:
- 之前用反射在 XuqmInitializerProvider 里调用 BugCollect,sdk-core 隐式依赖 sdk-bugcollect
- startCrashCapture 同时负责注册拦截器和触发上传,两者生命周期不同
新架构:
- sdk-core 完全干净,XuqmInitializerProvider 还原为只调用 autoInitialize
- sdk-bugcollect 自注册 BugCollectInitProvider(initOrder=89)
- Phase 1(同步):core init 完成后立即注册 UncaughtExceptionHandler,用
platformUrl 派生兜底 URL,落盘不依赖远端配置
- Phase 2(异步):awaitInitialization() 后用最新 bugCollectApiUrl 上传积压崩溃
- BugCollect.uploadPendingCrashes() 公开,供 Phase 2 调用
- startCrashCapture() 保持幂等,app 侧可选择性调用,不影响自动流程
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 10:11:08 +08:00
XuqmGroup
cc1557daf0
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>
2026-06-18 10:05:43 +08:00
XuqmGroup
e300cbdb83
fix(bugcollect): 修复崩溃文件未写入导致 fatal crash 不上报的 bug
...
根本原因:CrashCapture 调用无 Context 的 LogStorage.saveCrash 重载,
该重载通过反射获取 packageName 失败时返回空字符串,
导致崩溃文件路径变为 /data/data//files/xuqm_crashes(无效),
mkdirs() 静默失败,崩溃文件未写入,下次启动无数据可上报。
修复:
- CrashCapture.start() 新增 appContext: Context 参数
- 改为调用带 Context 的 saveCrash 重载,依赖 context.filesDir 获取可靠路径
- BugCollect.startCrashCapture() 传入 XuqmSDK.appContext
- LogStorage 删除不可靠的无 Context 重载及 getPackageName() 反射代码
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 09:43:47 +08:00
XuqmGroup
58d479523e
fix: uniquePropNames 去重逻辑修复,避免重复 bump 版本
2026-06-17 19:14:37 +08:00
Jenkins CI
0a93127f01
ci: bump module versions [sdk-bugcollect,sdk-bugcollect-plugin]
2026-06-17 19:09:09 +08:00
XuqmGroup
76ce61b06d
ci: sdk-bugcollect-plugin 随 sdk-bugcollect 自动联动,移除独立参数
2026-06-17 19:06:27 +08:00
Jenkins CI
5499376a08
ci: bump module versions [sdk-bugcollect]
2026-06-17 19:01:44 +08:00
Jenkins CI
ffcebf504a
ci: bump module versions [sdk-bugcollect-plugin]
2026-06-17 18:53:09 +08:00
XuqmGroup
229de4d498
fix: bugcollect-plugin Java 17 → 21(Jenkins agent 已有 Java 21)
2026-06-17 18:51:59 +08:00