Android性能优化--优化启动速度 - Go语言中文社区

Android性能优化--优化启动速度


一、初识应用启动

应用启动的流程

在安卓系统上,应用在没有进程的情况下,应用的启动都是这样一个流程:当点击app的启动图标时,安卓系统会从Zygote进程中fork创建出一个新的进程分配给该应用,之后会依次创建和初始化Application类、创建MainActivity类、加载主题样式Theme中的windowBackground等属性设置给MainActivity以及配置Activity层级上的一些属性、再inflate布局、当onCreate/onStart/onResume方法都走完了后最后才进行contentView的measure/layout/draw显示在界面上,所以直到这里,应用的第一次启动才算完成。

所以,应用的启动流程如下:

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

应用启动方式

应用的启动分为冷启动、热启动、温启动,而启动最慢、挑战最大的就是冷启动:系统和App本身都有更多的工作要从头开始!

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

2、热启动:当启动应用时,后台已有该应用的进程,比如按下home键,这种在已有进程的情况下,这种启动会从已有的进程中来启动应用,这种启动方式叫热启动。

3、温启动 :当启动应用时,后台已有该应用的进程,但是启动的入口Activity被干掉了,比如按了back键,应用虽然退出了,但是该应用的进程是依然会保留在后台,这种启动方式叫温启动。

应用在冷启动时,要执行三个任务:

  • 加载启动App;
  • App启动之后立即展示出一个空白的Window;
  • 创建App的进程;

而这三个任务执行完毕之后会马上执行以下任务:

  • 创建App对象;
  • 启动Main Thread;
  • 创建启动的Activity对象;
  • 加载View;
  • 布置屏幕;
  • 进行第一次绘制;

而一旦App进程完成了第一次绘制,系统进程就会用Main Activity替换已经展示的Background Window,此时用户就可以使用App了。
这里写图片描述
Google官方文档对应用启动优化的概述《Launch-Time Performance》

优化启动时的体验

应用启动时,由于启动缓慢导致的黑屏、白屏,对于这种问题我们可以在等待第一帧显示的时间里,加入一些配置以增加体验,比如加入Activity的background,这个背景会在显示第一帧前提前显示在界面上。

1、先为主界面单独写一个主题style,设置一张待显示的图片,这里我设置了一个颜色,然后在manifest中设置给MainActivity:

<style name="AppTheme.Launcher">
    <item name="android:windowBackground">@drawable/bg_color</item>
</style>
 <activity
           android:name=".MainActivity"
           android:label="@string/app_name"
           android:theme="@style/AppTheme.Launcher">
           <intent-filter>
               <action android:name="android.intent.action.MAIN" />
               <category android:name="android.intent.category.LAUNCHER" />
           </intent-filter>
       </activity>      

2、然后在MainActivity中加载布局前把AppTheme重新设置给MainActivity:

@Override
    protected void onCreate(Bundle savedInstanceState) {

        setTheme(R.style.AppTheme);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
}        

这样在启动时会先显示background,然后待界面绘制完成再显示主界面

优化启动速度

作为普通应用,App进程的创建等环节我们是无法主动控制的,可以优化的也就是Application、Activity创建以及回调等过程。

一般会拖慢启动速度的操作

Heavy activity initialization

  • 填充大的复杂布局
  • 磁盘, 或者网络I/O阻塞屏幕绘制
  • 加载并解码bitmaps
  • 栅格化VectorDrawable对象
  • activity中其他子系统的初始化

Heavy app initialization

  • 类似上述activity中的操作

优化策略

1、数据库及IO操作都移到工作线程,并且设置线程优先级为THREAD_PRIORITY_BACKGROUND,这样工作线程最多能获取到10%的时间片,优先保证主线程执行。

new Thread(new Runnable() {
            @Override
            public void run() {
                //设置线程优先级,不与主线程抢资源
                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                //...
            }
        }).start();

2、流程梳理,延后执行

考虑一些操作逻辑顺序上是否可以调整,过重的操作延迟初始化,或者用到的时候再初始化。去除重复的无用的操作。

懒加载方式:

getWindow().getDecorView().post(new Runnable() {
   @Override
   public void run() {
       myHandler.post(mLoadingRunnable);
    }
  });

在窗口完成以后进行加载,这里面的run方法是在onResume之后运行。

检查工具

  • 通过ADB命令

通过ADB命令统计应用的启动时间:

adb shell am start -W [packageName]/[packageName.MainActivity]

执行成功后将返回三个测量到的时间:

  1. ThisTime:一般和TotalTime时间一样,除非在应用启动时开了一个透明的Activity预先处理一些事再显示出主Activity,这样将比TotalTime小。
  2. TotalTime:应用的启动时间,包括创建进程+Application初始化+Activity初始化到界面显示。
  3. WaitTime:一般比TotalTime大点,包括系统影响的耗时。

这里写图片描述

  • 使用TraceView

使用TraceView 从代码层面分析性能问题,针对每个方法来分析,比如当我们发现我们的应用出现卡顿的时候,我们可以来分析出现卡顿时在方法的调用上有没有很耗时的操作,通过TraceView,可以得到两种数据。

  1. 单次执行最耗时的方法
  2. 执行次数最多的方法

使用TraceView做热点分析,找出最需要优化的点。关于TrackView的具体使用可查阅相关资料。

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/zxc123e/article/details/72779244
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-04-18 22:46:39
  • 阅读 ( 799 )
  • 分类:

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢