一、原因分析:

虽然热更新后,执行了 Updates.reloadAsync()重载jsbundle 但是此方法仅仅重置js层缓存的字体、图标库的映射关系。没有重置Native层的。

二、缓存分2层,缓存的内容:

在这里插入图片描述

在这里插入图片描述

原生层

三、如果每次热更新的ttf文件是新的,那硬盘上的原本的ttf文件会被删除吗?原本的热更新的包jsbundle会被删除吗?

在这里插入图片描述

在这里插入图片描述

解决方案 : 字体图标带上每次jsbundle的id.

/**
 * 热更新 reloadAsync 后原生进程不重启,同名字体族(fontFamily)会继续使用native层缓存的旧 TTF,
 * 且无法直接调用方法去清除native层字体映射缓存,导致新图标显示为「?」。
 *
 * 在热更新场景下把 updateId 拼进字体族名,强制走一次新的原生字体注册。
 */
export function resolveIconFontFamily(baseName) {
    if (
        !Updates.isEnabled ||
        Updates.isEmbeddedLaunch || // 前跑的 JS Bundle,是不是安装包里自带的那份(embedded),而不是后来从 OTA 服务器下载的更新包。
        !Updates.updateId
    ) {
        return baseName;
    }
    const suffix = String(Updates.updateId).replace(/-/g, '').slice(0, 8);
    return `${baseName}_${suffix}`;
}

——————————————————————————————————
const ICON_FONT_MAP = {
    [resolveIconFontFamily('customIconfont')]: require('~/assets/font/aliconfont/iconfont.ttf'), // 目前只有这个字体库会不断更新
    // 其他写死字体库
    [newCustomIconfont.font_family]: require('~/assets/font/newUIiconfont/iconfont.ttf'),
    'qweather-icons': require('~/static/fonts/qweather-icons.ttf')
};

——————————————————————————————————
const [fontsLoaded, fontsLoadedError] = useFonts(ICON_FONT_MAP); // 立刻预加载 iconfont;

踩坑:本意是每次热更新完,都执行Font.unloadAsync手动卸载字体(即下图方法)。再加载字体。但是实际上,在移动端,此方法也会报错。也无法直接深入native层去清除字体映射缓存。

在这里插入图片描述

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐