因爲要顯示一些奇奇怪怪的日文字符,咱們在應用裏放了一個字庫文件,譬如叫作jp.ttf
,放在assets
目錄下打包。java
開發、調試一切正常。但是忽然發現,在Android 2.2的設備上,文字沒法顯示。折騰一番後發現了一些故事,也產生了更多疑問。android
放在assets
目錄下的資源文件不會被映射到R.java
,訪問須要AssetManager
類。不一樣於res/raw
,res/raw
中的資源文件會被映射到R.java
,訪問時使用資源ID。app
能搜索到不少網頁(但內容幾乎相同)指出AssetManager
有個bug,不能處理單個超過1MB的文件。但沒有說明Android版本。從咱們對這個字庫的使用來看,Android 2.3以上沒有問題。google
找到Android Issue 39041提到AssetManager
的一個問題,回覆中5樓bite...@gmail.com說,調試
There is a bug in apk de/compression that does not allow using compressed assets which unpack into files larger than 1 mb. This problem is fixed in Android 2.3.code
不知道他是否是Project Member,在7樓,他又說,資源
Android smaller than 2.3 DOES NOT GUARANTEE that loading will succeed. This happens more frequently when there are a lot of similar bytes in a row in the asset file, but not necessary. To be sure you have to split the resource file into small files, that's it.開發
而Project Member kr...@android.com說,get
Also, do not read files a single byte at a time. Use a large byte buffer.input
不知道這裏「a large byte buffer」要求達到多少。咱們的字庫文件jp.ttf
是超過1MB了,確實也只在Android 2.2上遇到問題。而咱們的應用又必須支持Android 2.2。
又折騰一番後咱們發現,把這個jp.ttf
更名爲jp.xmf
,在Android 2.2上就能夠正常訪問了。
不管文件後綴名是啥,訪問方法是同樣的,
InputStream in = getResources().getAssets().open("jp.xmf");
第3點裏提到的「a large byte buffer」建議獲得了驗證,應用裏因爲某種緣由須要把這個文件讀到一個buffer裏再寫到另外一個路徑,這個buffer是1KB,若是調整成1MB,jp.ttf
就也能夠正常訪問了。最初,是這樣訪問的,
tf = Typeface.createFromAsset(getAssets(), "jp.xmf");
仍是不清楚爲何jp.xmf
能夠工做,jp.ttf
不行?
更新,12月23日。知道了爲何jp.xmf
能夠工做,jp.ttf
不行。這個問題多是試圖訪問在打包apk時被壓縮的資源文件而產生的,所以解決方法確實是改文件後綴名,改爲不會在打包apk時被壓縮的後綴名。譬如mp三、jpg,或者咱們曾經嘗試過的xmf。感謝這個提問裏CommonsWare的回答。
同時,咱們也發現以前「5」中的結論是錯誤的,對於jp.ttf
,在Android 2.2上增大buffer沒有解決問題。可能當時驗證的小夥伴一時糊塗用錯了手機。關於1MB的問題,還能夠參考這個提問。