性能优化

性能优化,简而言之,就是在不影响系统运行正确性的前提下,使之运行地更快,完成特定功能所需的时间更短。

1、布局优化  

        首先我们先从我们能看到的进行优化,也就是我们的布局。

        主要思想:布局中的层级少了,这就意味着Android的绘制工作少了,那么程序的性能自然就提高了。

        1.选择耗费性能较少的布局

        性能耗费低的布局= 功能简单 =FrameLayout、LinearLayout

        性能耗费高的布局= 功能复杂 =RelativeLayout(每一个控件都有一个Id,都会在R文件里创建对象,在UI界面复杂的时候可以用。)

        注:

        嵌套所耗费的性能> 单个布局本身耗费的性能

        即完成需求时:宁选择1个耗费性能高的布局,也不采用嵌套多个耗费性能低的布局

        2.减少布局的层级(嵌套)

        原理:布局层级少->> 绘制的工作量少 ->> 绘制速度快 ->> 性能提高

        <include>标签(布局复用需用到的标签)

标签可以将指定布局加载到当前的布局文件中,通过layout属性来设置指定的布局文件,标签只支持带有android:layout_*这种属性。

        <merge>标签(整体为merge)

标签主要要和标签搭配使用,当标签的最外层布局和所处的当前布局一样时,比如说都是垂直方向的LinearLayout,此时便可以将标签的最外层布局的LinearLayout改成标签

        <ViewStub>标签

标签主要是一个轻量级的按需加载的布局控件,特点是像标签一样包含一个布局文件,还有一个是可以在必要的时候显示和消失,所以ViewStub控件有利于显示一些网络加载或者异常时的界面。


2、绘制优化

        绘制优化是指View的onDraw方法要避免大量的操作,主要体现在内存和CPU两个方面:

        onDraw中不要创建新的局部对象

        因为onDraw可能会被频繁的调用而导致大量的对象被创建,这会导致占用过多的内存从而频繁地gc;(GC垃圾回收,执行GC时所有的线程操作都会暂停,等待GC的操作完成,大量不停的GC操作会占用帧间隔时间的16ms,在这16ms时间里做了长时间的GC操作,从而使其他操作时间变短)

        onDraw中不要进行耗时的操作

        频繁的耗时操作会占用CPU的时间大量的时间,导致程序卡顿。

        注意:

        这个主要是相对于我们的自定义View中,因为我们的自定义View会重写onDraw()方法。

3、内存泄漏优化

        内存泄漏:

        程序在销毁时,还有一些引用没有被释放(或者说GC没有回收),导致这些对象占用的内存无法被使用(无用的对象占据着内存空间,使得实际可使用内存变小,形象地说法就是内存泄漏了。)。

       内存泄漏的影响

        应用卡顿:泄漏的内存影响了GC的内存分配,过多的内存泄漏会影响应用的执行率。

        GC回收的原则:被全局变量(static)、栈变量和寄存器等直接引用和间接引用的对象不能被回收。

        常见的内存泄漏:

        1.静态变量导致的内存泄漏(静态变量伴随着整个App的存亡。)这个静态变量mContext引用这这个Activity。

        2.单例模式导致的内存泄漏,泄漏的原因是OrmHelper会一直持有context对象。

        3.属性动画导致内存泄漏 (在android3.0 Google 提供了属性动画),动画播放完之后, 尽管我们看不到动画的播放效果,但在内部处于无限循环播放的状态。

解决办法:解决方法就是在onDestory或动画结束监听中调用animator.cancle()

        4.集合对象没有清理导致的内存泄漏,我们通常把一些对象的引用加入到了集合中,当我们不需要该对象时,如果没有把它的引用从集合中清理掉,这样这个集合就会越来越大。

        5.资源对象没有手动关闭或处理,资源性对象(BraodcastReceiver,ContentObserver,File,Cursor,Stream,Bitmap)导致的内存泄漏。

        6.强引用数据导致的内存泄漏,new 出对象的时候,对象被引用的时候称之为强引用,当不在引用的时候就不再叫强引用,GC可以对其进行一个回收。

        7.匿名内部类导致内存泄漏:在我们的匿名内部类中,你可能不知道这个匿名内部类会不会造成内存泄漏,那么你就把他改为静态的,在onStop()/onDestroy()置为null。

        总结

        开发中尽量避免写出有内存泄漏的代码,但并不是每个内存泄漏都需要解决,我们只是尽量的让内存泄漏减少,来优化app内存。

        内存泄漏的优化分为两个方面,一方面实在开发过程中避免写出泄漏的代码,另一方面则是通过一些分析工具MAT,LeakCanary来找出潜在的内存泄漏继而解决。

内存泄漏分析工具(前提是你得有一个Eclipse)

下载网址:http://www.eclipse.org/mat/downloads.php

安装教程:https://blog.csdn.net/xorxos/article/details/50207869

导依赖:

debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5'

releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5'

testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5'

如果以上三个依赖不行,用下面的

debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3.1'  

releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3.1' 

记得在<application android:name=".AppApplication">配置。

        当我们运行App的时候,第一次的时候没有问题,然后我们退出App开始第二次运行。如果有内存泄漏的话会在你的手机上推送。(这个需要时间去等待GC的回收)

那么怎么去决绝被泄漏的对象呢,请看下面网址

https://www.jianshu.com/p/3f1a1cc1e964

我们主要关注的就三种:

        堆内存泄漏(Heap leak)

         对内存指的是程序运行中根据需要分配通过malloc,realloc new等从堆中分配的一块内存,再是完成后必须通过调用对应的 free或者delete 删掉。如果程序的设计的错误导致这部分内存没有被释放,那么此后这块内存将不会被使用,就会产生Heap Leak.

        系统资源泄漏(Resource Leak)

        主要指程序使用系统分配的资源比如Bitmap,handle ,SOCKET等没有使用相应的函数释放掉,导致系统资源的浪费,严重可导致系统效能降低,系统运行不稳定。

        内存溢出

        内存溢出就是你要求分配的内存超出了系统能给你的,系统不能满足需求,于是产生溢出。

4、响应速度优化(说白了就是让你的界面变得流畅)

        不要去频繁大量的new对象

        FPS表示每秒传递的帧数。在理想情况下,60 FPS 就感觉不到卡,这意味着每个绘制时长应该在16 ms 以内。但是 Android 系统很有可能无法及时完成那些复杂的页面渲染操作。Android 系统每隔 16ms 发出 VSYNC 信号,触发对 UI 进行渲染,如果每次渲染都成功,这样就能够达到流畅的画面所需的 60FPS。如果某个操作花费的时间是 24ms ,系统在得到 VSYNC 信号时就无法正常进行正常渲染,这样就发生了丢帧现象。那么用户在 32ms 内看到的会是同一帧画面,这种现象在执行动画或滑动列表比较常见,还有可能是你的 Layout 太过复杂,层叠太多的绘制单元,无法在 16ms 完成渲染,最终引起刷新不及时。

        响应速度优化的核心思想是避免在主线程做耗时的操作,将耗时的操作放在线程里执行。同时还要注意另一种不是很明显的造成ANR的原因:在主线程中长时间等待同步锁。

5、ListView优化

        采用ViewHolder进行缓存并且避免在getView中执行耗时操作。

6、BitMap优化

        android中图片是以bitmap形式存在的,那么bitmap所占内存,直接影响到了应用所占内存大小。android中图片是以bitmap形式存在的,那么bitmap所占内存,直接影响到了应用所占内存大小。

        而有三种压缩方式:采样率压缩,质量压缩,缩放法压缩(martix)

        BitMap优化参考网址:https://www.jianshu.com/p/f08f8b56e299

7、线程优化

        线程优化主要体现在避免大量的创建和销毁线程,因此线程优化的思想就是使用线程池。使用线程池的好处就是,可以重用线程避免创建和销毁大量线程,还可以控制并发数以避免阻塞。线程池的基本作用就是进行线程的复用。

        线程的创建和销毁都需要时间:

        1.大量的线程创建和销毁时,那么这些时间的消耗则比较明显,将导致性能上的缺失。

        2、大量的线程创建、执行和销毁是非常耗cpu和内存的,这样将直接影响系统的吞吐量,导致性能急剧下降,如果内存资源占用的比较多,还很可能造成OOM。

        3、大量的线程的创建和销毁很容易导致GC频繁的执行,从而发生内存抖动现象,而发生了内存抖动,对于移动端来说,最大的影响就是造成界面卡顿。

        使用线程池管理线程的优点:

        1、线程的创建和销毁由线程池维护,一个线程在完成任务后并不会立即销毁,而是由后续的任务复用这个线程,从而减少线程的创建和销毁,节约系统的开销。

        2、线程池旨在线程的复用,这就可以节约我们用以往的方式创建线程和销毁所消耗的时间,减少线程频繁调度的开销,从而节约系统资源,提高系统吞吐量。

        3、在执行大量异步任务时提高了性能。

        4、Java内置的一套ExecutorService线程池相关的api,可以更方便的控制线程的最大并发数、线程的定时任务、单线程的顺序执行等 。

        线程优化参考网址:http://zhengxiaoyong.me/2015/11/17/Android%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96%E4%B9%8B%E4%BD%BF%E7%94%A8%E7%BA%BF%E7%A8%8B%E6%B1%A0%E5%A4%84%E7%90%86%E5%BC%82%E6%AD%A5%E4%BB%BB%E5%8A%A1/

一些性能优化建议

        避免创建过多的对象

        不要过多使用枚举

        常量使用static final修饰

        使用Android特有的数据结构比如SparseArray和Pair等

        适当使用软引用和弱引用

        采用内存缓存LreCache和磁盘缓存DiskLruCache

        尽量采用静态内部类

更多优化的参考网址:https://www.jianshu.com/p/c55ef05c0047

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

推荐阅读更多精彩内容