在 iPhone 与 Android 的横空出世时候,大家还没有意识到,互联网还远远没有达到它应有的高度,移动互联网会创造更大的奇迹;过去十年可以说的上是移动互联网蓬勃发展的黄金期,相信每个人也都享受到了移动互联网红利,在此期间,移动互联网经历了曙光期、成长期、成熟期;现在来说已经进入饱和期
且招聘市场先于人才市场一步冷静下来,开发者们明显可以感知到企业招聘门槛的提高; 市场是个很奇妙的东西,人人都会就等于人人都不会,当发现开源库原理问不倒你的时候,面试官可能要拿性能优化开刀了;但技术可不是一朝一夕就可以提升上来的
就像性能优化,性能优化始终穿插在 App 整个研发生命周期中,尤其是从 1 到 N 的阶段,这个阶段增长开始放缓,所以说性能优化就是突破增长瓶颈,提升日活天花板的主要方式
像这类问题也只是冰山一角,在实际面试过程中往往会透过你对于复杂问题的解决方案判断出个人的技术功底:
例如:
可以毫不夸张的说,软件不停,优化不止!
但很多开发者对于优化这块都浅尝辄止,不仅对于底层原理了解不充分,连优化过程中使用什么工具都说不上个所以然,要是一旦遇到线上复杂环境的性能问题,整个人就懵逼了
但其实很多开发者经常遇到的那些让人措手不及的问题,只要对于出现问题的原因和处理思路有一个大概的认知都可以很好的解决,说通了,只需要搞懂底层原理,那些工作中难以处理的优化问题都可以迎刃而解!
如果你对于性能问题不能由点及面逆向分析,最终找到瓶颈点和优化方法,那么必须要跟着正确的路线学习!
所以在这里分享一张由大佬收集整理的 Android 性能优化学习思维导图
并且通过这张思维导图,融合了这些年的工作经历及对网上的资料查询和整理,最终将其整合成了一份 Android 性能优化的学习手册文档 ;有需要这份 思维导图及学习手册文档的朋友:可点击此处查看直达方式 或者点击下方小卡片 即可 免费获取,希望大家通过这个思维导图和学习手册,能够提供一个好的学习方向,查漏补缺,完善自身的不足之处;早日攻克性能优化这一难题点击 免费领取 Android 性能优化思维导图及学习手册文档
手册内容展示如下:
App 性能优化-启动优化
App 性能优化-UI 布局优化
Android 性能优化-卡顿优化和布局优化
Android 开发-优化 Glidel 加载超大 gif 图
以上的知识点文档都是免费获取的,有兴趣的小伙伴:可点击此处查看直达方式 或者点击下方小卡片 即可 直达获取
点击 免费领取 Android 性能优化思维导图及学习手册文档觉得手册内容有用的话,大家可以点赞分享一下
从事Android开发的人应该都知道,无论是在工作中还是在面试中,性能优化都是一个绕不过的坎,尤其是在一些大厂中,他们对性能的要求把控很严格,甚至将其定位考核标准之中。
像以下场景或多或少,大家都有遇到过:
看上去这些问题不是很难,但对于一些只做业务层开发,没有深入的去了解底层知识点的人来说,就比较头痛了。因为优化相关的内容,有不少要涉及到Framework 底层的知识点(比如:启动优化、UI渲染优化等),如果对底层逻辑掌握的不是很好,就没办法做好相关的优化工作。
相信大多是开发在做性能优化时,首先都会去找别人之前做过的一些相关案例,然后在套用到自己的应用开发中,虽然此方法看着很好很快捷,但是中间出现了什么问题,一时之间很难快速的定位问题出在哪?即便定位到问题的所在,一但涉及到底层,一时之间也很难解决,因为最终的优化方法和底层优化的逻辑不是你所设计。
根据项目种类应用的场景不同,优化的方案也会有所不同,自然它们的特性也会不一样。比如说,大型应用业务多,中小型应用功能单一,还有 IO 密集型应用、CPU 密集型应用、强调稳定性的应用,以及强调内存低占用的应用等等。面对不用类型的应用和业务,网上的案例就有些捉襟见肘了。
其次,这样做出来的优化并不体系。就拿内存优化举例子,我们可能会先按照网上的方案治理一下内存泄漏,再按照网上的方案优化一下图片。这样做优化不仅零碎,效果可能也不好。体系的优化是一套能覆盖到大部分情况和场景的方案,比如针对 Native 内存的优化方案有 A、B、C,针对 Java 内存的优化方案有 D、E、F,方案中要能清晰说明为什么要这样优化,思路是什么,原理是什么,如何估量和评估效果等等。
如果我们在做优化前没有把这些问题考虑进去,而盲目的去做,最后发现所做的优化很零散,没有一个完成的优化路线,几乎是东拼西凑的这种感觉,更不用说在工作中有什么质的提升了。
这也就是为什么有的人做了好几年的性能优化工作,无论在晋升答辩,还是面试中,依然很难脱颖而出。
性能优化的本质就是让运行在操作系统上的程序更合理的使用硬件资源,所以我们需要从硬件、系统、应用这三个维度入手,才能打造完备的知识体系,真正做好性能优化。
想要精进,要知道如何利用工具做性能优化,还要对底层原理充分了解,对架构设计有一定经验,例如你从任务管理角度做启动优化,就需要精通图论与框架设计,同时还需要熟悉Framework层执行流程,如果你对IO进行优化,就必须精通MMAP原理与框架封装的常用技术等...
这样才算精通对某个领域的性能优化。
精通意味着:
当然,在一些面试中,也会看到一些朋友在简历上写“精通性能优化”,但是让其描述,往往就是一些自己编写的业务,一些去除页面多余嵌套、使用线程池、ViewStub 这些非常浅的方案。
其实更多的,面试官还是希望能够听到,线上复杂环境,低端机/弱网等因素下,用户触发的一系列的体验问题。
想要搞清楚这些,那么必须对底层原理有着深度了解,对各种case非常丰富的经验;很多人经常遇到措手不及的问题,大多是对出现问题的情况和处理思路模糊不清,导致此原因就是因为没有搞懂底层原理。
所以考虑到以上总总因素,为了帮助到大家更全面的掌握性能优化和Framework 底层原理,将其在项目中会涉及到的所有核心知识点,都记录在于《性能优化核心知识点》与《Framework 核心知识点》两册之中,便于大家参考。
《Android Framework学习手册》:https://qr18.cn/AQpN4J
1.Handler 机制实现原理
2.Binder 原理
3.Zygote
4.AMS源码分析
6.深入PMS源码
7.WMS
8.……
Android 应用开发一直是一个备受关注的话题,随着移动互联网的快速发展和应用市场的日益竞争,如何提高应用的性能和用户体验成为开发者们必须面对的挑战。作为 Android 开发者,你是否还在苦苦挣扎于如何提高应用的性能优化问题?如果是,那么不妨来看看以下内容,获取一些实用的技术资料和解决方案,帮助你快速解决这些问题。
应用性能是用户体验的关键因素之一,如何提高应用的性能成为开发者必须面对的挑战。为此,我们推出了一份关于优化 Android 应用性能的技术资料,其中包括常见的性能瓶颈和解决方案、性能优化的工具和技巧、性能测试和调优的方法等。通过这份技术资料,你可以更好地了解 Android 应用性能优化的原理和方法,提高应用的响应速度、降低能耗和提高用户满意度。
Android 应用的性能优化是开发过程中必不可少的一部分,能够帮助应用更加流畅、响应更迅速、更加省电,提升用户体验。在本文中,我们将会介绍一些 Android 性能优化的技术,帮助您更好地优化应用。
布局层级过多和冗余的布局元素会影响应用的渲染效率,因此需要尽量减少布局层级和优化布局结构。例如,使用 ConstraintLayout 布局代替嵌套的 LinearLayout 和 RelativeLayout,使用 merge 标签和 ViewStub 延迟加载布局等。
在 UI 线程进行耗时操作会导致界面卡顿和响应迟缓,因此需要将耗时操作放在子线程中执行。例如,使用 AsyncTask 或者 HandlerThread 实现异步加载数据、图片等。
内存开销过大会导致应用的卡顿和崩溃,因此需要尽量减少内存占用和优化内存分配。例如,使用 ViewHolder 模式优化 ListView 和 RecyclerView 的布局,避免使用过多的 Bitmap 对象,尽量避免使用静态变量等。
过多的网络请求和缓存未命中会导致应用的响应迟缓和耗电量增加,因此需要合理使用缓存和优化网络请求。例如,使用 LruCache 对图片进行内存缓存,使用 OkHttp 和 Retrofit 优化网络请求等。
使用性能优化工具和框架可以帮助开发者更好地了解应用的性能瓶颈和优化方案,提高应用的响应速度和用户体验。例如,使用 Android Profiler 分析应用的性能,使用 LeakCanary 检测内存泄漏等。
如果您是一名 Android 开发者,那么您一定深知性能优化的重要性。在竞争激烈的应用市场中,一个高性能的应用可以吸引更多的用户和提高用户留存率。如果您想了解更多关于 Android 性能优化的技巧和方法,那么请继续往下阅读,我将为您分享一些宝贵的经验和建议。
您是否曾经遇到过这样的问题:应用界面卡顿、响应迟缓、耗电量过大?如果您的答案是肯定的,那么您需要进行一些性能优化的工作。《Android 应用的性能优化》可以帮助您解决这些问题,提升用户体验和应用竞争力。需要可以点击参考相关类目,领取这份性能优化资料。
Android核心技术进阶手册、实战笔记、面试题纲资料Android 应用的性能优化可以帮助您提高应用的性能和用户体验,吸引更多的用户和提高用户留存率。
Android 应用的性能优化是一项非常重要的工作,可以提升应用的竞争力和用户体验,吸引更多的用户和提高用户留存率。性能优化的内容非常丰富,包括但不限于以下几个方面:
交互是用户体验最直接的方面,交互场景大致可以分为四个部分: ui 呈现、应用程序启动、页面跳转和事件响应。对于以上四个方面,可以从以下两个方面进行优化:
主要原因是绘制的层级深、页面复杂、刷新不合理,由于这些原因导致卡顿的场景出现在UI和启动后的初始界面以及跳转到页面的回执上。
数据处理:导致这种卡顿场景的原因是数据处理量太大,一般分为三种情况,
一是数据处理在UI线程(这种应该避免),
二是数据处理占用CPU高,导致主线程拿不到时间片,
三是内存增加导致GC频繁,从而引起卡顿。
我们知道Android的绘制步骤是:Measure、Layout、Draw,所以布局的层级越深、元素越多、耗时也就越长。还有就是Android系统每隔16ms发出VSYNC信号触发对UI进行渲染如果每次渲染都成功这样就能达到流畅的画面所需的60FPS。如果某个操作花费的时间是24ms 系统在得到VSYNC信号时就无法进行正常渲染这样就发生了丢帧现象。
棉白杨现象有两个原因:
==绘制任务太重==,绘制一帧内容耗时太长。
根据问题的原因,我们可以通过以下方式进行优化:
布局优化
在Android种系统对View进行测量、布局和绘制时,都是通过对View数的遍历来进行操作的。如果视图的高度过高,会严重影响测量、布局和渲染的速度。Google也在API文档中建议View树的高度不宜超过10层。使用RelativeLayout替代LineraLayout作为默认根布局降低LineraLayout嵌套产生布局树的高度从而提高UI渲染的效率。
在布局优化方面,我们可以通过以下方式进行优化:
布局复用,使用标签重用layout;
提高显示速度,使用延迟View加载;
减少层级,使用标签替换父级布局;
注意使用wrap_content,会增加measure计算成本;
删除控件中无用属性;
透支是指屏幕上的一个像素在同一帧中被绘制多次。在多层次重叠的UI结构中如果不可见的UI也在做绘制的操作就会导致某些像素区域被绘制了多次从而浪费了多余的CPU以及GPU资源。我们可以通过开启手机的透支功能来检查页面是否透支。
为了避免过度绘制,我们可以从以下几个方面进行优化:
移除XML中非必须的背景,移除Window默认的背景、按需显示占位背景图片。
自定义View优化,使用 canvas.clipRect()来帮助系统识别那些可见的区域,只有在这个区域内才会被绘制。
应用一般都有闪屏页,优化闪屏页的UI布局,可以通过ProfileGPURendering检测丢帧情况。
你也可以通过启动加载逻辑来优化。可以使用分布式加载、异步加载和延迟加载策略来提高应用程序的启动速度。
数据准备。数据初始化分析,加载数据可以考虑使用线程初始化等策略。
Android开发中,通常是异步操作页面的,因此需要可以从刷新优化上来优化应用,主要有两个原则:
减少刷新次数;
缩小刷新区域;
在实现动画效果时,需要根据不同的场景选择合适的动画框架。在某些情况下,硬件加速可以用来提供流畅性。
在移动设备中,电池的重要性不言而喻,没有电什么也做不了。对于操作系统和设备开发者来说,功耗的优化并没有停下来追求更长的待机时间,但是对于一个应用来说,功耗的问题是不容忽视的,尤其是那些被归类为“电池杀手”的应用,最终被卸载。因此,应用程序开发人员在实现需求时需要最小化功耗。
Java虚拟机中的对象
内存泄漏
内存泄漏一般导致应用卡顿,极端情况会导致OOM,OOM的原因是因为超过内存的阈值。原因主要有两方面:
能够消耗大量内存的,绝大多数是因为图片加载。这是OOM出现最频繁的地方。图片加载,一个是控制每次加载的数量,二是保证每次滑动的时候不进行加载,滑动完进行加载。一般情况使用先进后出,而不是先进先出。不过一般我们图片加载都是使用fresco或者Glide等开源库。
下面是导致内存溢出的两种情况:
通过命令行查看内存消耗情况(adb shell dumpsys meminfo 包名 -d):
UI优化主要包括布局优化以及View的绘制优化。有时候我们打开某个软件,会出现卡顿的情况,这就是UI的问题。什么情况会导致卡顿呢?一般是如下几种情况:
可以看见,上面这些导致卡顿的原因都是我们平时开发中非常常见的。有些运行起来还可以的程序,一旦进行一些瞬时测试或压力测试,就会发现很多性能问题。
对于UI性能的优化还可以通过开发者选项中的GPU过度绘制工具来进行分析。在设置->开发者选项->调试GPU过度绘制(不同设备可能位置或者叫法不同)中打开调试后可以看见如下图(对settings当前界面过度绘制进行分析):
以下说明:
蓝色(1x过度绘制),淡绿(2x过度绘制),淡红(3x过度绘制),深红(4x过度绘制)代表了4种不同程度的Overdraw情况,我们的目标就是尽量减少红色Overdraw,看到更多的蓝色区域。
Overdraw有时候是因为UI布局存在大量重叠的部分,还有的时候是因为非必须的重叠背景。例如某个Activity有一个背景,然后里面的Layout又有自己的背景,同时子View又分别有自己的背景。仅仅是通过移除非必须的背景图片,这就能够减少大量的红色Overdraw区域,增加蓝色区域的占比。这一措施能够显著提升程序性能。
如果布局中既能采用RealtiveLayout和LinearLayout,那么直接使用LinearLayout,因为Relativelayout的布局比较复杂,绘制的时候需要花费更多的CPU时间。如果需要多个LinearLayout或者Framelayout嵌套,那么可采用Relativelayout。因为多层嵌套导致布局的绘制有大部分是重复的,这会减少程序的性能。
设置–>开发者选项–>GPU呈现模式分析–>在屏幕上显示为条形图,如图所示:
随着界面的刷新,界面上会以实时柱状图来显示每帧的渲染时间,柱状图越高表示渲染时间越长,每个柱状图偏上都有一根代表16ms基准的绿色横线,每一条竖着的柱状线都包含三部分(蓝色代表测量绘制Display List的时间,红色代表OpenGL渲染Display List所需要的时间,黄色代表CPU等待GPU处理的时间),只要我们每一帧的总时间低于基准线就不会发生UI卡顿问题(个别超出基准线其实也不算什么问题的)。
绘制优化主要是指View.onDraw方法需要避免执行大量的操作:
60dps是目前最合适的图像显示速度,也是绝大部分Android设备设置的调试频率,如果在16ms内顺利完成界面刷新操作可以展示出流畅的画面,而由于任何原因导致接收到VSYNC信号的时候无法完成本次刷新操作,就会产生掉帧的现象,刷新帧率自然也就跟着下降(假定刷新帧率由正常的60fps降到30fps,用户就会明显感知到卡顿)。
Android官方规定:Activity如果在5s内无响应事件(屏幕触摸事件或者键盘输入事件);BroadcastReceiver如果在10s内无法处理完成;Service如果20s内无法处理完成。这三种情况会导致ANR。
上面说的三种导致ANR的情况,绝大多数就是因为线程阻塞导致的。 那么应该如何处理呢?Android系统为我们提供了若干组工具类来解决此问题:
线程池
Android应用的启动方式分为三种:冷启动、暖启动、热启动,不同的启动方式决定了应用UI对用户可见所需要花费的时间长短,冷启动消耗的时间最长。基于冷启动方式的优化工作也是最考验产品用户体验的地方。
冷启动是在启动应用前,系统没有获取到当前APP的Activity、Service等等。例如,第一次启动APP,又或者说杀死进程后第一次启动。那么对比其他两种方式。冷启动自然是耗时最久的。
应用发生冷启动时,系统一定会执行下面的三个任务:
那么创建应用信息,系统就需要做:
这其中有两个creation 工作,分别为Application和Activity creation。它们均在View绘制展示之前。所以,在应用自定义的 Application类和第一个Activity类中,onCreate()方法做的事情越多,冷启动消耗的时间越长。
当应用中的Activities被销毁,但在内存中常驻时,应用的启动方式就会变为暖启动。相比冷启动,暖启动过程减少了对象初始化、布局加载等工作,启动时间更短。但启动时,系统依然会展示闪屏页,直到第一个Activity的内容呈现为止。
相比暖启动,热启动时应用做的工作更少,启动时间更短。热启动产生的场景很多,比如:用户使用返回键退出应用,然后马上又重新启动应用。
先对比一下下三种启动的时间:
可以看到三者的明显的差距。
为了提升用户体验,可以把闪屏页当作一个Fragment嵌套在MainActivity中,这样就可以在进入闪屏时直接预加载主页的View。闪屏页结束后直接remove掉就可以了。
对于启动的优化就是减少耗时操作,总结如下:
或者使用指令:adb shell am start -S -W[packageName]/[packageName.MainActivity],-S是重新启动应用,也可以查看启动时间:
本文主要做对Android中常见的性能优化浅析;如需深入了解性能优化这块,大家可以参考《Android性能优化》这个技术文档,里面记录了大部分的性能优化的方案。
Android性能优化解析内存优化问题是面试和平时开发中经常可能都会遇到的问题,也比较复杂,本文就常见问题做了简单的整理。Android性能优化有多种方式,在多个方面都有体现:
用户希望应用能够及时响应并快速加载,启动时间过长的应用不能满足这个期望,并且可能使用户失望。
启动太慢的结果:
Activity
带到前台(如果应用的所有Activity
都还驻留在内存中,则应用无需重复对象初始化、布局扩充和呈现。需要注意的是,如果程序的某些内存被系统清除,比如调用了onTrimMemory
方法,则需要重新创建这些对象以响应热启动事件);onCreate
方法开始重新创建活动,也可以从传递给onCreate
方法中保存的实例状态中获得某些对象的恢复)。冷启动流程:
APP
;APP
显示一个空白启动窗口;APP
进程(创建应用程序对象);Activity
;启动总结:
App
从被系统调用,再到第一个页面渲染到手机屏幕,我们通常只需要关注Application
中的onCreate
方法,第一个Activity
中onCreate
、onStart
、onResume
方法。
注意:如果在App
启动第一个Activity
时,该Activity
不但有自己的逻辑,还在onCreate
、onStart
或者onResume
方法中直接有跳转到了其它Activity
页面,那么跳转后的Activity
的这三个方法也需要进行优化。
在系统加载并启动App
时,需要耗费相应的时间,即使时间不到1S,用户也会感觉到当点击App
图标时会有“延迟”现象,为了解决这一个问题,Google
的做法是在App
创建的过程中,先展示一个空白的页面,让用户体会到点击图标之后立马就有响应,而这个空白页面的颜色则是根据我们在Manifest
文件中配置的主题颜色 来决定的,现在一般默认为白色。
可以为应用的加载设置主题背景,从而使应用的启动屏幕在主题背景上与应用的后续效果保持一致,而不是采用系统主题。
方案一:设置LauncherTheme
在LauncherTheme
中,设置系统“取消预览(空白窗体)”为true
,或者设置空白窗体为透明,这样用户从视觉上就无法看出黑白屏的存在:
<style name="AppTheme.LauncherTheme">
<!--设置系统的取消预览(空白窗口)为true-->
<item name="android:windowDisablePreview">true</item>
<!--设置背景为透明-->
<item name="android:windowIsTranslucent">true</item>
</style>
方案二:自定义Theme
主题
AppTheme
的主题;Activity
的Theme
设置为自定义主题;Activity
的onCreate
方法中,在super.onCreate
和setContentView
方法之前调用setTheme
方法,将主题设置为最初的AppTheme
。① 自定义主题
<style name="AppTheme.LaunchTheme1">
<item name="android:windowBackground">@mipmap/ic_launcher</item>
</style>
② 设置启动Activity
主题
<activity android:name=".MainActivity"
android:theme="@style/AppTheme.LaunchTheme1">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
③ 在代码中将主题设置回来
protected void onCreate(Bundle savedInstanceState){
setTheme(R.style.AppTheme)
super.onCreate(savedInstanceState);
}
Android4.4
及更高的版本中,logcat
包括一个输出行,其中包含命令为Displayed
的值,此值代表从启动进程到在屏幕上完成对应用Activity
绘制所经过的时间(MI6
测试,并没有);Activity
:ActivityManager:displayed com.sty.ne.appperformance/.MainActivity: +550ms
;adb
命令:adb shell Activity Manager
:adb[ -d | -e | -s <serialNumber>]shell am start -S -W
com.sty.ne.appperformance/.MainActivity
-c android.intent.category.LAUNCHER
-a android.intent.action.MAIN
adb shell am start -W com.sty.ne.appperformance/.MainActivity
显示结果如下:
GGGdeMac-mini:NeAppPerformance tian$ adb shell am start -W com.sty.ne.appperformance/.activity.SplashActivity
Starting: Intent{ act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER]cmp=com.sty.ne.appperformance/.activity.SplashActivity }
Status: ok
Activity: com.sty.ne.appperformance/.MainActivity
ThisTime: 186 (最后一个Activity启动耗时)
TotalTime: 395 (所有Activity启动耗时)
WaitTime: 417 (AMS启动Activity的总耗时)
Complete
private void findViews(){
final View viewRoot=findViewById(R.id.root);
viewRoot.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener(){
@Override
public boolean onPreDraw(){
viewRoot.getViewTreeObserver().removeOnPreDrawListener(this);
LauncherTimer.logEnd("tag3");
return false;
}
});
}
@Override
protected void onResume(){
super.onResume();
LauncherTimer.logEnd("tag1");
}
@Override
public void onWindowFocusChanged(boolean hasFocus){
super.onWindowFocusChanged(hasFocus);
LauncherTimer.logEnd("tag2");
}
// D/Time: 2/tag1 launcher time=101
// D/Time: 2/tag3 launcher time=139
// D/Time: 2/tag2 launcher time=146
traceview
统计:可以用代码统计,也可以用Android Studio
自带的cup profiler
来统计;缺点是代码侵入性强,会拖慢程序运行。Debug Trace
:@Override
public void onCreate(){
super.onCreate();
Debug.startMethodTracing("Launcher");
coreSize=Runtime.getRuntime().availableProcessors();
executorService=Executors.newFixedThreadPool(Math.max(2, Math.min(coreSize - 1, 4)));
application=this;
context=this.getApplicationContext();
AppProfile.context=context;
ScreenUtil.init(context);
initLog();
AppForegroundWatcher.init(context);
CrashReport.initCrashReport(getApplicationContext(), "e9bf59bd43", false);
Debug.stopMethodTracing();
//sdcard/Android/data/com.sty.ne.appperformance/files/Launcher.trace --> save as 导出来,用Profiler打开
}
sdcard/Android/data/com.sty.ne.appperformance/files/Launcher.trace
--> save as
导出来,用Profiler
打开,如下图所示:
缺点:只能记录应用内程序执行时间。
②CPU Profiler
:
不需要侵入代码(无需写Debug.startMethodTracing("Launcher"
),但是需要做如下配置:
run
-> edit configurations
;start recording a method trace on startup
;cpu
记录配置(profiling
菜单下勾选两个复选框);apply
--> profile
模式部署。systrace
统计命令行终端进入如下目录:/Users/tian/Library/Android/sdk/platform-tools/systrace
输入如下命令进入监听状态:
python systrace.py -o mynewtrace.html sched freq idle am wm gfx view binder_driver hal dalvik camera input res
此时运行代码,完成之后在命令行窗口按Enter
键结束监听,然后会生成目标文件mynewtrace.html
:
分析目标文件:
aop
方式统计异步优化主要是采用子线程来进行线程初始化,并行执行,减少执行时间。
@Override
public void onCreate(){
super.onCreate();
coreSize=Runtime.getRuntime().availableProcessors();
executorService=Executors.newFixedThreadPool(Math.max(2, Math.min(coreSize - 1, 4)));
application=this;
context=this.getApplicationContext();
AppProfile.context=context;
ScreenUtil.init(context);
async(new Runnable(){
@Override
public void run(){
initLog();
}
});
async(new Runnable(){
@Override
public void run(){
AppForegroundWatcher.init(context);
}
});
async(new Runnable(){
@Override
public void run(){
CrashReport.initCrashReport(getApplicationContext(), "e9bf59bd43", false);
}
});
}
异步优化需要关注的点:
api
不能创建Handler
;UI
操作。仅初始化立即需要的对象,不要创建全局静态对象,而是移动到单例模式,其中应用仅在第一次访问对象时初始化它们。
可以监听应用空闲时间,在空闲时间进行初始化。
public class DelayInit{
private Queue<Runnable> delayQueue=new LinkedList<>();
public void add(Runnable runnable){
delayQueue.add(runnable);
}
public void start(){
Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler(){
@Override
public boolean queueIdle(){
Runnable poll=delayQueue.poll();
if(poll !=null){
poll.run();
}
return !delayQueue.isEmpty();
}
});
}
}
其实出了启动优化外,Android 性能优化中还有 内存优化、网络优化、卡顿优化、存储优化……等,为了让大家一次都可以了解全,所以将其整合成名为《Android 性能优化核心知识点手册》,大家可以参考下:
Android 性能调优学习手册启动优化
内存优化
UI优化
网络优化
Android 性能调优学习手册Bitmap优化与图片压缩优化
多线程并发优化与数据传输效率优化
体积包优化
Android 性能调优学习手册