背景
当初安卓零碎无论是性能还是体验上其实都不输于 iOS,只是因为手机厂商多而杂,他们会改源码,自定义零碎,最初又过一遍不同开发程度工程师的手,导致很多手机即便在机器下面的跑分十分高,外面的 APP 运行也有卡顿景象。
而且这种卡顿会随着产品的更新迭代,性能的越发简单,UI 页面的越发丰盛,变得更加重大。
然而,产品性能的更新需要,新性能的开发和 UI 的丰盛都是用户的需要,是不可逆的趋势。在这样的状况下,优良的性能优化人才始终是几大头部互联网公司高价竞聘的对象。
性能优化的目标
- 晦涩(解决:卡顿)
- 稳固(解决:内存溢出、解体)
- 低耗损(解决:耗电快、流量大、网络慢)
- 小安装包(解决:APK 过大)
性能优化的方向
- 布局优化
- 绘制优化
- 网络优化
- APK 优化
- 内存优化
- 卡顿优化
- 耗电优化
- ListView/RecycleView 及 Bitmap/ 图片优化
- 数据库 SQLite 优化
- 启动优化
- 数据结构优化
- 稳定性优化
性能优化计划
布局优化
实质:缩小 View 的层级,进步测量、布局和绘制的速度。
罕用计划:
- 优先选择 LinearLayout 布局能够缩小 View 的层级(留神雷同组件可能 RelativeLayout 绘制工夫长);
- 应用 < include > 标签抽取罕用的布局组件中的独特局部(便于复用);
- 用 < ViewStub > 标签加载不罕用的布局,提早加载(须要的时候在 activity 中加载进去);
- 用 < Merge > 标签缩小布局的嵌套档次
绘制优化
实质:View 的 onDraw 办法要防止执行大量的操作
罕用计划:
onDraw 中不要创立新的部分对象(防止产生大量的长期对象占用过多内存);
onDraw 办法中不要做耗时的工作(尽量升高 onDraw 办法中的复杂度)
网络优化
实质:缩小流量耗费、电量耗费、用户等待时间,进步用户体验。
罕用计划:
- 尽量减少网络申请,可能合并的就尽量合并
- 防止 DNS 解析,依据域名查问可能会消耗上百毫秒的工夫,也可能存在 DNS 劫持的危险。能够依据业务需要采纳减少动静更新 IP 的形式,或者在 IP 形式拜访失败时 -
切换到域名拜访形式。- 大量数据的加载采纳分页的形式
- 网络数据传输采纳 GZIP 压缩
- 退出网络数据的缓存,防止频繁申请网络
- 上传图片时,在必要的时候压缩图片
APK 优化
实质:缩小安装包体积。
罕用计划:
- 缩小利用中不必要的资源文件,比方图片,在不影响 APP 成果的状况下尽量压缩图片,有肯定的成果
- 在应用了 SO 库的时候优先保留 v7 版本的 SO 库,删掉其余版本的 SO 库。
- res 资源优化
- 代码优化
- lib 资源优化
- assets 资源优化
- 代码混同
- 插件化
- 7z 极限压缩
PS:具体具体的操作实现实现原理,后文另外有专门的剖析。
内存优化
实质:防止内存透露、扩充内存。
罕用计划(从不同方向探讨):
扩充内存:
- 一个是在清单文件中的 Application 下增加 largeHeap=”true” 这个属性,另一个就是同一个利用开启多个过程来扩充一个利用的总内存空间。
- 第二种办法其实就很常见了,比方说我应用过个推的 SDK,个推的 Service 其实就是处在另外一个独自的过程中。
内存透露(多方向探讨):
动态变量导致的内存透露
方法:将外部类设为动态外部类或独立进去;应用 context.getApplicationContext()。
单例模式导致的内存透露
计划:传参 context.getApplicationContext()。
属性动画导致的内存透露
计划:在 Activity.onDestroy()中调用 Animator.cancel()进行动画。
Handler 导致的内存透露
计划:应用动态外部类 +WeakReference 弱援用;当外部类完结生命周期时清空音讯队列。
线程导致的内存透露
计划:将 AsyncTask 和 Runnable 设为动态外部类或独立进去;在线程外部采纳弱援用保留 Context 援用。
资源未敞开导致的内存透露
计划:在 Activity 销毁的时候要及时敞开或者登记。例如:
① BraodcastReceiver:调用 unregisterReceiver()登记;
②Cursor,Stream、File:调用 close()敞开;
③Bitmap:调用 recycle()开释内存(2.3 版本后无需手动)。
Adapter 导致的内存透露
计划:在结构 Adapter 时应用缓存的 convertView。
WebView 导致的内存透露
计划:其实防止 WebView 导致内存透露的最好办法就是让 WebView 所在的 Activity 处于另一个过程中,当这个 Activity 完结时杀死以后 WebView 所处的过程即可,我记得阿里钉钉的 WebView 就是另外开启的一个过程,应该也是采纳这种办法防止内存透露。
汇合类透露
计划:在 onDestry 时回收不须要的汇合。
PS:为什么会导致透露,以及透露的具体情况,更多原理,后文另外有专门的剖析整顿。
卡顿优化
实质:优化 UI、进步启动跳转还有响应的速度。
罕用计划:
- 不在主线程进行网络拜访 / 大文件的 IO 操作
- 绘制 UI 尽量减少绘制 UI 档次;缩小不必要的 view 嵌套,能够用 Hierarchy Viewer 工具来检测,前面会具体讲;
- 当布局是用的 FrameLayout,能够把它改成 merge,能够防止本人的帧布局和零碎的 ContentFrameLayout 帧布局重叠造成反复计算(measure 和 layout)
- 进步显示速度, 应用 ViewStub:当加载的时候才会占用。不加载的时候就是暗藏的,仅仅占用地位。
- 在 view 层级雷同的状况下,尽量应用 LinerLayout 而不是 RelativeLayout;因为 RelativeLayout 在测量的时候会测量二次,而 LinerLayout 测量一次,能够看下它们的源码;
- 删除控件中无用的属性;
- 布局复用. 比方 listView 布局复用
- 尽量避免适度绘制(overdraw), 比方:背景常常容易造成适度绘制。因为咱们布局设置了背景,同时用到的 MaterialDesign 的主题会默认给一个背景。这时应该把主题增加的背景去掉;还有移除
- XML 中非必须的背景
- 自定义 View 优化。应用 canvas.clipRect()来帮忙零碎辨认那些可见的区域,只有在这个区域内才会被绘制。也是防止适度绘制.
- 启动优化, 启动速度的监控,发现影响启动速度的问题所在,优化启动逻辑,进步利用的启动速度。比方闪屏页面,正当优化布局,加载逻辑优化,数据筹备.
- 正当的刷新机制,尽量减少刷新次数,尽量避免后盾有高的 CPU 线程运行,放大刷新区域。
耗电优化
实质:缩小电量耗费。
罕用计划:
- 正当的应用 wake_lock 锁,wake_lock 锁次要是绝对零碎的休眠 (这里就是为了省电,才做休) 而言的,意思就是我的程序给 CPU 加了这个锁那零碎就不会休眠了,这样做的目标是为了全力配合咱们程序的运行。有的状况如果不这么做就会呈现一些问题,比方微信等及时通信的心跳包会在熄屏不久后进行网络拜访等问题。所以微信外面是有大量应用到了 wake_lock 锁。
- 应用 jobScheduler2,集中处理一些网络申请,有些不必很及时的解决能够放在充电的时候解决,比方,图片的解决,APP 下载更新等等;
- 计算优化,避开浮点运算等。
- 数据在网络上传输时,尽量压缩数据后再传输,倡议用 FlatBuffer 序列化技术,这个比 json 效率高很多倍,不理解 FlatBuffer,倡议找材料学习一下。
现如今,国内挪动互联网红利期已过,Android 开发也从最后的一人难求,到起初的一个岗位百人竞投,口多食寡的状况间接导致整个行业对求职者的要求越来越高,Android 开发越来越标准,间接导致我的项目对品质要求的晋升。启动优化、内存优化、App 解体监控等性能调优也逐步成了人手必备的技能。
学习资源和路线
我这里就分享一份由大佬亲自收录整顿的性能优化学习笔记,另外还有 Android 学习 PDF+ 架构视频 + 面试文档 +Android 开发面试专题材料,高级进阶架构材料和视频。
总结
这些都是我当初空闲时还会重复翻阅的精品材料。外面对近几年的大厂面试高频知识点都有具体的解说。置信能够无效地帮忙大家把握常识、了解原理,帮忙大家在将来获得一份不错的答卷。
心愿能帮忙大家在技术的路线上更进一步。当然,你也能够拿去查漏补缺,晋升本身的竞争力。真心心愿能够帮忙到大家,Android 路漫漫,共勉!
因为文章篇幅无限,文档资料内容较多,本能够提供链接下载,但无奈容易被谐和,所以全副存档,须要这些文档这里的敌人,能够【点击这里收费获取】,心愿可能共同进步,共勉!