【学习资料】浅议那些Android中的性能优化
发布时间:2016年02月21日 17:55分 来源:博为峰教育网采编 关键词:Android性能优化 | 上一篇 | 下一篇 |
性能优化是一个大的范畴,如果有人问你在Android性能优化如何做的,也许都不知道从哪开始说起。首先要明白的是,为什么我们的App需要优化,最显而易见的时刻:用户说,刷这么久都没反应,取关卸载算了。
这跟什么有关,我们先苍白的反驳一下,用户设备老旧网又烂,关安卓开发者何事,根本不用优化。可是,老板拍板了,施压给CTO,然后CTO又来找你:Y的今天必须给我想办法优化了,不然不准回家。好吧,为什么从UI的表象上看,App又卡且又慢而且还错乱。我们试着来剖析下吧。把minSDK改到4.0+,连手机都不愿意换,还能指望它能给你带来多少营收么,直接pass掉吧。4.0前的系统bug不少,不能为了弥补这些bug而降低了整体的高性能。
UI设计
首先要明白的是UI的绘制流程:measure-layout-draw,measure与layout都需要for loop所有的子控件,汇集起来才能完成绘制,布局。所以子控件越多,所消耗的时间越长(inflate,layout_weight,relative,多层嵌套等),减少不必要的子控件或层级,是相当有必要的。你可以通过merge,viewstub这些标签来减少层级嵌套。如果你的空间观念没那么好,可以用Hierarchy Viewer工具来检查。
对于List view或者Grid View这种多item 的组件来说,复用item可以减少inflate次数,通过set Tag,getTag的View Holder方式实现复用,这里要注意的是,holder中的控件最好reset后再赋值,避免图片,文字错乱。
对于ViewPager第一次显示时卡顿以及左右滑动卡顿,有以下几种优化方式:
View Pager同时缓存page数最好为最小值3,如果过多,那第一次显示时,View Pager所初始化的pager就很多,这样pager累积渲染耗时就会增多,看起来就卡。每个pager应该只在显示时才加载网络或数据库(User Visible Hint=true),最好不要预加载数据,以免造成浪费。
图片显示不出来或者加载时间太长,怎么办?分两部分,下载速度,加载速度。
对于下载,要控制好同时下载的最大任务数(平均速度慢),同时给Input Stream再包一层缓冲流会更快(如Buffered Input Stream)。
对于加载速度,我们要知道一点,虽然下载的图片可能只有几百K,但是decode 成bitmap所占用的内存可是成倍的,尽可能的减小图片size是根本因素,让服务端提供不同分辨率的图片才是最好的解决方案,内存总有耗尽的时刻,别老想着大分辨率会更清晰,实际就只有150*150的空间,非给弄张1000*1000的图片是不恰当的。另外论加载速度:内存>硬盘>网络,合理的使用内存缓存也是关键。假如自己写不好,没关系,有那么多开源的图片缓存框架,不用自己操心。
缓存
有很多种缓存方式,也不用Stay列举了,我们要说的是搭配使用。比方说,以前我们一直在用强引用,Hash Map,后来我们发现占内存,我们就用软引用,弱引用来及时回收,再后来因为回收机制不可控,所以又有了 lrucache,disk lrucache通过算法来平衡内存与硬盘缓存。随着android 版本的推进与演化,我们也应该拥抱变化。如果你的App 里还有软引用,弱引用的地方,不妨再check下。
比方说网络+数据库。网络我们一般都是去主动获取,而非被动接受。那如果说数据是重复的或者未更改的呢?那我们去取一次网络数据有什么意义呢?我的解决方案是给每个activity或 fragment或每个组件设置一个最大请求间隔,比如一个listview,第一次请求数据时,保存一份到数据库,并记下时间戳,当下次重新初始化时,判断是否超过最大时间间隔(如5分钟),如果没有,只加载数据库数据,不需要再做网络请求。当然,还有一些隐式的http请求框架会缓存服务器数据,在一定时间内不再请求网络,或者当服务器返回304时将之前缓存的数据直接返回。