Android assets的一个bug
摘要
Android assets目录下资源文件超过1MB的问题。
由于要显示一些奇奇怪怪的日文字符,我们在应用里放了一个字库文件,譬如叫做jp.ttf
,放在assets
目录下打包。
开发、调试一切正常。可是突然发现,在Android 2.2的设备上,文字无法显示。折腾一番后发现了一些故事,也产生了更多疑问。
放在assets
目录下的资源文件不会被映射到R.java
,访问需要AssetManager
类。不同于res/raw
,res/raw
中的资源文件会被映射到R.java
,访问时使用资源ID。
能搜索到很多网页(但内容几乎相同)指出AssetManager
有个bug,不能处理单个超过1MB的文件。但没有说明Android版本。从我们对这个字库的使用来看,Android 2.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.
不知道他是不是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说,
Also, do not read files a single byte at a time. Use a large byte buffer.
不知道这里“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
不行?
Android assets目录下资源文件超过1MB的问题。
由于要显示一些奇奇怪怪的日文字符,我们在应用里放了一个字库文件,譬如叫做jp.ttf
,放在assets
目录下打包。
开发、调试一切正常。可是突然发现,在Android 2.2的设备上,文字无法显示。折腾一番后发现了一些故事,也产生了更多疑问。
放在
assets
目录下的资源文件不会被映射到R.java
,访问需要AssetManager
类。不同于res/raw
,res/raw
中的资源文件会被映射到R.java
,访问时使用资源ID。能搜索到很多网页(但内容几乎相同)指出
AssetManager
有个bug,不能处理单个超过1MB的文件。但没有说明Android版本。从我们对这个字库的使用来看,Android 2.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.
不知道他是不是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说,
Also, do not read files a single byte at a time. Use a large byte buffer.
不知道这里“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时被压缩的后缀名。譬如mp3、jpg,或者我们曾经尝试过的xmf。感谢这个提问里CommonsWare的回答。
同时,我们也发现之前“5”中的结论是错误的,对于jp.ttf
,在Android 2.2上增大buffer没有解决问题。可能当时验证的小伙伴一时糊涂用错了手机。关于1MB的问题,还可以参考这个提问。
Android assets的一个bug的更多相关文章
- sqlite在Android上的一个bug:SQLiteCantOpenDatabaseException when nativeExecuteForCursorWindow
更多内容在这里查看 https://ahangchen.gitbooks.io/windy-afternoon/content/ ::-/com.company.product W/System.er ...
- 一个难倒 3年 android开发经验 " 工程师 " 的 "bug"
一个关于 imageView 设置 scaleType 的问题. 就在刚才 晚上9 点多的时候,我的一个外包伙伴发一个工程代码我,叫我去看下这样一个"bug",说折腾了很久,图片选 ...
- [android开发IDE]adt-bundle-windows-x86的一个bug:无法解析.rs文件--------rs_core.rsh file not found
google的android自带的apps写的是相当牛逼的,将其导入到eclipse中方便我们学习扩展.可惜关于导入的资料太少了,尤其是4.1之后的gallery和camera合二为一了.之前导4.0 ...
- android app上线后bug的处理
app上线后,后期维护显得尤为重要,今天给大家分享一下app上线后出现bug后的解决方法 1.继承Application类,重写onCreate方法 import java.io.File; impo ...
- 关于Android Assets读取文件为File对象
关于Android Assets读取文件为File对象的问题,在Assets里面放置文件,在使用的时候,一般是使用AssetManger对象,open方法获取InputStream 然后进行其他操作. ...
- android 自己创建一个凝视模板
android 自己创建一个凝视模板 作为一名程序猿 不仅要有一个写代码的能力,养成一个良好的编写习惯也是非常重要的. 今天给大家具体介绍一下怎样创建凝视模板,给每一个类和方法都自己手动去凝视信息也 ...
- androidstudio canary5一个bug
Android Studio最新开发版一直跟着升级.到Canary5的时候出了一个bug. app build.gradle添加自己编译的aar库,原本一直使用: compile(name:'ijkp ...
- Android 系统自动重启Bug(高通平台)
点击打开链接 最近客户反馈了一个Bug,我们的系统用着用着会自动重启,尤其是在拨号的时候极容易死机或者进入下载模式.根据老大和高通的支持得到了一个解决方案. 在Android系统中,有这么一个文件夹: ...
- CSharp程序员学Android开发---3.Android内部元素不填充BUG
最近公司组织项目组成员开发一个Android项目的Demo,之前没有人有Andoid方面的开发经验,都是开发C#的. 虽说项目要求并不是很高,但是对于没有这方面经验的人来说,第一步是最困难的. 项目历 ...
随机推荐
- python中filter(),reduce()函数
filter()函数 是 Python 内置的另一个有用的高阶函数,filter()函数接收一个函数 和一个list,这个函数的作用是对每个元素进行判断,返回 True或 False,filter() ...
- net core 小坑杂记之配置文件读取 02 (控制器里读)
上次更新博客的时候提到了如何在EF的上下文里读取配置,这次介绍一下在控制器里如何读取. 先说一种简单易懂的: 首先以键值对的形式在appsettings里添加一条配置信息,接着Startup里注入配置 ...
- HTTPS建立连接的过程
HTTP建立连接的过程点击:HTTP三次握手.一次HTTP请求都发生了什么 一.HTTPS HTTP是超文本传输协议.HTTP协议传输的数据都是未加密的,也就是明文的,因此使用HTTP协议传输隐私 ...
- scrapy之持久化存储
scrapy之持久化存储 scrapy持久化存储一般有三种,分别是基于终端指令保存到磁盘本地,存储到MySQL,以及存储到Redis. 基于终端指令的持久化存储 scrapy crawl xxoo - ...
- Django的contenttypes
这是一个django内置的表结构,为的就是通过两个字段让表和N张表创建FK关系. 比如说有两种不同课程,这两种课程都有价格周期和策略.如果最低级的则是给每个表创建一个价格策略.如果非要在同一个表内使用 ...
- 软件工程(FZU2015) 赛季得分榜,第10回合(alpha冲刺)
SE_FZU目录:1 2 3 4 5 6 7 8 9 10 11 12 13 积分规则 积分制: 作业为10分制,练习为3分制:alpha30分: 团队项目分=团队得分+个人贡献分 个人贡献分: 个人 ...
- Dockers 学习
Docker镜像操作,有五个常用的命令: a.拉取镜像,后跟镜像仓库名称,如果要指定某个版本,可以带上tag. > docker pull <repo>[:tag] b.列出所有镜像 ...
- Pyspider上手
pyspider安装: pip3 install Pyspider 启动服务操作 1.打开cmd:输入 pyspider --help 回车,可以查看帮助信息,pyspider all ...
- source map
一.source map 概述 我们在打包中,将开发环境中源代码经过压缩,去空格,babel编译转化,最终可以得到适用于生产环境的项目代码,这样处理后的项目代码和源代码之间差异性很大,会造成无法deb ...
- 如何入门vue之二
学习完指令之后我们需要学习的就是组件. 在学习组件前我们要了解一下 methods 用来处理事件的. computed用来计算属性 他就是类似于data一样只不过是动态的处理数据 里面写的方法当成属 ...