[译] Android App 性能优化

zpzj5834 7年前
   <p><img src="https://simg.open-open.com/show/27b2be29bc8a0cc0bb4550fbaf7166da.png"></p>    <h2>提高Android 应用性能</h2>    <p>开发Android系统的应用程序,开发人员获得了很多的自由,App的拥有者也见证了用户的不断增长。不过,在此过程中开发者也面对着很多应用开发的挑战。</p>    <ul>     <li>开发人员发现很多Android os版本很难跟进开发。</li>     <li>运行Android系统的设备类型有170+种,这也是Android开发一个巨大的挑战。每种设备有不同的屏幕尺寸、摄像头按钮、键盘形式等等,使得开发成为一个噩梦。</li>    </ul>    <p>记住以下几点,我们可以在一定程度上提高我们应用程序的性能。以下介绍会降低程序的性能的因素和我们可以做的一些提升。</p>    <h3>Slow Rendering</h3>    <p>Slow Rendering 是最常见的性能问题。设计师希望我们做出的效果和我们最后做出的效果可能是不同的, 如果过分追求可视化的效果,可能会导致开发的失败。</p>    <p>渲染是根据时间来定义的,以保证60fps的平滑运行,不发生掉帧或者延时。</p>    <h3>什么会引起Slow Rendering</h3>    <p>系统每16ms尝试绘制一次界面,这意味着我们的应用必须在16ms内完成所有的更新界面的逻辑。</p>    <p><img src="https://simg.open-open.com/show/e3b6dd90db639d3c5f73e45418373e67.png"></p>    <p>如果我们的应用不能在16ms完成逻辑会怎么样呢:</p>    <p><img src="https://simg.open-open.com/show/003e91dadb456e63f79d7ab43f30f3c4.png"></p>    <p>以上图中就是掉帧。举例来说,如果我们的逻辑处理时间消耗了24ms,就会发生掉帧。系统尝试去绘制新的一帧,但是更新逻辑还没有完成。所以系统只能不刷新界面。这使得用户看到的界面是32ms刷新而不是16ms。即使只掉了一帧,动画也会看出不够流畅。</p>    <h3>以下的工具可以用于提高渲染效果</h3>    <ol>     <li> <p>Hierarchy Viewer</p> <p>Hierarchy Viewer是Android设备查看器中内嵌的一个工具,可以帮助我们查看层级布局中各个View的属性和布局速度。它可以帮助我们发现由于界面层级结构引起的性能问题,帮助我们简化布局,减少过度绘制。</p> </li>     <li> <p>GPU渲染模式分析</p> <p>GPU渲染模式分析可以快速可视化显示每一帧相对于16ms的实际绘制时间。</p> </li>    </ol>    <p>打开GUP渲染模式分析的方法如下:</p>    <ul>     <li><strong>设置> 开发者工具</strong></li>     <li>在监控设置里选择 <strong>GPU呈现模式分析</strong></li>     <li>在弹出的选择框中选择 <strong>在屏幕上显示为条形图</strong></li>     <li>打开需要调试的应用,可以看到代表着绘制时间的条形图:bar_chart:。</li>    </ul>    <p>屏幕上的横坐标显示时间的流动,纵坐标显示每帧的绘制时间。如果绘制时间超过了16ms的基准线,用户就会感觉到应用卡顿。</p>    <h2>应用启动时间</h2>    <p>App启动有两种情况,每种启动情况会影响应用从图标到用户可见使用的时间。</p>    <h3>冷启动</h3>    <p>冷启动是指应用从0开始启动,即应用在设备重启或者在被系统kill掉之后的第一次启动。</p>    <p>在冷启动时,系统有三个任务:</p>    <ul>     <li>装置并启动App</li>     <li>随着应用的启动立即展示一个黑色的启动窗口</li>     <li>创建应用进程</li>    </ul>    <h3>热启动</h3>    <p>相比冷启动,热启动更简单,消耗更小。在热启动中,系统的工作就是把activity放置到前台。如果应用中的所有Activity是保留在内存中,app就可以不用重复初始化对象,布局设置,和渲染。</p>    <h3>如何解决应用启动延时的问题</h3>    <ul>     <li> <p>只初始化必要的对象,比如,可以把全局静态变量放置在单例模式中,这样应用在真正使用变量时才会初始化而不是在应用启动时。</p> </li>     <li> <p>压扁应用层级,减少冗余的view和嵌套。</p> </li>     <li> <p>资源初始化放置在异步线程中执行。</p> </li>     <li> <p>让应用先加载并展示view,之后再更新view依赖于bitmap或者其他资源的属性。</p> </li>    </ul>    <h3>布局</h3>    <p>布局是App直接影响用户体验的一个重要部分。如果实现不合理,则在展示时导致内存资源紧张。每一个在app中小部件或者布局,都需要执行初始化、布局、和绘制。比如:使用LinearLayout的嵌套实例可能会导致视图层次结构过深。</p>    <p>如何优化布局呢</p>    <ol>     <li> <p>优化布局层级</p> <p>使用基本的布局结构可以获得最有效的布局。然而,每一个在app中小部件或者布局,都需要执行初始化、布局、和绘制。比如:使用LinearLayout的嵌套实例可能会导致视图层次结构过深。此外,嵌套多个使用了 layout_weight 属性的LiaearLayout会非常耗时,因为每个child要被计算两次。这一点在布局被多次加载时更要注意,比如在listview或者gridview中加载。</p> </li>     <li> <p>复用布局 <Layouts></p> <p>复用布局非常强大,允许我们创建复杂的可复用的布局。比如,一个yes/no的button,一个自定义的进度条,或者一个Textview。也就是说可以单独提取、管理在多个布局中使用的通用元素,然后在layout中include它们。</p> </li>     <li> <p>按需加载视图</p> <p>有时我们的布局中有些复杂的布局很少使用,无论是项目详细信息,进度指示器还是撤消消息,可以通过仅在需要时加载视图来减少内存使用并加快渲染速度。</p> </li>    </ol>    <h2>电池使用</h2>    <p>电量使用也是Android开发中需要优化的一个很重要的部分,有助于用户的存留。</p>    <p>节约电量使用一些建议:</p>    <ul>     <li>减少网络请求的次数</li>     <li>避免使用唤醒锁</li>     <li>谨慎使用GPS</li>     <li>谨慎使用Alarm 管理器</li>     <li>使用批量调度</li>    </ul>    <p> </p>    <p>来自:http://www.jianshu.com/p/aeafdc970009</p>    <p> </p>