您的位置:首页 > 移动开发 > Android开发

Android性能优化学习篇

2017-11-03 18:14 302 查看
参考文章

Android APP耗电优化:

http://blog.csdn.net/lhd201006/article/details/52851366

Android应用的电量消耗和优化的策略:

http://blog.csdn.net/tskyfree/article/details/46877671

Android性能优化(渲染机制、内存与GC、电量优化)带工具找问题

http://blog.csdn.net/jiankeufo/article/details/56844343

性能优化十五之电量优化案例:

http://blog.csdn.net/hpc19950723/article/details/69569255

一、渲染机制

具体渲染原理参考之前的一篇文章讲的很详细

http://blog.csdn.net/zhangcanyan/article/details/52817989

渲染性能的优化问题也就是要解决卡顿的问题。

卡顿的原因:

layout太过复杂,无法在16ms内完成渲染

UI上有层叠太多的绘制单元

动画执行的次数过多

解决及需要的工具:

1.HierarchyViewer 查找Activity中的布局是否过于复杂

2.以使用手机设置里面的开发者选项,打开Show GPU Overdraw等选项进行观察,找到哪里Overdraw区域较多;

3.使用TraceView来观察CPU的执行情况;

TraceView 简介及其案例实战请参考

http://www.cnblogs.com/sunzn/p/3192231.html

根据里面方法调试自己的代码使得调用函数耗费的时间达到最少可以解决代码性能问题

二、电量优化

耗电量多的一些原因:

为了省电,有些工作可以放当手机插上电源的时候去做。往往这样的情况非常多。像这些不需要及时地和用户交互的操作可以放到后面处理。比如:360手机助手,当充上电的时候,才会自动清理手机垃圾,自动备份上传图片、联系人等到云端。例如:拍照和图片处理是否可以做一些优化,假如现在手机的电量比较低,并且没有充电,拍照动作是要立马执行的,但是图片的处理是否可以放在用户插上手机充电器之后去处理?

获取到手机目前的充电状态的方法

public boolean getChargeState(){
IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent batteryStatus = this.registerReceiver(null, filter);
int chargePlug = batteryStatus.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
boolean usbCharge = (chargePlug == BatteryManager.BATTERY_PLUGGED_USB);
boolean acCharge = (chargePlug == BatteryManager.BATTERY_PLUGGED_AC);
boolean wirelessCharge = false;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
wirelessCharge = (chargePlug == BatteryManager.BATTERY_PLUGGED_WIRELESS);
}
return (usbCharge || acCharge || wirelessCharge);
}


以下总结耗电可能的原因:

http://blog.csdn.net/lhd201006/article/details/52851366

网络请求耗电,而且手机数据网络进行http请求比无线网进行http请求更加耗电,因为数据网络调用到一些底层的硬件模块,就如GPS一样,当手机打开GPS功能后,也是启动了一些硬件模块就会明显增加耗电;

高频的刷新UI界面,刷新UI界面其实就是进行layout的绘制,如果一个Activity的布局嵌套太多层,那么每一层layout都会刷新一次,例如动画等等这些都会造成耗电

数据库,SD卡文件操作,这些都是属于耗时操作,当操作次数很少的时候基本不会有耗电问题,但是当短时间内操作次数很多的话,也会明显的增加耗电,同时也有可能造成页面卡顿

AlarmManager,例如一些推送的心跳包实现,AlarmManager会定时唤醒CPU去执行一些任务,也是造成耗电的一大源头

手机网络环境不好的时候会频繁的切换网络,因为网络数据交互的时候,系统也是会被唤醒的,所以APP如果在监听了网络切换广播后做了大量的操作,一样会增加耗电

针对一些任务队列的处理,如果队列堆积的任务太多,导致循环执行太久也会造成耗电,因为占用了CPU资源去执行代码,我们的log日志工具保存到文件就是用任务队列实现的,当压力测试SDK一次性接受1万条消息的时候,那内存就表上来了,跟了下发现日志保存队列里面积压了4千多个任务,这时候即使手机锁屏,也还会不断的把队列中的任务执行完然后CPU才会休眠下去的,同样会造成严重的耗电,耗内存,好在release版本的日志都是关闭的

执行一些高运算量的代码,例如json数据解析,一些二进制协议的数据编码和解码

接收系统的一分钟广播,然后做一些程序逻辑处理,其实接收一分钟广播不耗电,耗电的是一分钟执行一次程序处理

Wake Lock使用不当导致没有及时的释放,Wake Lock可以阻止cpu进入休眠的,如果没有及时的release会造成cpu无法休眠,程序耗电严重

如果程序中有定时任务,在cpu休眠之后,定时任务就会被挂起不执行,这时候并不会造成太大的耗电,但是如果这个定时任务的时间间隔很短,1秒执行一次,那么当手机app集成了推送,推送就会有心跳包通过AlarmManager来唤醒,每次唤醒的时候就会再去执行挂起的定时任务,虽然执行定时任务的耗电量可能比心跳包的耗电量少很多,不过还是需要注意的,积少成多

其实android中的Log日志的打印也会耗电的,在日常开发中,我们可能不仅会把log打印到AndroidStudio里面,有可能还会保存起来,而且可能在打印对象信息数据的时候会用到json格式转换,这些都会增加耗电,但是在正式发布的apk包中日志管理一般都是关闭的

在手机锁屏后,CPU会过一段时间才休眠,如果程序中有定时任务,在CPU休眠后会被挂起不执行,但是在CPU休眠之前,定时任务还是会一直的执行的,之前遇到过这么一个问题,我们采用Picasso库:Picasso.with(context)

针对以上原因进行相应的优化

针对Http请求:

对http请求数据做GZIP压缩,当前流行的http第三方看默认都支持GZIP压缩

Http缓存,Http协议有一个Cache机制,当发出http请求的时候会先到指定目录下检查是否已经存在这个请求的数据,如果存在并且还没过时,那么就会直接返回;而一些第三方例如OkHttp也有有自己的缓存机制OKHTTP缓存

合并Http请求来减少Http请求次数,因为Http底层也是TCP连接,对于每个Http请求,发出请求的时候都会创建TCP连接,请求结束后会断开TCP连接,那么当Http请求次数很多的时候就会频繁的创建和断开TCP连接,如果把当中一些请求进行合理的合并,那么就会减少Http请求次数

制定合理的Http请求数据格式和返回数据格式,做到请求数据中没有冗余字段

4.可以在Http请求数据格式里面加一个字段dataVersion代表本地已有数据的版本号,然后传到服务器,服务器的数据表中也有一个字段是dataVersion,当服务器数据被修改的时候,dataVersion就加一,当检测到客户端传上来的dataVersion小于服务器数据表中的dataVersion的时候就返回最新数据,否则可以直接返回空数据代表当前本地数据已经是最新数据,这样就不会每次请求http的时候都会返回大量数据,当数据没有被改变的时候直接返回空,减少了http请求过程中的数据交互(但是要考虑一点,只有一些请求数据量比较大的才适合,因为增加了dataVersion字段后无论给客户端还是服务端也都相应的增加了维护的成本)

针对数据库,SD卡文件操作:

APP在对数据库或者SD卡文件操作的时候无非也是涉及到一些数据的转换,json转换,可以采用json解析效率高的第三方库,例如fast json,Jackson,gson

可以把一些需要持久化到数据库或者文件中的数据先缓存在内存中,然后在一个时间点一起触发一同更新到数据库或者文件中;例如,在进入Activity的时候会首先从数据库中搜索出帐户信息并且展示在界面,然后会再去发Http请求服务器的帐户信息数据,再把服务器最新的帐户信息数据刷新到界面中,同时也存在一个内存对象中,这时候先不更新到数据库,当退出这个Activity界面的时候可以去检测帐户数据是否发生改变,如果改变了就更新到数据中;这么做的好处是:如果在Activity界面多次修改数据,那最新的数据都是只更新到内存中的,当Activity退出后才把最新的帐户信息数据更新到数据库中,没必要更改一次就同时把数据更新一次到数据库

SD卡的文件读写操作比数据库要快,数据库也是属于文件,但是在写数据的时候还要经过sqlite的一些列数据库操作,但是SD卡在写数据的时候是直接写到文件中的,所以针对与简单数据,标志变量或者数据条数很少的数据,而且安全性要求也不高的数据可以直接存在文件中,例如SharedPreferences中,只有关系型的数据,数据安全性较高的,数据记录条数比较多的可以选择数据库存储,而且如果数据库进行加密后,对于数据库的读写操作会更慢了

针对数据库操作尽量不要直接使用android里面的Sqlite来手写读写的那些sql语句,可以选择一些orm框架库,例如ormlite,GreenDao等等,我们选择的是ormlite,因为ormlite数据库加密已经有现成的库可以提供使用
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android 性能优化