本文主要是介绍android 系统性能优化(70)---Android 性能优化,内存检测、卡顿优化、耗电优化、APK瘦身——详解篇,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
Android 性能优化,内存检测、卡顿优化、耗电优化、APK瘦身——详解篇
导语
一、性能检测工具
(一)网易开源的Emmagee , https://github.com/NetEase/Emmagee
Emmagee(机关枪)是网易杭州研究院QA团队开发的一个简单易上手的Android性能监测小工具,主要用于监控单个App的CPU,内存,流量,启动耗时,电量,电流等性能状态的变化,且用户可自定义配置监控的频率以及性能的实时显示,并最终生成一份性能统计文件。对于手游实时分析CPU和内存占比帮助非常大。
(1)优势
- 开源;
- 无需root权限;
- 支持2.2以及以上版本。但由于Google 安全限制,在7.0版本手机已不支持。
- 实时展示数据;
- 操作简单,支持自定义采集频率;
- CSV格式保存数据,方便为电脑使用Excel表格打开;
(2)检测案例步骤
1、在GitHub下载安装包Apk
2、运行Emmagee.app。可以设置采集频率。
3、点击APP"测试报告"查看,也可以配置邮件下发CSV文件。而我选择盗取文件到电脑上用Excel表格看。
(本地内部存储Emmagee目录”storage\sdcard0\Emmagee\某日期时间_APP包名.csv”的文件,即为监控数据)
操作adb查看命令:
$ adb shell //回车 $ cd storage/sdcard0/Emmagee/ //回车 $ ls //回车 ,结果如下: 20180605154517_com.daojia.csv 20180605160747_me.ele.csv
*手机导出的csv文件出现乱码,原因是由于导出的CSV文件编码为UTF-8 。解决办法:(Windows)使用记事本打开另存为“ANSI编码”的CSV格式文件即可。(Mac OS)文本编辑打开重新保存即可。
上面分别是对到家点餐APP、饿了么点餐APP的CSV检测数据。移动文件到电脑Excel打开查看:
(二)腾讯开源的GT,https://github.com/TencentOpen/GT
(1)什么是GT?
GT是一款同时支持安卓手机端和IOS手机端性能测试工具。
GT(随身调),即仅凭一部手机,无需连接电脑,就可以对APP进行快速的性能测试(CPU、内存、流量、电量、帧率/流畅度等)、 开发日志的查看、Crash日志查看、网络数据包的抓取、APP内部参数的调试、真机代码耗时统计等等;更重要的是,您可以在任意真实场所、 任何时候做如上的系列事情,这就是“随身调”。
如果您觉得GT提供的功能还不够满足您的需要, 您还可以利用GT提供的基础API自行开发有特殊功能的GT插件(仅iOS版支持), 帮助您解决更加复杂的APP调试、测试问题。
(2)如何使用?
GT支持iOS和Android两个手机平台,其中: Android版由一个可直接安装的GT控制台APP 和GT SDK插件扩展检测。GT控制台可以独立安装使用,SDK需嵌入被调测的应用、并利用GT控制台进行信息展示和参数修改。 iOS版是一个Framework包,必须嵌入APP工程,编译出带GT的APP才能使用;iPhone和iPad应用都能支持。
以下为Android版GT控制台APP 检测基础功能案例,使用步骤:
1、应用宝下载GT.APP,安装运行GT。
2、选择应用
3、选择关注的监控数据 4、结果展示
(三)科大讯飞的iTest,http://www.liqucn.com/rj/410791.shtml
iTest官方介绍:
该工具由科大讯飞测试技术部开发,在多个项目中成功应用,具有较高的准确性和稳定性。它填补了手机端自动化测试的空白,以实用高效为宗旨,记录特定应用的性能消耗情况,包括cpu、内存、流量、电量等信息。效果图如下所示。
遗憾本人寻遍全网,只能查找下载安装Apk的地址,查阅其他的相关介绍和资料太少。
毕竟科大讯飞在业界是很有名气的是讯飞语音。
(四)Google的开源Battery Historian,https://github.com/google/battery-historian
纵坐标 | 解释 |
---|---|
CPU runing | cpu运行的状态,是否被唤醒 |
Kernel only uptime | 只有内核运行时间 |
Activity Manager Proc | 活跃的用户进程 |
Mobile network type | 网络类型 |
Mobile radio active | 移动蜂窝信号 BP侧耗电 |
Crashes(logcat) | 某个时间点出现crash的应用 |
Doze | 是否进入doze模式 |
Device active | 和Doze相反 |
JobScheduler | 异步作业调度 |
SyncManager | 同步操作 |
Temp White List | 电量优化白名单 |
Phone call | 是否打电话 |
GPS | 是否使用GPS |
Network connectivity | 网络连接状态(wifi、mobile是否连接) |
Mobile signal strength | 移动信号强度(great\good\moderate\poor) |
Wifi scan | 是否在扫描wifi信号 |
Wifi supplicant | 是否有wifi请求 |
Wifi radio | 是否正在通过wifi传输数据 |
Wifi signal strength | wifi信号强度(great\good\moderate\poor) |
Wifi running | wifi组件是否在工作(未传输数据) |
Wifi on | 同上 |
Audio | 音频是否开启 |
Camera | 相机是否在工作 |
Video | 是否在播放视频 |
Foreground process | 前台进程 |
Package install | 是否在进行包安装 |
Package active | 包管理在工作 |
Battery level | 电池当前电量 |
Temperature | 电池温度 |
Charging on | 在充电 |
Logcat misc | 是否在导出日志 |
(五)Android 自带 Lint 工具
- 硬编码会提示以级别警告,例如:在布局文件中写了三层冗余的LinearLayout布局、直接在TextView中写要显示的文字、字体大小使用dp而不是sp为单位,就会在编辑器右边看到提示。
- 使用Android Studio的lint可以清除无用的资源文件(点击菜单栏的Analyze -> Run Inspection by Name, 输入unused resource)。
二、性能优化
- 追求流畅,防止卡顿
- 追求稳定,防止闪退
- 追求续航,防止耗损
- 追求精简,防止臃肿
(最重要是稳定,app出现闪退崩溃是致命的。相比之下卡顿耗损安装包大都还好些。)
(一)追求稳定,防止闪退
- public class CommUtil {
- private static CommUtil instance;
- private Context context;
- private CommUtil(Context context) {
- this.context=context;
- }
- public static CommUtil getInstance(Context context){
- if( null==instance){
- instance= new CommUtil(context);
- }
- return instance;
- }
- }
- public class MainActivity extends AppCompatActivity {
-
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- CommUtil instance = CommUtil.getInstance( this); //
- }
- }
这时,我们可以借助内存分析工具,可以显示内存数据的可视化页面,方便定位内存泄漏的代码。使用分析工具如下:
(1)Memory Monitor 工具:
(2)Memory Analyzer 工具:
MAT(Memory Analyzer Tool) 是一个快速,功能丰富的 Java Heap 分析工具,通过分析 Java 进程的内存快照 HPROF 分析,从众多的对象中分析,快速计算出在内存中对象占用的大小,查看哪些对象不能被垃圾收集器回收,并可以通过视图直观地查看可能造成这种结果的对象。
检测步骤如下:
(a)屏幕多次翻转,出现内存持续增高时。点击 Dump java Heap就会生成运行内存快照hprof文件。
(b)然后将APP完全退出,重新启动,打开Android Monitor 再次点击Dump java Heap 生成一份还没操作(旋转屏幕)前的内存快照hprof文件。现在就已经生成好了2份hprof文件, 一份是没有旋转过屏幕的 ,一份是旋转过屏幕多次的。
(c)然后选中Android Studio 最左边的Captures 进行将hprof文件导出。导出的时候需要选择保存的目录以及文件名。
(d)打开MAT ,导入我们的2个hprof文件 Open File-->选择文件-->Leak Suspects Report-->Finish:*案例参考
可以通过检索包名,查看某个类的实例个数和所在内存数据,还可以查看被引用的内存数据。如下:
Objects:实例个数
Shallow Heap:所占内存大小
Retained Heap:释放后能回收多少内存
(3)LeakCanary工具:
小结
(二)追求流畅,防止卡顿
- 界面绘制:主要原因是绘制的层级深、页面复杂、刷新不合理,由于这些原因导致卡顿的场景更多出现在 UI 和启动后的初始界面以及跳转到页面的绘制上。
- 数据处理:导致这种卡顿场景的原因是数据处理量太大,一般分为三种情况,一是数据在处理 UI 线程,二是数据处理占用 CPU 高,导致主线程拿不到时间片,三是内存增加导致 GC 频繁,从而引起卡顿。
(1)布局优化
- 布局复用,使用<include>标签重用layout;
- 提高显示速度,使用<ViewStub>延迟View加载;
- 减少层级,使用<merge>标签替换父级布局;
注意使用wrap_content,会增加measure计算成本;
删除控件中无用属性;
(2)绘制优化
布局上的优化。移除 XML 中非必须的背景,移除 Window 默认的背景、按需显示占位背景图片
自定义View优化。使用 canvas.clipRect() 帮助系统识别那些可见的区域,只有在这个区域内才会被绘制。
(3)启动优化
应用一般都有闪屏页SplashActivity,优化闪屏页的 UI 布局,可以通过 Profile GPU Rendering 检测丢帧情况。
闪屏页的存在可以说就是启动优化,通常在闪屏页延迟2秒跳转到主界面,但是在进入首页的时候,首页复杂的View渲染以及必须在UI线程执行的业务逻辑,必然拖慢了启动速度。启动闪屏页虽然简单执行快,首页却复杂执行慢,应用启动前轻后重。
所以要启动加载逻辑优化。可以采用分布加载、异步加载、延期加载策略来提高应用启动速。例如,把SplashActivity改成SplashFragment,应用程序的入口变成MainActivity,在MainActivity中先展示SplashFragment,显示完毕后再移除SplashFragment。这样,在SplashFragment的2S的友好时间内进行数据准备的同时,首页的View就能够被加载,首页的业务逻辑就能够被执行。在闪屏页窗口加载完毕后,我们加载activity_main的布局,考虑到这个布局有可能比较复杂,耽误View的解析时间,可以采用ViewStub的形式进行懒加载。
(4)刷新优化
- 减少刷新次数;
- 缩小刷新区域;
(5)动画优化
需要实现动画效果时,需要根据不同场景选择合适的动画框架来实现。有些情况下,可以用硬件加速方式来提供流畅度降低动画卡顿。
(三)节省——耗电优化
在移动设备中,电池的重要性自然不言而喻,如果手机没电了应用功能技术实现再怎么牛逼,用户也什么都干不成。对于Android操作系统和设备各大开发商来说,对手机耗电的优化从没有停止过,不断地追求更长的待机时间。而对于开发一款应用来说,绝不可以忽略电量耗损的问题,被归为“电池杀手”的应用,最终的结果无疑是走向被用户卸载的道路。比如,有些应用为了保持应用进程长期在后台存活,使用各种不合理进程保活方案,破坏操作系统“生态平衡”,导致用户电量严重耗损,虽然这种流氓开发行为并不违法吧,但是也属于不道德的行为,也同样会被同行所被鄙视的行为。
在 Android5.0 以前,关于应用电量消耗的测试即麻烦又不准确,而5.0 之后Google专门引入了一个获取设备上电量消耗信息的API—— Battery Historian。Battery Historian 是一款由 Google 提供的 Android 系统电量分析工具,直观地展示出手机的电量消耗过程,通过输入电量分析文件,显示消耗情况。
最后提供一些可供参考耗电优化的方法:
(1)计算优化。算法、for循环优化、Switch..case替代if..else、避开浮点运算。
(2)避免 Wake Lock 使用不当。
(3)使用 Job Scheduler 管理后台任务。
(四)安装包——APK瘦身
其实APK大小对应用使用并没有影响,但应用的安装包越大,用户下载的门槛越高。例如,应用版本的迭代更新,特别是当用户在移动网络情况下,又不得不去下载安装包,才能使用产品满足自身需求。因此,开发应该减小安装包大小,使得让更多用户愿意下载产品和体验产品。
(1)安装包的组成结构
assets文件夹。存放一些配置文件、资源文件,assets不会自动生成对应的 ID,而是通过 AssetManager 类的接口获取。
res。res 是 resource 的缩写,这个目录存放资源文件,会自动生成对应的 ID 并映射到 .R 文件中,访问直接使用资源 ID。
META-INF。保存应用的签名信息,签名信息可以验证 APK 文件的完整性。
AndroidManifest.xml。这个文件用来描述 Android 应用的配置信息,一些组件的注册信息、可使用权限等。
classes.dex。Dalvik 字节码程序,让 Dalvik 虚拟机可执行,一般情况下,Android 应用在打包时通过 Android SDK 中的 dx 工具将 Java 字节码转换为 Dalvik 字节码。
resources.arsc。记录着资源文件和资源 ID 之间的映射关系,用来根据资源 ID 寻找资源。
(2)减少安装包大小
1.代码混淆。使用IDE 自带的 proGuard 代码混淆器工具 ,它包括压缩、优化、混淆等功能。
2.资源优化。比如使用 Android Lint 删除冗余资源,资源文件最少化等。(这个前面已经讲过了)
3.图片优化。比如利用 PNG 优化工具 对图片做压缩处理。如果应用在4.0版本以上,推荐使用 WebP图片格式。
4.可以使用 微信开源资源文件混淆工具 —— AndResGuard 。一般可以压缩apk的1M左右大。5. 插件化热修复开发 。比如功能模块放在服务器上,按需下载,可以减少安装包大小。6.避免重复或无用功能的第三方库。例如,百度地图接入基础地图即可、讯飞语音无需接入离线、图片库Glide\Picasso等
三、总结
综上所述,对应用进行性能优化已然成为当下开发工程师应该具备的基本技能之一,也是对开发工程师是否有能力维护高质量应用程序的重要考核之一。另外,性能优化是一个非常具有挑战性的工作,上面列出很多分析检查的工具和方法,但是真正优化工作远不止如此,想要进行完美的性能优化绝非一日之功,需要考验开发者长期研究的耐心和深厚的技术功底。
这篇关于android 系统性能优化(70)---Android 性能优化,内存检测、卡顿优化、耗电优化、APK瘦身——详解篇的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!