CHANGELOG.md 8.5 KB

Jigsort Solitaire

拼图游戏

1.1.0 (开发中)

� 启动与体验优化

优化第三方 SDK 初始化与原生闪屏体验 (AppLovin & FCM)

  • 问题: 用户首次开启应用时,会先进入游戏界面 home_screen ,随后再触发 AppLovin 原生的全屏合规弹窗(Terms & Conditions),导致游戏观感被生硬打断;同时应用中存在 flutter_native_splash 原生闪屏与内部自定义 Loading 页相互交叠的问题。
  • 重构与优化方案:
    1. 净化 home_screen,彻底移除侵入性的第三方 SDK 初始化代码(解耦业务与基础服务),并去除了多余的内部过渡页逻辑。
    2. main.dart 启动时,使用 FlutterNativeSplash.preserve() 从底层主动接管并冻结设备的原生闪屏。
    3. 将包含阻塞性 UI(如 GDPR/合规询问框)的 AppLovin 初始化、FCM 和 Adjust 前置汇总至顶层引导流程。在未点完原生弹窗或超时前,底部始终由启动图保护掩盖。
    4. 一切准备就绪后,调用 FlutterNativeSplash.remove(),瞬间露出加载完备的游戏大厅。
  • 预期影响: 彻底解决第三方大屏广告合规授权首读时“糊主界面突兀感”,摒弃原有的套壳多重闪屏体验,在提高首次运行流畅平滑度的同时,100% 保留隐私合规安全性。

�🐛 崩溃和稳定性修复

动画系统空值检查 (Crashlytics Fix)

  • 问题: 页面销毁时,动画 frame callback 仍在队列中执行,导致访问已被 null 的 board 对象
  • 错误: Null check operator used on a null value at board_play.dart:580
  • 修复: 在所有 animation listener 方法中添加 board == null 检查
    • _moveAnimationListener()
    • _successAnimationListener()
    • _dealingAnimationListener() / _dealingAnimationStatusListener()
    • _flipAnimationListener() / _flipAnimationStatusListener()
    • _mergeAnimationListener() / _mergeAnimationStatusListener()
    • _prepareAnimationListener() / _prepareAnimationStatusListener()
  • 预期影响: 消除动画相关的 null pointer crash(影响低端设备)

修复发牌音效定时器 _totalDealingDuration 空指针崩溃 (Crashlytics Fix)

  • 问题: 在 board_play.dart 中,发牌动画启动 Timer.periodic 播放音效,闭包异步引用了 _totalDealingDuration。当用户在动画期间退出关卡导致页面销毁、board 置空时,获取 board!.pieces.length 抛出 Null check operator used on a null value
  • 错误: Null check operator used on a null value at _BoardPlayState._totalDealingDuration(board_play.dart:709)
  • 修复:
    1. 缓存时长变量:在启动 Timer.periodic 前,用局部变量缓存计算结果,隔离由于计时器异步执行导致的对上下文内生命周期的访问。
    2. 定时器生命周期判断:在定时器回调中增加 !mounted 判断并立刻 timer.cancel()
    3. Get 方法空安全:在 _totalDealingDuration 的 get 方法中增加 board == null 兼容。

Moloco VastActivity 初始化 (AndroidManifest Fix)

  • 问题: Moloco SDK VastActivity 启动时,context 未被初始化
  • 错误: kotlin.UninitializedPropertyAccessException: lateinit property context has not been initialized
  • 修复方案:
    1. 升级 Moloco Adapter: 3.0.0.0 → 3.1.0.0
    2. 强化 ProGuard 规则,防止混淆 service_locator 和 xenoss 包
  • 预期影响: 消除 Moloco mediation SDK 的初始化失败

过滤网络图片加载引起的伪致命崩溃 (ImageStream Fix)

  • 问题: 用户网络抖动或代理切断连接时,底层的 ImageStreamCompleter 抛出异常,进而被 FlutterError.onError 无差别捕获并上报为致命崩溃(Fatal Exception)
  • 错误: FlutterError: ClientException: Software caused connection abort / Exception: Downloaded data is too small
  • 修复:
    1. 抽取共用的 isEnvIssue() 网络探针逻辑
    2. 新增对 'Software caused connection abort''Downloaded data is too small' 字眼的豁免判断
    3. 拦截 FlutterError.onError,将渲染层级捕获到的网络/资源加载异常过滤并只记为 Warning,阻止其调用 recordFlutterFatalError
  • 预期影响: 净化由于单纯网络不稳定引起的 Crash 虚高,保持后台错误板数据的真实性和准确性(不再将无害的网络断流视为应用闪退)

📊 设备兼容性增强

智能设备黑名单系统

  • 问题分析: Crash 和 ANR 集中在特定低端设备上:
    • Crash 设备: Samsung A系列(Exynos GPU缺陷)/ Vivo 系列 / Redmi / MediaTek 低端机
    • ANR 设备: ROM 臃肿的手机(HORNOR / Zuum 等)
    • 非手机设备: JVC / TCL 等被误装的 TV/平板
  • 新增 Remote Config 参数:

    ad_crash_prone_devices         # Crash 高发设备(完全禁用广告)
    ad_anr_prone_devices           # ANR 高发设备(禁用广告以防主线程阻塞)
    non_phone_devices              # 非手机设备(限制某些广告功能)
    
  • 默认黑名单(可通过 Firebase Console 远程更新):

    ad_crash_prone_devices=
    "samsung a21s,samsung a31,samsung a12,redmi lancelot,oppo op4efdl1,vivo 2015,vivo 2111,huawei,infinix,motorola borag,motorola hawaiip"
    ad_anr_prone_devices=
    "hornor hngfy-m,zuum covet,vivo 1820"
    non_phone_devices=
    "jvc,tcl,transformer"
    
  • ApplovinAdsController 增强:

    • 新增 _isAnrProneDevice 标记
    • 新增 _isNonPhoneDevice 标记
    • 优化 _shouldSkipAds() 逻辑,统一判断是否跳过所有广告
    • 增强日志输出(更清晰的 Crash/ANR/非手机设备识别)
  • 预期影响:

    • Samsung A12/A21s/A31 crash 率降低 70-80%
    • ANR 高发设备的主线程阻塞显著减少
    • 避免 TV/平板 上的适配性问题

🧹 技术债务清理

  • 规范化设备检测日志(使用 emoji 标记严重程度)
  • 整合设备黑名单管理(从多个地方统一到 Remote Config + ApplovinAdsController)
  • 完善 dispose 流程中的资源释放顺序

📝 文档更新

  • 更新 MEMORY_OPTIMIZATION_GUIDE.md,补充设备黑名单管理章节
  • 添加设备兼容性问题排查指南

1.0.9+9

1.0.8+8 2026-01-29

性能优化

  • 切换渲染引擎为skia,性能比impeller略差,但较稳定
  • 优化预加载逻辑,解决冷启动卡顿率高的问题
  • 阶梯图片质量机制(三种阶梯宽度,分别为1200, 1800, 2400),低端手机采用1200,高端手机1800,平板2400, 避免直接使用原图,分辨率过大的原图进入渲染管道应是导致低端手机crash的主要原因
  • 优化 jc_audio_player, 引入线程池处理 SoundPool 播放,不堵塞UI主线程,解决发牌高频音效触发导致的ANR。
  • banner广告优化,Key 隔离,减少潜在风险
  • 修复切换到任务列表,背景音乐pause后又再次播放的bug, 提升了应用前后台切换性能(main.dart中使用了GlobalKey的原因)
  • 其他优化

1.0.9+9

  • 进入拼图初始化优化, 如果图片损坏,自动删除磁盘缓存并尝试重新下载,避免锁死在这一关
  • download优化,增加防抖;缓存文件写入优化, 先写入tmp文件,再重命名,保证是原子操作,避免写入“半截”文件的可能性
  • "下一关"按钮防抖和安全pop up优化(根据firebase报错的修改)
  • 内存分级, 低内存设备不展示banner广告
  • 启动优化, 启动main中所有堵塞性的await, 改为立即启动ui,后台并行初始化firebase,本地存储等await动作; 广告延迟加载,分散启动压力
  • home page 页面优化, 采用recorder预录制方案优化绘制性能,优化发牌动画, 大幅减少 ui jank
  • 资源竞争优化:
    1. 关卡结束点击next, 立即释放资源pop up返回主页再播放插屏, 而不是在play页面播放完插屏广告再返回,这样的好处是可以立即释放play页面资源,为插屏广告腾出内存空间。 用户体验也会更好,广告结束直接就在首页,不会闪;
    2. 页面切换或退出, 手动销毁banner广告
    3. 游戏界面延迟2秒加载banner,刚进入play时各种初始化发牌翻牌动画, 资源比较紧张, 如果叠加banner渲染,容易造成竞争
  • 黑名单机制: hisense, itel, huawei y9 等高频ANR设备列入黑名单, 不展示广告。 (配合firebase remote config 使用支持以远程配置, 增加配置参数 ad_crash_prone_devices, 格式为逗号分隔的设备名称(如 "hisense,itel,huawei y9") )
  • 低端机的不启用自适应 Banner,因其渲染开销较大