APP 优化 - app 启动优化

大家都遇到过自己 app 启动时间有些长,屏幕白屏的问题吧。一个正常的商业 app 在启动时时会加载一大票组件的初始化的,功能越多需要加载的组件越多,那么 app 启动的时间就越长,app 白屏或黑屏的时间也越长,怎么办呀,今天就来优化一下,谈谈思路,不涉及过多代码

下面是几个 app 启动优化可供参考的案例:


app 启动方式

1、冷启动
App没有启动过或App进程被killed, 系统中不存在该App进程。需要创建App进程, 加载相关资源, 启动Main Thread, 初始化首屏Activity等。在这个过程中, 屏幕会显示一个空白的窗口(颜色基于主题), 直至首屏Activity完全启动。

2、热启动
热启动意味着你的App进程只是处于后台, 系统只是将其从后台带到前台, 展示给用户。在这个过程中, 屏幕会显示一个空白的窗口(颜色基于主题), 直至activity渲染完毕。

3、温启动
介于冷启动和热启动之间, 一般来说在以下两种情况下发生:

用户back退出了App, 然后又启动. App进程可能还在运行, 但是activity需要重建
用户退出App后, 系统可能由于内存原因将App杀死, 进程和activity都需要重启
启动优化主要是针对冷启动. 热启动和温启动都相对较快。

2206304-b6fe84c9f4b8284e.png

关于 StartingWindow 的解释

StartingWindow 我也是才刚刚看到大家说的, 之前一直在此处有疑虑额,但是一直没搞明白,其实就是在 app 在冷启动时先显示一个空白的 window 给大家看,这个 window 叫做 StartingWindow

不错的解释:

application以及activity初始化是一个相当复杂的过程,而白屏或者黑屏恰恰就是这个过程的产物:在应用程序刚启动到应用程序初始化完全之间有一段时间空隙,这时候系统创建了一个空白窗口,叫StartingWindow。这个窗口让人感觉activity已经启动了只是没填充好数据。它是个临时窗口,对应的WindowType是TYPE_APPLICATION_STARTING。这个空白窗口是为了告诉用户,系统已经接受到操作,正在响应。应用程序初始化完成加载完第一帧之后,这个窗口就会被移除。

Window的顶层是DecorView,所以StartingWindow显示一个空DecorView,但是会给这个DecorView应用 launch activity指定的Theme,如果 launch activity没有指定Theme就用application的。activity启动时,windowBackground比setContentView()要先加载,这一段时间如果Theme是Light,屏幕就是白色的;如果是Dark,就会显示黑屏。上述就是黑白屏的原因了


1. 一个正常的 app 启动我们都这么干吧

友盟统计,推送,地图,IM,自家的各种组件,这些很耗时的,尤其是第三方组件

魅族工程师统计过,若是 app 启动时间超过 400 毫秒,那么用户在桌面点击你的应用图标后,将感觉到明显的卡顿

2. app 启动的过程

app 的过程是怎么样的,这 400 毫秒都包含哪些生命周期函数呢~,这里不做深入展开,仅仅看看 app 启动涉及到的生命周期函数及其顺序

  • 点击桌面图标后,安卓系统会 fork 创建出一个新的进程分配给该应用,之后会依次创建和初始化Application类。当这些操作走完之后,你才能看到 SplashActivity 的第一眼。

  • Application ——>attachBaseContext()——>onCreate()——>Activity——>onCreate()——>配置主题中背景等属性——>onStart()——>onResume()——>测量布局绘制显示在界面上

那么在这期间,我们若是在 Application 的 onCreate 做了太多的 SDK的初始化的话,这段时间您的屏幕都是你手机默认主题的颜色(白色/黑色),这就是为什么我们做的APP会出现白屏

3. 那怎么优化呢

优化思路主要有2个:

  • 把 Application 的 onCreate 中的初始化操作尽量都放在非 UI 线程,这样不会卡 UI ,大众做法是启动一个 IntentService
  • 并不是所有的初始化操作都可以放到 非 UI 线程的,并且系统本身也是很耗时的,若是不想让用户看白屏,那么可以给 app 设置一个背景,先让用户看启动图,产生一个 app 已经启动的假象

关于分割各个组件初始化方法方案看这个,有的必须在 application,其次的放 splashActivity,最后没什么影响的异步线程

4. 如何给 app 设置背景

这里思路也有3个:

  • 给 application 的 theme 设置 windowBackground
  • 给 SplashActivity 的 theme 设置 windowBackground
  • 给 SplashActivity 加透明背景,这样在 app 启动时会透明,就跟没启动一样,一直到后面我们改的 activity 的 theme 加载出来

这里推荐第二种方法,因为 application 的 theme 设置是全局所有 Activity 都有效的,若是 给 application 的 theme 设置 windowBackground 后,所有的 Activity windowBackground 都会设置成这样,这会造成过度绘制的问题,另外这种效果也不是我们想要的

那么给 SplashActivity 的 theme 设置 windowBackground 就成了我们的选择,为啥呢,因为 app 启动时 ,为了不让我们看大黑屏会默认启动一个空内容的 window 先显示着,这个 window 的背景就是 application theme 的 windowBackground ,若是没有的话就用 SplashActivity theme 的 windowBackground

这个体验才是最好的,经测试 4.X 版本也没问题,这里我们在 application 的 onCreate 里延迟3秒,并且给 SplashActivity theme 设置 windowBackground,然后我们看看效果如何

application 设置:

class MyApplication : Application() {

    override fun onCreate() {
        super.onCreate()

            Thread.sleep(3000)
    }
}

theme 设置:

        <style name="SplashTheme" parent="AppTheme">
            <item name="android:windowBackground">@drawable/ic_dog</item>
        </style>

        <activity
            android:name=".MainActivity" android:theme="@style/SplashTheme">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>

效果:


录的不是很好,大家见谅,狗狗还是很可爱的~,最后 view 显示的那一下,gif 没提现出来,大家脑补一下吧~

app 启动优化的思路基本上就是这样了,大家翻再多的资料也不会出这个圈了

然后有个流氓的,launch activity 透明背景,让用户以后还没启动呢,这样太流氓了,我不喜欢,据说微信即使这么干的,这样其实体验也不是非常好

对于首个加载的Activity,可以使用透明背景:可以减少application加载主题的消耗

<style name= "EmptyTheme">
   <item name="android:windowIsTranslucent">true</item>
  <item name="android:windowNoTitle">true</item>
</style>

然后,在onCreate第一行执行:setTheme(R.style.AppTheme);


5. 很有意思的拼启动图片

我们直接使用大图作为启动画面的话是会话不少内存的,要是图片简单的话可以使用 SVG 矢量图,或是不给启动页设置主图背景,而是添加一个 imageview 进来,完事手动回收资源,再 GC,这样可以尽可能节省内存资源

要知道 drawable 里面的静态 png 图片除非我们拿到其 bitmap 对象手动标记回收,否则系统会一直保持在内存中,对于频繁使用的小图来说这是一种优化,但是对于仅仅使用一次的大图来说这就不合了

但是呢今天看到了一个很有意思的做大,使用 layer-list + 小图 拼一个大图出来,这样也可以实现节约内存的目的

<style name="SplashTheme" parent="AppTheme">
        <item name="android:windowTranslucentStatus">true</item>
        <item name="android:windowBackground">@drawable/logo_splash</item>
    </style>

<!--@drawable/logo_splash文件-->
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 如果item下的 bitmap 没有设置 gravity ,再API 23 以下,会出错! -->
    <item
        android:drawable="@color/splashBg"
        android:gravity="fill" />

    <item android:gravity="top">
        <bitmap
            android:gravity="top"
            android:src="@drawable/splash_top" />
    </item>

    <item
        android:bottom="72dp"
        android:gravity="bottom|center_horizontal">
        <bitmap
            android:gravity="bottom"
            android:src="@drawable/splash_bottom" />
    </item>
</layer-list>

这里还有更多玩法哦,甚至还有启动页动画实现的,值得看

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容

  • 一触即发 App启动优化最佳实践 文中的很多图都是Google性能优化指南第六季中的一些截图 Google给出的优...
    eclipse_xu阅读 5,079评论 7 95
  • 1、通过CocoaPods安装项目名称项目信息 AFNetworking网络请求组件 FMDB本地数据库组件 SD...
    阳明先生_x阅读 15,967评论 3 119
  • 转载自一触即发 App启动优化最佳实践 一触即发 App启动优化最佳实践 文中的很多图都是Google性能优化指南...
    CP9阅读 601评论 0 3
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,448评论 25 707
  • 你从树洞里钻出来 毛茸茸的大尾巴 这可是我常来说悄悄话的树洞哦 你居然 居然住在里面 我好像有点喜欢你了 你递来几...
    竹喧归浣女阅读 168评论 0 4