首页 购物 网址 三丰软件 | 小说 美女秀 图库大全 游戏 笑话 | 下载 开发知识库 新闻 开发 图片素材
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
移动开发 架构设计 编程语言 Web前端 互联网
开发杂谈 系统运维 研发管理 数据库 云计算 Android开发资料
资讯 业界资讯 软件杂谈 编程开发 网站建设 网络观查 搜索引擎 移动应用 网站运营 网络地图
开发 移动开发 Web前端 架构设计 编程语言 互联网 数据库 系统运维 云计算 开发杂谈
[移动开发] Android 5.0 system_fonts.xml文件的解析过程
Android 5.0 system_fonts.xml文件的解析过程

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文件的解析过程
需要两个比较重要的数据结构:
  1. Font
public static class Font {
        public String fontName;        //用于存储Fontfile的文件所在的Path
        public int weight;             //新增加的字段,表示字体大小
        public boolean isItalic;       //是否为斜体
    }
  1. 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这个对象中
  1. 对与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);
    }
  1. 对 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文件的解析


 此文从网络中自动搜索生成,不代表本网站赞成被搜索网站的内容或立场    查看原文
360图书馆 软件开发资料 文字转语音 购物精选 软件下载 美食菜谱 新闻资讯 电影视频 小游戏 Chinese Culture 股票 租车
生肖星座 三丰软件 视频 开发 短信 中国文化 网文精选 搜图网 美图 阅读网 多播 租车 短信 看图 日历 万年历 2018年7日历
2018-7-20 14:17:15
 
  网站联系 软件世界网-www.sjsjw.com ©2014 蜀ICP备06016416号 三峰网旗下网站