Android 应用多角度启动优化

本文详细探讨了Android应用的启动优化,包括冷启动和热启动的概念,启动速度的测量方法,以及多种优化策略。优化措施涵盖MultiDex、启动窗口、Application与ContentProvider、Activity和Fragment的优化,特别强调了布局优化,如减少过度绘制、合理使用ConstraintLayout和去除不必要的背景等,旨在提升应用的启动速度和用户体验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一、介绍

1.1、冷启动和热启动

1.2、启动速度测量

1.2.1、TraceCompat

二、优化方式 

2.1、MultiDex启动优化

2、 子进程中执行dexOpt

2.2、启动窗口优化(设置主题)

2.3、Allpication,ContentProvider优化

2.4、Activity优化

2.4.1、Activity View的加载流程

2.4.2、懒加载IdleHandler

2.4.3、异步加载布局AsyncLayoutInflater

​2.5、Fragement优化

2.6、布局优化

2.6.1、诊断过度绘制,优化过度绘制

2.6.2、合理使用控件Constaintlayout

ViewStub

2.6.3、去掉window的默认背景

3.6.4、去掉其他不必要的背景有时候为了方便会先给Layout设置一个整体的背景,再给子View设置背景,这里也会造成重叠,如果子View宽度mach_parent,可以看到完全覆盖了Layout的一部分,这里就可以通过分别设置背景来减少重绘。再比如如果采用的是selector的背景,将normal状态的color设置为“@android:color/transparent",也同样可以解决问题。这里只简单举两个例子,我们在开发过程中的一些习惯性思维定式会带来不经意的Overdraw,所以开发过程中我们为某个View或者ViewGroup设置背景的时候,先思考下是否真的有必要,或者思考下这个背景能不能分段设置在子View上,而不是图方便直接设置在根View上。

3.6.5、ClipRect


一、介绍

1.1、冷启动和热启动

  • 冷启动当启动应用时,后台没有该应用的进程,这时系统会重新创建一个新的进程分配给该应用,然后再根据启动的参数,启动对应的进程组件,这个启动方式就是冷启动
  • 热启动当启动应用时,后台已有该应用的进程(例:按back键、home键,应用虽然会退出,但是该应用的进程是依然会保留在后台,可进入任务列表查看),所以在已有进程的情况下,这种启动会从已有的进程中来启动对应的进程组件,这个方式叫热启动

1.2、启动速度测量

1.2.1、TraceCompat

  • TraceCompat.beginSection(“xxx”);// 手动埋点起始点
  • TraceCompat.endSection();// 手动埋点结束点
  • python systrace.py -b 32768 -t 5 -a packageName -o trace.html sched gfx view wm am app
  • 使用python命令生成报告
  • cd到Android/sdk/platform-tools/systrace
  • 执行python命令,python环境没有配置好的话可使用Home Brew install一下
  • python systrace.py -b 32768 -t 10 -a 包名 -o browser.html sched gfx view wm am app
  • adb shell am start -w 包名/类名

 

返回的结果,就是标准的应用程序的启动时间

  • ThisTime:最后一个Activity启动耗时;
  • TotalTime:启动时经历的所有Activity启动耗时;
  • WaiteTime:AMS启动所有Activity的总时间

 

http://static.open-open.com/lib/uploadImg/20151231/20151231215915_677.png

  • startTime记录的刚准备调用startActivityAndWait()的时间点
  • endTime记录的是startActivityAndWait()函数调用返回的时间点
  • WaitTime = startActivityAndWait()调用耗时。

二、优化方式 

应用进程不存在的情况下,从点击桌面应用图标,到应用启动(冷启动),会经历以下流程:

  1. Launcher startActivity
  2. AMS startActivity
  3. Zygote fork 进程
  4. ActivityThread main()
  5. ActivityThread.attach
  6. handleBindApplication
  7. Application.attachBaseContext
  8. ContentProvider.installContentProviders
  9. Application.onCreate
  10. ActivityThread 进入loop循环
  11. Activity生命周期回调,onCreate、onStart、onResume...

2.1、MultiDex启动优化

目前 Android 5.0 以上的设备已经自身支持了 MultiDex 功能,也就是说在安装 apk 的时候,系统已经会帮我们把 apk 里面的所有 dex 文件都做好 Optimize 处理,所以不需要我们在代码里启用 MultiDex 了。但是对于 Android 5.0 以下的设备,依然要求我们启用 MultiDex。而这些系统的设备在第一次运行 App 的时候,需要对所有的 Secondary Dexes 文件都进行一次解压以及 Optimize 处理(生成 odex 文件),这段时间会有明显的耗时,所有会产生明显的卡顿现象。

配置:

android {
    defaultConfig {
        ...
	multiDexEnabled true // Enable MultiDex.
	//定义main dex中必须保留的类
multiDexKeepProguard file('mainDexClasses.pro')
        ...
    }
    ...
}
dependencies {
  implementation 'androidx.multidex:multidex:2.0.0'
}

1、在Application的attachBaseContext启动新进程执行dexOpt

protected void attachBaseContext(Context base) {
    // 只有5.0以下需要执行 MultiDex.install
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
        MULTI_DEX = MULTI_DEX + "_" + getVersionCode(base);
        if (SystemUtil.isInMainProcess(base)) {
            // 判断有没有执行过dexOpt
            if (!dexOptDone(base)) {
                preLoadDex(base);
            }
        }
        if (!KwaiApp.isMultiDeXProcess(base)) {
            MultiDex.install(base);
        }
    }
    super.attachBaseContext(base);
}

/**
   * 是否进行过DexOpt操作。
   * 
   * @param context
   * @return
   */
private boolean dexOptDone(Context context) {
    SharedPreferences sp = context.getSharedPreferences(MULTI_DEX, MODE_MULTI_PROCESS);
    return sp.getBoolean(MULTI_DEX, false);
}

/**
   * 在单独进程中提前进行DexOpt的优化操作;主进程进入等待状态。
   *
   * @param base
   */
public void preLoadDex(Context base) {
    // 在新进程中启动PreLoadDexActiv
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值