自定義中文字體解決方案

一個應用調用自定義字體,在部分機器上無法正確使用自定義的字體。有些甚至是同一款機器,所以分辨率之類的因素可以排除。最後發現是版本原因,系統版本低於Android 2.3的機器上通通出問題,2.3以上的正常。但代碼都是針對Android 1.6的API的啊,別說2.3,連2.0的API都沒用到。查詢Android 2.3的highlights,看到下面這句話:


There is no longer a limit on the size of compressed .apk assets that can be read.

從2.3開始,對可讀取的壓縮後的.apk中的資源的大小不再有限制。這意味着在2.3之前都是有限制的。翻看LogCat中的記錄,會有如下的信息:

Data exceeds UNCOMPRESSE_DATA_MAX ( XXXXXXXXXX vs 1048576)

其中XXXXXXX是一個大於1048576的值。也就是說,在壓縮打包到APK文件中的資源文件,在解壓後的大小不能超過1MB。否則在Android 2.3之前的系統中就無法正確讀取該資源文件。而我們用的中文字體文件的大小顯然超過了1MB,失敗的原因就在這裏。怎麼辦?

中文社區中對此有這樣的一篇廣爲轉載的文章,《Asset限制文件大小UNCOMPRESS_DATA_MAX爲1MB》,其中的結論是:

目前解決的方法只有將文件放入到sdcard,但這樣除了microsd的讀取IO效率和耗電量解決不是很好,同時sd卡移除時可能存在問題,解決的方法如果數據量大的化通過sqlite是一種解決方法,同時openFileOutput方式讀取也是不錯的選擇,看來android操作系統中最安全控制的嚴格,但犯了一個不小的錯誤。

字體文件顯然沒辦法塞到sqlite裏面,要求所有的用戶都有SD卡也不太友好。又翻到一篇相關的英文文章,Dealing with Asset Compression in Android Apps。從中可以看出,Android 2.3之前的版本只對壓縮過的資源文件的原始大小做了限制,這種限制可能是出於計算性能的考慮。對於沒有壓縮的文件,是沒有大小限制的。哪些文件不會壓縮?圖片、音頻、視頻,包括這些後綴:

“.jpg”, “.jpeg”, “.png”, “.gif”, “.wav”, “.mp2″, “.mp3″, “.ogg”, “.aac”, “.mpg”, “.mpeg”, “.mid”, “.midi”, “.smf”, “.jet”, “.rtttl”, “.imy”, “.xmf”, “.mp4″, “.m4a”, “.m4v”, “.3gp”, “.3gpp”, “.3g2″, “.3gpp2″, “.amr”, “.awb”, “.wma”, “.wmv”

從Android的源代碼中可以知道,Android的打包工具是通過文件的後綴名來判斷文件是否需要壓縮的。如果文件的後綴名是上面這些後綴,文件就不會被壓縮,大小也就沒有限制;如果文件的後綴不是上面這些,就對其進行壓縮,並且在Android 2.2上有1MB的大小限制。字體文件後綴通常是.ttf,屬於要被壓縮的,在Android 2.2之前的版本中就有了體積限制。不過,看到這裏,解決方案也出來了,把字體文件的.ttf後綴改成上述任意一個後綴,然後修改相應的代碼就可以。好猥瑣的解決方案啊~~

結論:中文社區的水平似乎還是跟老外有點差距,或者是高手的分享意願不強烈;Android本身及其相關的開發工具的源代碼是值得去讀讀的;Android裏面有一些看似奇怪的條條框框,這種非API的版本變化,如果不在2.3以下的機器上測試是根本發現不了的。


-------------------------------------------------------

我做的實現:

         Typeface face=Typeface.createFromAsset(getAssets(),"fonts/STXINGKA.jpg");
         tv.setTypeface(face);


這裏使用的是華文行楷,文件大小爲:3.83MB


實現效果:







發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章