Android比较实用的性能优化

  Android设备做为一种移动设备,不管是内存仍是CPU的性能都受到了很大的限制,这致使Android程序的性能问题异常突出,随着产品的不断更新迭代,对于性能优化提出了更高的要求。本篇文章从稳定性、流畅性、耗损、安装包大小四个方面对Android开发提供了一些容易上手、切实有效的性能优化方法,为Android开发中有关性能优化方面的学习提供一个参考。

1.稳定性(解决内存溢出、崩溃等问题),内存优化

了解 内存如何分配和回收机制,对 内存优化会有必定的认识和掌握。能够借助 内存分析工具,方便定位须要内存优化的代码。

(1)Memory Monitor 工具:

  Android Studio自带的一个内存监视工具,它能够很好地帮助咱们进行内存实时分析。经过点击Android Studio右下角的Memory Monitor标签,打开工具能够看见较浅蓝色表明free的内存,而深色的部分表明使用的内存从内存变换的走势图变换,能够判断关于内存的使用状态,例如当内存持续增高时,可能发生内存泄漏;当内存忽然减小时,可能发生GC等

(2)Memory Analyzer 工具:

  MAT(Memory Analyzer Tool) 是一个快速,功能丰富的 Java Heap 分析工具,经过分析 Java 进程的内存快照 HPROF 分析,从众多的对象中分析,快速计算出在内存中对象占用的大小,查看哪些对象不能被垃圾收集器回收,并能够经过视图直观地查看可能形成这种结果的对象。
检测步骤以下:

(a)屏幕屡次翻转,出现内存持续增高时。点击 Dump java Heap就会生成运行内存快照hprof文件。html

(b)而后将APP彻底退出,从新启动,打开Android Monitor 再次点击Dump java Heap 生成一份还没操做(旋转屏幕)前的内存快照hprof文件。如今就已经生成好了2份hprof文件, 一份是没有旋转过屏幕的 ,一份是旋转过屏幕屡次的。java

(c)而后选中Android Studio 最左边的Captures 进行将hprof文件导出。导出的时候须要选择保存的目录以及文件名。git

(d)打开MAT ,导入咱们的2个hprof文件 Open File-->选择文件-->Leak Suspects Report-->Finishgithub

能够经过检索包名,查看某个类的实例个数和所在内存数据,还能够查看被引用的内存数据。算法

  Objects:实例个数
  Shallow Heap:所占内存大小
  Retained Heap:释放后能回收多少内存数据库

(3)LeakCanary工具:

  简单,傻瓜式操做。能够在GitHup官网查阅https://github.com/square/leakcanary,咱们能够在Gradle文件里添加依赖。这个工具是Square公司在Github开源的。行业内不是有一句话嘛,Square出品必属精品,主流的库像okhttp、Picasso、retrofit、Dagger等都出自Square之手。说到这不得不让我联想到一位在Android开发领域神通常存在的人物,他就是大名鼎鼎的Jake Wharton(杰克.沃顿),ButterKnife的创造者,也参与贡献了Retrofit, okhttp等。canvas

 

(4)Android Lint 工具:

 

    Android Lint Tool 是Android Sutido种集成的一个Android代码提示工具,它能够给你布局、代码提供很是强大的帮助。
硬编码会提示以级别警告,例如:在布局文件中写了三层冗余的LinearLayout布局、直接在TextView中写要显示的文字、字体大小使用dp而不是sp为单位,就会在编辑器右边看到提示。使用Android Studio的lint能够清除无用的资源文件(点击菜单栏的Analyze -> Run Inspection by Name, 输入unused resource)。
    固然以上都是一个简单的举例,Lint的功能很是强大,你们应该养成写完代码查看Lint的习惯,这不只让你及时发现代码种隐藏的一些问题,更能让你养成良好的代码风格,要知道,这些Lint提示可都是Google大牛们汗水合智慧的结晶。

小结

    影响稳定性的缘由不少,好比内存使用不合理、代码异常场景考虑不周全、代码逻辑不合理等,都会对应用的稳定性形成影响。其中最多见的两个场景是:Crash 和 ANR,这两个错误将会使得程序没法使用。因此作好Crash全局监控,处理闪退同时把崩溃信息、异常信息收集记录起来,以便后续分析;合理使用主线程处理业务,不要在主线程中作耗时操做,防止ANR程序无响应发生。

 

2.流畅性(卡顿优化)

卡顿的场景一般是发生在用户交互体验最直接的方面。影响卡顿的两大因素,分别是界面绘制和数据处理。
  • 界面绘制:主要缘由是绘制的层级深、页面复杂、刷新不合理,因为这些缘由致使卡顿的场景更多出如今 UI 和启动后的初始界面以及跳转到页面的绘制上。
  • 数据处理:致使这种卡顿场景的缘由是数据处理量太大,通常分为三种状况,一是数据在处理 UI 线程,二是数据处理占用 CPU 高,致使主线程拿不到时间片,三是内存增长致使 GC 频繁,从而引发卡顿。
卡顿场景大概分为四个方面,以下图所示。
 

分析UI卡顿:缓存

    咱们知道Android的绘制步骤是:Measure、Layout、Draw,因此布局的层级越深、元素越多、耗时也就越长。还有就是Android操做系统每隔 16ms 发出 VSYNC 信号,触发对 UI 进行渲染,若是每次渲染都成功,这样就可以达到流畅的画面所需的 60FPS。若是某个操做花费的时间是 24ms ,系统在获得 VSYNC 信号时就没法正常进行正常渲染,这样就发生了丢帧现象。那么用户在 32ms 内看到的会是同一帧画面,没法在 16ms 完成渲染,最终引发刷新不及时。性能优化

    总结以上,两个根本缘由:一、绘制任务过重,绘制一帧内容耗时太长;二、主线程太忙,根据系统传递过来的 VSYNC 信号来时,还没准备好数据,致使丢帧。微信

(1)布局优化

    在Android种系统对View进行测量、布局和绘制时,都是经过对View数的遍从来进行操做的。若是一个View数的高度过高就会严重影响测量、布局和绘制的速度。Google也在其API文档中建议View高度不宜哦过10层。如今版本种Google 使用RelativeLayout替代LineraLayout做为默认根布局,目的就是下降LineraLayout嵌套产生布局树的高度,从而提升UI渲染的效率。
  • 布局复用,使用<include>标签重用layout;
  • 提升显示速度,使用<ViewStub>延迟View加载;
  • 减小层级,使用<merge>标签替换父级布局;
  • 注意使用wrap_content,会增长measure计算成本;

  • 删除控件中无用属性;

(2)绘制优化

    过分绘制是指在屏幕上的某个像素在同一帧的时间内被绘制了屡次。在多层次重叠的 UI 结构中,若是不可见的 UI 也在作绘制的操做,就会致使某些像素区域被绘制了屡次,从而浪费了多余的 CPU 以及 GPU 资源。如何避免过分绘制?
  • 布局上的优化。移除 XML 中非必须的背景,移除 Window 默认的背景、按需显示占位背景图片

  • 自定义View优化。使用 canvas.clipRect() 帮助系统识别那些可见的区域,只有在这个区域内才会被绘制。

(3)启动优化

    应用通常都有闪屏页SplashActivity,优化闪屏页的 UI 布局,能够经过 Profile GPU Rendering 检测丢帧状况。

    (另外,还能够IDE自带的一款UI绘制检测图形化数据分析工具 Systrace ,4.0版本以上版本可使用。)

 闪屏页的存在能够说就是启动优化,一般在闪屏页延迟2秒跳转到主界面可是在进入首页的时候,首页复杂的View渲染以及必须在UI线程执行的业务逻辑,必然拖慢了启动速度。启动闪屏页虽然简单执行快,首页却复杂执行慢,应用启动前轻后重。

    因此要启动加载逻辑优化。能够采用分布加载、异步加载、延期加载策略来提升应用启动速。例如,把SplashActivity改为SplashFragment,应用程序的入口变成MainActivity,在MainActivity中先展现SplashFragment,显示完毕后再移除SplashFragment。这样,在SplashFragment的2S的友好时间内进行数据准备的同时,首页的View就可以被加载,首页的业务逻辑就可以被执行。在闪屏页窗口加载完毕后,咱们加载activity_main的布局,考虑到这个布局有可能比较复杂,耽误View的解析时间,能够采用ViewStub的形式进行懒加载。

(4)刷新优化

  1. 减小刷新次数;
  2. 缩小刷新区域;

(5)动画优化

      须要实现动画效果时,须要根据不一样场景选择合适的动画框架来实现。有些状况下,能够用硬件加速方式来提供流畅度下降动画卡顿。

3.耗损(耗电、流量消耗)

 3.1耗电优化

在移动设备中,电池的重要性天然不言而喻,若是手机没电了应用功能技术实现再怎么牛逼,用户也什么都干不成。对于Android操做系统和设备各大开发商来讲,对手机耗电的优化从没有中止过,不断地追求更长的待机时间。而对于开发一款应用来讲,毫不能够忽略电量耗损的问题,被归为“电池杀手”的应用,最终的结果无疑是走向被用户卸载的道路。好比,有些应用为了保持应用进程长期在后台存活,使用各类不合理进程保活方案,破坏操做系统“生态平衡”,致使用户电量严重耗损,虽然这种流氓开发行为并不违法吧,可是也属于不道德的行为,也一样会被同行所被鄙视的行为。

 

    在 Android5.0 之前,关于应用电量消耗的测试即麻烦又不许确,而5.0 以后Google专门引入了一个获取设备上电量消耗信息的API—— Battery Historian。Battery Historian 是一款由 Google 提供的 Android 系统电量分析工具,直观地展现出手机的电量消耗过程,经过输入电量分析文件,显示消耗状况。

 

    最后提供一些可供参考耗电优化的方法:

(1)计算优化。算法for循环优化Switch..case替代if..else、避开浮点运算。

        浮点运算:计算机里整数和小数形式就是按普通格式进行存储,例如102四、3.1415926等等,这个没什么特色,可是这样的数精度不高,表达也不够全面,为了可以有一种数的通用表示法,就发明了浮点数。浮点数的表示形式有点像科学计数法(*.*****×10^***),它的表示形式是0.*****×10^***,在计算机中的形式为 .***** e ±***),其中前面的星号表明定点小数,也就是整数部分为0的纯小数,后面的指数部分是定点整数。利用这样的形式就能表示出任意一个整数和小数,例如1024就能表示成0.1024×10^4,也就是 .1024e+004,3.1415926就能表示成0.31415926×10^1,也就是 .31415926e+001,这就是浮点数。浮点数进行的运算就是浮点运算。浮点运算比常规运算更复杂,所以计算机进行浮点运算速度要比进行常规运算慢得多。

(2)避免 Wake Lock 使用不当。

    Wake Lock是一种锁的机制,主要是相对系统的休眠而言的,,只要有人拿着这个锁,系统就没法进入休眠意思就是个人程序给CPU加了这个锁那系统就不会休眠了,这样作的目的是为了全力配合咱们程序的运行。有的状况若是不这么作就会出现一些问题,好比微信等及时通信的心跳包会在熄屏不久后中止网络访问等问题。因此微信里面是有大量使用到了Wake_Lock锁。系统为了节省电量,CPU在没有任务忙的时候就会自动进入休眠。有任务须要唤醒CPU高效执行的时候,就会给CPU加Wake_Lock锁。你们常常犯的错误,咱们很容易去唤醒CPU来工做,可是很容易忘记释放Wake_Lock。
 

(3)使用 Job Scheduler 管理后台任务。

   在Android 5.0 API 21 中,google提供了一个叫作JobScheduler API的组件,来处理当某个时间点或者当知足某个特定的条件时执行一个任务的场景,例如当用户在夜间休息时或设备接通电源适配器链接WiFi启动下载更新的任务。这样能够在减小资源消耗的同时提高应用的效率。

 3.2流量优化

3.2.1 对通信录式、我的信息式的数据进行数据库的存储;
3.2.2 对浏览类的数据进行三级缓存

4.安装包(缩小apk大小)

 详见本人的另外一篇文章—— Android性能优化之apk终极瘦身策略
相关文章
相关标签/搜索