应用启动优化

Android应用程序启动时,可以通过log日志查看其启动时间,启动一个Activity时,会有相应的启动耗时输出比如:ActivityManager: Displayed com.tw.launchpro1/.MainActivity: +951ms

1.1. 预研

建立两个空项目App,packageName不同,分别为com.tw.launchpro1com.tw.launchpro2,只包含一个Activity,通过测试比对其启动时间。

1.1.1. AppCompatActivity

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
}

启动时间对比:

06-23 11:14:09.253  1003  1171 I ActivityManager: Displayed com.tw.launchpro1/.MainActivity: +956ms
06-23 11:14:13.359  1003  1171 I ActivityManager: Displayed com.tw.launchpro2/.MainActivity: +952ms
06-23 11:14:17.397  1003  1171 I ActivityManager: Displayed com.tw.launchpro1/.MainActivity: +957ms
06-23 11:14:20.478  1003  1171 I ActivityManager: Displayed com.tw.launchpro2/.MainActivity: +964ms
06-23 11:14:26.593  1003  1171 I ActivityManager: Displayed com.tw.launchpro1/.MainActivity: +944ms
06-23 11:14:30.477  1003  1171 I ActivityManager: Displayed com.tw.launchpro2/.MainActivity: +950ms

两个App的启动时间基本相同。

1.1.2. Activity

修改launchpro2.MainActivity,使它继承自Activity。

class MainActivity : Activity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
}

启动时间对比:

06-23 11:15:50.018  1003  1171 I ActivityManager: Displayed com.tw.launchpro1/.MainActivity: +951ms
06-23 11:15:53.812  1003  1171 I ActivityManager: Displayed com.tw.launchpro2/.MainActivity: +707ms
06-23 11:16:04.844  1003  1171 I ActivityManager: Displayed com.tw.launchpro1/.MainActivity: +952ms
06-23 11:16:09.812  1003  1171 I ActivityManager: Displayed com.tw.launchpro2/.MainActivity: +705ms
06-23 11:16:14.044  1003  1171 I ActivityManager: Displayed com.tw.launchpro1/.MainActivity: +959ms
06-23 11:16:17.936  1003  1171 I ActivityManager: Displayed com.tw.launchpro2/.MainActivity: +719ms

直接继承自Activity的应用,比继承自AppCompatActivity启动时间更快,大概提速240ms。其启动时间为710ms左右。

1.1.3. OtherApp

直接修改我们的Activity继承自Activity,启动时间降到710ms左右,对比一下其它应用,Zoom和微信:

1003  1171 I ActivityManager: Displayed us.zoom.videomeetings/com.zipow.videobox.LauncherActivity: +527ms
1003  1171 I ActivityManager: Displayed us.zoom.videomeetings/com.zipow.videobox.WelcomeActivity: +215ms
1003  1171 I ActivityManager: Displayed com.tencent.mm/.ui.LauncherUI: +648ms
1003  1171 I ActivityManager: Displayed us.zoom.videomeetings/com.zipow.videobox.LauncherActivity: +386ms
1003  1171 I ActivityManager: Displayed us.zoom.videomeetings/com.zipow.videobox.WelcomeActivity: +147ms
1003  1171 I ActivityManager: Displayed com.tencent.mm/.ui.LauncherUI: +547ms

测试的两次Zoom的启动时间分别为527ms386ms,而微信的启动时间为648ms547ms。我们上面的应用的启动Activity,只设置了一个layout,启动时间居然也比Zoom和微信的启动时间长,是否是Theme设置的问题?

下面的时间为今日头条App的启动时间:

// 有广告页面
06-23 18:36:57.136  1003  1171 I ActivityManager: Displayed com.ss.android.article.news/.activity.SplashBadgeActivity: +1s160ms
06-23 18:37:01.513  1003  1171 I ActivityManager: Displayed com.ss.android.article.news/.activity.MainActivity: +886ms
06-23 18:37:07.117  1003  1171 I ActivityManager: Displayed com.ss.android.article.news/.activity.SplashBadgeActivity: +1s229ms
06-23 18:37:13.223  1003  1171 I ActivityManager: Displayed com.ss.android.article.news/.activity.MainActivity: +902ms
06-23 18:37:22.350  1003  1171 I ActivityManager: Displayed 
// 无广告页面
com.ss.android.article.news/.activity.MainActivity: +856ms (total +1s715ms)
06-23 18:37:33.251  1003  1171 I ActivityManager: Displayed com.ss.android.article.news/.activity.MainActivity: +898ms (total +1s781ms)

SplashBadgeActivity是头条App的启动广告页面,该页面的启动时间为1s200ms左右,而主页MainActivity的启动时间大概为900ms。 无广告时,在SplashBadgeActivity中不显示View直接进入到MainActivity页面,总共时间为1.7s左右。

1.1.4. Theme

反编译Zoom.apk,查看它的LauncherActivity的Theme设置。

<application android:icon="@drawable/zm_launcher" android:label="@string/zm_app_name" android:largeHeap="true"
             android:name="com.zipow.videobox.ZoomApplication">
    <activity android:icon="@drawable/zm_launcher" android:label="@string/zm_app_name"
              android:name="com.zipow.videobox.LauncherActivity" android:theme="@style/ZMTheme.Transparent">
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
            <category android:name="android.intent.category.LAUNCHER"/>
        </intent-filter>
    </activity>
</application>

它的theme为ZMTheme.Transparent,在xml里面查看该theme的配置项:

<style name="ZMTheme" parent="@android:style/Theme">
    <item name="android:buttonStyle">@style/ZMButton</item>
    // ...
</style>

<style name="ZMTheme.Transparent" parent="@style/ZMTheme">
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:windowFrame">@null</item>
    <item name="android:windowNoTitle">true</item>
    <item name="android:windowIsTranslucent">true</item>
    <item name="android:windowContentOverlay">@null</item>
    <item name="android:backgroundDimEnabled">false</item>
    <item name="android:colorBackgroundCacheHint">@null</item>
</style>

该theme继承自Android原生的Theme,除此之外,添加了windowBackgroundwindowFramewindowIsTranslucent。尝试将该theme配置添加到launchpro2.MainActivity,再对比启动时间:

06-23 11:22:57.882  1003  1171 I ActivityManager: Displayed com.tw.launchpro1/.MainActivity: +713ms
06-23 11:23:02.770  1003  1171 I ActivityManager: Displayed com.tw.launchpro2/.MainActivity: +684ms
06-23 11:23:08.874  1003  1171 I ActivityManager: Displayed com.tw.launchpro1/.MainActivity: +712ms
06-23 11:23:13.269  1003  1171 I ActivityManager: Displayed com.tw.launchpro2/.MainActivity: +683ms
06-23 11:23:24.831  1003  1171 I ActivityManager: Displayed com.tw.launchpro1/.MainActivity: +709ms
06-23 11:23:29.992  1003  1171 I ActivityManager: Displayed com.tw.launchpro2/.MainActivity: +668ms

和没添加该theme的launchpro1.MainActivity1相比,启动时间似乎少了20ms,但基本可以忽略不记,远未达到Zoom的500ms以内的启动速度。

1.1.5. setContentView()

继续在上面的基础上,修改launchpro2.MainActivity,在其它onCreate方法中,不调用setContentView设置其它布局,测试其启动时间:

06-23 11:33:51.634  1003  1171 I ActivityManager: Displayed com.tw.launchpro1/.MainActivity: +708ms
06-23 11:33:55.780  1003  1171 I ActivityManager: Displayed com.tw.launchpro2/.MainActivity: +610ms
06-23 11:34:00.817  1003  1171 I ActivityManager: Displayed com.tw.launchpro1/.MainActivity: +699ms
06-23 11:34:06.345  1003  1171 I ActivityManager: Displayed com.tw.launchpro2/.MainActivity: +614ms
06-23 11:34:11.561  1003  1171 I ActivityManager: Displayed com.tw.launchpro1/.MainActivity: +713ms
06-23 11:34:17.830  1003  1171 I ActivityManager: Displayed com.tw.launchpro2/.MainActivity: +610ms

未调用setContentView()时,启动时间大概在610ms左右。比有设置的时候降了几十Ms。

1.1.6. DaggerActivity

修改两个工程中的Activity都继承自AppCompatActivity,并在launchpro2.MainActivity应用中引用dagger框架,使用inject注入,再对比其启动时间:

06-23 14:08:26.406  1003  1171 I ActivityManager: Displayed com.tw.launchpro2/.MainActivity: +1s97ms
06-23 14:08:32.061  1003  1171 I ActivityManager: Displayed com.tw.launchpro1/.MainActivity: +968ms
06-23 14:08:41.411  1003  1171 I ActivityManager: Displayed com.tw.launchpro2/.MainActivity: +1s56ms
06-23 14:08:53.256  1003  1171 I ActivityManager: Displayed com.tw.launchpro1/.MainActivity: +924ms
06-23 14:09:01.340  1003  1171 I ActivityManager: Displayed com.tw.launchpro2/.MainActivity: +1s76ms
06-23 14:09:06.792  1003  1171 I ActivityManager: Displayed com.tw.launchpro1/.MainActivity: +944ms

使用inject注入的Activity,比未使用的启动时间要多100ms左右。

猜想:如果在项目中有大量Inject注入配置需要在Application.onCreate()前进行注入,App的启动时间可能会更长。

1.2. 结论

  1. AppCompatActivity相比Activity,由于其添加了AppTheme样式设计支持它会造成大概240ms的开销。
  2. Dagger依赖注入组件,如果有大量的Dagger依赖配置,也会导致额外的启动开销。
  3. setContentView(),在xml避免有大量的View层级嵌套造成解析耗时开销。
  4. Application.onCreate(),避免在该方法进行大量操作,比如第三方SDK,文件读写等。

adb shell am start -W us.zoom.videomeetings/com.zipow.videobox.LauncherActivity adb shell am start -W com.tw.launchpro1/.MainActivity adb shell am start -W com.tencent.mm/.ui.LauncherUI

results matching ""

    No results matching ""