Android performance optimization – startup process cold start thermal start

1. Start the applicationMethods

   Generally speaking, there are two ways to start: cold Start and warm start.

  1. Cold start: When the application is started, there is no process of the application in the background, then the system will recreate a new one The process is assigned to the application, and the startup method is cold start.

  2, hot start: when the application is started, there is already a process of the application in the background (for example: press the back key, the home key , Although the application will exit, the process of the application will still remain in the background and you can enter the task list to view), so in the case of an existing process, this startup will start the application from the existing process. This way Called hot start.

  Features

  1, cold start: cold start because the system will re-create a new process assigned to it, so it will first create and initialize the Application class, and then create and initialize the MainActivity class (including a series of measurements, layout, Draw), and finally displayed on the interface.

  2. Hot start: Hot start will start from the existing process, so hot start will not go. Application This step is to go directly to MainActivity (including a series of measurement, layout, and drawing), so the hot start process only needs to create and initialize a MainActivity, instead of creating and initializing an Application,

   Because an application from the creation of a new process to the destruction of the process, the Application will only be initialized once.

2. Application startup process

  Cold start process: When you click on the app’s start icon, the Android system forks from the Zygote process to create a new process and assign it to the application, and then it will create and initialize the application one by one

  windowBackground and other attributes set to MainActivity and configure some attributes on the Activity level , And then inflate layout, when the onCreate/onStart/onResume method is finished, the measure/layout/draw of contentView is finally displayed on the interface, so until here,

   is the first launch of the application, and the interface we see at this time is the so-called first frame. So, to summarize, the application startup process is as follows:

  Application’s constructor method——> attachBaseContext()——>onCreate()——>Activity construction method——>onCreate()——>Configure the background and other properties in the theme——>onStart()——>onResume()——>Measurement layout drawing display On the interface.

  The general process is as follows:

  1. Click on the desktop icon, Launcher will start the default Acticity of the program, and then start various activities according to the logic of the program

  2, to start Activity, you need to use the ActivityManagerService service process of the application framework layer (Service is also started by the ActivityManagerService process); in the Android application framework layer, ActivityManagerService is a very important interface, < /span>

   It is not only responsible for starting Activity and Service, but is also responsible for managing Activity and Service .

    Step 1. Whether to start the Activity through the Launcher, or to start a new one by calling the startActivity interface inside the Activity Activity, through Binder inter-process communication into the ActivityManagerService process, and call the ActivityManagerService.startActivity interface;

    Step 2. ActivityManagerService call ActivityStack.startActivityMayWait to prepare the relevant information of the Activity to be started;

    Step 3. ActivityStack notifies ApplicationThread to schedule Activity start , ApplicationThread here represents the process that calls the ActivityManagerService.startActivity interface. For the scenario of clicking on the application icon, this process is the Launcher,

     For the scenario of calling startActivity inside the Activity, this process is the process where the Activity is located;

    Step 4. ApplicationThread does not perform the actual startup operation. It enters the ActivityManagerService process by calling the ActivityManagerService.activityPaused interface to see if a new process needs to be created to start the Activity;

    Step 5. For the scenario where the Activity is started by clicking the application icon, the ActivityManagerService will call startProcessLoc in this step ked to create a new process, and for starting a new activity by calling startActivity inside the activity, this step does not need to be performed,

     because the new Activity is started in the same process as the original Activity;

    Step 6. ActivityManagerServic Call the ApplicationThread.scheduleLaunchActivity interface to notify the corresponding process to perform the operation to start the Activity;

    Step 7. ApplicationThread to start the Activity operation Forward to ActivityThread, ActivityThread imports the corresponding Activity class through ClassLoader, and then starts it.

3. White screen and black screen encountered during cold start and optimized startup time

  

  1, white screen problem:

   Android Studio 2.0 is upgraded with Instant Run. In order to allow us to quickly deploy the code, Instant Run actually has a very complex logic behind it. For example, if you want to establish a server in the APK to communicate with Android Studio, and compare and replace code differences, white screen problems may occur during the development process.

   general release version of the program will not have this phenomenon;

   if it will continue If there is a white screen problem, you can view the style file

1
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> ...... <item name="android:windowIsTranslucent">trueitem< code class="html plain">> <item name="android:windowNoTitle">trueitem> style>

   has added two attributes, windowIsTranslucent and windowNoTitle, set these two attributes to true, you can make the window transparent when the program is initialized. The main interface of the program will be displayed after the end, so you can't see the white screen interface at all.

  2. Optimization of startup time

   first measure the startup time of the activity-------Activity’s reportFullyDrawn( ) Method

 You need to call Activity’s reportFullyDrawn(). It will report in the log how long it took from the apk initialization (the same time as the previous Displayed) to the reportFullyDrawn() method being called.

The log displayed by the reportFullyDrawn() method is similar to this:

ActivityManager: Displayed com.Android.myexample/.StartupTiming: +768ms

on 4.4 Calling the reportFullyDrawn() method will crash (but the log can still be printed normally), prompting that the UPDATE_DEVICE_STATS permission is required, but this permission can only be authorized by the system app. The solution is to adjust it like this

  try{
code>reportFullyDrawn();
  }catch(SecurityException E){
  }
   There is also a method to measure the startup time, which is also worth mentioning, that is the screenrecord command

   First start the screenrecord command with the-bugreport option (it can add a timestamp to the frames-it should be a feature in L):

  $adbshellscreenrecord--bugreport/sdcard /launch.mp4
   Then click the app icon, wait for the app to display, ctrl-C screenrecord, use the adb pull command to export the file to the computer.

  $adb pull/sdcard/launch. mp4

   Now you can open the recorded video to see what happened. You need a video player that can be viewed frame by frame (Quicktime on the mac is fine, it’s not clear which player is best to use on other os). Now play frame by frame, notice that there is a frame timestamp at the top of the video.

   keep going until you find the app icon is highlighted. At this time, the system has processed the click event on the icon, started the app, and recorded the time of this frame. Continue playing frames until you see the first frame of the entire UI of the app. According to different situations (whether there is a start window, whether there is a start screen, etc.),

  The actual sequence of events and windows may change There are different. For a simple app, you will first see the startup window, and then gradually fade out the real UI of the app. After you see any content on the UI, you should record the first frame. At this point, the app has completed the layout and drawing and is ready to display. At the same time, the time at which this frame occurred is also recorded.

   now subtract these two times ((UI displayed)-(icon tapped)); get the app from clicking to drawing Ready all the time. Although this time includes the time before the process starts, at least it can be used to compare with other apps.

  

Android cold start time optimization

Cold start time refers to the moment when the user clicks on your app until the system calls Activity.onCreate( ). During this time period, WindowManager will first load the windowBackground in the app theme style as the preview element of the app, and then actually load the activity layout

Cold start time optimization

   After knowing the principle of Android cold start time, you can pass some tips To optimize the cold start time, so that your app loading becomes "faster" (faster in visual experience). We can make a .9 picture of the background style to start the Activity, and then use this .9 picture as the windowBackground.

  

  Picture production After that, we can use it as a preview element in the cold start phase of the app, with the following settings:

  • Customize a Theme for the started Activity

    1
    2
    3
    <style name="AppTheme.Launcher">
    <item name="android:windowBackground">@drawable/window_background_statusbar_toolbar_tabitem>
    style>

      

  • Apply the new Theme to settings to< code>AndroidManifest.xml

    < div id="highlighter_436631" class="syntaxhighlighter html">

    1
    2
    3
    4
    5
    6
    7< /span>
    8
    9
    <activity < /div>

    android :name=".MainActivity"
    android:theme="@style/AppTheme.Launcher">
    <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
    intent-filter code>>
    < code class="html keyword">activity>

      

< /li>

  • As a new Theme is set for MainActivity, this will overwrite the original Theme, so you need to set it back to the original Theme in MainActivity

  • Copy code
    public class MainActivity extends AppCompatActivity {@Override protected void onCreate(Bundle savedInstanceState) {// Make sure this line comes before calling super.onCreate( ).  setTheme(R.style.AppTheme); super.onCreate (savedInstanceState);} } 
    copy code

    < div>

    Time: 2019-09-10 16:53:25 Reading (6)

    One. Start the applicationMethod

    < p>   Generally speaking, there are two ways to start: cold start and hot start.

      1. Cold start: When the application is started, there is no process of the application in the background, then the system will recreate a new one The process is assigned to the application, and the startup method is cold start.

      2, hot start: when the application is started, there is already a process of the application in the background (for example: press the back key, the home key , Although the application will exit, the process of the application will still remain in the background and you can enter the task list to view), so in the case of an existing process, this startup will start the application from the existing process. This way Called hot start.

      Features

      1, cold start: cold start because the system will re-create a new process assigned to it, so it will first create and initialize the Application class, and then create and initialize the MainActivity class (including a series of measurements, layout, Draw), and finally displayed on the interface.

      2. Hot start: Hot start will start from the existing process, so hot start will not go. Application This step is to go directly to MainActivity (including a series of measurement, layout, and drawing), so the hot start process only needs to create and initialize a MainActivity, instead of creating and initializing an Application,

       Because an application from the creation of a new process to the destruction of the process, the Application will only be initialized once.

    2. Application startup process

      Cold start process: When you click on the app’s start icon, the Android system forks from the Zygote process to create a new process and assign it to the application, and then it will create and initialize the application one by one

      windowBackground and other attributes set to MainActivity and configure some attributes on the Activity level , And then inflate layout, when the onCreate/onStart/onResume method is finished, the measure/layout/draw of contentView is finally displayed on the interface, so until here,

       is the first launch of the application, and the interface we see at this time is the so-called first frame. So, to summarize, the application startup process is as follows:

      Application's constructor method——> attachBaseContext()——>onCreate()——>Activity construction method——>onCreate()——>Configure the background and other properties in the theme——>onStart()——>onResume()——>Measurement layout drawing display On the interface.

      The general process is as follows:

      1. Click on the desktop icon, Launcher will start the default Acticity of the program, and then start various activities according to the logic of the program

      2, to start Activity, you need to use the ActivityManagerService service process of the application framework layer (Service is also started by the ActivityManagerService process); in the Android application framework layer, ActivityManagerService is a very important interface, < /span>

       It is not only responsible for starting Activity and Service, but is also responsible for managing Activity and Service .

        Step 1. Whether to start the Activity through the Launcher, or to start a new one by calling the startActivity interface inside the Activity Activity, through Binder inter-process communication into the ActivityManagerService process, and call the ActivityManagerService.startActivity interface;

        Step 2. ActivityManagerService call ActivityStack.startActivityMayWait to prepare the relevant information of the Activity to be started;

        Step 3. ActivityStack notifies ApplicationThread to schedule Activity start , ApplicationThread here represents the process that calls the ActivityManagerService.startActivity interface. For the scenario of clicking on the application icon, this process is the Launcher,

         For the scenario of calling startActivity inside the Activity, this process is the process where the Activity is located;

        Step 4. ApplicationThread does not perform the actual startup operation. It enters the ActivityManagerService process by calling the ActivityManagerService.activityPaused interface to see if a new process needs to be created to start the Activity;

        Step 5. For the scenario where the Activity is started by clicking the application icon, in this step, the ActivityManagerService will call startProcessLocked to create A new process, and for starting a new activity by calling startActivity inside the activity, this step does not need to be performed,

        Because the new Activity is started in the process where the original Activity is located;

        Step 6. ActivityManagerServic calls ApplicationThread. The scheduleLaunchActivity interface informs the corresponding process to perform the operation of starting the Activity;

        Step 7. ApplicationThread forwards the operation of starting the Activity to ActivityThread , ActivityThread imports the corresponding Activity class through ClassLoader, and then starts it up.

    3. White screen and black screen encountered during cold start and optimized startup time

      

      1, white screen problem:

       Android Studio 2.0 is upgraded with Instant Run. In order to allow us to quickly deploy the code, Instant Run actually has a very complex logic behind it. For example, if you want to establish a server in the APK to communicate with Android Studio, and compare and replace code differences, white screen problems may occur during the development process.

       general release version of the program will not have this phenomenon;

       if it will continue If there is a white screen problem, you can view the style file

    1
    < style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> ...... <item name="android:windowIsTranslucent">trueitem> <item name="android:windowNoTitle">trueitem> style >

       added two properties, windowIsTranslucent and windowNoTitle, set these two properties to true, you can make the window transparent when the program is initialized, and the main interface of the program after the initialization is over Will be displayed, so you can’t see the white screen interface at all.

      2. Optimization of startup time

       first measure the startup time of the activity-------Activity’s reportFullyDrawn() method p>

     You need to call Activity’s reportFullyDrawn().它将在log里报告从apk初始化(和前面Displayed的时间是一样的)到reportFullyDrawn() 方法被调用用了多长时间。

          reportFullyDrawn()方法显示的log也是类似这样:

          ActivityManager: Displayed com.Android.myexample/.StartupTiming: +768ms

         在4.4上调用reportFullyDrawn()方法会崩溃(但是log还是能正常打印),提示需要UPDATE_DEVICE_STATS权限 ,但是这个权限只有系统app才能授权。解决的办法是这样调

     
      try{
        reportFullyDrawn();
      }catch(SecurityException e){
      }
      还有一种测量启动时间的方法也值得一提,那就是screenrecord命令

      首先启动带—bugreport选项(它可以在frames 中添加时间戳-应该是L中的特性)的screenrecord 命令:

      $ adb shell screenrecord --bugreport /sdcard/launch.mp4
      然后点击app的图标,等待app显示,ctrl-C screenrecord, 使用adb pull命令把文件导出到电脑。

      $ adb pull /sdcard/launch.mp4

      现在你可以打开录制视频看看发生了什么。你需要一个能逐帧查看的视频播放器(mac上的Quicktime 就可以,不清楚其它os上什么播放器这个功能最好使)。现在逐帧播放,注意视频的上方有一个frame 时间戳。

      一直往前直到你发现app图标高亮了为止。这个时候系统已经处理了图标上的点击事件,开始启动app了,记录下这一帧的时间。继续播放帧直到你看到了app整个UI的第一帧为止。根据不同情况(是否有启动窗口,是否有启动画面等等),

      事件和窗口发生的实际顺序可能会有不同。对于一个简单的app来说,你会首先见到启动窗口,然后渐变出app真实的UI。在你看到UI上的任何内容之后,你应该记录下第一帧,这时app完成了布局和绘制,准备开始显示出来了。同时也记录下这一帧所发生的时间。

      现在把这两个时间相减 ((UI displayed) - (icon tapped)); 得到app从点击到绘制就绪的所有时间。虽然这个时间包含了进程启动之前的时间,但是至少它可以用于跟其他app比较。

      

    Android冷启动时间优化

     

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

    冷启动时间优化

      知道了Android冷启动时间的原理之后,就可以通过一些小技巧来对冷启动时间进行优化,从而让你app加载变得”快“一些(视觉体验上的快)。我们可制作一个启动Activity的背景样式的.9图片,然后把这个.9图片做为windowBackground。

      

      图片制作好之后,我们就可以用它做为app冷启动阶段的预览元素,如下设置:

    • 为启动的Activity自定义一个Theme

      1
      2
      3
      <style name="AppTheme.Launcher">
          <item name="android:windowBackground">@drawable/window_background_statusbar_toolbar_tabitem>
      style>

        

    • 将新的Theme应用到设置到AndroidManifest.xml

      1
      2
      3
      4
      5
      6
      7
      8
      9
      << /code>activity
          android:name=".MainActivity"
          android:theme="@style/AppTheme.Launcher">
        
          <intent-filter>
              <action android:name="android.intent.action.MAIN" />
              <category android:name="android.intent.category.LAUNCHER" />
          intent-filter>
      activity>

        

    • 由于给MainActivity设置了一个新的Theme,这样做会覆盖原来的Theme,所以在MainActivity中需要设置回原来的Theme

    复制代码
    public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { // Make sure this line comes before calling super.onCreate().  setTheme(R.style.AppTheme); super.onCreate(savedInstanceState); } }
    复制代码

     

     

     

    1
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> ...... <item name="android:windowIsTranslucent">trueitem> <item name="android:windowNoTitle">trueitem> style>

    1
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> ...... <item name="android:windowIsTranslucent">trueitem> <item name="android:windowNoTitle">trueitem> style>

    1
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> ...... <item name="android:windowIsTranslucent">trueitem> <item name="android:windowNoTitle">trueitem> style>

    1

    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> ...... <item name="android:windowIsTranslucent">trueitem> <item name="android:windowNoTitle">trueitem> style>

    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> ...... <item name="android:windowIsTranslucent">trueitem> <item name="android:windowNoTitle">trueitem> style>

     

      try{
        reportFullyDrawn();
      }catch(SecurityException e){
      }
      还有一种测量启动时间的方法也值得一提,那就是screenrecord命令

      首先启动带—bugreport选项(它可以在frames 中添加时间戳-应该是L中的特性)的screenrecord 命令:

      $ adb shell screenrecord --bugreport /sdcard/launch.mp4
      然后点击app的图标,等待app显示,ctrl-C screenrecord, 使用adb pull命令把文件导出到电脑。

      $ adb pull /sdcard/launch.mp4

      现在你可以打开录制视频看看发生了什么。你需要一个能逐帧查看的视频播放器(mac上的Quicktime 就可以,不清楚其它os上什么播放器这个功能最好使)。现在逐帧播放,注意视频的上方有一个frame 时间戳。

      一直往前直到你发现app图标高亮了为止。这个时候系统已经处理了图标上的点击事件,开始启动app了,记录下这一帧的时间。继续播放帧直到你看到了app整个UI的第一帧为止。根据不同情况(是否有启动窗口,是否有启动画面等等),

      事件和窗口发生的实际顺序可能会有不同。对于一个简单的app来说,你会首先见到启动窗口,然后渐变出app真实的UI。在你看到UI上的任何内容之后,你应该记录下第一帧,这时app完成了布局和绘制,准备开始显示出来了。同时也记录下这一帧所发生的时间。

      现在把这两个时间相减 ((UI displayed) - (icon tapped)); 得到app从点击到绘制就绪的所有时间。虽然这个时间包含了进程启动之前的时间,但是至少它可以用于跟其他app比较。

      

    Android冷启动时间优化

     

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

    冷启动时间优化

      知道了Android冷启动时间的原理之后,就可以通过一些小技巧来对冷启动时间进行优化,从而让你app加载变得”快“一些(视觉体验上的快)。我们可制作一个启动Activity的背景样式的.9图片,然后把这个.9图片做为windowBackground。

      

      图片制作好之后,我们就可以用它做为app冷启动阶段的预览元素,如下设置:

    • 为启动的Activity自定义一个Theme

      1
      2
      3
      <style name="AppTheme.Launcher">
          <item name="android:windowBackground">@drawable/window_background_statusbar_toolbar_tabitem>
      style>

        

    • 将新的Theme应用到设置到AndroidManifest.xml

      1
      2
      3
      4
      5
      6
      7
      8
      9
      <activity
          android:name=".MainActivity"
          android:theme="@style/AppTheme.Launcher">
        
          <intent-filter>
              <action android:name="android.intent.action.MAIN" />
              <category android:name="android.intent.category.LAUNCHER" />
          intent-filter>
      activity>

        

    • 由于给MainActivity设置了一个新的Theme,这样做会覆盖原来的Theme,所以在MainActivity中需要设置回原来的Theme

    复制代码
    public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { // Make sure this line comes before calling super.onCreate().  setTheme(R.style.AppTheme); super.onCreate(savedInstanceState); } }
    复制代码

     

     

      try{
        reportFullyDrawn();
      }catch(SecurityException e){
      }
      还有一种测量启动时间的方法也值得一提,那就是screenrecord命令

      首先启动带—bugreport选项(它可以在frames 中添加时间戳-应该是L中的特性)的screenrecord 命令:

      $ adb shell screenrecord --bugreport /sdcard/launch.mp4
      然后点击app的图标,等待app显示,ctrl-C screenrecord, 使用adb pull命令把文件导出到电脑。

      $ adb pull /sdcard/launch.mp4

      现在你可以打开录制视频看看发生了什么。你需要一个能逐帧查看的视频播放器(mac上的Quicktime 就可以,不清楚其它os上什么播放器这个功能最好使)。现在逐帧播放,注意视频的上方有一个frame 时间戳。

      一直往前直到你发现app图标高亮了为止。这个时候系统已经处理了图标上的点击事件,开始启动app了,记录下这一帧的时间。继续播放帧直到你看到了app整个UI的第一帧为止。根据不同情况(是否有启动窗口,是否有启动画面等等),

      事件和窗口发生的实际顺序可能会有不同。对于一个简单的app来说,你会首先见到启动窗口,然后渐变出app真实的UI。在你看到UI上的任何内容之后,你应该记录下第一帧,这时app完成了布局和绘制,准备开始显示出来了。同时也记录下这一帧所发生的时间。

      现在把这两个时间相减 ((UI displayed) - (icon tapped)); 得到app从点击到绘制就绪的所有时间。虽然这个时间包含了进程启动之前的时间,但是至少它可以用于跟其他app比较。

      

    Android冷启动时间优化

     

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

    冷启动时间优化

      知道了Android冷启动时间的原理之后,就可以通过一些小技巧来对冷启动时间进行优化,从而让你app加载变得”快“一些(视觉体验上的快)。我们可制作一个启动Activity的背景样式的.9图片,然后把这个.9图片做为windowBackground。

      

      图片制作好之后,我们就可以用它做为app冷启动阶段的预览元素,如下设置:

    • 为启动的Activity自定义一个Theme

      1
      2
      3
      <style name="AppTheme.Launcher">
          <item name="android:windowBackground">@drawable/window_background_statusbar_toolbar_tabitem>
      style>

        

    • 将新的Theme应用到设置到AndroidManifest.xml

      1
      2
      3
      4
      5
      6
      7
      8
      9
      <activity
          android:name=".MainActivity"
          android:theme="@style/AppTheme.Launcher">
        
          <intent-filter>
              <ac tion android:name="android.intent.action.MAIN" />
              <category android:name="android.intent.category.LAUNCHER" />
          intent-filter>
      activity>

        

    • 由于给MainActivity设置了一个新的Theme,这样做会覆盖原来的Theme,所以在MainActivity中需要设置回原来的Theme

    复制代码
    public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { // Make sure this line comes before calling super.onCreate().  setTheme(R.s tyle.AppTheme); super.onCreate(savedInstanceState); } }
    复制代码

     

     

      try{

        reportFullyDrawn();

      }catch(SecurityException e){

      }

      还有一种测量启动时间的方法也值得一提,那就是screenrecord命令

      首先启动带—bugreport选项(它可以在frames 中添加时间戳-应该是L中的特性)的screenrecord 命令:

      $ adb shell screenrecord --bugreport /sdcard/launch.mp4
      然后点击app的图标,等待app显示,ctrl-C screenrecord, 使用adb pull命令把文件导出到电脑。

      $ adb pull /sdcard/launch.mp4

      现在你可以打开录制视频看看发生了什么。你需要一个能逐帧查看的视频播放器(mac上的Quicktime 就可以,不清楚其它os上什么播放器这个功能最好使)。现在逐帧播放,注意视频的上方有一个frame 时间戳。

      一直往前直到你发现app图标高亮了为止。这个时候系统已经处理了图标上的点击事件,开始启动app了,记录下这一帧的时间。继续播放帧直到你看到了app整个UI的第一帧为止。根据不同情况(是否有启动窗口,是否有启动画面等等),

      事件和窗口发生的实际顺序可能会有不同。对于一个简单的app来说,你会首先见到启动窗口,然后渐变出app真实的UI。在你看到UI上的任何内容之后,你应该记录下第一帧,这时app完成了布局和绘制,准备开始显示出来了。同时也记录下这一帧所发生的时间。

      现在把这两个时间相减 ((UI displayed) - (icon tapped)); 得到app从点击到绘制就绪的所有时间。虽然这个时间包含了进程启动之前的时间,但是至少它可以用于跟其他app比较。

      

    Android冷启动时间优化

     

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

    冷启动时间优化

      知道了Android冷启动时间的原理之后,就可以通过一些小技巧来对冷启动时间进行优化,从而让你app加载变得”快“一些(视觉体验上的快)。我们可制作一个启动Activity的背景样式的.9图片,然后把这个.9图片做为windowBackground。

      

      图片制作好之后,我们就可以用它做为app冷启动阶段的预览元素,如下设置:

    • 为启动的Activity自定义一个Theme

      1
      2
      3
      <style name="AppTheme.Launcher">
          <item name="android:windowBackground">@drawable/window_background_statusbar_toolbar_tabitem>
      style>

        

    • 将新的Theme应用到设置到AndroidManifest.xml

      1
      2
      3
      4
      5
      6
      7
      8
      9
      <activity
          android:name=".MainA ctivity"
          android:theme="@style/AppTheme.Launcher">
        
          <intent-filter>
              <action android:name="android.intent.action.MAIN" />
              <category android:name="android.intent.category.LAUNCHER" />
          intent-filter>
      activity>

        

    • 由于给MainActivity设置了一个新的Theme,这样做会覆盖原来的Theme,所以在MainActivity中需要设置回原来的Theme

    复制代码
    public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { // Make sure this line comes before calling super.onCreate().  setTheme(R.style.AppTheme); super.onCreate(savedInstanceState); } }
    复制代码

     

     

      $ adb shell screenrecord --bugreport /sdcard/launch.mp4
      然后点击app的图标,等待app显示,ctrl-C screenrecord, 使用adb pull命令把文件导出到电脑。

      $ adb shell screenrecord --bugreport /sdcard/launch.mp4
      然后点击app的图标,等待app显示,ctrl-C screenrecord, 使用adb pull命令把文件导出到电脑。

      $ adb pull /sdcard/launch.mp4

      $ adb pull /sdcard/launch.mp4

    1
    2
    3
    <style name="AppTheme.Launcher">
        <item name="android:windowBackground">@drawable/window_background_statusbar_toolbar_tabitem>
    style>

      

    1
    2
    3
    <style name="AppTheme.Launcher">
        <item name="android:window Background">@drawable/window_background_statusbar_toolbar_tabitem>
    style>

      

    1
    2
    3
    <style name="AppTheme.Launcher">
        <item name="android:windowBackground">@drawable/window_background_statusbar_toolbar_tabitem>
    style>

    1
    2
    3
    <style name="AppTheme.Launcher">
        <item name="android:windowBackground">@drawable/window_b ackground_statusbar_toolbar_tabitem>
    style>

    1
    2
    3
    <style < code class="html plain">name="AppTheme.Launcher">
        <item name="android:windowBackground">@drawable/window_background_statusbar_toolbar_tabitem>
    style>

    1

    2

    3

    <st yle name="AppTheme.Launcher">
        <item name="android:windowBackground">@drawable/window_background_statusbar_toolbar_tabitem>
    style>

    <style name="AppTheme.Launcher">

        <item name="android:windowBackground">@drawable/window_background_statusbar_toolbar_tabitem>

    style>

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <activity
        android:name=".MainActivity"
        android:theme="@style/AppTheme.Launcher">
      
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        intent-filter>
    activity>

      

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <activity
        android:name=".MainActivity"
        android:theme="@style/AppTheme.Launcher">
      
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        intent-filter>
    activity>

      

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <activity
        android:name=".MainActivity"
        android:theme="@style/AppTheme.Launcher">
      
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        intent-filter>
    activity>

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <activity
        android:name=".MainActivity"
        android:theme="@style/AppTheme.Launcher">
      
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        intent-filter>
    activity>

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <activity
        android:name=".MainActivity"
        android:theme="@style/AppTheme.Launcher">
      
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        intent-filter>
    activ ity>

    1

    2

    3

    4

    5

    6

    7

    8

    9

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

    <activity

        android:name=".MainActivity"

        android:theme="@style/AppTheme.Launcher">

      

        <intent-filter>

            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />

        intent-filter>

    activity>

    复制代码
    public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { // Make sure this line comes before calling super.onCreate().  setTheme(R.style.AppTheme); super.onCreate(savedInstanceState); } }
    复制代码

    复制代码

    复制代码

     

     

    时间:2019-09-10 16:53:25 阅读(6)