拿小车举例,你们知道什么是一辆小车的性能吗?同窗甲说,是否省油、加速是否够快、开起来是否稳定、安全等等。web
没错,那就是小车的性能。数据库
那App的性能又是指什么呢?同窗乙说,App启动是否够快,运行是否流畅,是否省电、省流量,安装包体积是否够小等等。json
是的,这就是App的性能。缓存
咱们知道,一辆小车性能越好,加速越快,跑的越稳,越省油。安全
App也同样,性能越好,运行更流畅、更稳定、更省流量、电量,包的体积也会更小,这能给用户带来优秀的体验,进而也会提高App的知名度。性能优化
既然App性能那么重要,那咱们就要掌握App性能优化的技能了。服务器
掌握App性能优化,是Android开发人员进阶中高级的必备技能。那如何进行App的性能优化呢?网络
咱们能够从这几个方面入手:卡顿优化、内存优化、稳定性优化、耗电优化、安装包大小优化、数据库SQLite优化、网络优化。数据结构
接下来,咱们逐一展开讲解。框架
可分为四个大的方向:
UI包括绘制和渲染。
启动可分为冷启动、热启动。
跳转包括页面间跳转和先后台切换。
包括:点击、滑动、系统事件、按键。
可分为如下两方面缘由:
首先,咱们要明白这样一个概念,人类肉眼在看每秒60帧(即:每帧16ms)的画面时,是不会感觉画面卡顿,当低于60帧/秒,咱们就会感觉到画面卡顿了。
Android系统每隔16ms就发出Vsync,触发对UI的渲染。若是每次都在<=16ms内完成渲染,界面就会流畅;若是每次都在>16ms才能完成渲染,就会形成丢帧,界面就会卡顿。
主要包括数据处理耗时,数据处理占用CPU太高,内存增长致使频繁GC等。
Hierarchy View,Profile GPU Rendering,TraceView,Systrace
减小布局层级嵌套,布局复用,删除无用属性,使用ViewStub提升显示速度。
经常使用布局的优化,自定义View的优化。
UI布局,逻辑加载优化,数据准备策略优化。
减小刷新次数,缩小刷新区域,避免后台有较高的CPU线程运行。
其余:好比,使用动画效果,根据不一样场景选择合适的动画框架实现。有些状况,可使用硬件加速来提升流畅度。
Android应用都是在Android虚拟机上运行的,内存分配和垃圾回收都是由Android虚拟机来完成的。
建立-使用-销毁(包括:不可见-不可达-收集-终结-对象再分配)。
Android系统内存分配,其实是对堆的分配和释放。
年轻代、老年代、持久代。
全部新生成的对象都放在年轻代。
年轻代分为一个Eden区和两个Survivor区。
GC时,当Eden区满时,还存活的对象会被复制到其中一个Survivor区(A)。
当这个Survivor区(A)也满时,就会被复制到另外一个Survivor区(B)。
当Survivor区(B)也满时,从第一个Survivor(B)复制过来而且还存活的对象,就会被复制到老年代。
在年轻代经历了N次垃圾回收仍然存活的到对象,就被放到老年代。
主要存放静态文件,好比Java类,方法等。
持久代对垃圾回收没有明显影响。
若是持久代空间过小,可经过-XX:MaxPermSize =< N配置。
资源类的对象未关闭。
注册系统事件未注销:使用Sensor Manager等系统服务,Context.getSystemService(int name)获取系统服务。
类的静态变量持有大数据对象:如,activity的静态变量持有该activty的引用。
非静态内部类的静态实例。
Handler形成内存泄漏。
WebView。
匿名类:new AsyncTask,new Thead,TimerTask。这些匿名类对象结束以前一直持有对应activity的引用,致使activity实例没法被回收,形成内存泄漏。
Memory Monitor,Heap Viewer,Allocation Tracker,Memory Analyzer Tool,LeakCanary。
根据实际需求,合理使用强引用,软引用,弱引用,虚引用。
增长内存复用:好比合理使用系统自带的资源,视图,图片,对象池等的复用。
留意自动装箱。
使用最优数据类型,好比使用ArrayMap,避免使用枚举类型,使用LruCache等。
图片压缩,图片缓存。
Crash,ANR。
稳定性主要依赖代码优化,逻辑实现的优化来提高。因此从代码层面来看,分析工具主要有:Android Lint,Findbugs,Checkstyle,PMD,FireLine。
App耗电严重,会给用户带来很是差的体验,致使用户卸载应用。
这是Google出的Android系统电量分析工具。
避免浮点运算等等。
节省流量,提升用户对App的好感度。
使用ProGuard工具进行压缩,优化,混淆。ProGuard的原理:压缩,优化,混淆。
使用Android Lint删除冗余资源,使资源文件最小化。
使用AAPT,TinyPng压缩图片,使用webP图片格式等。
对比选择最优库,不要引入多个相似功能的库。若是有相关库的源码,可根据实际需求,抽取须要的代码从新编译库,让库尽量的小。
可将功能模块放服务器,须要用时再加载。
文章APK极限压缩:
索引是对数据库表中一列或多列数据进行排序的一种数据结构。可理解为一个指向表中数据的指针,与一本书的目录相似。
加快表中数据查询速度。
建立索引自己也会形成资源开销。
表索引:CREATE INDEX index_name ON table_name。
单列索引:CREATE INDEX index_name ON table_name(column_name)。
惟一索引:CREATE UNIQUE INDEX index_name ON table_name(column_name)。
组合索引:CREATE INDEX index_name ON table_name(column1,column2)。
主键索引:ALTER TABLE table_name ADD CONSTRAINT index_name PRIMARY KEY(primaryKey)。
合理使用索引,可加快数据库表数据的查询速率。
对数据库原子性的操做。
为数据的总体性执行带来可靠安全性,为更新和删除操做带来很大优化。
保证数据的完整性,安全性,提升数据更新,删除操做的效率。
尽可能少用cursor.getColumnIndex()。
用StringBuilder(非线程安全)或StringBuffer(线程安全)来拼接字符串。
查询时,只返回须要的数据或结果。
cursor使用后要及时关闭。
网络优化很差,形成用户流量消耗大,耗电快,用户等待时间长体验差等。
Network Monitor,Charles,Fiddler,Stecho。
API设计要合理。
使用GZIP压缩。
选择合适的数据格式:json,xml,protocol Buffer。
图片下载:
使用缩略图。
使用WebP图片。
根据设备规格,指定图片尺寸请求图片。
使用完善的合适的图片加载框架:Glide,Picasso等。
图片上传:通常要支持断点续传。
适当缓存,可以让App看起来更快。
使用DiskLruCache。
网络情况好(如:WiFi状态下),可一次异步发起多个业务模块的数据请求。
休眠状态(即:熄屏状态下),尽可能不要发起网络请求。
充电状态,可适当作一些必要的网络请求,但要控制频率。
弱网状态下,可压缩和减小数据传输量;不要自动加载图片,用占位图显示;页面视图先显示,网络请求延迟提交。
划分网络请求的优先级,同一页面,同一模块,重要的数据优先请求。
网络差,减小请求量;网络好,提升请求量。
合并网络请求,减小请求次数。好比,本地埋点数据,无需实时上报,可先本地缓存,再根据上报策略,选择合适时机一并上报。
IP直连,省去DNS解析时间。
使用HttpDns,防止运营商域名劫持或跨网访问问题。
使用本地缓存,让App在离线状态也能使用。
优先使用缓存;当没有缓存或缓存国旗,再请求网络数据。
App性能优化,是一个持续地过程,须要咱们不断提升本身性能优化的能力,才能提升App的性能,才能打造出"快,省,稳"的极佳体验App。
加油~~
你们有好的建议和见解,都欢迎在评论区留言,一块儿交流学习,谢谢🙏。