Android assets的一個bug

因爲要顯示一些奇奇怪怪的日文字符,咱們在應用裏放了一個字庫文件,譬如叫作jp.ttf,放在assets目錄下打包。java

開發、調試一切正常。但是忽然發現,在Android 2.2的設備上,文字沒法顯示。折騰一番後發現了一些故事,也產生了更多疑問。android

  1. 放在assets目錄下的資源文件不會被映射到R.java,訪問須要AssetManager類。不一樣於res/rawres/raw中的資源文件會被映射到R.java,訪問時使用資源ID。app

  2. 能搜索到不少網頁(但內容幾乎相同)指出AssetManager有個bug,不能處理單個超過1MB的文件。但沒有說明Android版本。從咱們對這個字庫的使用來看,Android 2.3以上沒有問題。google

  3. 找到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。

  1. 又折騰一番後咱們發現,把這個jp.ttf更名爲jp.xmf,在Android 2.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的問題,還能夠參考這個提問

相關文章
相關標籤/搜索