参考文章:Android性能优化总结
android性能优化典范
Android性能优化的方向
1.复杂的布局
2.耗电量
3.内存的占用
4.频繁的网络请求
5.代码的执行效率
一、复杂的布局影响:
复杂的布局会造成界面的过度绘制,过度绘制是指屏幕上的某一个像素点被多次绘制。例如我们有一些不可见或者没有必要的布局,它也再做绘制操作(可以参考布局源码)。这时就造成了GPU和CPU的流失。参考Android中RelativeLayout和LinearLayout性能分析线性布局和测量时间要比相对布局的测量时间快3倍左右,这是因为相对布局中的view依靠依赖关系进行了位置的摆放,所以在源码中相对布局首先横向测量一次子View然后纵向又测量了一次子view。
第一次是进行了横向的测量,第二次进行了纵向的测量。
而线性布局的测量只进行了一次
根据设定的不同方向,进行不同的测量。
同时Relativelayout的测量方法还有一个问题:(摘抄自Android中RelativeLayout和LinearLayout性能分析)
View的measure方法里对绘制过程做了一个优化,如果我们或者我们的子View没有要求强制刷新,而父View给子View的传入值也没有变化(也就是说子View的位置没变化),就不会做无谓的measure。但是上面已经说了RelativeLayout要做两次measure,而在做横向的测量时,纵向的测量结果尚未完成,只好暂时使用myHeight传入子View系统,假如子View的Height不等于(设置了margin)myHeight的高度,那么measure中上面代码所做得优化将不起作用,这一过程将进一步影响RelativeLayout的绘制性能。而LinearLayout则无这方面的担忧。解决这个问题也很好办,如果可以,尽量使用padding代替margin。
测试过度绘制的方法:部分手机的开发者选项里有GPU测试这一选项。
GPU测试实例:
1.红色位置采用的是相对布局。所以在布局的使用上推荐FrameLayout>LinearLaytou>Relativelayout
2.尽量减少没有必要的布局嵌套
推荐测试工具:无线UIViewer—强烈推荐App工具,可在手机端直接实现HierarchyViewer的功能,查看任意界面的UI布局。
二、使用布局标签优化
include引入重复的布局。
当多个页面使用一种样式的布局时,可以将重复的布局抽出来,单独成立一个新的布局,当其他布局需要的时候,可以使用include标签引入进去。
merge合并布局
当子布局和父布局是同一类型时,可以使用merge标签作为子布局的布局标签。解决布局重复的问题。
ViewStub
ViewStub是一个在加载前不可见的,并且可以延时加载的布局。ViewStub在不调用infalte方法,或visable方法前,它所指定的布局是不可见的。
ViewStub test=findviewbyId(R.id.test_viewstub);
if(可以显示){
test.inflate();
}
影响耗电量的部分重要因素:
大量的数据传输
频繁的网络切换
长时间的后台服务
某些方法在断网情况下还不断的去尝试请求网络。
参考android性能优化典范和Android开发者文档发现,使用无线电波进行数据传输是最为耗电的,使用预取(prefetching),捆绑(bundle)的方式进行数据的传输,这些操作都是为了最小化电量的消耗,批量处理请求和根据网络连接类型来处理来解决耗电量的问题
典型的 3G 无线电网络有三种能量状态:
Full power:当无线连接被激活的时候,允许设备以最大的传输速率进行操作。
Low power:一种中间状态,对电量的消耗差不多是 Full power 状态下的50%。
Standby:最小的能量状态,没有被激活或者需求的网络连接。
也就是说我们在使用无线电波进行数据传输时,可能会在一下3种状态下进行。每一个新建立的连接开始都处于Full Power状态。这会相当耗电。(关于无线电传播数据具体内容请阅读http://www.research.att.com/articles/featured_stories/2011_03/201102_Energy_efficient?fbid=8xEDul3FFK0)
解决方式
1.预取数据方式:单词连接以最大能力将用户所有可能需要到的数据请求下来。个人理解为将数据请求下来后,保存到本地数据库内,用户再次进入app后,优先阅读本地保存的数据,当用户需要请求最新的数据时,只比本地数据更新的数据,这样也可以有效的减少数据传输的容量。
2.批量处理:参照android开发文档给出的例子,我们可以将所有可能要请求的数据放在请求队列,执行请求队列的任务时只发起一次无线电波进行请求,而不是发现有新的任务就发出无线电进行请求。
如何做到批处理呢:
使用Job Scheduler
1.首先定义一个JobService
下面是笔者结合googlesample写的JobService的列子,JobServcie的工作是将日志统一收集后一并发送的工作。
2.定义要执行的任务,该任务在JobService中执行
LogGroup里面装的是配置好的日志信息,myLogStore负责把所有的日志上传。里面是多个请求
3.将任务交给JobServcie
将任务交给JobService时需要配置一些信息,这些信息表示在满足什么情况条件下执行任务
JobInfo. Builder负责配置满足的信息。schedule负责执行任务。
使用ArrayMap和SparseArray代替HashMap
http://blog.csdn.net/u010687392/article/details/47809295
http://blog.csdn.net/u010687392/article/details/47809295