Android性能优化主要从卡顿、内存泄漏和崩溃、代码质量和逻辑、安装包过大四方面入手。在使用时避免出现卡顿,响应速度快,减少用户等待的时间,满足用户期望;同时减低 crash 率和 ANR 率,不要在用户使用过程中崩溃和无响应;节省流量和耗电,减少用户使用成本,避免使用时导致手机发烫;安装包小可以降低用户的安装成本。
1、卡顿优化
Android 系统每隔 16ms 发出 VSYNC 信号,触发对 UI 进行渲染,如果每次渲染都成功,这样就能够达到流畅的画面所需的 60FPS。在理想情况下,60 FPS 就感觉不到卡,这意味着每个绘制时长应该在16 ms 左右。如果某个操作花费的时间是 24ms ,系统在得到 VSYNC 信号时就无法正常进行正常渲染,这样就发生了丢帧现象。也就是延迟了。
布局优化:
合理使用背景色,避免重复绘制背景色,例如:父布局和子布局的背景色一样的,子布局无需在设背景色,父布局设置即可
减少布局嵌套,一般不建议超过5层,google推出ConstraintLayout可以使用
合理使用 include、merge 和 ViewStub,使用include和merge增加复用,减少层级; ViewStub 按需加载
尽可能少用wrap_content。wrap_content 会增加布局 measure 时计算成本,在已知宽高为固定值时,不用wrap_content
删除控件中无用的属性
绘制优化:在onDraw中不要创建嵌套对象和做耗时的任务;在databinding数据刷新的是尽量局部刷新,不要全局刷新。
启动优化:尽量在Application和Activity onCreate中进行耗时操作,同时避免在生命周期避免 I/O 操作、反序列化、网络操作、布局嵌套等
2、内存优化
通常在以下的场景容易导致内存泄漏:
资源性对象未关闭。比如Cursor、File、Bitmap等,往往都用了一些缓冲,在不使用时,应该及时关闭它们
注册对象未注销。比如事件注册后未注销,会导致观察者列表中维持着对象的引用。例如EventBus或者RxJava
单类或者静态变量持有大数据对象
引用的context是生命周期短造成,比如Toast,我们传入的是MainActivity,但MainActivity没有用了,需要被销毁,但我们的Tost依然持有其引用导致无法回收,这就导致了内存泄漏
匿名内部类或非静态内部类的静态实例
Handler临时性内存泄漏。如果Handler是非静态的,容易导致 Activity 或 Service 不会被回收
容器中的对象没清理造成的内存泄漏
WebView。WebView 存在着内存泄漏的问题,在应用中只要使用一次 WebView,内存就不会被释放掉
手动注册广播时,退出时忘记 unregisterReceiver()
Service 执行完后忘记 stopSelf()
3、稳定性和耗电优化
Android 应用的稳定性影响稳定性的原因很多,比如内存使用不合理、代码异常场景考虑不周全、代码逻辑不合理等。其中最常见的两个场景是:Crash 和 ANR,这两个错误将会使得程序无法使用。可以下面的方法进行解决:
提高代码质量,例如代码审查、checkstyle统一风格、处理复杂逻辑时最好自己画下流程图
代码静态扫描工具。常见工具有Android Lint、Findbugs、Checkstyle、PMD等
Crash监控和上传。把一些崩溃的信息,异常信息及时地记录下来,以便后续分析解决;或者有条件的可以使用bugly,把异常信息上报
推荐使用 JobScheduler,来调整任务优先级等策略来达到降低损耗的目的
计算优化,避开浮点运算等耗时计算
避免 WaleLock 使用不当
4、安装包大小优化
安装包过大,对用户的下载欲望有影响,特别是在移动网络下,提高用户进入门槛,虽然现在移动网络已经无限流量,但apk过大加大了安装时间,常用应用安装包的构成,如图所示:
lib文件夹:存放一些第三方库文件。
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 寻找资源。
减少安装包大小的常用方案
代码混淆。使用proGuard 代码混淆器工具,它包括压缩、优化、混淆等功能。
资源优化。比如使用 Android Lint 删除冗余资源,资源文件最少化等。
图片优化。比如利用 AAPT 工具对 PNG 格式的图片做压缩处理,降低图片色彩位数等,或者使用webp格式图片。
插件化。比如功能模块放在服务器上,按需下载,可以减少安装包大小。
减少lib。能自己写的lib尽量自己写,第三方lib可能会带有你未必需要的代码;还有就是如果不想支持x86架构的手机,可以删除x86lib,或者打包的时候排除x86包。
删除lombok。这个apk使用lombok,虽然带来了get,set的方便,但是apk也增大了,可以根据具体需求来决定是否使用。