MicroKibaco / CrazyDailyQuestion

每日一问: 水滴石穿,聚沙成塔,坚持数月, 必有收获~
35 stars 1 forks source link

2019-08-14: 说说你是怎么做启动优化的,以及对启动优化的理解(提示:可以从冷启动和热启动的角度出发)? #12

Open zhjlong opened 5 years ago

skylarliuu commented 5 years ago

一、启动分类

二、优化思路

作为普通应用,App进程的创建等环节我们是无法主动控制的。开发人员唯一能做的就是在Application 和 第一个 Activity 中,减少 onCreate() 方法的工作量,从而缩短冷启动的时间。像应用中嵌入的一些第三方 SDK,都建议在 Application 中做一些初始化工作,开发人员不妨采取懒加载的形式移除这部分代码,而在真正需要用到第三方 SDK 时再进行初始化。

Google也给出了启动加速的方向:

三、优化方案

1.主题切换

5.0以下某些低端机会出现ANR或者长时间卡顿不进入引导页,而罪魁祸首是MultiDex.install(Context context)的dexopt过程耗时过长。

解决思路

liu1813565583 commented 5 years ago

一、应用的启动方式

  通常来说,启动方式分为两种:冷启动和热启动。

  1、冷启动:当启动应用时,后台没有该应用的进程,这时系统会重新创建一个新的进程分配给该应用,这个启动方式就是冷启动。

  2、热启动:当启动应用时,后台已有该应用的进程(例:按back键、home键,应用虽然会退出,但是该应用的进程是依然会保留在后台,可进入任务列表查看),所以在已有进程的情况下,这种启动会从已有的进程中来启动应用,这个方式叫热启动。

  特点

  1、冷启动:冷启动因为系统会重新创建一个新的进程分配给它,所以会先创建和初始化Application类,再创建和初始化MainActivity类(包括一系列的测量、布局、绘制),最后显示在界面上。

  2、热启动:热启动因为会从已有的进程中来启动,所以热启动就不会走Application这步了,而是直接走MainActivity(包括一系列的测量、布局、绘制),所以热启动的过程只需要创建和初始化一个MainActivity就行了,而不必创建和初始化Application,

  因为一个应用从新进程的创建到进程的销毁,Application只会初始化一次。

Android冷启动时间优化

 冷启动时间是指当用户点击你的app那一刻到系统调用Activity.onCreate()之间的时间段。在这个时间段内,WindowManager会先加载app主题样式中的windowBackground做为app的预览元素,然后再真正去加载activity的layout布局

冷启动时间优化   知道了Android冷启动时间的原理之后,就可以通过一些小技巧来对冷启动时间进行优化,从而让你app加载变得”快“一些(视觉体验上的快。

liyilin-jack commented 5 years ago

Skylar同学提到,要进行启动优化,首先要定位问题,那怎么才能定位问题呢?

一般是使用两个工具来定位,一是traceview,在代码要检测的代码部分startTrace和stopTrace,然后查看trace文件进行分析;二是使用systrace脚本进行分析;

我必须要说的是,首先startTrace和stopTrace必须成对使用,才能生成trace跟踪文件;其次,改方法只适合线下使用,因为记录各种运行信息的同时会拖慢程序运行的速度;第三,可能会把小问题扩大化,引向错误的优化方向。

其实我们可优化的点很有限,一是application的启动耗时,而是mainActivty的启动耗时。 针对一,一般是因为application中执行了太多的任务,我们可以使用异步优化的思路来减少阻塞执行的耗时;针对某些有依赖关系的任务,还可以使用countdownLaunch来进行阻塞等待异步任务完成再往下执行。

针对二,可能导致的原因,一是布局复杂导致的加载阻塞耗时,这个可以通过布局异步加载来缓解,具体可以看我的博客异步加载布局探索。二是启动时出发的生命周期中执行了太多的任务,可以适当的进行延迟初始化。

MicroKibaco commented 5 years ago

  学习本课题重点偏实践,尤其是工具使用.以及具体问题分析,本课题大概会花费我两天时间总结.先列个大纲,后续慢慢填充.你是否遇到过以下问题

如果有,希望以下大纲能够帮助到你,有问题一块儿探讨~

应用启动方式分类:

优化方向

ApplicationActivty 以及 进程优化

一.启动时间检测方式

adb shell am start -W packagename/首屏Activity

说明环境搭建成功了~ systrace

三.如何获取方法耗时

四.异步优化

  sharePrefrence存储过程中不要在异步线程使用apply(),线程不安全.

五.异步初始化,启动器

六.延迟初始化

七.线程优化

八.业务优化

  懒加载,和启动无关的业务模块学会迁移到其他页面

九.闪屏优化

  SplashActivtyMainActivity 合二为一,但是相关逻辑要进行特殊判断,逻辑处理相对复杂,不推荐

十.GC 优化

十一.系统调用优化

  在启动过程不要做有关系统调度情况,如:Binder调用等待,PMS操作等.

十二.I/O 优化

  我们要注意这些线程是否有阻塞情况.数据超过100kb,sp保存数据异步线程可以用commit(),onPause,sp会强制磁盘未落地,如果读写操作未完成会造成卡顿ANR,如需保存大的数据,可以考虑MMKV替代sp或者考虑在Application重写getSharePrefrence()方法.

十三.类的加载

十四.保活

   保活可以减低你的Application创建和初始化时间,让冷启动变为温启动,不过在Android7.0阉割了某些广播属性,保活越来越难.

十五.插件化和热修复

  Tinker 框架在加载补丁后,应用启动速度会降低 5%~10%,360加固也会降低启动时间,所以我们在使用的时候,需要做出一些权衡和选择.

十六.启动监控

参考资料

zhengjunke commented 5 years ago

Application启动优化: 1、布局优化 我们的启动页Activity包含有启动图控件、闪屏广告图控件、闪屏广告视频控件、首次安装介绍图控件。对于布局优化而言,除了启动图控件外,其他都不是App启动时都要初始化的控件,这时我们可以使用ViewStub。针对指定的业务场景,初始化指定的控件。 2、避免I/O操作 我们知道I/O操作不是实时的,例如数据库的读写、SharedPreferences#apply()。我们要注意这些操作有没阻塞主线程地执行,同时我们可以利用StrictMode严格模式,利用它可以检测我们在启动的时候有没正确进行磁盘读写操作。 3、注意图片bitmap的加载速度和编码格式 我们可以知道,启动页大部分的情况下都是图片的显示,那么我们在图片这方面怎么抠细节呢,那就是对各种第三方图片加载库的选用了Glide、Picasso、Fresco等,还有是PREFER_ARGB_8888、PREFER_RGB_565的选取问题,大家可以针对属于自己项目情况进行选取。 4、对矢量图VectorDrawable对象的使用 矢量图的核心是省时间、省空间。而对于某些用户,它的启动图可能不是一张图片,它十分简约,就一个logo,这个时候我们可以考虑一下矢量图的用法。 5、注意Activity中的启动生命周期的回调 我们在Application#onCreate()优化,将某些不是很必要的网络请求,搬到了欢迎页中,但是我们也不能直接将这个网络请求操作直接拷贝到启动页的onCreate()中,我们可以巧妙地利用Activity生命周期中的Activity#onWindowFocusChanged(boolean hasFocus) ,这个是所有控件初始化完的真正回调,我们可以将网络操作放在这里,当然我们还可以使用Service。

gys0000 commented 5 years ago

放上我参考的文章: Android 性能优化(一) —— 启动优化提升60% Android:手把手教你如何优雅的实现APP启动速度优化

启动优化应该可以分两大类:一类视觉优化,一类逻辑优化。 上一个问题是说出你理解的程序启动过程,我们要优化的就是从点击app图标到页面展示这一段。

在应用启动的过程中,在应用程序启动后立刻会展示启动窗口,这也就是我们后边进行视觉优化的地方,展示启动窗口的同时我们会在后台准备创建应用程序的创建。 android 程序启动

视觉优化

对启动主题进行操作 1.把启动主题设置成透明

<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="android:windowFullscreen">true</item>
<item name="android:windowIsTranslucent">true</item>
</style>

这样操作,我们点击app图标之后回有短暂的停留然后进入应用的首页,这还是会有体验上的不快。 2.把启动主题设置成一张图片

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowBackground">@drawable/lunch</item>  //闪屏页图片
<item name="android:windowFullscreen">true</item>
<item name="android:windowDrawsSystemBarBackgrounds">false</item><!--显示虚拟按键,并腾出空间-->
</style>

这样点击app图标之后,立即会展示一张图片,短暂停留之后进入应用首页。这样的体验会比透明的主题要好。

逻辑优化

从进程被创建到执行Activity的onWindowFocusChanged()这段时间是我们要进行优化的区域。 这里大概写一些优化的方面 1.Application的优化