看完了文档里关于图片介绍的几篇文章,结合项目和一些网上的文章,谈下在android平台显示图片的一些个人想法。


1.从设计角度,最好不要让手机显示大于手机屏幕数倍的大图片,如果源图是个大图,加载时把图片缩小到屏幕大小,使用在decode图片时使用option选项,直接加载缩小后的图片。网上不少人说先读取图片InputStream流,再通过BitmapFactory.decodeStream(InputStream is)加载速度会快些,我看了api level 14的代码实现,无论调用哪个decode方法,最后都是调用的这个方法。电脑上没低版本的源码,不确定低版本是不是也是这样实现。


2.加载一张图片,无论是为控件设背景图还是显示一张图片,如果图片源不是在内存中的,最好不要直接在UI线程中加载它,推荐使用AsyncTask异步加载图片。原因很简单,在UI线程加载图片,加载期间会阻塞UI线程,如果加载图片时间太长了,会产生ANR问题。

这里有个疑惑,如果图片是资源文件,要不要使用异步加载?我认为资源文件没有必要使用异步加载。通常使用的方法有BitmapFactory.decodeResource(Resource res, int id, Options opts) 或者 setBackgroundResource(int resid)。他们最终都是通过AssetManager.openNonAsset(int cookie, String fileName, int accessMode)获取一个InputStream,而这个方法是个native方法,没有去读它的native实现,但android引入资源文件这一机制,而这一机制并没有为写代码时带来太多帮助,那么它应该是文件加载优化的产物。


3.对于缓存,文档建议不要超过初始分配内存的1/8。我觉得这个不要滥用,因为不需要缓存的,你缓存了,白白被消耗一部分内存。也不要拘泥于这个百分比,因为在android中图片是消耗内存的大户,普通手机1/8的初始内存,还缓存不了两张全屏的大图,命中率太低了还不如不用缓存。对于需要大量显示图片的应用或模块,你内存不给它用,还留着干什么。


4.谨防超大屏幕。对于超大屏,显示图片消耗的内存是惊人的,所以你的应用在显示图片时,要提醒自己它有可能应用到超大屏的手机上。如果一个activity中需要持有几个大图(或者源为小图,但需要被拉伸为大图)的引用,一定要记得在activity销毁时,单独释放图片的内存,因为你退出activity,通常系统并不会销毁它,所以它持有的引用也会保留。如果需要几张大图叠加实现某种效果,最好单独加载每张图片,把它画到一张画布上,把原来的图片释放。这样的话,最终只消耗一张图片大小的内存。

自己开发中遇到过一个case: 有几款手机,在进入某个activity时很容易crash,我检查了代码,没有什么错误。实现的功能就是显示一个普通的全屏场景,场景是由几张图叠加出来的,一张背景,一张草地等等,UI基本是加载layout.xml实现,在代码中仅仅对UI做了少量微调。分析下内存发现,一进入这个activity,堆内存就增加35M左右,而且退出activity后,这些内存并没有减少。之前觉得不合理,后来发现手机竟然是1960x1080的分辨率,一张全屏的图片大小差不多要消耗8M内存,这一堆图加起来如果有3张全屏图大小,就得24M内存,再加上一些动画和其它缓存,占三十多兆也不足为怪了。最后解决办法是分别加载每张图片,画到一张上面,释放原来的内存。在activity结束后,把图片内存释放。测试结果是,这样优化后,不仅解决了crash,整个应用速度也流畅不少。


5.为图片单独创建进程。可以在一个新的进程中创建一个ContentProvider存储图片或者把显示图片的activity单独运行在另外一个线程中。

更多相关文章

  1. 毕加索的艺术——Picasso,一个强大的Android图片下载缓存库,OkHtt
  2. Android 内存泄漏总结
  3. (4.4.1.3)android内存管理方式
  4. android ListView常见问题解决方法(滚动背景变黑,去除滑动时阴影,拖
  5. Android 内存泄漏相关
  6. android使用ImageView加载本地SdCard图片和加载网络图片
  7. 源码分析android 系统framework(二)之view的布局加载流程
  8. Android的内存优化管理
  9. Android性能优化(三)之内存管理

随机推荐

  1. Android(安卓)MediaExtractor Constructi
  2. androidstudio启动的时候报错,启动不了
  3. android 截获键盘事件
  4. Android(安卓)Textview实现文字颜色渐变
  5. Android:RxJava
  6. Android(安卓)如何获取系统字体大小
  7. Android(安卓)图片加边框
  8. android 读取网络在传输数据时的状态
  9. Android(安卓)service实例
  10. Android创建和配置布局动画