手游上线第三天,一款中端机型点开背包就闪退,日志里是空指针。渠道审核要三到五天,等不起,只能走热更新。
热更新换的是包里的一部分
发版换整包,热更新换包里的部分内容。常见三种:脚本层用 Lua 或 JS,资源层是图片、配置、关卡,原生层是 so 和 dex。前两种成熟,第三种风险最高,各应用平台的政策也不一样。
Lua 项目的典型流程
客户端启动先请求版本接口,拿到 manifest,里面记着每个脚本的 md5 和大小。本地逐个比对,缺哪个下哪个,下完校验 md5,再写进可写目录。require 的搜索路径要按可写目录优先、包内兜底排,顺序反了新脚本根本加载不到。下载中断得能续传,最怕半截文件被当成完整版本加载。
原生代码为什么难
Android 上 Tinker 这类方案靠补丁 dex,启动时插到 ClassLoader 前面,还要处理 ART 编译、多 dex、签名校验,一个环节对不上就是启动黑屏。iOS 不允许下发可执行代码,JSPatch 早被禁了。真要做原生热修,灰度从百分之一开始,别一次全量。
版本号要能回滚
每打一个补丁就递增一个补丁号,服务端记着哪个版本配哪个补丁。线上出问题,把补丁号指回上一个,客户端下次启动自己回退。没有回滚能力的方案,等于把引信攥在自己手里。
灰度和监控放一起看
按设备号取模分批放量,百分之一、百分之十、百分之五十、全量,每档至少观察半天。崩溃率、启动耗时、关键页面转化一起盯,崩溃率涨 0.1 个百分点就该停。
踩过的几个坑
- 缓存没清:补丁改了全局配置,本地旧值还在,表现是更新了也没用
- 下载用 http:被运营商劫持,补丁里被插了广告
- 目录同名:热更目录和资源目录重名,覆盖后原包资源丢失
补丁什么时候生效
多数方案在启动页加载完补丁再进游戏,冷启动要多等两三秒,玩家感觉得到。把下载放到后台、下次启动再生效,体验好但修复慢一拍。灰度期宁可慢,也别让人卡在启动页。
能发版就别热更。热更只用来救崩溃和支付中断这类事故,把所有改动都塞进补丁,早晚会在某个机型上炸。