chatapp3-flutter/需求进度.md
2026-04-14 14:49:28 +08:00

15 KiB
Raw Blame History

需求进度

当前总目标

  • 控制当前 Flutter Android 发包体积,持续定位冗余组件、超大资源和不合理构建配置,并把每一步处理结果落盘记录。

已完成模块

  • 创建并持续维护进度跟踪文件。
  • 已修复首页房间封面显示链路:兼容接口 roomCover/cover 双字段,并补齐编辑房间成功后的封面内存回写。
  • 完成仓库结构、依赖引用、资源体积和 APK 组成的第一轮排查。
  • 移除 4 个当前未在业务层直接使用的插件依赖:loading_indicator_view_plussocial_sharing_plusflutter_foreground_taskon_audio_query,并清理相关平台声明。
  • 修补 image_cropper 5.0.1 Android 兼容问题,切换到本地 path 依赖以恢复构建。
  • 完成 Android release 签名回退配置,解决仓库缺少 yumi.jks / yumi_debug.jks 时无法继续本地构建分析的问题。
  • 完成 release 包体分析,确认 universal APK 过大主要由多 ABI 与 Agora/Tencent 原生 so 导致。
  • 去除 Gradle 中与 Flutter 冲突的硬编码 abiFilters,确认 --split-per-abi 可以正常产出分架构 APK。
  • 完成 TinyPNG 环境核查,并接入可执行的 Ruby 批量压缩脚本。
  • 已完成 TinyPNG 第一轮批量压缩,sc_images + assets 总量已从 47.25 MB 降到 22.54 MB
  • 已增强 TinyPNG 脚本,支持断点续跑、单文件目标和失败项重试。
  • 已完成 TinyPNG 网络失败项补跑6 张 SSL_connect 异常图片已全部压缩成功。
  • 已完成图片压缩后的 release 复测,确认分 ABI APK 体积继续显著下降。
  • 已切换 Android release 为真正的瘦身模式:开启 minifyshrinkResourceszipAlign
  • 已完成开启瘦身配置后的 Android release 复测,并接入 split-debug-info 保存 Dart symbols。
  • 已生成统一的 Python 打包脚本 scripts/build_release.py,开始接管 AAB、分 ABI APK 与 iOS 包流程。
  • 已完成 scripts/build_release.py 的 Android / iOS 真机冒烟验证,产物归档目录与 manifest 均已生成。
  • 已按当前需求再次完成正式 AAB 出包。
  • 已定位 Google Play 上传阻塞点:当前 AAB 使用的是 Android Debug 证书签名,不是正式 upload key。
  • 已确认当前项目属于“首次上架的新应用”,后续应走 Play App Signing 首发流程,而不是兼容老签名迁移流程。
  • 已梳理 Google Play 首次上架所需的 Play App Signingupload key、重新打包与提审步骤。
  • 已澄清首次生成 upload keystore 时的“密钥库口令”是本地自行设置的密码,与 Google 提供的 deployment_cert.der 证书文件无关。
  • 已为新应用生成正式 upload keystore,并接入工程的 release 签名配置。
  • 已重新打出正式 AAB,并确认其签名已经从 Android Debug 切换到新的 upload key。
  • 已定位 FOREGROUND_SERVICE_MEDIA_PROJECTION 的来源为 Agora full-screen-sharing 依赖,并开始从主 Manifest 覆盖移除。
  • 已移除 FOREGROUND_SERVICE_MEDIA_PROJECTION 相关声明并重新打出正式 AAB
  • 已按当前需求打出正式 arm64-v8a 单架构 APK
  • 已将新的 google-services.json 替换进工程,准备重新打包验证。

进行中模块

  • 评估 iOS 正式签名参数接入后导出 .ipa 的流程。
  • 继续评估 Agora 扩展 so 与 release shrink 策略是否还能进一步裁剪。
  • 评估 12 张 TinyPNG 不支持解码的特殊 webp 是否需要改格式或换工具处理。

关键技术决策

  • 先做高置信度瘦身优先清理未使用插件、ABI 配置和超大图片,暂不贸然删除核心业务能力。
  • 避开仓库中用户已有未提交改动,只改必要文件并持续把结果写入本文件。
  • 包体分析聚焦 release 产物,不被 build/、iOS 中间产物等本地缓存误导。
  • Android 架构裁剪交给 Flutter 构建命令驱动,不再在 Gradle 中硬编码 abiFilters
  • image_cropper 采用本地 path 依赖加最小补丁策略,避免升级带来的业务回归面。
  • Android 签名配置采用条件回退:正式 keystore 不存在时自动回退到 debug 签名,仅用于本地分析验证。
  • 图片压缩优先走 TinyPNG以尽量保持画质稳定失败项按原因分流处理。
  • TinyPNG 的 SSL_connect 视为可重试网络抖动;Image could not be decoded 视为 TinyPNG 对特殊/动图 WebP 的能力边界,先记录不阻塞其余压缩。

已改动文件

  • 需求进度.md
  • lib/services/room/rc_room_manager.dart
  • lib/shared/business_logic/models/res/room_res.dart
  • lib/shared/business_logic/models/res/follow_room_res.dart
  • lib/shared/business_logic/models/res/my_room_res.dart
  • lib/shared/business_logic/models/res/sc_edit_room_info_res.dart
  • lib/shared/business_logic/models/res/join_room_res.dart
  • .gitignore
  • android/key.properties
  • pubspec.yaml
  • pubspec.lock
  • lib/ui_kit/components/dialog/dialog.dart
  • android/app/src/main/AndroidManifest.xml
  • android/app/google-services.json
  • ios/Runner/Info.plist
  • scripts/tinypng_batch.rb
  • scripts/build_release.py
  • tinypng-progress.json
  • tinypng-report.json
  • local_packages/image_cropper-5.0.1-patched/android/src/main/java/vn/hunghd/flutter/plugins/imagecropper/ImageCropperPlugin.java
  • local_packages/image_cropper-5.0.1-patched/
  • android/app/build.gradle.kts
  • android/app/upload-keystore.jks
  • android/app/upload_certificate.pem
  • build/symbols/android/
  • build/symbols/ios/
  • dist/release/smoke-android/
  • dist/release/smoke-ios/
  • sc_images/
  • assets/

已验证结果

  • 当前工作区存在用户已有未提交改动,后续处理均避开覆盖。
  • 首页 party/follow/history/mine 以及房间详情使用的房间封面模型已兼容 roomCovercover 两种返回字段,上传封面后不会再因为字段名不一致掉回空占位。
  • 目录体积排查显示:build/4.7G.dart_tool/347Mios/250Msc_images/48Mlocal_packages/6.1M
  • 当前包体过大的主要原因已经确认:
  • universal APK 带入了 arm64-v8aarmeabi-v7ax86_64 三套 ABI。
  • Agora 与腾讯 IM 原生 so 很大,其中 libagora-rtc-sdk.so 合计约 79.4MBlibImSDK.so 合计约 10.2MB
  • 资源目录中 sc_images/indexsc_images/roomsc_images/personsc_images/splash 是最主要的大图来源。
  • flutter build apk --release --target-platform android-arm64 --analyze-size 已成功执行,当前 universal release APK 约 271MB
  • flutter build apk --release --split-per-abi 已成功执行,压缩前分架构 APK 约为:
  • app-arm64-v8a-release.apk161.4MB
  • app-armeabi-v7a-release.apk138.8MB
  • app-x86_64-release.apk148.6MB
  • loading_indicator_view_plussocial_sharing_plusflutter_foreground_taskon_audio_query 已从当前依赖链路中移除。
  • 当前图片资源统计为 412TinyPNG 两轮处理后总量已从 47.25 MB 降到 22.27 MB,累计节省约 24.99 MB
  • 当前 TinyPNG 已成功压缩 400 张图片,剩余失败 12 张。
  • 当前压缩收益最大的图片包括:
  • sc_images/person/sc_icon_edit_userinfo_bg.png2640776 -> 436823,节省约 2.10 MB
  • sc_images/splash/sc_splash.png2373335 -> 379804,节省约 1.90 MB
  • sc_images/room/sc_icon_room_defaut_bg.png2243222 -> 704696,节省约 1.47 MB
  • sc_images/index/sc_icon_index_bg.png1422169 -> 420635,节省约 0.96 MB
  • 失败项已分型:
  • 12 张为 TinyPNG 无法解码的特殊/动图 webp
  • 当前 TinyPNG 进度与统计文件已落盘:tinypng-progress.jsontinypng-report.json
  • 图片压缩后再次执行 flutter build apk --release --split-per-abi,当前分架构 APK 已下降到:
  • app-arm64-v8a-release.apk135.2MB,比压缩前少 26.2MB
  • app-armeabi-v7a-release.apk112.6MB,比压缩前少 26.2MB
  • app-x86_64-release.apk122.4MB,比压缩前少 26.2MB
  • 可以确认:这轮图片压缩带来的资源收益已经真实反映到最终 APK 体积中。
  • 在开启 minifyshrinkResourceszipAlign 并追加 --split-debug-info=build/symbols/androidAndroid release 继续下降为:
  • app-release.aab181.8MB
  • app-arm64-v8a-release.apk128.7MB,比上一轮 135.2MB 再少 6.5MB
  • app-armeabi-v7a-release.apk105.8MB,比上一轮 112.6MB 再少 6.8MB
  • app-x86_64-release.apk115.8MB,比上一轮 122.4MB 再少 6.6MB
  • build/symbols/android 已生成 3 份符号文件,总计约 14MB,后续可用于 Dart 堆栈还原。
  • scripts/build_release.py --platform android --output-dir dist/release/smoke-android 已验证通过,归档结果为:
  • android/google-play/ 下输出 yumi-v1.0.0-b1-google-play.aab 与 Dart symbols
  • android/local/ 下输出 arm64-v8a.apkarmeabi-v7a.apk
  • android/testing/ 下单独输出 x86_64-test.apk
  • 同时生成 build_manifest.json,已记录产物路径、大小和 sha256
  • scripts/build_release.py --platform ios --output-dir dist/release/smoke-ios 已验证通过,当前无签名模式下输出:
  • ios/archive/yumi-v1.0.0-b1.xcarchive
  • ios/symbols/app.ios-arm64.symbols
  • 当前 iOS 无签名构建会跳过 .ipa 导出;如需正式 .ipa,脚本需追加 --ios-codesign
  • 已将 dist/ 加入 .gitignore,避免打包产物持续污染工作区状态
  • 本轮按需执行 flutter build appbundle --release --split-debug-info=build/symbols/android 已成功,产物为:
  • build/app/outputs/bundle/release/app-release.aab
  • 当前 AAB 体积约 181.8MB
  • 本地校验 app-release.aab 证书后确认:
  • 证书所有者为 C=US, O=Android, CN=Android Debug
  • 当前 AAB 的 SHA16B:72:BF:6F:D1:7A:F2:99:CD:F3:14:EE:18:A6:29:67:F8:05:E6:B4
  • 这说明当前 release 构建仍在回退使用 debug signing无法直接作为 Google Play 正式发布包
  • 已生成新的 upload 证书文件:
  • android/app/upload-keystore.jks
  • android/app/upload_certificate.pem
  • 新 upload key 当前指纹为:
  • SHA1: C1:80:AF:BF:6E:1F:F2:F4:49:58:72:87:A2:BC:54:07:E7:D2:D9:A3
  • SHA256: 81:D6:3A:43:31:FA:83:87:0E:C3:5B:52:B8:C1:05:7C:3A:32:EC:24:37:0B:11:E4:2F:8C:62:4E:D4:AC:0C:3B
  • release 构建已改为从 android/key.properties 读取正式 upload keystore不再依赖当前的 debug 回退配置
  • flutter build appbundle --release --split-debug-info=build/symbols/android 已重新执行,当前正式产物仍为:
  • build/app/outputs/bundle/release/app-release.aab
  • 当前 AAB 体积约 181.8MB
  • 重新校验该 AAB 后,签名者已变为:
  • CN=Yumi Upload, OU=Mobile, O=Yumi, L=Shanghai, ST=Shanghai, C=CN
  • deployment_cert.der 已核实为 Google 侧 app signing 证书,指纹为:
  • SHA1: 3F:E1:78:DC:C3:29:4F:74:20:DF:27:54:CF:AF:46:46:D6:A1:94:78
  • SHA256: F9:BF:D0:89:F9:D7:FD:B2:53:24:A7:DB:59:E1:52:6F:54:A3:93:95:4E:88:7F:1C:4B:D6:03:66:E7:1A:1F:85
  • 已确认当前存在两套不同证书:
  • 本地 upload key:用于你上传 AAB 到 Google Play
  • Google app signing key:用于 Google Play 最终给用户分发签名包
  • FOREGROUND_SERVICE_MEDIA_PROJECTION 在当前 release 合并报告中的来源已确认是 io.agora.rtc:full-screen-sharing:4.5.2
  • 该依赖同时还带入了:
  • io.agora.rtc2.extensions.MediaProjectionMgr$LocalScreenCaptureAssistantActivity
  • io.agora.rtc2.extensions.MediaProjectionMgr$LocalScreenSharingService
  • 主 Manifest 已添加 tools:node="remove" 覆盖规则,准备重新打包验证最终合并结果
  • 重新打包后release manifest merger 报告已显示:
  • uses-permission#android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION
  • REJECTED from [io.agora.rtc:full-screen-sharing:4.5.2]
  • 当前 release 中已不再检测到以下声明:
  • android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION
  • io.agora.rtc2.extensions.MediaProjectionMgr$LocalScreenCaptureAssistantActivity
  • io.agora.rtc2.extensions.MediaProjectionMgr$LocalScreenSharingService
  • 新的正式产物已重新生成:
  • build/app/outputs/bundle/release/app-release.aab
  • 当前 AAB 体积仍约 181.8MB
  • 新 AAB 证书仍为本地 upload key
  • SHA1: C1:80:AF:BF:6E:1F:F2:F4:49:58:72:87:A2:BC:54:07:E7:D2:D9:A3
  • 本轮按需执行 flutter build apk --release --split-per-abi --target-platform android-arm64 --split-debug-info=build/symbols/android 已成功,产物为:
  • build/app/outputs/flutter-apk/app-arm64-v8a-release.apk
  • 当前 arm64-v8a APK 体积约 128.7MB
  • 已核对新旧 google-services.json
  • 原文件与新文件都匹配包名 com.org.yumi
  • 下载文件已成功覆盖到 android/app/google-services.json
  • 当前工程内文件 SHA256 为:
  • a1706496a01f74d27e6c60598144cecc978934b02a87567e1ced887b5b0185d5

已知问题

  • ios/Podfile.lock 还保留旧插件记录,因为本轮未执行 pod install;但 Flutter 当前依赖链路已经不再包含已移除插件。
  • universal APK 仍然会非常大;当前正确发包方式应优先使用 --split-per-abi 或直接产出 aab
  • 仍有 12webp 被 TinyPNG 拒绝解码,推测是动画或特殊编码格式,不能继续直接走 TinyPNG 常规压缩。
  • split-debug-info 会把 Dart symbols 额外落到构建目录,发包时需要和正式包一起留档,不能丢。
  • iOS 当前验证走的是 --no-codesign,因此只产出 .xcarchive,不会自动导出可直接分发的 .ipa
  • Flutter/Xcode 当前给出两条 iOS 提醒:
  • 未来 iOS 版本将要求 UIScene 生命周期支持
  • Launch image 仍是默认占位资源,提交前建议替换
  • android/key.properties 保存了本地 upload keystore 口令,必须自行妥善备份,且不要提交到仓库
  • 由于已显式移除 Agora 本地屏幕共享相关组件,如果业务后续要启用“屏幕共享/录屏推流”,需要再单独恢复相关 manifest 声明

下一步要做什么

  • 将新的 AAB 上传到 Play Console并在首发流程中继续使用 Google 管理的 app signing key。
  • 在需要配置 Google 登录、Firebase、支付等生产环境指纹时优先登记 Google 的 deployment_cert.der 指纹;如平台要求上传者证书,再额外登记本地 upload key 指纹。
  • 如果需要正式 iOS 分发包,为 scripts/build_release.py 补入 --ios-codesign 所需签名参数并导出 .ipa
  • 继续评估 Agora 扩展库是否都需要,优先核查 lip syncspatial audioclear visionsegmentationface capture 等扩展 so 能否裁剪。
  • 决定是否处理剩余 12 张特殊 webp:改格式、换压缩工具,或维持现状。