Android图片下载"不容易" - Go语言中文社区

Android图片下载"不容易"


640?wx_fmt=jpeg


大家早上好,今天其实本来应该发我写的文章的,不过看到邮箱里有几篇文章已经挤压了快两个星期了,相信投稿作者们肯定等得很焦急,那么今天依旧发投稿文章。


本篇文章来自 老萌主,虽然不是多么高深的技术,但是对下载图片这个小功能做了细致的研究。一直只会使用成熟的开源框架无法得到成长,本篇文章将带你探究自己写图片下载时所需要注意的“坑”。


老萌主 的博客地址:http://blog.csdn.net/laomengzhu


写在前面


由于项目对图片加载需求的特殊性,现有图片加载框架无法满足,就自己写了一个简单的图片加载功能,在写的过程中遇到了一些坑,下面就分享下我在图片下载这条线上遇到的坑 和 怎么解决这些坑的。


下载数据


我们使用如下代码先把图片数据下载到内存里面:


640?wx_fmt=png


Oh, beautiful code~~ 但是,你中枪了!


640?wx_fmt=jpeg


试想,你的APP最大可用内存 64M,你现在下载的是一个 80M 的图片会怎么样?Bomb,你的APP炸了,你看,我还没开始(decode)就结束。


在Android开发中提起 OOM 大家立马会想到 "Decode Bitmap",但是OOM并不是"Decode Bitmap"的专属,这里就说明不decode也会出现OOM。我们得想办法解决这个问题,谁也不想做秒男。既然内存不够用,那我们先把数据保存成文件,然后 decodeFile


640?wx_fmt=png


诶~,这下没有OOM,但是下载耗时多了好多,原因是每次下载10kb数据就需要写一次文件,IO操作相比内存操作是很耗时的。动作太慢没感觉(其实还是秒男,只是变成了0.5倍速了),不行,我要做真男人。


640?wx_fmt=jpeg


内存只是不够用并不是不能用了,我们能不能分出5M的内存,先把数据下载到这快内存里面,当这块内存装满时,把这5M的数据拿出来保存到文件里,当然可以,这就是 BufferedOutputStream :


640?wx_fmt=png


这样,下载5M数据,之前要写512(5*1024/10)次文件,现在只需要写一次,速度自然就提上来了。现在才是真男人,速度可以接受,不会OOM


那这个5M怎么来的呢?这个大小取决与你要加载的图片大小分布,目的就是为了在内存允许的情况下让大部分的图片只需要一次写操作就能搞定,尽可能的减小由于写操作带来的速度影响。例如,你的APP加载的图片大部分是1M以内,只有极少数大于1M,那这个大小就是1M


回过头来看这三种方式,其实就是 空间换时间、时间换空间、权衡方案


解析Bitmap


老司机都知道为了防止解析图片时OOM,我们一般先只解析出图片尺寸信息,然后根据尺寸信息和我们实际显示大小来计算出 inSampleSize 的值,然后去 deocde 一个缩放过的图片,代码可能是这样的:


640?wx_fmt=png


如果你是这样写的,那么你又中枪了(WTF)!


640?wx_fmt=jpeg


假如图片原始大小480x800,你要显示的大小是250x420,你得到的 inSampleSize 将会是 1,因为 int/int 是取整的,不会对图片做缩放,这可能就是OOM的隐患。


我们在计算 inSampleSize 的时候应该是向上取整:


640?wx_fmt=png


好啦,剩下的就只需要 decodeBitmap 啦,强无敌!!!


640?wx_fmt=png


我解析出一张美美哒图,你们呢?


640?wx_fmt=jpeg




如果你有好的技术文章想和大家分享,欢迎向我的公众号投稿,投稿具体细节请在公众号主页点击“投稿”菜单查看。


欢迎长按下图 -> 识别图中二维码或者扫一扫关注我的公众号:

640?wx_fmt=jpeg

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/c10WTiybQ1Ye3/article/details/78098799
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢