Android系统字体源文件获取方案问询:FreeType+OpenGL渲染场景
Android 获取系统字体TTF数据的可行方案
刚好之前做过类似的需求,Android上确实有不需要硬猜系统文件路径就能获取系统字体原始数据的方案,分两种场景给你说明:
一、API 26+ 用官方原生Font API(推荐)
从Android 8.0开始,官方提供了更完善的字体操作API,能直接从Typeface拿到字体的二进制数据,完全绕开文件路径:
- 先通过字体名称创建对应的
Typeface实例:
// 替换成你需要的系统字体名称,比如"serif"、"monospace"等 Typeface systemFont = Typeface.create("sans-serif", Typeface.NORMAL);
- 从
Typeface里取出FontFamily,再拿到具体的Font对象,最后获取字节缓冲:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { FontFamily fontFamily = systemFont.getFontFamily(); List<Font> fontList = fontFamily.getFonts(); if (!fontList.isEmpty()) { Font targetFont = fontList.get(0); // 这个ByteBuffer就是TTF字体的原始二进制数据 ByteBuffer fontBuffer = targetFont.getBuffer(); // 直接把这个Buffer传给FreeType加载就行,完美适配你的渲染器 } }
这个方法是官方完全支持的,不存在路径兼容问题,是最优解。
二、兼容API <26的低版本方案
如果要支持Android 7.1及以下,上面的API用不了,这时候可以通过AssetManager访问系统字体的assets资源:
Android系统字体其实都放在系统的assets目录下,你可以直接通过AssetManager打开对应的字体文件,不需要知道绝对路径:
AssetManager assetManager = getContext().getAssets(); try { // 这里以Roboto常规体为例,对应sans-serif字体 InputStream fontStream = assetManager.open("fonts/Roboto-Regular.ttf"); // 把流转换成字节数组,供FreeType使用 byte[] fontBytes = new byte[fontStream.available()]; fontStream.read(fontBytes); fontStream.close(); // 现在fontBytes就是你要的TTF数据了 } catch (IOException e) { e.printStackTrace(); }
这个方法需要你记住常用系统字体对应的assets文件名,比如:
sans-serif→Roboto-Regular.ttfsans-serif-bold→Roboto-Bold.ttfserif→NotoSerif-Regular.ttfmonospace→DroidSansMono.ttf
虽然需要记对应关系,但比猜/system/fonts/下的路径靠谱多了,大部分厂商的低版本设备都兼容。
小提示
- API 26+ 可以用
Typeface.getFontList()获取设备上所有可用的系统字体名称,能动态适配不同设备的字体情况。 - 绝对不要直接访问
/system/fonts/这类系统路径,高版本Android会限制权限,而且不同厂商的路径可能不一样,很容易出问题。
内容的提问来源于stack exchange,提问作者sweatervest
相关产品推荐
相关产品推荐

