本文的思维导图(这里使用的是MindNode)
android-interview-questions-06-advanced.png目录
内存优化
尽量避免使用枚举
相比基本数据类型, 枚举占用的内存更多, 因此, Android官方也建议避免使用枚举
Enums often require more than twice as much memory as static constants. You should strictly avoid using enums on Android.
使用SparseArray,ArrayMap代替HashMap
SparseArray | ArrayMap | |
---|---|---|
场景 | 替代Key为基本数据类型的HashMap | 替代Key为Object数据类型的HashMap |
目的 | 减少内存占用 | 减少内存占用 |
优点 | 节约内存 / No auto-boxing | 节约内存 |
缺点: | 大数据量时效率低 / 只在android可用 | 大数据量时效率低 / 只在android可用 |
更多参考Android Memories by Romain Guy / SparseArray vs HashMap / android use ArrayMap SparseArray instead of HashMap
使用Parcelable序列化
Serializable | Parcelable | |
---|---|---|
特点 | 实现简单但效率较低 | 效率更高但实现比较麻烦(推荐插件Android Parcelable Code Generator) |
原理 | 依赖反射, 同时产生大量临时对象会依赖GC | 过程完全由自己实现和控制 |
范围 | Java项目中都可用 | 只在android可用 |
在使用Intent传递数据时, 尽量使用Parcelable做序列化, 尤其当数据是Object类型时
详细参考PARCELABLE VS. JAVA SERIALIZATION IN ANDROID APP DEVELOPMENT
Bitmap
-
优先加入高分辨率资源 因为低分辨率图片适配高分辨率设备时图片会放大
-
对大图使用inSampleSize采样 生成缩略图应用到目标大小的的ImageView
-
对于超清大图使用BitmapRegionDecoder, 按区域加载并显示图片
详细参考Android 开发绕不过的坑:你的 Bitmap 究竟占多大内存 / Android 高清加载巨图方案 拒绝压缩图片
合理使用多进程
例如将Music Player分成两个独立的进程: UI + Play Service, 这样UI进程的资源就可以在Music Player后台长时间播放时释放
虽然这样的场景下, 可以降低内存占用, 但是通常情况下新的进程是会带来更多的内存开销的, 所以多进程的内存优化方式需要谨慎使用
性能优化
Layout
-
使用include对布局进行复用
-
减少复杂布局, 同时尽量避免使用Alpha通道
-
在子线程加载资源, 并对资源进行复用(RecyclerView中ViewHolder)
-
Lazy Load资源和View
WebView缓存
if (NetStatusUtil.isConnected(getApplicationContext())) {
webSettings.setCacheMode(WebSettings.LOAD_DEFAULT); //根据cache-control决定是否从网络上取数据。
} else {
webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); //没网,则从本地获取,即离线加载
}
使用Parcelable序列化
同上, 详细参考: 内存优化 - 使用Parcelable序列化
Bitmap
- 使用图片缓存: LruCache & DiskLruCache = Least Recently Used + LinkedHashMap + (Runtime Memory / 8)
详细参考LruCache
合理使用多线程
理论上, 除了UI操作以外的其他任何操作都是可以放在子线程中的
Android多线程详细参考android学习 之 Service
但是, 我们也并不鼓励"滥用"多线程, 因为
-
多线程有额外的系统开销
-
多线程往往伴有同步问题
-
多线程还需要考虑通信, 如果使用不当, 反而会引起内存问题(详细参考android开发 之 内存泄漏)
更多参考Performance Tips
打包优化
图片格式
常见图片格式的文件大小: png > jpg > webp, 但实际开发中主要还是使用png, 这是因为
-
png无损 而jpg有损
-
png有alpha通道 而jpg没有
-
png有硬解码加速 而jpg待考证
-
iOS会对png进行压缩和优化 而对jpg没有任何优化
-
在启动页等较大背景图片时 可以考虑使用jpg
-
webp支持alpha通道 压缩比例高 显示效果不错 但是鉴于没有广泛应用 所以酌情考虑使用
图片其他
-
对于简单图形可以使用代码实现
-
使用9-Patch+图片拉伸来适应不同屏幕的需求
-
多主题使用一套图片 + blending (详细参考iOS中使用blend改变图片颜色)
总之: 在开发过程中, 尽量少尽量小地引入图片
ProGuard
-
压缩: 移除无效的类、属性、方法等
-
优化: 优化字节码, 并删除未使用的结构
-
混淆: 将类名、属性名、方法名混淆为难以读懂的字母
在线化
-
酌情使用在线图片资源
-
插件化实现在线功能: React Native / NativeScript
精简
-
清理不用的图片资源, 语言资源等
-
使用优化过体积更小的第三方库
小结
由于经验和眼界有限, 本文肯定会有很多遗漏和错误, 欢迎大家留言和补充
附录
更多文章, 请支持我的个人博客
网友评论