那些Android上的性能优化

性能优化是一个大的范畴,如果有人问你在Android中如何做性能优化的,也许都不知道从哪开始说起。

首先要明白的是,为什么我们的App需要优化,最显而易见的时刻:用户say,什么狗屎,刷这么久都没反应,取关卸载算了。

这跟什么有关,我们先苍白的反驳下,尼玛用户设备老旧网又烂,关我屁事,根本不用优化。可是,老板拍板了,施压给CTO,然后CTO又来找你:Y的今天必须给我想办法优化了,不然不准回家。

好吧,为什么从UI的表象上看,App又卡又慢而且还错乱。我们试着来剖析下吧。

题外话:把minSDK改到4.0+,去特么的low用户,连手机都不愿意换,还能指望它能给你带来多少营收么,直接pass掉吧。4.0前的系统bug不少,不能为了弥补这些bug而降低了整体的高性能。

好了,让我们先从UI说起:

首先要明白的是UI的绘制流程:measure-layout-draw,measure与layout都需要for loop所有的子控件,汇集起来才能完成绘制,布局。所以子控件越多,所消耗的时间越长(inflate,layout_weight,relative,多层嵌套等),减少不必要的子控件或层级,是相当有必要的。你可以通过merge,viewstub这些标签来减少层级嵌套。如果你的空间观念没那么好,可以用HierarchyViewer工具来检查。

对于Listview或者GridView这种多item的组件来说,复用item可以减少inflate次数,通过setTag,getTag的ViewHolder方式实现复用,这里要注意的是,holder中的控件最好reset后再赋值,避免图片,文字错乱。

对于ViewPager第一次显示时卡顿以及左右滑动卡顿,有以下几种优化方式:

  1. ViewPager同时缓存page数最好为最小值3,如果过多,那么第一次显示时,ViewPager所初始化的pager就会很多,这样pager累积渲染耗时就会增多,看起来就卡。
  2. 每个pager应该只在显示时才加载网络或数据库(UserVisibleHint=true),最好不要预加载数据,以免造成浪费

图片显示不出来或者加载时间太长,怎么办?分两部分,下载速度,加载速度。

  1. 对于下载,要控制好同时下载的最大任务数(平均速度慢),同时给InputStream再包一层缓冲流会更快(如BufferedInputStream)。
  2. 对于加载速度,我们要知道一点,虽然下载的图片可能只有几百K,但是decode成bitmap所占用的内存可是成倍的,尽可能的减小图片size是根本因素,让服务端提供不同分辨率的图片才是最好的解决方案,内存总有耗尽的时刻,别老想着大分辨率会更清晰,实际就只有150150的空间,非给弄张10001000的图片是不恰当的。另外论加载速度:内存>硬盘>网络,合理的使用内存缓存也是关键。假如自己写不好,没关系,有那么多开源的图片缓存框架,不用自己操心。

再说缓存

有很多种缓存方式,也不用Stay列举了,我们要说的是搭配使用。

  1. 比方说,以前我们一直在用强引用,HashMap,后来我们发现占内存,我们就用软引用,弱引用来及时回收,再后来因为回收机制不可控,所以又有了lrucache,disklrucache通过算法来平衡内存与硬盘缓存。随着android版本的推进与演化,我们也应该拥抱变化。如果你的App里还有软引用,弱引用的地方,不妨再check下。
  2. 比方说网络+数据库。网络我们一般都是去主动获取,而非被动接受。那如果说数据是重复的或者未更改的呢?那我们去取一次网络数据有什么意义呢?我的解决方案是给每个activity或fragment或每个组件设置一个最大请求间隔,比如一个listview,第一次请求数据时,保存一份到数据库,并记下时间戳,当下次重新初始化时,判断是否超过最大时间间隔(如5分钟),如果没有,只加载数据库数据,不需要再做网络请求。当然,还有一些隐式的http请求框架会缓存服务器数据,在一定时间内不再请求网络,或者当服务器返回304时将之前缓存的数据直接返回。

反正也说到网络了,那我们也来说说

  1. 现在有很多现成HTTP框架供我们使用,我们几乎只用写配置就可以搞定一个url请求,但是这里有很多需要服务端配合的,比如:json数据格式,WebP代替jpg,支持断点续传,多个请求合并成一个,尽量不做重定向,服务器缓存以及负载均衡等。
  2. 对客户端本身,除了上述的实现,我们还需要合理的缓存,控制最大请求并发量,及时取消已失效的请求,过滤重复请求,timeout时间设置,请求优先级设置等。

优化可不是一个人的事,实现一个功能简单,但是想优化重构,那是很不容易的事。需要多方面的预判与联调。合理的假设与实践是优化最重要的手段。


说完这些具体的点,我们再来说说一些常识,或者称之为代码规范。

  1. 你要知道for loop中不要声明临时变量,不到万不得已不要在里面写try catch。
  2. 明白垃圾回收机制,避免频繁GC,内存泄漏,OOM(有机会专门说)
  3. 合理使用数据类型,比如StringBuilder代替String,(笔试题最常见的是str+="str"中有几个对象) ,少用枚举enum,少用父类声明(List,Map)
  4. 如果你有频繁的new线程,那最好通过线程池去execute它们,减少线程创建开销。
  5. 你要知道单例的好处,并正确的使用它。
  6. 多用常量,少用显式的"action_key",并维护一个常量类,别重复声明这些常量。
  7. 如果可以,至少要弄懂设计模式中的策略模式,组合模式,装饰模式,工厂模式,观察者模式,这些能帮助你合理的解耦,即使需求频繁变更,你也不用害怕牵一发而动全身。需求变更不可怕,可怕的是没有在写代码之前做合理的设计。

当然还有很多很多,Stay所说的也只是一个大的轮廓,还是需要自己不断的尝试。会开发写代码跟会做产品的区别还是蛮大的,仅仅是态度就能刷死80%的码农了。当你碰到一些需要优化的地方,耐心的去分析,时间的累积会让你成为真正的工程师。


另外优化也没有绝对的完美,每一次优化都是基于当前的业务来做的,要明白沟通是最好的优化,不盲从,不随便,三思而后行。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,393评论 25 707
  • 0. 前言 前面有被用户投诉 APP 流量消耗厉害: 于是乎考虑了流量方面的问题。暂时 APP 中涉及流量的几个方...
    zyl06阅读 23,904评论 5 62
  • 在最好的年华遇见你喜欢的人真的是很庆幸的是,然后结婚生子,可是生活总是不如意,每天度日如年,我什么时候能熬过去啊,...
    帆帆他娘亲阅读 102评论 0 0
  • 摄影撰文:高加索孤狼 这里没有早中晚,日出日落才是作息时间表。 漫漫黄沙,千年的轮回,胡杨是新疆的象征。 粗犷,豪...
    自由行领队阅读 1,693评论 0 2
  • ​摘自:https://help.aliyun.com/document_detail/29343.html?sp...
    许你一枝花阅读 1,177评论 0 1