自动化零件服务商 - 供应SMC,FESTO,CKD全新正品气动元件
自动化零件服务商 - 供应SMC,FESTO,CKD全新正品气动元件
自动化零件服务商 - 供应SMC,FESTO,CKD全新正品气动元件

前言

Android车载对于启动时间要求比较严格,所以优化Android启动时间是比较重要的任务。

下面是详细记录Android系统优化开机时间优化相关的内容,基于Android13。

本文为摘抄内容,记录于此,方便自己查阅。文末有作者链接,感谢。

正文

内容分为三个部分

  • 开机时间检测方法

  • 影响开机时间的Android启动流程

  • 开机时间优化方案

开机时间检测方法

  • logcat

    长按power键开机,等待adb进程启动后(一般出现Android字样后),执行如下命令抓取开机logcat

    1. adb logcat -b all > logcat.txt
    复制

    打开logcat.txt,搜索logcat关键字”boot_progress“、“sf_stop_bootanim”、“wm_boot_animation_done”

    或者直接执行以下命令过滤logcat

    1. adb logcat -b events | grep -E "boot_progress|sf_stop_bootanim|wm_boot_animation_done"
    复制
    1. 01-01 00:26:20.817   781 I boot_progress_start: 7646
    2. 01-01 00:26:22.785   781 I boot_progress_preload_start: 9615
    3. 01-01 00:26:24.676   781 I boot_progress_preload_end: 11506
    4. 01-01 00:26:25.482 1515 I boot_progress_system_run: 12312
    5. 01-01 00:26:26.457 1515 I boot_progress_pms_start: 13286
    6. 01-01 00:26:26.741 1515 I boot_progress_pms_system_scan_start: 13571
    7. 01-01 00:26:28.123 1515 I boot_progress_pms_data_scan_start: 14953
    8. 01-01 00:26:28.133 1515 I boot_progress_pms_scan_end: 14962
    9. 01-01 00:26:28.291 1515 I boot_progress_pms_ready: 15121
    10. 02-06 02:55:39.303 1515 I boot_progress_ams_ready: 18518
    11. 02-06 02:55:41.095 1515 I boot_progress_enable_screen: 20311
    12. 02-06 02:55:44.067   904 1003 I sf_stop_bootanim: 23282
    13. 02-06 02:55:44.068 1515 1549 I wm_boot_animation_done: 23283
    复制

    上面是Android系统启动的各个阶段耗时,可以看到,整个开机过程耗时23.283秒,其中从按下power键到zygote启动,耗时7.646秒。

    各阶段的解释如下:

    启动阶段说明
    boot_progress_startLinux kernel启动到Zygote进程启动的时间,包含从kernel启动到Init启动Zygote的时间
    boot_progress_preload_startART虚拟机启动耗时/Zygote开始启动
    boot_progress_preload_end虚拟机资源装载耗时/Zygote启动结束
    boot_progress_system_runSystem Server进程启动耗时
    boot_progress_pms_startAndroid一些在PMS前需要启动服务的启动耗时,package scan开始
    boot_progress_pms_system_scan_startsystem目录开始scan时间点
    boot_progress_pms_data_scan_startdata目录开始scan时间点/system目录扫描耗时
    boot_progress_pms_scan_end扫描结束时间点/data目录扫描耗时
    boot_progress_pms_readyPMS启动扫描包耗时
    boot_progress_ams_readyPMS后的系统服务启动时间
    boot_progress_enable_screenAMS启动完成后开始激活屏幕
    sf_stop_bootanimsurfaceflinger结束开机动画
    wm_boot_animation_done从enable_screen到animation_done包含壁纸和keyguard的绘制时间

    注意,logcat只能看到上层启动后的log,即zygote启动后,开机期间kernel层的耗时无法通过logcat观察。

  • 串口log和kernel log

    • 串口log可以使用串口线连接Android设备和PC,使用串口工具抓取log,常用的串口工具有很多,xshell、MobaXterm等。

    • kernel log是在开机后执行如下命令抓取:

    1. adb shell dmesg > dmesg.txt
    复制

    log里面搜关键字 “KPI” 、”first stage” 、”second stage“,此关键字为kernel的各个启动阶段。

    uart log和kernel log都可以显示整个开机过程时间。

    1. Start Shut Down UEFI Boot Services: 4337 ms
    2. EBS
    3. BDS: LogFs sync skipped,Unsupported
    4. App Log Flush : 6 ms
    5. Exit
    6. 0.000000 Booting Linux on physical CPU 0x0
    7. 0.000000 Linux version 4.14.117 (quetelet075835e499751) (clang version 8.0.12 for Android NDK) #1 SMP PREEMPT Tue Dec 26 07:14:58 UTC 2023
    8. 0.000000 Boot CPU: AArch64 Processor [51af8014]
    9. 0.000000 Machine: Qualcomm Technologies, Inc. trinket pm6125 + pmi632 Qualcomm Technologies, Inc. TRINKET IOT IDP NO PMI Overlay
    10. 0.000000 earlycon: msm_geni_serial0 at MMIO 0x0000000004a90000 (options '')
    11. 0.000000 efi: Getting EFI parameters from FDT:
    12. 0.000000 efi: Getting EFI parameters from FDT:
    13. 0.000000 efi: UEFI not found.
    14. 0.000000 mem-offline: no memory to offline for DDR size:4255121408
    15. 0.000000 OF: reserved mem: OVERLAP DETECTED!
    16. 0.000000 OF: reserved mem: 0x000000005c000000--0x000000005cf00000 overlaps with cont_splash_region@5c000000 (0x000000005c000000--0x000000005cf00000)
    17. 0.000000 Reserved memory: created CMA memory pool at 0x0000000f8f000000, size 4 MiB
    18. 0.000000 OF: reserved mem: initialized node sdp region, compatible id shared-dma-pool
    19. 0.000000 Reserved memory: created CMA memory pool at 0x0000000f8e000000, size 16 MiB
    20. 0.000000 OF: reserved mem: initialized node qseecom_ta_region, compatible id shared-dma-pool
    21. 0.000000 OF: reserved mem: initialized node qseecom_ta_region, compatible id shared-dma-pool
    22. 0.000000 OF: reserved mem: initialized node sdp region, compatible id shared-dma-pool
    23. 0.000000 OF: reserved mem: initialized node sdp region, compatible id shared-dma-pool
    24. 0.000000 Reserved memory: created CMA memory pool at 0x0000000f54000000, size 8 MiB
    25. 0.000000 Reserved memory: created CMA memory pool at 0x0000000f54000000, size 8 MiB
    26. 0.000000 OF: reserved mem: initialized node sdp region, compatible id shared-dma-pool
    27. 0.000000 Reserved memory: created CMA memory pool at 0x0000000f34000000, size 32 MiB
    28. 0.000000 Reserved memory: created CMA memory pool at 0x0000000f34000000, size 32 MiB
    29. 0.000000 OF: reserved mem: initialized node linux,cma, compatible id shared-dma-pool
    30. 0.000000 Reserved memory: created CMA memory pool at 0x0000000f45b00000, size 16 MiB
    31. 0.000000 OF: reserved mem: initialized node dump_mem_region, compatible id shared-dma-pool
    32. 0.000000 OF: reserved mem: initialized node pool_dump_mem_region, compatible id shared-dma-pool
    33. 0.000000 Reserved memory: created DMA memory pool at 0x0000000457000000, size 6 MiB
    34. 0.000000 OF: reserved mem: initialized node hyp_region@45700000, compatible id removed-dma-pool
    35. 0.000000 Reserved memory: created DMA memory pool at 0x000000045e000000, size 1 MiB
    36. 0.000000 Reserved memory: created DMA memory pool at 0x000000045a000000, size 0 MiB
    37. 0.000000 Reserved memory: created DMA memory pool at 0x000000045bfff000, size 0 MiB
    38. 0.000000 OF: reserved mem: initialized node sec_apps_region, compatible id removed-dma-pool
    39. 0.000000 OF: reserved mem: initialized node sec_apps_region@0x46000000, compatible id removed-dma-pool
    40. 0.000000 Reserved memory: created DMA memory pool at 0x0000000460000000, size 45 MiB
    41. 0.000000 Reserved memory: created DMA memory pool at 0x0000000462000000, size 45 MiB
    42. 0.000000 Reserved memory: created DMA memory pool at 0x0000000462000000, size 5 MiB
    43. 0.000000 Reserved memory: created DMA memory pool at 0x00000004ab000000, size 5 MiB
    复制

bootchart

bootchart 是一个用于 linux 启动过程性能分析的开源工具软件,在系统启动过程中自动收集 CPU 占用率、磁盘吞吐率、进程等信息,并以图形方式显示分析结果,可用作指导优化系统启动过程。

bootchart 让用户可以很直观的查看系统启动的过程和各个过程耗费的时间,以便让用户能够分析启动过程,从而进行优化以提高启动时间。

这部分就省略了,直接看参考文中的吧。

Android启动流程

开机框架

引用Gityuan大佬的一张开机流程图

[摘]Android系统优化之开机时间优化

Android启动流程大体为:BootRom -> BootLoader -> Kernel -> Init -> Zygote -> SystemServer ->Launcher

[摘]Android系统优化之开机时间优化
Loader层
  • Boot ROM

    电源按下,引导芯片代码开始从预定义的地方(固化在ROM)开始执行,加载引导程序到RAM,然后执行。

  • Boot Loader

    这是Android系统系统之前的引导程序,主要用来检测外部的RAM以及设置网络、内存、初始化硬件参数等。

Kernel层

Kernel层是指Android内核层,到这里才刚刚开始进入Android系统。

  • 启动swapper进程(pid=0),该进程又称为idle进程,,系统初始化过程Kernel由无到有开创的第一个进程,,用于初始化进程管理、内存管理,加载Display、Camera Driver、Binder Driver等相关工作(图中kernel层蓝色区块)。

  • 启动kthreadd进程(pid=2),是Linux系统的内核进程,会创建内核工作线程kworkder,软中断线程ksoftirqd,thermal等一系列内核守护进程。kthreadd进程是所有内核进程的父进程。

Linux内核加载主要包括初始化kernel核心(内存初始化,打开中断,初始化进程表等)、初始化驱动、启动内核后台(daemons)线程、安装根(root)文件系统等。后续启动第一个用户级进程init(pid=1)。

Native层

Native层主要包括启动init进程(Android的第一个用户空间进程)、HAL层(硬件抽象层)以及开机动画等。init进程是所有用户进程的鼻祖。同时init进程也会孵化一系列用户进程,还会启动关键的服务以及孵化Zygote进程。

  • init进程会孵化出ueventd、logd、healthd、installd、adbd、lmkd等用户守护进程。

  • init进程还启动servicemanager(binder服务管家)、bootanim(开机动画)等重要服务。

  • init进程孵化出Zygote进程,Zygote进程是Android系统的第一个Java进程,Zygote是所有Java进程的父进程,Zygote进程本身是由init进程孵化而来的。

Framework层

Framework层分为Java frameword和C++ framework,分别由system_server进程和media_server进程负责启动和管理。

zygote本身是一个native的应用程序,刚开始的名字为“app_process”,运行过程中,通过系统调用将自己名字改为zygote。在上图中的红色线,便是zygote fork出来的进程,所有的app进程都是由zygote fork产生的。

下面列举Zygote进程孵化的部分子进程:

进程名解释
system_serverJava framework的各种service都依赖此进程
com.android.phone电话应用进程
android.process.acore通讯录进程
android.process.media多媒体应用进程
com.android.settings设置进程
com.android.wifiwifi应用进程
  • zygote进程

    由init进程通过解析init.rc文件后fork生成的,Zygote进程主要包含:

    • 加载ZygoteInit类,注册Zygote Socket服务端套接字

    • 加载虚拟机

    • preloadClasses

    • preloadResouces

  • system_server进程

    由zygote进程fork而来,system_server是zygote孵化的第一个进程,system_server负责启动和管理整个java framework,包含ActivityManager、PowerManager等服务。

  • media_server进程

    由init进程fork而来,负责启动和管理整个C++ framework,包含SurfaceFlinger、AudioFlinger、Camera Service等服务。

app层
  • zygote进程孵化出的第一个app进程是Launcher,这是用户看到的桌面app。

  • zygote进程还会创建Browser,Phone,Email等app进程,每个app至少运行在一个进程上。

  • 所有的app进程都是由zygote进程fork生成的。

具体的启动过程,此文不便详述,都是代码分析,复杂且枯燥。

开机时间优化方案

以下均为framework层的优化,kernel层优化不在研究范围。

  • 精简方向

    精简初始化脚本:减少开机时的初始化时间。

    高通平台关注以下.rc & .sh文件:

    1. init.rc  
    2. init.target.rc  
    3. init.qcom.rc  
    4. init.sh
    5. init.qcom.sh  
    6. init.qcom.post_boot.sh
    复制
  • 裁剪方向

    移除非必须Apks、Features、Sensor等,减少PackageScan时间。

    • 裁剪预置APK

      针对具体应用场景,可以将没用的apk裁剪掉,比如automotive可以裁掉Launcher,因为automotive自带CarLauncher。

      可通过如下命令查看设备中所有的apk:

      1. adb shell pm list package -f
      复制

      Android中的内置APK介绍见:Android主要应用和进程说明

      裁剪方法:

      1. diff --git /build/make/core/main.mk /build/make/core/main.mk
      2. index a8f46c1..d9d507b 100644
      3. --- a/core/main.mk
      4. +++ b/core/main.mk
      5. @@ -1267,6 +1267,7 @@ define product-installed-files
      6.   $(eval ### Filter out the overridden packages and executables before doing expansion) \
      7.   $(eval _pif_overrides := $(call module-overrides,$(_pif_modules))) \
      8.   $(eval _pif_modules := $(filter-out $(_pif_overrides), $(_pif_modules))) \
      9. + $(eval _pif_modules := $(filter-out $(modules_product_packages_remove), $(_pif_modules))) \
      10.   $(eval _pif_modules := $(filter-out $(PRODUCT_PACKAGES_DEL), $(_pif_modules))) \
      11.   $(eval ### Resolve the :32 :64 module name) \
      12.   $(eval _pif_modules := $(sort $(call resolve-bitness-for-modules,TARGET,$(_pif_modules)))) \
      13. @@ -1363,6 +1364,9 @@ else ifdef FULL_BUILD
      14.     endif
      15.   endif
      16. + # App removal list
      17. + modules_product_packages_remove := $(PRODUCT_PACKAGES_REMOVE)
      复制
      1. diff --git /build/make/core/product.mk /build/make/core/product.mk
      2. index 90e960b..c556037 100644
      3. --- a/core/product.mk
      4. +++ b/core/product.mk
      5. @@ -40,6 +40,9 @@ _product_list_vars += PRODUCT_PACKAGES_ENG
      6. _product_list_vars += PRODUCT_PACKAGES_TESTS
      7. _product_var_list += PRODUCT_PACKAGES_DEL
      8. +# App removal list
      9. +_product_list_vars+= PRODUCT_PACKAGES_REMOVE
      10. +
      11. # The device that this product maps to.
      12. _product_single_value_vars += PRODUCT_DEVICE
      13. _product_single_value_vars += PRODUCT_MANUFACTURER
      复制
      1. diff --git /device/qcom/{product}/{product}.mk /device/qcom/{product}/{product}.mk
      2. index 163cac2..89a3078 100755
      3. --- a/{product}.mk
      4. +++ b/{product}.mk
      5. @@ -60,6 +60,8 @@ PRODUCT_BUILD_USERDATA_IMAGE := true
      6. +# App removal list
      7. +PRODUCT_PACKAGES_REMOVE += \
      8. + Calendar \
      9. + Email \
      10. + SnapdragonMusic \
      11. + DeskClock \
      复制

      注意:/device/qcom/{product}/{product}.mk取决于厂商的产品名称

    • 移除不需要的Features

      针对具体应用场景,可以将没用的Features裁剪掉,比如automotive可以裁掉<feature name="android.software.print" />

      可通过如下命令查看设备中所有的Features:

      1. adb shell pm list features
      复制

      裁剪方法:

      1. diff --git /frameworks/native/data/etc/android.software.print.xml /frameworks/native/data/etc/android.software.print.xml
      2. index 713a7f7..e76bb88 100644
      3. --- /frameworks/native/data/etc/android.software.print.xml
      4. +++ /frameworks/native/data/etc/android.software.print.xml
      5. @@ -15,5 +15,5 @@
      6. -->
      7. <permissions>
      8. -   <feature name="android.software.print" />
      9. +<!--   <feature name="android.software.print" />-->
      10. </permissions>
      复制
    • 禁用不需要的Sensors

      针对具体应用场景,可以将没用的Sensor裁剪掉。

      可通过如下命令查看设备中所有支持的Sensor:

      1. adb shell dumpsys sensorservice
      复制
  • 配置优化方向

    • 优化PinnerService配置

      PinnerService是用于锁定某些模块在内存中,避免这些模块被移出\移入内存从而提高程序的运行效率。

      优化目的是减少非首次开机启动Service的时间。

      修改/frameworks/base/core/res/res/values/config.xml,添加如下配置:

      1. <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
      2. ... ...
      3.   <!-- Default files to pin via Pinner Service -->
      4.    <string-array translatable="false" name="config_defaultPinnerServiceFiles">
      5.     <item>"/system/framework/arm/boot-framework.art"</item>
      6.     <item>"/system/lib/libjavacrypto.so"</item>
      7.     <item>"/system/lib/libhidltransport.so"</item>
      8.     <item>"/system/framework/arm/boot-core-libart.oat"</item>
      9.     <item>"/system/framework/arm/boot-conscrypt.oat"</item>
      10.     <item>"/system/framework/arm/boot-core-libart.art"</item>
      11.     <item>"/system/framework/arm/boot-ext.art"</item>
      12.     <item>"/system/framework/arm/boot.art"</item>
      13.     <item>"/system/framework/arm/boot-framework.art"</item>
      14.    </string-array>
      15. ... ...
      16. </resources>
      复制

      注意:芯片商(例如高通)的代码可能会存在客制化,AOSP的位置可能会被覆盖,如果有,则以芯片商的代码为准。

    • 使用32Bit程序

      定义了32Bit的程序,机器在apk的使用及服务的申明都会有略微的精简,在设备启动时加载的资源会少,故加载时间会少。

      修改方式:

      /device/qcom/{product}/BoardConfig.mk

      1. TARGET_ARCH := arm
      2. TARGET_ARCH_VARIANT := armv8-2a
      3. TARGET_CPU_ABI := armeabi-v7a
      4. TARGET_CPU_ABI2 := armeabi
      5. TARGET_CPU_VARIANT := cortex-a9
      6. #TARGET_2ND_ARCH := arm
      7. #TARGET_2ND_ARCH_VARIANT := armv8-2a
      8. #TARGET_2ND_CPU_ABI := armeabi-v7a
      9. #TARGET_2ND_CPU_ABI2 := armeabi
      10. #TARGET_2ND_CPU_VARIANT := cortex-a9
      复制

      device/generic/art/armv8/armv8.mk

      1. # Force 32bits executables.
      2. PRODUCT_DEFAULT_PROPERTY_OVERRIDES += ro.zygote=zygote32
      复制
    • 关闭默认开关

      默认关闭功能开关,开机期间不再自动启动,加快开机进度。

      主要修改/frameworks/base/packages/SettingsProvider/res/values/defaults.xml

      • 关闭锁屏显示通知

        1. <!-- Default for Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 1==on -->
        2. -    <integer name="def_lock_screen_show_notifications">1</integer>
        3. +    <integer name="def_lock_screen_show_notifications">0</integer>
        复制
      • 关闭手势唤醒

        1. <!-- Default for Settings.Secure.WAKE_GESTURE_ENABLED -->
        2. -    <bool name="def_wake_gesture_enabled">true</bool>
        3. +    <bool name="def_wake_gesture_enabled">false</bool>
        复制
      • 关闭双击唤醒

        1. <!-- Default state of tap to wake -->
        2. -    <bool name="def_double_tap_to_wake">true</bool>
        3. +    <bool name="def_double_tap_to_wake">false</bool>
        复制
      • 关闭充电振动

        1. <!-- Default for Settings.Secure.CHARGING_VIBRATION_ENABLED -->
        2. -    <bool name="def_charging_vibration_enabled">true</bool>
        3. +    <bool name="def_charging_vibration_enabled">false</bool>
        复制
      • 关闭充电提示音

        1. <!-- Default for Settings.Secure.CHARGING_SOUNDS_ENABLED -->
        2. -    <bool name="def_charging_sounds_enabled">true</bool>
        3. +    <bool name="def_charging_sounds_enabled">false</bool>
        复制
      • 关闭蓝牙和wifi

        1. <bool name="def_bluetooth_on">false</bool>
        2. <bool name="def_wifi_display_on">false</bool>
        复制
      • 关闭自动旋转

        1. <bool name="def_accelerometer_rotation">false</bool>
        复制
      • 关闭Wifi Debugging

        1. <!-- Disable WiFi Debugging -->
        2.    <bool translatable="false" name="config_wifi_enable_wifi_firmware_debugging">false</bool>
        复制
  • 删除开机动画

    Animation的资源大小和播放时长一直是影响开机时间的重要因素之一,移除开机动画将有效地加快开机速度。

    frameworks/base/cmds/bootanimation/BootAnimationUtil.cpp

    1. bool bootAnimationDisabled() {
    2.    char value[PROPERTY_VALUE_MAX];
    3.    //将获取结果改为1,则无法进入到开机动画流程中
    4.    //property_get("debug.sf.nobootanimation", value, "0");
    5.    property_get("debug.sf.nobootanimation", value, "1");
    6.    if (atoi(value) > 0) {
    7.        return true;
    8.   }
    9.    property_get("ro.boot.quiescent", value, "0");
    10.    if (atoi(value) > 0) {
    11.        // Only show the bootanimation for quiescent boots if this system property is set to enabled
    12.        if (!property_get_bool("ro.bootanim.quiescent.enabled", false)) {
    13.            return true;
    14.       }
    15.   }
    16.    return false;
    17. }
    复制
  • 开机过程CPU满载

    开机过程中让CPU火力全开,能有效减少开机时间

    /device/qcom/common/rootdir/etc/init.qcom.rc

    1. on early-init
    2. +   write /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor performance
    3. +   write /sys/devices/system/cpu/cpu1/cpufreq/scaling_governor performance
    4. +   write /sys/devices/system/cpu/cpu2/cpufreq/scaling_governor performance
    5. +   write /sys/devices/system/cpu/cpu3/cpufreq/scaling_governor performance
    6. +   write /sys/devices/system/cpu/cpu4/cpufreq/scaling_governor performance
    7. +   write /sys/devices/system/cpu/cpu5/cpufreq/scaling_governor performance
    8. +   write /sys/devices/system/cpu/cpu6/cpufreq/scaling_governor performance
    9. +   write /sys/devices/system/cpu/cpu7/cpufreq/scaling_governor performance
    复制

    注意:

    • init.qcom.rc是高通定制的init脚本,是开机时必然执行的。

    • 如果CPU原本就已经满载了,那么此修改则无效果。

    • 不同平台CPU的配置不尽相同。

  • 移除SystemService

    SystemServer进程启动后,会启动很多SystemService,根据实际场景,裁剪非必要的Service

    frameworks/base/services/java/com/android/server/SystemServer.java

    1. // Start services.
    2.        try {
    3.            t.traceBegin("StartServices");
    4.            startBootstrapServices(t);
    5.            startCoreServices(t);
    6.            startOtherServices(t);
    7.            startApexServices(t);
    8.       } catch (Throwable ex) {
    9.            Slog.e("System", "******************************************");
    10.            Slog.e("System", "************ Failure starting system services", ex);
    11.            throw ex;
    12.       } finally {
    13.            t.traceEnd(); // StartServices
    14.       }
    复制

    可裁剪的Service如下,仅供参考

    1. 1.VibratorService         震动器服务  
    2. 2.ClipboardService         粘贴板服务  
    3. 3.FingerprintService       指纹  
    4. 4.BatteryService           电池服务,当电量不足时发广播  
    5. 5.AlarmManagerService     闹钟服务  
    6. 6.WallpaperManagerService 壁纸管理服务  
    7. 7.StatusBarManagerService 状态栏管理服务  
    复制

    注意:

    • 从framework层的角度去看问题,我们会发现功能及服务的裁剪,是最直接、最有效地时间及空间优化方法,它可以做到时间与空间的两者兼顾。

    • 注意app与Service,Service与Service之间的耦合性,避免引起机器的异常,无法开机;

  • 移除app源码

    修改下面文件中的 PRODUCT_PACKAGES 字段的内容,将不需要的内置应用的名称删除,这样可以缩短 scan packages 的过程。

    1. 1.build/target/product/core.mk  
    2. 2.build/target/product/full_base.mk  
    3. 3.build/target/product/full_base_telephony.mk  
    4. 4.build/target/product/generic_no_telephony.mk  
    复制

    同时,可以删除 /packages/apps/ 路径下不必要的 app 源码,这样可以缩短编译时间。

  • apk odex

    apk odex优化就是以空间换时间,加快apk启动速度,缺点是会消耗内存。

    /device/qcom/{product}/{product}.mk加入WITH_DEXPREOPT=true, 打开odex优化

    Android.bp中添加

    1. android_app {
    2.   dex_preopt: {
    3.       enabled: true,
    4.   },
    5. }
    复制

    Android.mk中添加

    1. makefile
    2. LOCAL_DEX_PREOPT := true
    复制
  • PMS优化

    Apk的扫描安装耗时是大头。通常采用多线程方案,针对Dir或者Dir中的package进行多线程扫描.

    PMS多线程扫描apk,4线程改成8线程,注意,如果客户做了CPU绑核, Android所分配的CPU资源受到限制,导致改成8线程之后反向优化了。

    frameworks/base/services/core/java/com/android/server/pm/ParallelPackageParser.java

    1. class ParallelPackageParser {
    2.    private static final int QUEUE_CAPACITY = 30;
    3. //   private static final int MAX_THREADS = 4;
    4.    private static final int MAX_THREADS = 8;
    5.    
    6.    //省略部分代码
    7. }
    复制
  • Zygote优化

    Zygote主要是优化class和resource的预加载,可以减少部分不需要预加载的class和resource,具体优化哪些,根据实际需求来添加。

    注意:并不是预加载越少越好,如果开机必须启动的进程所需要的class和resource在zygote阶段被优化了,那么也会在该进程自启动时也会去加载,这样优化就是无效的。

    1. diff --git /frameworks/base/config/preloaded-classes /frameworks/base/config/preloaded-classes
    2. index f2530519247..d6ac1e22e3f 100644
    3. --- /frameworks/base/config/preloaded-classes
    4. +++ /frameworks/base/config/preloaded-classes
    5. @@ -806,7 +806,6 @@ android.app.VoiceInteractor$Request
    6. android.app.VoiceInteractor
    7. android.app.Vr2dDisplayProperties$1
    8. android.app.Vr2dDisplayProperties
    9. -android.app.VrManager
    10. android.app.WaitResult$1
    11. android.app.WaitResult
    12. android.app.WallpaperColors$1
    13. @@ -2471,12 +2470,6 @@ android.hardware.display.Time$1
    14. android.hardware.display.Time
    15. android.hardware.display.VirtualDisplayConfig$1
    16. android.hardware.display.VirtualDisplayConfig
    17. -android.hardware.display.WifiDisplay$1
    18. -android.hardware.display.WifiDisplay
    19. -android.hardware.display.WifiDisplaySessionInfo$1
    20. -android.hardware.display.WifiDisplaySessionInfo
    21. -android.hardware.display.WifiDisplayStatus$1
    22. -android.hardware.display.WifiDisplayStatus
    23. android.hardware.face.Face$1
    24. android.hardware.face.Face
    25. android.hardware.face.FaceManager$1
    复制
  • 移除手势导航

    1. diff --git /frameworks/base/packages/overlays/Android.mk /frameworks/base/packages/overlays/Android.mk
    2. index 69641e69a9f..71f5fd00520 100644
    3. --- /frameworks/base/packages/overlays/Android.mk
    4. +++ /frameworks/base/packages/overlays/Android.mk
    5. @@ -20,17 +20,8 @@ LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
    6. LOCAL_LICENSE_CONDITIONS := notice
    7. LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../NOTICE
    8. LOCAL_REQUIRED_MODULES := \
    9. - DisplayCutoutEmulationCornerOverlay \
    10. - DisplayCutoutEmulationDoubleOverlay \
    11. -   DisplayCutoutEmulationHoleOverlay \
    12. - DisplayCutoutEmulationTallOverlay \
    13. - DisplayCutoutEmulationWaterfallOverlay \
    14. FontNotoSerifSourceOverlay \
    15. NavigationBarMode3ButtonOverlay \
    16. - NavigationBarModeGesturalOverlay \
    17. - NavigationBarModeGesturalOverlayNarrowBack \
    18. - NavigationBarModeGesturalOverlayWideBack \
    19. - NavigationBarModeGesturalOverlayExtraWideBack \
    20. preinstalled-packages-platform-overlays.xml
    21. include $(BUILD_PHONY_PACKAGE)
    复制
  • 关闭壁纸服务

    frameworks/base/core/res/res/values/config.xml

    1. <!-- True if WallpaperService is enabled -->
    2.    <bool name="config_enableWallpaperService">true</bool>
    复制
  • 调整窗口动画渲染

    frameworks/base/packages/SettingsProvider/res/values/defaults.xml

    1. <fraction name="def_window_animation_scale">100%</fraction>
    2. -   <fraction name="def_window_transition_scale">100%</fraction>
    3. +   <fraction name="def_window_animation_scale">25%</fraction>
    4. +   <fraction name="def_window_transition_scale">25%</fraction>
    复制

    如果想关闭animaton,直接将数值改为0即可。

    注意:芯片商可能会定制defaults.xml,所以在修改时请留意是否改全。

  • Google优化方案

    详见:source.android.google.cn/docs/core/p…

实战总结

对于Android开机时间优化,framework层可优化的空间较小,通过trace可以看到,一个Service的启动或者众多apk的扫描操作,往往都是在几毫秒或者几十毫秒内完成的,所以,即使关闭某个service的启动或者裁剪部分apk,优化效果也是毫秒级别的,不是很明显,但聚少成多,通过多种优化方案,累加优化时间,最终呈现出来的优化效果就是肉眼可见的。

而Kernel层的优化空间往往是较大的,都是秒级别的优化幅度,通过底层和上层双向优化,最终能达到比较理想的优化效果。

参考文章

  1. Android系统优化–开机时间优化

自动化零件服务商 - 供应SMC,FESTO,CKD全新正品气动元件

相关文章

自动化零件服务商 - 供应SMC,FESTO,CKD全新正品气动元件

暂无评论

none
暂无评论...