You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Compose使用Noto CJK Variable Font Collection时fontWeight不生效及大体积字体引发OOM的问题求助

Android Compose使用Noto CJK Variable Font Collection时fontWeight不生效及大体积字体引发OOM的问题求助

我现在遇到两个和Compose加载可变CJK字体相关的问题,想请教大家:

一、背景与第一个问题:Variable Font通过XML转Typeface后,Compose中指定fontWeight不生效

我的最终目标是从Variable Font Collection (VFC) 文件加载字体。国内多数手机支持全局自定义字体,但这类字体对Unicode CJK汉字的支持普遍不全,会导致显示不一致,所以从开发初期我就决定在App中嵌入Noto字体,希望通过VFC来减小APK体积。

因为Compose没有直接支持TTC索引的Font()方法,所以我采用了XML定义font family的方案(XML支持android:ttcIndex属性),再将其转为原生Typeface,最后转换成Compose的FontFamily使用。但测试常规可变字体时发现了问题:Text()组件并不会显示我指定的fontWeight,而是会回退到XML中定义的FontWeight.Normal(如果有的话),或者最接近的权重值。

我做的具体操作:

  1. 将Noto Sans CJK JP可变字体文件放到/res/font目录
  2. 创建font XML配置文件(比如sans_jp.xml),内容如下:
<font-family xmlns:android="http://schemas.android.com/apk/res/android">
    <font android:font="@font/noto_sans_variable_jp"
        android:fontVariationSettings="'wght' 100"
        android:fontWeight="100"/>
    <!-- 省略100到900之间的其他权重配置项 -->
    <font android:font="@font/noto_sans_variable_jp"
        android:fontVariationSettings="'wght' 900"
        android:fontWeight="900"/>
</font-family>
  1. 在Activity中将XML转为原生Typeface:
val jp = resources.getFont(R.font.sans_jp)
  1. 在Compose的Text组件中使用:
import androidx.compose.ui.text.font.FontFamily as ComposeFontFamily

Text(
    text = "測試文本",
    fontFamily = ComposeFontFamily(jp),
    fontWeight = FontWeight(900)
)

异常表现:

  • 在Compose Preview中,文本会回退到XML中定义的最小权重100
  • 在真机上运行时,文本会回退到权重400
  • 补充:如果Typeface的 fallback链是相同权重的不同字体,就没有这个问题,所以我怀疑是Compose内部处理原生Typeface的逻辑有问题?

二、第二个问题:Variable Font Collection体积过大导致OOM

后来我尝试实现了自定义的Font类和AndroidFont.TypefaceLoader来处理VFC,但又遇到了新问题:这类VFC文件体积实在太大——无衬线版本就有30+MB,衬线版本更是超过50MB,直接导致App随机出现OOM崩溃。(其实之前我也知道直接加载这么大的文件大概率会OOM,但还是想有没有办法解决这个问题,或者有没有更优的加载方案?)

想请教各位大佬,这两个问题有没有可行的解决思路?


内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 13:28:00