一、前言

APP优化是我们进阶高级开发工程师的必经之路, 而APP启动速度的优化,也是我们开启APP优化的第一步。 用户在使用我们的软件时,交互最多最频繁的也就是APP的启动页面,如果启动页面加载过慢,很可能造成用户对我们APP的印象过差,进而消耗了用户的耐心,更严重可能导致用户的卸载行为。这也是微信始终坚持使用“一个小人望着地球”作为启动页面的背景,并且坚持不添加启动广告的的原因。

二、APP的三种启动方式

来看一下Google官方文档《Launch-Time Performance》对应用启动优化的概述;

应用的启动可以分为冷启动,热启动和温启动,而启动最慢、耗时最长的就是冷启动。

冷启动(cold start)

当应用启动时,后台没有该应用的进程(常见如:进程被杀、首次启动等),这时系统会重新创建一个新的进程分配给该应用。

热启动(hot start)

这种启动会从已有的进程中来启动应用,通俗来讲就是已经启用的应用,通过back键或者home键回到系统主界面,再次通过最近任务重新打开Activity的过程。开销比冷启动更小。

暖启动(warm start)

暖启动产生的场景很多。常见如:1。用户使用返回键退出应用,然后马上又重新启动应用。2.应用被内存清除,再次打开应用,会通过OnCreate()中保存的实例状态恢复。

冷启动是从头开始启动APP,而其他两种启动方式是从后台活动返回到前台的一个过程。热启动和暖启动没有明显的区分界限,我们姑且把热启动和暖启动统称为热启动。开发中我们更多的关注冷启动优化,本文也是从Android的实例从发,分析冷启动的启动过程,并给出冷启动的优化方案。

三、APP的冷启动过程

冷启动开始时,系统会依次执行三个任务去启动APP:

  • 加载和启动应用程序
  • APP启动后,立即创建一个空白的启动Window
  • 创建APP的进程

在这三个任务执行后,系统创建了应用进程,那么应用进程接下来会执行下一步:

  • 创建APP对象
  • 开启一个主线程
  • 创建启动页的Activity
  • 加载View
  • 布局view到屏幕
  • 进行初始绘制显示视图

当应用进程完成初始绘制之后,系统进程用启动页的Activity来替换当前显示的空白Window,这个时刻用户就可以使用App了。

四、APP启动时间

APP的启动时间是我们可以检验优化效果的依据,启动时间是指打开应用从初始化到显示启动页Activity的这一段时间。 Google官方的解释:APP startup time

使用过logcat查看启动时间

在Android4.4(API level 19)以上的Android版本上,当启动应用时Android Studio自动会在logcat中输出启动时间。 这个时间从应用启动(创建进程)开始计算,到完成视图的第一次绘制(即Activity内容对用户可见)为止。

如Display显示:

I/ActivityManager: Displayed com.example.app/com.example.app.SplashActivity: +1s742ms (total +49s450ms)
复制代码

reportFullyDrawn()方法

Activity 的reportFullyDrawn()方法, 它会在Logcat里打印从apk初始化到reportFullyDrawn()方法被调用用了多长时间(文章的reportFullyDrawn()SplashActivity中的onCreate()中执行,可以看到显示的时间和Displayed的是一摸一样的)

I/ActivityManager: Fully drawn com.example.app/com.example.app.SplashActivity: +1s742ms (total +49s450ms)
复制代码

执行adb命令手动查看启动时间

adb shell am start -W [packagename]/[packagename.SplashActivity]

复制代码

输出:

Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.example.app/.SplashActivity }
Status: ok
Activity: com.example.app/.SplashActivity
ThisTime: 1368
TotalTime: 1368
WaitTime: 1432
Complete

复制代码

ThisTime:最后一个启动的Activity的启动耗时;

TotalTime:自己的所有Activity的启动耗时;

只用关注TotalTime就行了

启动时间标准

官方给出,当启动时间超出以下指标时,会被认为启动时间过长,这是就需要考虑仔细优化启动时间。

  • 冷启动时间超过5s
  • 热启动时间超过1.5s
  • 暖启动时间超过2s

说了一大堆启动的基础知识,下边开始讲解真正的优化实战

五、启动优化实战

解决应用刚启动时的白屏问题

前边讲到,应用初始化会进行一系列进程的创建,资源的初始化工作,这段时间系统会先分配一个空白的Window,这会造成用户打开应用到显示第一个可交互的Activity,会经历一段白屏的时间。

这时我们可以在给app定义一个主题去解决,在Activity显示出来之前先显示一个主题背景,去填补空白的Window阶段。

定义一个Splash主题

    <!--Splash launcher-->
    <style name="LauncherTheme" parent="AppTheme">
        <item name="android:windowBackground">@mipmap/ic_splash_bg</item>
        <item name="android:windowFullscreen">true</item>
        <item name="android:windowContentOverlay">@null</item>
    </style>
复制代码

manifest中引用该主题

 <activity android:name=".activity.SplashActivity"
            android:theme="@style/Launcher">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
复制代码

最后记得在启动页显示以后恢复默认的APP主题

  override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setTheme(R.style.AppTheme)
        setContentView(R.layout.activity_splash)

  }
复制代码

这种方法只是视觉上给用户一种快速启动的感觉,不能减少实际的启动时间。

避免Application初始化过重

随着我们工程越做越大,第三方库和组件也逐渐被依赖到我们的项目中,避免不了会在Application的onCreate()中执行很多第三方库的初始化工作。大量的初始化工作导致该生命周期过于沉重,可能会加长应用的启动时间,因此我们应该对这些第三方库进行分类和优化。

  • 必须在onCreate()且是主进程中初始化
  • 可以延迟,但是需要在Application中初始化
  • 可以延迟到启动页的生命周期回调中初始化
  • 延迟到用的时候再初始化

大家可以根据自身项目去整理代码,可以延迟执行的应该放在IntentService或者Work Thread中进行初始化。

  • 例如EventBus 需要在Activiy中使用的,必须在Application中初始化
  • 例如Bugly ,GrowingIO等类似库的可以放在Work Thread中初始化
  • 例如地图定位、ImageLoad可以延迟到使用之前初始化
  • SplashActivity中网络加载的资源,可以首次加载存放在缓存中,下次启动的时候再显示
  • 注意有些第三方库必须在主线程中初始化
  • 避免耗时操作,如数据库I/O操作不要放在主线程执行
  • 删除无用或重复的代码
  • 减少首屏Activity中的网络请求密度

更多有关Android性能优化的分享

完整学习笔记pdf全部免费分享,需要的朋友只需要点赞支持一下后,【点击这里直达免费获取方式

优化心得和实战经验

性能问题是造成App用户流失的罪魁祸首之一。App的性能问题包括崩溃、网络请求错误或超时、响应速度慢、列表滚动卡顿、流
量大、耗电等等。而导致App性能低下的原因有很多,除去设备硬件和软件的外部因素,其中大部分是开发者错误地使用线程、
锁、系统函数、编程范式、数据结构等导致的。即便是最有经验的程序员,也很难在开发时就能避免所有导致性能低下的“坑”,因
此解决性能问题的关键是在于能不能尽早地发现和定位这些“坑”。

1、移动端性能监控方案Hertz
2、Android性能优化后续
3、Android性能优化之虚拟机调优
4、Android UI 性能优化
5、性能提示
6、美团外卖Android Lint代码检查实践
7、使用Android Studio和MAT进行内存泄漏分析
8、手淘全链路性能优化
9、手Q Android缓存监控与优化实践
10、微信读书(Android)阅读引擎卡顿监控测试

1.png

响应速度

启动时间和响应时间是App带给用户的最直观的性能体验。因此,无论是何种类型的App,我们都不能忽视响应时间的测试。除了稳定性以外,对于性能纬度来说,哪个方面的性能是最重要的呢?毫无疑问,就是应用的启动速度。

1、 Android App 启动优化全记录
2、Android 中如何计算 App 的启动时间?
3、应用启动时间
4、Android 冷启动优化除了老三样还有哪些新招?
5、支付宝 App 构建优化解析:通过安装包重排布优化 Android 端启动性能
6、Redex 初探与 Interdex:Andorid 冷启动优化

流畅度

在不同层次的开发工程师手里,因为技术水平的参差不齐,即使很多手机在跑分软件性能非常高,打开应用依然存在卡顿现象。

另外,随着产品内容迭代,功能越来越复杂,UI页面也越来越丰富,也成为流畅运行的一种阻碍。综上所述,对APP进行性能优化已成为开发者该有的一种综合素质,也是开发者能够完成高质量应用程序作品的保证。

完整学习笔记pdf全部免费分享,需要的朋友只需要点赞支持一下后,【点击这里直达免费获取方式
1、Android 中的卡顿丢帧原因概述 - 方法论
2、Android 中的卡顿丢帧原因概述 - 系统篇
3、Android 中的卡顿丢帧原因概述 - 应用篇
4、Android 无障碍服务导致的整机卡顿案例分析
5、显示性能指标
6、渲染速度缓慢
7、Android 流畅度检测原理简析
8、Android JankTracker 原理解析
9、App流畅度优化:利用字节码插桩实现一个快速排查高耗时方法的工具

内存

Android 低内存会导致性能问题 , 具体表现就是响应慢和卡顿 。比如启动一个应用要花比平时更长的时间 ;滑动列表会掉更多帧 ;后台的进程减少导致冷启动变多 ;手机很容易发热发烫等 。

1、 Android 中低内存对性能的影响
2、 Android OOM案例分析
3、 Android 代码内存优化建议 - Android 资源篇
4、 Android 代码内存优化建议 - Android 官方篇
5、 Android 代码内存优化建议 - Java 官方篇
6、 Android 内存优化(1) - MAT 使用入门
7、 Android 内存优化之二 - MAT使用进阶
8、 Android 内存优化之三 - 打开 MAT 中的 Bitmap 原图
9、 Android 代码内存优化建议 - OnTrimMemory 优化
10、Android LowMemoryKiller原理分析
11、Android匿名共享内存(Ashmem)原理

图形栈

Android系统中图形系统是相当复杂的,包括WindowManager,SurfaceFlinger,Open GL,GPU等模块。 其SurfaceFlinger作为负责绘制应用UI的核心,从名字可以看出其功能是将所有Surface合成工作。 不论使用什么渲染API, 所有的东西最终都是渲染到”surface”. surface代表BufferQueue的生产者端, 并且 SurfaceFlinger所消费, 这便是基本的生产者-消费者模式. Android平台所创建的Window都由surface所支持, 所有可见的surface渲染到显示设备都是通过SurfaceFlinger来完成的.

1、 LWN大作:Android display pipeline本身以及进程调度!
2、 Android 中的 Hardware Layer 详解
3、 Android硬件加速原理与实现简介
4、 Android图形系统概述
5、 Choreographer原理
6、 SurfaceFlinger启动篇
7、 SurfaceFlinger绘图篇
8、 Android应用程序UI硬件加速渲染技术简要介绍和学习计划
9、 Android应用程序UI硬件加速渲染环境初始化过程分析
10、Android应用程序UI硬件加速渲染的预加载资源地图集服务(Asset
Atlas Service)分析
11、Android应用程序UI硬件加速渲染的Display List构建过程分析
12、Android应用程序UI硬件加速渲染的Display List渲染过程分析
13、Android应用程序UI硬件加速渲染的动画执行过程分析
14、Android中的GraphicBuffer同步机制-Fence
15、Android P 图形显示系统——硬件合成HWC2
16、Android P 图形显示系统——Android VirtualDisplay解析
17、Android P 图形显示系统—— 上层Client和SurfaceFlinger的交互
18、Android P 图形显示系统—— SurfaceFlinger合成流程(一)
19、Android P 图形显示系统—— SurfaceFlinger合成流程(二)

性能优化不是更新一两个版本就可以解决的,是持续性的需求,持续集成迭代反馈。在实际的项目中,在项目刚开始的时候,由于人力和项目完成时间限制,性能优化的优先级比较低,等进入项目投入使用阶段,就需要把优先级提高,但在项目初期,在设计架构方案时,性能优化的点也需要提早考虑进去,这就体现出一个程序员的技术功底了。

如果你也想提升自己移动开发的性能优化技术,或者是正在准备移动开发岗的面试,我觉得这份笔记你必定不能错过。

资料领取

以上完整学习笔记pdf全部免费分享,需要的朋友只需要点赞支持一下后,【点击这里直达免费获取方式