Android性能优化汇总(逐步更新中...)

Android中的性能优分为以下几个方面:布局优化、网络优化、安装包优化、内存优化

一.布局优化

布局优化的本质就是减少View的层级。常见的布局优化方案如下:

  • 在LinearLayout和RelativeLayout都可以完成布局的情况下优先选择RelativeLayout,可以减少View的层级,但是注意相同组件可能RelativeLayout绘制时间长
  • 将常用的布局组件抽取出来使用 < include > 标签
  • 通过 < ViewStub > 标签来加载不常用的布局
  • 使用 < Merge > 标签来减少布局的嵌套层次

二.网络优化:

常见的网络优化方案如下

  • 尽量减少网络请求,能够合并的就尽量合并
  • 避免DNS解析,根据域名查询可能会耗费上百毫秒的时间,也可能存在DNS劫持的风险。可以根据业务需求采用增加动态更新IP的方式,或者在IP方式访问失败时切换到域名访问方式。
  • 大量数据的加载采用分页的方式
  • 网络数据传输采用GZIP压缩
  • 加入网络数据的缓存,避免频繁请求网络
  • 上传图片时,在必要的时候压缩图片

三.安装包优化

安装包优化的核心就是减少apk的体积,常见的方案如下:

  • 使用混淆,可以在一定程度上减少apk体积,但实际效果微乎其微
  • 减少应用中不必要的资源文件,比如图片,在不影响APP效果的情况下尽量压缩图片,有一定的效果
  • 在使用了SO库的时候优先保留v7版本的SO库,删掉其他版本的SO库。原因是在2018年,v7版本的SO库可以满足市面上绝大多数的要求,可能八九年前的手机满足不了,但我们也没必要去适配老掉牙的手机。实际开发中减少apk体积的效果是十分显著的,如果你使用了很多SO库,比方说一个版本的SO库一共10M,那么只保留v7版本,删掉armeabi和v8版本的SO库,一共可以减少20M的体积。

四.Android内存优化

Android的内存优化在我看来分为两点:避免内存泄漏、扩大内存,其实就是开源节流

其实内存泄漏的本质就是较长生命周期的对象引用了较短生命周期的对象。

1.常见的内存泄漏:
  • 静态变量导致的内存泄漏
    详情:一个静态变量又是非静态内部类会一直持有对外部类的引用,导致外部类Activity无法被回收。
    解决办法:将内部类设为静态内部类或独立出来;使用context.getApplicationContext()
  • 单例模式导致的内存泄漏
    详情:单例传入参数this来自Activity,使得持有对Activity的引用。
    解决办法:传参context.getApplicationContext()
  • 属性动画导致的内存泄漏
    详情:没有在onDestroy()中停止无限循环的属性动画,使得View持有了Activity。
    解决办法:在Activity.onDestroy()中调用Animator.cancel()停止动画。
  • Handler导致的内存泄漏
    详情:Message持有对Handler的引用,而非静态内部类的Handler又隐式持有对外部类Activity的引用,使得引用关系会保持至消息得到处理,从而阻止了Activity的回收。
    解决办法:使用静态内部类+WeakReference弱引用;当外部类结束生命周期时清空消息队列。
  • 线程导致的内存泄漏
    详情:AsyncTask/Runnable以匿名内部类的方式存在,会隐式持有对所在Activity的引用。
    解决办法:将AsyncTask和Runnable设为静态内部类或独立出来;在线程内部采用弱引用保存Context引用
  • 资源未关闭导致的内存泄漏
    详情:未及时注销资源导致内存泄漏,如BraodcastReceiver、File、Cursor、Stream、Bitmap等。
    解决办法:在Activity销毁的时候要及时关闭或者注销。例如:
    BraodcastReceiver:调用unregisterReceiver()注销;
    Cursor,Stream、File:调用close()关闭;
    Bitmap:调用recycle()释放内存(2.3版本后无需手动)。
  • Adapter导致的内存泄漏
    详情:不使用缓存而只依靠getView() 每次重新实例化Item,会给gc制造压力。
    解决办法:在构造Adapter时使用缓存的convertView
  • WebView导致的内存泄漏。
    详情:WebView比较特殊,即使是调用了它的destroy方法,依然会导致内存泄漏。
    解决办法:其实避免WebView导致内存泄漏的最好方法就是让WebView所在的Activity处于另一个进程中,当这个Activity结束时杀死当前WebView所处的进程即可,我记得阿里钉钉的WebView就是另外开启的一个进程,应该也是采用这种方法避免内存泄漏。
2.扩大内存

为什么要扩大我们的内存呢?有时候我们实际开发中不可避免的要使用很多第三方商业的SDK,这些SDK其实有好有坏,大厂的SDK可能内存泄漏会少一些,但一些小厂的SDK质量也就不太靠谱一些。那应对这种我们无法改变的情况,最好的办法就是扩大内存。

扩大内存通常有两种方法:

  • 一个是在清单文件中的Application下添加largeHeap="true"这个属性,另一个就是同一个应用开启多个进程来扩大一个应用的总内存空间。
  • 第二种方法其实就很常见了,比方说我使用过个推的SDK,个推的Service其实就是处在另外一个单独的进程中。

Android中的内存优化总的来说就是开源和节流,开源就是扩大内存,节流就是避免内存泄漏。

3.检测、分析内存泄漏的工具
  • MemoryMonitor:随时间变化,内存占用的变化情况
  • MAT:输入HRPOF文件,输出分析结果
    a. Histogram:查看不同类型对象及其大小
    b.DominateTree:对象占用内存及其引用关系
    c.MAT使用教程
  • LeakCanary:实时监测内存泄漏的库(LeakCanary原理)

五数据结构优化

  • 比如HashMap和ArrayMap,优先使用ArrayMap;
  • 优先使用基本类型,而非包装类
  • 减少占内存较大的枚举的使用
  • 采用三级缓存机制:LRUCache
  • 图片压缩:inSampleSize、RGB_565替换RGB_8888
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,389评论 25 707
  • 用两张图告诉你,为什么你的 App 会卡顿? - Android - 掘金 Cover 有什么料? 从这篇文章中你...
    hw1212阅读 12,680评论 2 59
  • 被文同时发布在CSDN上,欢迎查看。 APP内存的使用,是评价一款应用性能高低的一个重要指标。虽然现在智能手机的内...
    大圣代阅读 4,803评论 2 54
  • 最近负能量有点多,心里比较纠结,思维走进牛角尖。今天的文章也是迟迟不想写,但是想想大家都是在相同的环境下,有着...
    吕姜瑶阅读 412评论 0 0
  • 喜欢像夏天的味道,新鲜又温热,没有参杂不合适的味道。 喜欢总让人想起夏日的白球鞋,干净而美好,那些闷热漫长的午后仿...
    池池雾阅读 167评论 0 0