头条
应用启动页
把window的背景设置为闪屏页,一旦MainActivity加载完毕就显示主页了。
虽然用户也会看到一个类似的闪屏页,但那个闪屏页实际只是activity在theme中设置的background。
- @drawable/splash_logo
Application中的onCreate()中耗时io操作进行新开线程处理,组件的注册,初始化延时操作。
绘制性能
过度绘制
Overdraw有时候是因为你的UI布局存在大量重叠的部分,还有的时候是因为非必须的重叠背景。常见的是背景资源,根布局中设置了一遍,子布局中又进行多次设置。通过移除重复的背景资源,可减少过度绘制的发生。(开发者模式中可开启,应对应用的每一个页面进行检测)。
gpu monitor
在开发者模式中开启GPU呈现模式图,分析每一个页面的gpu运行状态(需考虑在低端手机上的表现)。
蓝色偏高,说明是单位消息里CPU太耗时,得把方法的执行都打出来看看哪个耗时。比如,在某处先看看是不是应该出现onMeasure,然后可以通过sdk自带的View布局工具,看一下哪个View的onMeasure耗时最多。
红色偏高,说明GPU忙不过来。优化过渡绘制,使用离屏缓存来优化。
黄色偏高,说明半透明GPU不仅在忙着绘制你的window也还忙着绘制别的,可能的情况为透明window叠加多了,window里的contentView有多个且相对复杂,或者GPU降频了等等,想具体分析需要查看GPU的trace。
HierarchyViewer
可完整,详细体现出每一个布局的创建耗时,优化每一个‘红灯’。
布局复用,层级嵌套
结合HierarchyViewer分析,不多累赘。
自定义组件
部分复杂且可循环利用的ui需考虑写成自定义组件,手动实现onMeasure,onLayout同时亦可解决嵌套层级问题;此外可考虑动态添加控件以减少解决 xml 加载时间(inflate本身是io操作,而手机性能下降很大的一个原因就是io性能变差)。
内存管理
memory monitor
可在android studio中观测memory的变化,在运行每一个页面的时候观测memory monitor中曲线变化,留意是否存在以下情形:
高内存占用
普通页面布局不复杂,加载图片少,却占用大量内存,如100M以上。
内存抖动
大量对象频繁的创建,销毁能引起内存抖动。
gc回收不明显
如在简洁页面下,手动gc,回收内存较少,且内存占用大,应考虑内存泄露 。
降低内存占用
a.在存在大量图片页面,尽可能采用软引用/弱引用对图片进行管理,降低对系统的负荷。
b.页面关闭时,主动进行释放资源(background置null等)。
c.Config常量文件拆分,按功能模块建立常量类,按需加载,减小常量池的大小(目前项目常量数,普遍在500个左右)。
内存泄露
可参考之前的文章
常见内存泄露场景
a.单例
尤其是部分带ui的单例,如dialog,因持有Context而发生泄露
b.内部类
内部类(非静态内部类)的存在需依赖外部类实例(持有引用),常见的是Handler的泄露
c.观察者模式的反注册,常见的广播,各种事件总线
d.长连接,持续性
网络,流,数据库连接,动画的关闭
e.native方法泄露
常见于bitmap的泄露,未对bitmap进行回收处理。
资源兜底回收
复杂页面,抑或引用大量资源的页面,在关闭页面后,主动释放资源。
内存分析工具
a.MAT
b.Android studio自带memory monitor
c. leakcanary
d.其他三方类库(github上的haha等项目)
网络请求
在已有的功能基础上增加请求合并的功能,常见的实现方式为,在同一个请求队列中,对相同的请求进行合并以减少网络请求次数。
应用体积压缩(瘦身)
删选so库 了解应用的设备分布范围,常见的如x86平台的可以忽略(即不支持)
defaultConfig { applicationId APPLICATION_ID minSdkVersion MIN_SDK_VERSION as int targetSdkVersion TARGET_SDK_VERSION as int versionCode VERSION_CODE as int versionName VERSION_NAME multiDexEnabled MULTI_DEX_ENABLE as boolean ndk { abiFilters 'armeabi-v8a' //abiFilters 'x86', 'x86_64', 'armeabi','armeabi-v7a','armeabi-v8a' } }压缩资源
a.采用tinypng可将图片压缩至原图的20%-50%
b.Drawable xml替代图片:常见的纯色的背景,同时由于是直接将 Shape 信息传到底层由 GPU 进行渲染,有一定程度上性能提升。
c.只保存一份图片资源(慎重)
目前市面上大部分机型都处于 xxhdpi 的适配范围,因此可以考虑只保留 xxhdpi 目录下一份图片资源。
d.删减资源
buildTypes { release { minifyEnabled true shrinkResources true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' }}e.移除未使用的备用资源
android { defaultConfig { ... resConfigs "en", "fr" }}f.管理三方类库(因在建立项目之初即需考虑的问题)
如项目中引入三方类库为解决某一个问题时(常见的是一些ui效果,在开发之初无充裕的时间成本),因此在优化阶段建议手动实现已减少依赖。
合并,精简类库
某些带有重复功能的类库,类似的volley与okhttp,glide的类库,存在功能上的重叠,建议删选。
低内存
在OnTrimMemory中主动释放可回收资源,取消动画效果,减少/合并网络请求。
AS自带工具使用
lint 检测整个项目,Win下可在Terminal中执行命令
gradlew lint
或选中lint项
lint.png
根据文档建议修改(原则上消除每一个文件中的warning).
也可以自定义规则检测项目代码规范。
删除无用资源:
在Refactor中选择 Remove Unsed Resources...
Remove Unsed Resources....png
其他代码细节
枚举
如仅仅实现标识静态常量的功能,不建议使用枚举,直接采用接口更为便捷,合理;在要保证参数类型安全的情况下(编译时类型安全),完全可以使用,不用在意这么点内存占用。
上一篇:优化种族计划
下一篇:搜索引擎优化操作过程