美文网首页
Android性能优化——启动优化

Android性能优化——启动优化

作者: jxiang112 | 来源:发表于2022-04-12 11:34 被阅读0次

打开应用如果需要需要用户等待很长时间,比如10秒,那么会给用户一个很差的使用体验,甚至会导致用户的流失。所以应用的启动时间要在一个合理的时间范围,才能提升用户的使用体验,所以也就有了启动优化的必要性。

启动方式

系统会根据应用的当前状态,分为三种启动方式:冷启动、热启动、温启动

冷启动

冷启动一般指的的是当前应用没被打开,即进程不存在,需要走完应用的启动应用的流程,启动应用的具体流程可以参考Activity启动流程一文。
冷启动的大致流程有:

  • binder进程间通信,进入AMS启动应用
  • 创建并显示应用空白启动窗口,即应用的预览视图
  • process创建并启动进程
  • 进入ActivityThread启动主线程
  • 创建应用对象Application,并初始化、调用其生命周期attach、onCreate
  • 创建主Activity,并初始化、调用其attach、生命周期onCreate等
  • 加载view并进行绘制渲染
热启动

热启动一般指的是应用从后台切回前台的操作,回调对应生命周期如:onRestart、onResume等。开销相比冷启动要低很多。

温启动

温启动的开销介于冷启动和热启动之间,以下是是常见的温启动方式:

  • 用户退出应用后又重新启动应用。此时进程还在,只是activity不在,所以会走:创建activity并初始化并调用其相应的生命周期,如onCreate等,接着加载并渲染view
  • 应用处于后台时,由于内存等其他原因系统将应用从内存中退出,接着用户又重新启动应用。此时进程和activity需要重启,但会传递state bundle ,可以减少一些资源的创建开销。

我们一般对冷启动方式进行优化,也对应的优化了热启动、温启动的方式,因为冷启动包括了热启动和温启动的流程。

启动优化点

启动有哪些优化点呢?我们可以从冷启动的流程可以进行针对性的优化。冷启动的流程中binder进程间通信、process创建并启动进程、进入ActivityThread启动主线程、创建应用对象Application、创建主Activity这些是系统的流程,我们干预不了,但是我们可以干预:

  • 禁用空白窗口
  • Application的attach、onCreate;
  • Activity的生命周期
  • view的加载及绘制
空白Window

启动应用时如果时间比较长,会长时间显示一个空白的预览窗口,给用户很不友好的体验。
解决方案1:禁用创建并显示应用空白启动窗口可以在主题中设置android:windowDisablePreview为false,这样可以减少一定的启动时间开销,但是带来的问题是:如果启动时间比较长可能会出现用户启动应用的过程中没有收到任何反馈,会让用户无法确定应用是否在正常运行。
解决方案2(推荐):不禁用空白窗口,给主题设置一个背景图片android:windowBackground,这样用户看到就不是空白窗口而是应用闪屏图片,一个过渡效果。

优化Application

Application的事务有的在attach、有的在onCreate中进行,我们尽可能不要在Application的启动流程attach、onCreate做耗时的任务,如读写文件、其他io操作、耗时计算、创建大内存对象或者创建大量对象等,因为会严重影响启动时间。在开发大项目的时候会接入各种库,很多库都是建议甚至要求在Application中进行初始化,所以得要权衡。
优化建议:

  • 不必要的初始化,在使用时再进行初始化
  • 有必要但优先级低的初始化,可以配合闪屏超时逻辑进行延迟初始化,如handler.post or handler.postDelay(runnable, xxx)
  • 耗时操作放入子线程,如读写文件、io操作等
  • 不要在在Application启动阶段是创建大内存对象或者创建大量对象,因为容易引起内存抖动进而触发GC,GC可能会阻塞所有线程(包括主线程),一般GC阻塞线程时间很短,但频繁的GC,阻塞线程的时间累加起来就多。
优化Activity

启动应用是对Activity的优化与对Application的优化是差不多一样的,不要初始化及onCreate中做没必要、过多的计算,优化建议:

  • 不必要的初始化则去除
  • 必要的初始化,如果耗时转入子线程中处理
  • 不要创建大内存对象或者大量对象
  • 对Activity的view进行优化
    • 避免过度绘制:避免重叠的view、避免重叠的背景、减少透明度的使用
    • 减少view层级,考虑使用constrainlayout、Relativelayout减少层级
    • view复用,使用include、merge、viewstub等
    • 绘制流程如measure、layout、onDraw中避免创建大内存对象或者大量对象

启动瓶颈检测与分析

启动时间

可以通过在logcat中过滤Displayed查看应用启动时间,Displayed值包括:

  • binder进程间通信
  • 创建并启动进程
  • 启动应用主线程
  • 创建应用对象Application,并初始化、生命周期方法
  • 创建Activity,并初始化、生命周期方法
  • view加载及绘制
    logcat中Displayed的值形如:
system_process I/ActivityManager: Displayed com.yuezhuanstore.app/com.fn.demo40new.MainActivity: +499ms

开发如果发现Displayed的值不在设定的范围值,则需要考虑进行启动优化了,以下是各个启动方式启动时间视为过长,需要考虑进行优化:

  • 冷启动>=5秒视为启动时间过长(可通过Displayed观测)
  • 热启动>=1.5秒视为启动时间过长(自行打印需要的时间)
  • 温启动>=2秒视为启动时间过长(可通过Displayed观测)
检测与分析

检测与分析瓶颈的好方法就是使用Android studio CPU性能分析器,在Application启动的生命周期attach或者onCrreate中使用Debug的startMethodTracing()方法开始跟踪记录启动信息,在启动的Activity完成绘制时(getViewTreeObserver().addOnPreDrawListener()作为首帧绘制完成)调用Debug的stopMethodTracing()方法停止追踪启动信息,最终绘制sdcard的应用目录下生产对应的trace文件。
startMethodTracing和stopMethodTracing是成对出现,内部可以出现多对,startMethodTracing可以设置名称作为每对trace文件的名称,如:

public class DemoApplication  extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        Debug.startMethodTracing("application");
        //.....
        Debug.stopMethodTracing();
    }
}

在主Activity:

public class MainActivity extends Activity {
   @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Debug.startMethodTracing("MainActivity");
        findViewById(R.id.page_container).getViewTreeObserver().addOnPreDrawListener(new       ViewTreeObserver.OnPreDrawListener() {
            @Override
            public boolean onPreDraw() {
                findViewById(R.id.page_container).getViewTreeObserver().removeOnPreDrawListener(this);
                Debug.stopMethodTracing();
                return false;
            }
        });
    }
}

最终会在sdcard/android/data/packagename/files目录中生成了application和MainActivity两个trace文件,追踪记录的是application的onCreate的日志信息、MainActivity的onCreate及首帧绘制的日志信息。
我们将这两个文件导出,通过android studio的cpu性能分析器cpu profiler从本地文件加载trace进行分析。CPU性能分析器怎么检测及分析性能瓶颈,在后续的文件进行分析讲解。

相关文章

  • 收集_性能优化

    Android性能优化(一)之启动加速35%Android性能优化(二)之布局优化面面观Android性能优化(三...

  • Android性能优化--内存优化

    转载自:Android性能优化--内存优化 上一篇文章关于Android性能优化--启动优化探讨了启动优化相关的知...

  • Android系统原理

    Android性能优化(一)App启动原理分析及启动时间优化 - CSDN博客 Android性能优化(二)布局渲...

  • Android性能优化之路

    Android性能优化目录 1 Android性能优化之内存泄漏2 Android性能优化之启动速度3 Andro...

  • 性能问题_01参考文章

    参考文章 : Android性能优化(一)之启动加速35% Android性能优化(二)之布局优化面面观 Andr...

  • Android性能优化之启动速度优化

    Android性能优化之启动速度优化 Android app 启动速度优化,首先谈谈为什么会走到优化这一步,如果一...

  • Android 性能优化

    app性能优化 android优化分为: 内存优化 UI优化 电量优化 apk瘦身优化 启动优化 下面通过各种百度...

  • Android性能优化(下)

    Android性能优化 内存泄漏和性能优化方式Android性能优化(上)数据库优化和网络优化Android性能优...

  • Android优化文章精选

    Android性能优化典范 Android性能优化典范 - 第1季Android性能优化之渲染篇Android性能...

  • [笔记]Android性能优化 中

    [笔记]Android性能优化 上[笔记]Android性能优化 中[笔记]Android性能优化 下 7.And...

网友评论

      本文标题:Android性能优化——启动优化

      本文链接:https://www.haomeiwen.com/subject/vvvisrtx.html