那些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第一次显示时卡顿以及左右滑动卡顿,有以下几种优化方式:
ViewPager同时缓存page数最好为最小值3,如果过多,那么第一次显示时,ViewPager所初始化的pager就会很多,这样pager累积渲染耗时就会增多,看起来就卡。
每个pager应该只在显示时才加载网络或数据库(UserVisibleHint=true),最好不要预加载数据,以免造成浪费
图片显示不出来或者加载时间太长,怎么办?分两部分,下载速度,加载速度。
对于下载,要控制好同时下载的最大任务数(平均速度慢),同时给InputStream再包一层缓冲流会更快(如BufferedInputStream)。
对于加载速度,我们要知道一点,虽然下载的图片可能只有几百K,但是decode成bitmap所占用的内存可是成倍的,尽可能的减小图片size是根本因素,让服务端提供不同分辨率的图片才是最好的解决方案,内存总有耗尽的时刻,别老想着大分辨率会更清晰,实际就只有150*150的空间,非给弄张1000*1000的图片是不恰当的。另外论加载速度:内存>硬盘>网络,合理的使用内存缓存也是关键。假如自己写不好,没关系,有那么多开源的图片缓存框架,不用自己操心。
再说缓存
有很多种缓存方式,也不用Stay列举了,我们要说的是搭配使用。
- 比方说,以前我们一直在用强引用,HashMap,后来我们发现占内存,我们就用软引用,弱引用来及时回收,再后来因为回收机制不可控,所以又有了lrucache,disklrucache通过算法来平衡内存与硬盘缓存。随着android版本的推进与演化,我们也应该拥抱变化。如果你的App里还有软引用,弱引用的地方,不妨再check下。
- 比方说网络+数据库。网络我们一般都是去主动获取,而非被动接受。那如果说数据是重复的或者未更改的呢?那我们去取一次网络数据有什么意义呢?我的解决方案是给每个activity或fragment或每个组件设置一个最大请求间隔,比如一个listview,第一次请求数据时,保存一份到数据库,并记下时间戳,当下次重新初始化时,判断是否超过最大时间间隔(如5分钟),如果没有,只加载数据库数据,不需要再做网络请求。当然,还有一些隐式的http请求框架会缓存服务器数据,在一定时间内不再请求网络,或者当服务器返回304时将之前缓存的数据直接返回。
反正也说到网络了,那我们也来说说
现在有很多现成HTTP框架供我们使用,我们几乎只用写配置就可以搞定一个url请求,但是这里有很多需要服务端配合的,比如:json数据格式,WebP代替jpg,支持断点续传,多个请求合并成一个,尽量不做重定向,服务器缓存以及负载均衡等。
对客户端本身,除了上述的实现,我们还需要合理的缓存,控制最大请求并发量,及时取消已失效的请求,过滤重复请求,timeout时间设置,请求优先级设置等。
优化可不是一个人的事,实现一个功能简单,但是想优化重构,那是很不容易的事。需要多方面的预判与联调。合理的假设与实践是优化最重要的手段。
说完这些具体的点,我们再来说说一些常识,或者称之为代码规范。
你要知道for loop中不要声明临时变量,不到万不得已不要在里面写try catch。
- 明白垃圾回收机制,避免频繁GC,内存泄漏,OOM(有机会专门说)
合理使用数据类型,比如StringBuilder代替String,(笔试题最常见的是str+="str"中有几个对象) ,少用枚举enum,少用父类声明(List,Map)
如果你有频繁的new线程,那最好通过线程池去execute它们,减少线程创建开销。
你要知道单例的好处,并正确的使用它。
多用常量,少用显式的"action_key",并维护一个常量类,别重复声明这些常量。
如果可以,至少要弄懂设计模式中的策略模式,组合模式,装饰模式,工厂模式,观察者模式,这些能帮助你合理的解耦,即使需求频繁变更,你也不用害怕牵一发而动全身。需求变更不可怕,可怕的是没有在写代码之前做合理的设计。
当然还有很多很多,Stay所说的也只是一个大的轮廓,还是需要自己不断的尝试。会开发写代码跟会做产品的区别还是蛮大的,仅仅是态度就能刷死80%的码农了。当你碰到一些需要优化的地方,耐心的去分析,时间的累积会让你成为真正的工程师。
另外优化也没有绝对的完美,每一次优化都是基于当前的环境来做的,要明白沟通是最好的优化,不盲从,不随便,三思而后行。
Android上如何做性能优化的?大概写三年代码就能差不多知道了。
那些Android中的性能优化的更多相关文章
- Android 中 SQLite 性能优化
数据库是应用开发中常用的技术,在Android应用中也不例外.Android默认使用了SQLite数据库,在应用程序开发中,我们使用最多的无外乎增删改查.纵使操作简单,也有可能出现查找数据缓慢,插入数 ...
- Android中的性能优化
由于手机硬件的限制,内存和CPU都无法像pc一样具有超大的内存,Android手机上,过多的使用内存,会容易导致oom,过多的使用CPU资源,会导致手机卡顿,甚至导致anr.我主要是从一下几部分进行优 ...
- 在 Android开发中,性能优化策略十分重要
在 Android开发中,性能优化策略十分重要本文主要讲解性能优化中的布局优化,希望你们会喜欢.目录 示意图 1. 影响的性能 布局性能的好坏 主要影响 :Android应用中的页面显示速度 2. 如 ...
- 转——Android应用开发性能优化完全分析
[工匠若水 http://blog.csdn.net/yanbober 转载请注明出处.] 1 背景 其实有点不想写这篇文章的,但是又想写,有些矛盾.不想写的原因是随便上网一搜一堆关于性能的建议,感觉 ...
- Android 应用开发性能优化完全分析
1 背景 其实有点不想写这篇文章的,但是又想写,有些矛盾.不想写的原因是随便上网一搜一堆关于性能的建议,感觉大家你一总结.我一总结的都说到了很多优化注意事项,但是看过这些文章后大多数存在一个问题就是只 ...
- 【转】Android应用开发性能优化完全分析
http://blog.csdn.net/yanbober/article/details/48394201 1 背景 其实有点不想写这篇文章的,但是又想写,有些矛盾.不想写的原因是随便上网一搜一堆关 ...
- Android应用开发性能优化完全分析
1 背景 其实有点不想写这篇文章的,但是又想写,有些矛盾.不想写的原因是随便上网一搜一堆关于性能的建议,感觉大家你一总结.我一总结的都说到了很多优化注意事项,但是看过这些文章后大多数存在一个问题就是只 ...
- ym——Android之ListView性能优化
转载请注明本文出自Cym的博客(http://blog.csdn.net/cym492224103),谢谢支持! Android之ListView性能优化 假设有看过我写过的15k面试题的朋友们一定知 ...
- <只看这个就够了。。。>Android自动化测试及性能优化
Android自动化测试及性能优化 分类: Android Java Tools2012-12-09 23:31 4300人阅读 评论(0) 收藏 举报 软件自动化测试对于程序员来说能够确保软件开发的 ...
随机推荐
- Mathematics:DNA Sorting(POJ 1007)
DNA排序 题目大意:给定多个ACGT序列,按照字母顺序算出逆序数,按逆序数从小到大排列 这题其实很简单,我们只要用一个归并排序算逆序数,然后快排就可以了(插入排序也可以,数据量不大),但是要注意的是 ...
- AIX系统的环境变量设置
AIX系统的环境变量设置 用户环境的定义是通过设置环境变量来实现的.AIX系统主要使用两大类profile文件来定义用户环境.一类是用来为所有用户定制环境,另一类是为个人定义自己的环境. 登录时,sh ...
- 【python】解压文件
参考:http://essen.iteye.com/blog/1941489 tarfile模块 具体使用方法: https://docs.python.org/2/library/tarfile.h ...
- 在JAVA中如何跳出当前的多重嵌套循环
可以使用return,但使用return后,会跳出整个函数,多重循环后面的代码无法执行. public static void main(String[] args) { // TODO Auto-g ...
- linux下U盘文件只读的解决办法
. 在终端运行如下命令 tail -f /var/log/syslog . 插入有只读文件系统故障的U盘 . 观察命令行输出 输出局部如下: Jul :: cslouis-pc kernel: [15 ...
- ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(一) 之 基层数据搭建,让数据活起来(数据获取)
大家好,本篇是接上一篇 ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(零) 前言 ASP.NET SignalR WebIM系列第二篇.本篇会带领大家将 LayIM ...
- Mysql游标
14.6.6.1 Cursor CLOSE Syntax 14.6.6.2 Cursor DECLARE Syntax 14.6.6.3 Cursor FETCH Syntax 14.6.6.4 Cu ...
- samba 报错
[root@GitLab data_nfs]# smbclient //localhost/public WARNING: The security=share option is deprecate ...
- Memcached驱动(C#)
using Memcached.ClientLibrary; using System; using System.Collections.Generic; using System.IO; usin ...
- 11.外观模式(Facade Pattern)
using System; namespace ConsoleApplication4 { class Program { /// <summary> /// 不使用外观模式的情况 /// ...