Android5.0system_fonts.xml文(wén)件的解析過程 - 新聞資(zī)訊 - 雲南小程序開發|雲南軟件開發|雲南網站(zhàn)建設-西山區知普網絡科技工作室

159-8711-8523

雲南網建設/小程序開發/軟件開發

知識

不管是網站(zhàn),軟件還是小程序,都要直接或間接能為您産生價值,我們在追求其視覺表現的同時,更側重于功能的便捷,營銷的便利,運營的高效,讓網站(zhàn)成為營銷工具,讓軟件能切實提升企業(yè)内部管理水平和(hé)效率。優秀的程序為後期升級提供便捷的支持!

您當前位置>首頁 » 新聞資(zī)訊 » 技術(shù)分享 >

Android5.0system_fonts.xml文(wén)件的解析過程

發表時間:2020-10-19

發布人:葵宇科技

浏覽次數:121

Android 5.0 system_fonts.xml文(wén)件的解析過程

起首看看看5.0 中(zhōng)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中(zhōng)靜态類實現了對system_fonts.xml文(wén)件的的解析過程

一. system_fonts.xml文(wén)件存在設備的/system/etc/system_fonts.xml 中(zhōng)
二. Typyface文(wén)件對system_fonts.xml文(wén)件的解析過程
須要兩個(gè)比較重要的數據構造:
  1. Font
public static class Font {
        public String fontName;        //用于存儲Fontfile的文(wén)件地點的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文(wén)件的初始化代碼:
private static void init() {
        // Load font config and initialize Minikin state
        //以下(xià)根據設備文(wén)件的絕對路(lù)徑(/system/etc/system_fonts.xml緝獲得File對象,就沒什麼好分析的了
        File systemFontConfigLocation = getSystemFontConfigLocation();
        File configFilename = new File(systemFontConfigLocation, FONTS_CONFIG);

        //無關(guān)代碼直接給省去了,直接分析解析代碼(殘剩的代碼後頭再進行分析)
        try {
            FileInputStream fontsIn = new FileInputStream(configFilename); //打開文(wén)件,沒什麼可(kě)以分析的
            FontListParser.Config fontConfig = FontListParser.parse(fontsIn);//所有的核心都在這個(gè)parse中(zhōng)進行處理的
            .....

        } catch (RuntimeException e) {
        ..............
        }
    }

要想知道parse到底幹了什麼,直接看源代碼
    /* Parse fallback list (no names) */
    public static Config parse(InputStream in) throws XmlPullParserException, IOException {
        try {
            XmlPullParser parser = Xml.newPullParser(); //很明顯這個(gè)是一個(gè)Xml文(wén)件解析對象類,不須要去深究了
            parser.setInput(in, null);
            parser.nextTag();
            return readFamilies(parser); //重點分析這個(gè)函數
        } finally {
            in.close();
        }
    }

parse的在應用輸入流創建了Xml解析對象後,和(hé)行工作就轉交給readFamilies這個(gè)函數了
    private static Config readFamilies(XmlPullParser parser)
            throws XmlPullParserException, IOException {
        Config config = new Config(); //設備文(wén)件的所有解析結不雅都是存儲于這個(gè)變量中(zhōng)

        parser.require(XmlPullParser.START_TAG, null, "familyset");
        while (parser.next() != XmlPullParser.END_TAG) {
            if (parser.getEventType() != XmlPullParser.START_TAG) continue;
            //以下(xià)兩個(gè)if 前提可(kě)知,該解析隻對 'family' 标簽和(hé) '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;
    }

大年夜膳绫擎代碼可(kě)以知道,readFamilies針對family 和(hé) alias 标簽裡的内容進行分析,其他内容都進行忽視處理,并且處理的結不雅都保存的Config這個(gè)對象中(zhōng)
  1. 對與family 标簽中(zhōng)的内容進行解析的過程,readFamily函數的調用
    private static Family readFamily(XmlPullParser parser)
            throws XmlPullParserException, IOException {

        //family 标簽可(kě)能有三個(gè)屬性: 分别是name lang variant,所以以下(xià)三行完查對對應屬性的攫取
        String name = parser.getAttributeValue(null, "name");
        String lang = parser.getAttributeValue(null, "lang");
        String variant = parser.getAttributeValue(null, "variant");

        /* 1. 以family為父标簽,font可(kě)認為其子(zǐ)标簽,font标簽描述的是:ttf文(wén)件的存儲路(lù)徑(path)、文(wén)字的大年夜小(weight)、
        *     style等特點.
        *  2. family可(kě)以有多個(gè)font标簽,即在同一個(gè)family下(xià)的font是屬于同一字體族
        */ 
        List<Font> fonts = new ArrayList<Font>();

        //鈣揭捉環完查對屬于同一字體族的font屬性:weight , style , fullFilename(絕對路(lù)徑)的攫取
        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;
    }

就如(rú)許,就完成了對xml文(wén)件的解析

相關(guān)案例查看更多