首页 > 代码库 > Android 5.0 system_fonts.xml文件的解析过程
Android 5.0 system_fonts.xml文件的解析过程
<style id="custom" type="text/css"></style><body>
Android 5.0 system_fonts.xml文件的解析过程
首先看看看5.0 中familyset version="22" 的格式
20 <family name="sans-serif">
21 <font weight="100" style="normal">Roboto-Thin.ttf</font>
22 <font weight="100" style="italic">Roboto-ThinItalic.ttf</font>
23 <font weight="300" style="normal">Roboto-Light.ttf</font>
24 <font weight="300" style="italic">Roboto-LightItalic.ttf</font>
25 <font weight="400" style="normal">Roboto-Regular.ttf</font>
26 <font weight="400" style="italic">Roboto-Italic.ttf</font>
27 <font weight="500" style="normal">Roboto-Medium.ttf</font>
28 <font weight="500" style="italic">Roboto-MediumItalic.ttf</font>
29 <font weight="900" style="normal">Roboto-Black.ttf</font>
30 <font weight="900" style="italic">Roboto-BlackItalic.ttf</font>
31 <font weight="700" style="normal">Roboto-Bold.ttf</font>
32 <font weight="700" style="italic">Roboto-BoldItalic.ttf</font>
33 </family>
35 <!-- Note that aliases must come after the fonts they reference. -->
36 <alias name="sans-serif-thin" to="sans-serif" weight="100" />
37 <alias name="sans-serif-light" to="sans-serif" weight="300" />
38 <alias name="sans-serif-medium" to="sans-serif" weight="500" />
39 <alias name="sans-serif-black" to="sans-serif" weight="900" />
40 <alias name="arial" to="sans-serif" />
41 <alias name="helvetica" to="sans-serif" />
42 <alias name="tahoma" to="sans-serif" />
43 <alias name="verdana" to="sans-serif" />
在Typeface.java中静态类实现了对system_fonts.xml文件的的解析过程
一. system_fonts.xml文件存在设备的/system/etc/system_fonts.xml 中
二. Typyface文件对system_fonts.xml文件的解析过程
需要两个比较重要的数据结构:
- Font
public static class Font {
public String fontName; //用于存储Fontfile的文件所在的Path
public int weight; //新增加的字段,表示字体大小
public boolean isItalic; //是否为斜体
}
- Family
public static class Family {
public String name; //对应于Family的名字, eg:sans-serif
public List<Font> fonts; //属于该Family的Font集合
public String lang; //语言属性
public String variant;
}
再看看system_fonts.xml文件的初始化代码:
private static void init() {
// Load font config and initialize Minikin state
//以下根据配置文件的绝对路径(/system/etc/system_fonts.xml)得到File对象,就没什么好分析的了
File systemFontConfigLocation = getSystemFontConfigLocation();
File configFilename = new File(systemFontConfigLocation, FONTS_CONFIG);
//无关代码直接给省去了,直接分析解析代码(剩余的代码后头再进行分析)
try {
FileInputStream fontsIn = new FileInputStream(configFilename); //打开文件,没什么可以分析的
FontListParser.Config fontConfig = FontListParser.parse(fontsIn);//所有的核心都在这个parse中进行处理的
.....
} catch (RuntimeException e) {
..............
}
}
要想知道parse到底干了什么,直接看源代码
/* Parse fallback list (no names) */
public static Config parse(InputStream in) throws XmlPullParserException, IOException {
try {
XmlPullParser parser = Xml.newPullParser(); //很明显这个是一个Xml文件解析工具类,不必要去深究了
parser.setInput(in, null);
parser.nextTag();
return readFamilies(parser); //重点分析这个函数
} finally {
in.close();
}
}
parse的在利用输入流创建了Xml解析工具后,和行工作就转交给readFamilies这个函数了
private static Config readFamilies(XmlPullParser parser)
throws XmlPullParserException, IOException {
Config config = new Config(); //配置文件的所有解析结果都是存储于这个变量中
parser.require(XmlPullParser.START_TAG, null, "familyset");
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() != XmlPullParser.START_TAG) continue;
//以下两个if 条件可知,该解析只对 ‘family‘ 标签和 ‘alias‘ 标签里的内容进行解析
if (parser.getName().equals("family")) {
config.families.add(readFamily(parser));
} else if (parser.getName().equals("alias")) {
config.aliases.add(readAlias(parser));
} else {
skip(parser);
}
}
return config;
}
从上面代码可以知道,readFamilies针对family 和 alias 标签里的内容进行分析,其他内容都进行忽略处理,并且处理的结果都保存的Config这个对象中
- 对与family 标签中的内容进行解析的过程,readFamily函数的调用
private static Family readFamily(XmlPullParser parser)
throws XmlPullParserException, IOException {
//family 标签可能有三个属性: 分别是name lang variant,所以以下三行完成对对应属性的读取
String name = parser.getAttributeValue(null, "name");
String lang = parser.getAttributeValue(null, "lang");
String variant = parser.getAttributeValue(null, "variant");
/* 1. 以family为父标签,font可以为其子标签,font标签描述的是:ttf文件的存储路径(path)、文字的大小(weight)、
* style等特性.
* 2. family可以有多个font标签,即在同一个family下的font是属于同一字体族
*/
List<Font> fonts = new ArrayList<Font>();
//该循环完成对属于同一字体族的font属性:weight , style , fullFilename(绝对路径)的读取
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() != XmlPullParser.START_TAG) continue;
String tag = parser.getName();
if (tag.equals("font")) {
String weightStr = parser.getAttributeValue(null, "weight");
//若weight属性不存在,默认为400
int weight = weightStr == null ? 400 : Integer.parseInt(weightStr);
boolean isItalic = "italic".equals(parser.getAttributeValue(null, "style"));
String filename = parser.nextText();
String fullFilename = "/system/fonts/" + filename;
fonts.add(new Font(fullFilename, weight, isItalic));
} else {
skip(parser);
}
}
return new Family(name, fonts, lang, variant);
}
- 对 alias 标签的内容的都取,readAlias. alias其实就是对family进行重命名(alias只能对已知的family的名字进行重命名)
eg : 名字为 sans-serif-thin的family必须在该句前出现
<alias name="sans-serif-thin" to="sans-serif" weight="100" />
private static Alias readAlias(XmlPullParser parser)
throws XmlPullParserException, IOException {
Alias alias = new Alias();
alias.name = parser.getAttributeValue(null, "name");
alias.toName = parser.getAttributeValue(null, "to");
String weightStr = parser.getAttributeValue(null, "weight");
if (weightStr == null) {
alias.weight = 400;
} else {
alias.weight = Integer.parseInt(weightStr);
}
skip(parser); // alias tag is empty, ignore any contents and consume end tag
return alias;
}
就这样,就完成了对xml文件的解析
Android 5.0 system_fonts.xml文件的解析过程
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。