安卓10开机时间优化分析

本文从以下六点分析开机时间

  1.软件环境
  2.开机时间测试方法
  3.开机各阶段重要的时间节点
  4.bootchart工具使用说明
  5.Android开机时间日志信息
  6.开机时间优化方案

一、软件环境

 平台:android10.0  qcom  sm6125
 场景:手机4+64
 时间:2020.08.04

二、开机时间测试方法

   测试方法:刷机user版本的软件,开机后,需要联网等待5分钟,然后重启机器5次后,再开始计时抓取log,同时手指触摸屏幕,感觉到振动开始用秒表计时,直到看到Launcher界面,停止秒表计时,这个阶段就是用户主观感受到的开机时间。

三、开机各阶段重要的时间节点

四、bootchart工具使用说明

bootchart是android原生自带的性能分析工具,可以收集android开机过程中的log。再利用jar包能够将开机时各个进程呈现在图表中。可以比较直观的看到开机时哪些比较耗时。

4.1有源码的情况下并且设备可以连接pc机,采用下述方法生成bootchart.png

4.1.1启用Bootchart

在pc机上安装bootchart工具,命令如下: sudo apt-get install bootchart pybootchartgui

android中的bootchart源码位于system/core/init目录下,bootchart.cpp中有个do_bootchart_start()函数

代码中时通过判断是否有/data/bootchart/enabled文件来启动bootchart的,所以创建一个这个文件即可启动

4.1.2设置收集数据时间

这个在源码中没有找到相应的说明

创建/data/bootchart/start文件存储bootchart采样时间(s)

adb shell ‘echo 120 > /data/bootchart/start’

4.1.3生成图表

启用bootchart并且设置好时间后,重启机器,会在/data/bootchart下生成log文件,从源码中可以看到当前会生成哪些日志文件。除了这个log文件之外还会生成一个header文件,也是必须的。

重启设备,init运行时将自动创建文件夹/data/bootchart/,并在其中保存采样数据,采样数据由5个文件组成:

然后利用bootchart工具把这些日志转成png图片

执行 /system/core/init/grab-bootchart.sh 自动生成png图片

4.2没有源码或者设备无法连接pc机的情况下采用下述方法生成bootchart.png

使用bootchart.jar处理日志压缩文件

从https://sourceforge.net/projects/bootchart/下载bootchart源码,放到ubuntu目录下,执行ant生成bootchart.jar

将手机 /data/bootchart/ 下文件 (header proc_diskstats.log proc_ps.log proc_stat.log) pull出来copy到服务器,执行下压缩命令生成bootchart.tgz

tar zcvf bootchart.tgz header proc_diskstats.log proc_ps.log proc_stat.log

使用jar转成png图

java -jar bootchart.jar bootchart/bootchart.tgz

4.3代码中新加功能Comparing two bootcharts,对比两个bootchart图.

通过compare-bootcharts.py脚本对比所选两个进程的开始结束时间点,从而得到对应进程之间的耗时差距. 当我们使用grab-bootchart.sh脚本获取对应的bootcahrt图时,会在PC的/tmp/android-bootchart目录下留下bootchart.tgz压缩包.然后将所要比较的两个bootchart的压缩包放在两个不同的目录base_bootchart_dir, exp_bootchart_dir.执行如下命令:

system/core/init/compare-bootcharts.py base_bootchart_dir exp_bootchart_dir

就可以得到如下信息:

可以看到开机动画一个结束时间为26.4s, 一个为29.6s,两者相差3.2s

五、Android开机时间日志信息

Android是基于Linux内核的系统,因此Android的启动过程是分为两个阶段:
1) 第一个阶段就是Linux内核的启动;
2) 第二个阶段就是Android框架的启动,包括核心服务+程序。

  Linux内核通过printk打印的log信息,这些log写入到了/dev/kmsg文件中,在Shell终端可以通过   dmesg命令查看这些log信息。 下面我们分别从两种log信息中找到如何统计系统启动时间的方法:

5.1 通过dmesg信息统计系统启动时间 首先,我们通过dmesg命令抓取Linux内核的log信息(部分系统可能需要先执行 adb root): adb shell cat /proc/bootmsg > bootmsg.txt $ adb shell dmesg > dmesg.txt

 log里面搜关键字"KPI" "first stage" "second stage"

5.2. 通过logcat统计系统的启动时间

Android的log系统是独立于Linux内核log系统的, Android系统把Log分为了四类,不同的类别记录不同的Log信息:

main - 主要的Log信息,大部分应用级别的Log信息都在这里
events - 系统事件相关的Log信息
radio - 无线/电话相关的Log信息
system - 低级别的系统调试Log信息
默认通过logcat抓取的是main信息

如果想抓取指定类别的log信息的方法,在logcat命令后加-b参数,例如:
$ adb logcat -d -v time -b “main” > main.txt $
adb logcat -d -v time -b “events” > events.txt $
adb logcat -d -v time -b “system” > system.txt $
adb logcat -d -v time -b “radio” > radio.txt
那么,如何统计Android系统的启动时间呢? 我们可以重点关注events类别的log信息,
通过如下命令: $ adb logcat -d -b events | grep “boot”
如图所示,这是我在高通的SM6125开发板上抓取的log信息

|boot_progress_start|代表着系统进入用户空间,标志着kernel启动完成,Android屏幕点亮,开始显示启动动画,即9.353s开始闪烁Android字样。
|boot_progress_preload_start|Zygote启动
|boot_progress_preload_end|Zygote结束
|boot_progress_system_run|SystemServer ready,开始启动Android系统服务,如PMS,APMS等 |boot_progress_pms_start|PMS开始扫描安装的应用
|boot_progress_pms_system_scan_start|PMS先行扫描/system目录下的安装包
|boot_progress_pms_data_scan_start|PMS扫描/data目录下的安装包
|boot_progress_pms_scan_end|PMS扫描结束
|boot_progress_pms_ready|PMS就绪
|boot_progress_ams_ready|AMS就绪
|boot_progress_enable_screen|AMS启动完成后开始激活屏幕,从此以后屏幕才能响应用户的触摸,它在WindowManagerService发出退出开机动画的时间节点之前,而真正退出开机动画还会花费少许时间,具体依赖animation zip 包中的desc.txt。wm_boot_animation_done才是用户感知到的动画结束时间节点
|sf_stop_bootanim|SF设置service.bootanim.exit属性值为1,标志系统要结束开机动画了,可以用来跟踪开机动画结尾部分消耗的时间 |wm_boot_animation_done|开机动画结束,这一步用户能直观感受到开机结束。

六、开机时间的优化方案

6.1bootloader阶段uart串口log关闭-------节省了 1.5 秒

6.1.1/ARM9/Nicobar/boot_images/QcomPkg/Library/UartQupv3Lib/UartXBLLoaderOs.c

6.1.2ARM9/Nicobar/boot_images/QcomPkg/XBLLoader/boot_uart.c

6.1.3 kernel/msm-4.14/arc/arm64/configs/vendor/trinket-perf_deconfig&trinket_deconfig

6.2 修改驱动log控制台输出等级-------节省了 1.5 秒

kernel-msm-4.14\kernel\printk\printk.c
Kerne-msm-4.14-include-linux-kern_levels.h
device/qcom/common/rootdir/etc/init.qcom.sh ++++++
buildvariant=getprop ro.build.type
case “$buildvariant” in
“userdebug” | “eng”)
#set default loglevel to KERN_INFO
echo “7 7 1 7” > /proc/sys/kernel/printk
;;
*)
#set default loglevel to KERN_WARNING
echo “3 3 1 4” > /proc/sys/kernel/printk
;;
esac
6.3 通过移除不使用的内核配置和减少驱动程序-------节省了 0.3 秒

kernel的优化先check一遍config的配置,kernel中config的配置种类繁多,就算是工作几年的kernel工程师也不一定能清楚每一个config值的作用。Android提供了一个基础配置表。
综合比较后的结果,本地一点点调试,查找资料。最终去掉了如下config:

这里说下config的配置有y,n,m,m表示编译成模块,不编译进内核。不配置的话相当于n。
CONFIG_DEBUG_INFO 不能去掉, 会引起CTS不过。由于config的的各项值可能散落在kernel的不同文件中,我们可以单独编译下kernel,然后去out目录下查看obj/KERNEL_OBJ/.config 文件,这里面的配置项是完全的。

6.4 优化开机时间,去除PMS不需要的GC操作-------节省了 0.1 秒

优化开机时间,去除PMS不需要的GC操作

PMS.java构造方法,第五阶段pms.systemready最后调用的gc

阶段1:BOOT_PROGRESS_PMS_START

阶段2:BOOT_PROGRESS_PMS_SYSTEM_SCAN_START

阶段3:BOOT_PROGRESS_PMS_DATA_SCAN_START

阶段4:BOOT_PROGRESS_PMS_SCAN_END

阶段5:BOOT_PROGRESS_PMS_READY

6.5 PMS开机扫描APK多线程处理方案-------节省了 0.3 秒

Android开机性能的优化是每个手机项目的必须点.针对开机性能,Apk的扫描安装耗时是大头,通常采用多线程方案,针对Dir或者Dir中的package进行多线程扫描.这里介绍我司项目中一种针对package进行优化扫描的方案(来源于高通)

相关代码:

PackageManagerService

private void scanDirLI(File dir, final int parseFlags, int scanFlags, long currentTime) {
final File[] files = dir.listFiles();
if (ArrayUtils.isEmpty(files)) {
Log.d(TAG, "No files in app dir " + dir);
return;
}

    if (DEBUG_PACKAGE_SCANNING) {
        Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags
                + " flags=0x" + Integer.toHexString(parseFlags));
    }

    Log.d(TAG, "start scanDirLI:"+dir);
    // use multi thread to speed up scanning
    int iMultitaskNum = SystemProperties.getInt("persist.pm.multitask", 6);
    Log.d(TAG, "max thread:" + iMultitaskNum);
    final MultiTaskDealer dealer = (iMultitaskNum > 1) ? MultiTaskDealer.startDealer(
            MultiTaskDealer.PACKAGEMANAGER_SCANER, iMultitaskNum) : null;

    for (File file : files) {
        final boolean isPackage = (isApkFile(file) || file.isDirectory())
                && !PackageInstallerService.isStageName(file.getName());
        if (!isPackage) {
            // Ignore entries which are not packages
            continue;
        }
       if (RegionalizationEnvironment.isSupported()) {
         if (RegionalizationEnvironment.isExcludedApp(file.getName())) {
           Slog.d(TAG, "Regionalization Excluded:" + file.getName());
           continue;
        }
       }

        final File ref_file = file;
        final int ref_parseFlags = parseFlags;
        final int ref_scanFlags = scanFlags;
        final long ref_currentTime = currentTime;
        Runnable scanTask = new Runnable() {
            public void run() {
                try {
                    scanPackageTracedLI(ref_file, ref_parseFlags | PackageParser.PARSE_MUST_BE_APK,
                            ref_scanFlags, ref_currentTime, null);
                } catch (PackageManagerException e) {
                    Slog.w(TAG, "Failed to parse " + ref_file + ": " + e.getMessage());

                    // Delete invalid userdata apps
                    if ((ref_parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
                            e.error == PackageManager.INSTALL_FAILED_INVALID_APK) {
                        logCriticalInfo(Log.WARN, "Deleting invalid package at " + ref_file);
                        removeCodePathLI(ref_file);
                    }
                }
            }
        };

        if (dealer != null)
            dealer.addTask(scanTask);
        else
            scanTask.run();
    }

    if (dealer != null)
        dealer.waitAll();
    Log.d(TAG, "end scanDirLI:"+dir);
}

MultiTaskDealer

package com.android.server.pm;

import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;

import android.util.Log;

public class MultiTaskDealer {

public static final String TAG = "MultiTaskDealer";
public static final String PACKAGEMANAGER_SCANER = "packagescan";
private static final boolean DEBUG_TASK = false;

private static HashMap> map = new HashMap>();

public static MultiTaskDealer getDealer(String name) {
    WeakReference ref = map.get(name);
    MultiTaskDealer dealer = ref!=null?ref.get():null;
    return dealer;
}

public static MultiTaskDealer startDealer(String name,int taskCount) {
    MultiTaskDealer dealer = getDealer(name);
    if(dealer==null) {
        dealer = new MultiTaskDealer(name,taskCount);
        WeakReference ref = new WeakReference(dealer);
        map.put(name,ref);
    }
    return dealer;
}

public void startLock() {
    mLock.lock();
}

public void endLock() {
    mLock.unlock();
}

private ThreadPoolExecutor mExecutor;
private int mTaskCount = 0;
private boolean mNeedNotifyEnd = false;
private Object mObjWaitAll = new Object();
private ReentrantLock mLock = new ReentrantLock();

public MultiTaskDealer(String name,int taskCount) {
    final String taskName = name;
    ThreadFactory factory = new ThreadFactory()
    {
        private final AtomicInteger mCount = new AtomicInteger(1);

        public Thread newThread(final Runnable r) {
            if (DEBUG_TASK) Log.d(TAG, "create a new thread:" + taskName);
            return new Thread(r, taskName + "-" + mCount.getAndIncrement());
        }
    };
    mExecutor = new ThreadPoolExecutor(taskCount, taskCount, 5, TimeUnit.SECONDS,
            new LinkedBlockingQueue(), factory){
        protected void afterExecute(Runnable r, Throwable t) {
            if(t!=null) {
                t.printStackTrace();
            }
            MultiTaskDealer.this.TaskCompleteNotify(r);
            if (DEBUG_TASK) Log.d(TAG, "end task");
            super.afterExecute(r,t);
        }
        protected void beforeExecute(Thread t, Runnable r) {
            if (DEBUG_TASK) Log.d(TAG, "start task");
            super.beforeExecute(t,r);
        }
    };
}

public void addTask(Runnable task) {
    synchronized (mObjWaitAll) {
        mTaskCount+=1;
    }
    mExecutor.execute(task);
    if (DEBUG_TASK) Log.d(TAG, "addTask");
}

private void TaskCompleteNotify(Runnable task) {
    synchronized (mObjWaitAll) {
        mTaskCount-=1;
        if(mTaskCount<=0 && mNeedNotifyEnd) {
            if (DEBUG_TASK) Log.d(TAG, "complete notify");
            mObjWaitAll.notify();
        }
    }
}

public void waitAll() {
    if (DEBUG_TASK) Log.d(TAG, "start wait all");
    synchronized (mObjWaitAll) {
        if(mTaskCount>0) {
            mNeedNotifyEnd = true;
            try {
                mObjWaitAll.wait();
            } catch (Exception e) {
            }
            mNeedNotifyEnd = false;
        }
        if (DEBUG_TASK) Log.d(TAG, "wait finish");
        return;
    }
}

}
简要分析

  1. iMultitaskNum
    int iMultitaskNum = SystemProperties.getInt(“persist.pm.multitask”, 6);
    iMultitaskNum代表是task数量,即线程数量.一般来说,线程数量一般等于CPU数量,让CPU资源获得最大的利用.
    2.MultiTaskDealer.startDealer
    调用MultiTaskDealer.startDealer方法,建立线程池.
    3.dealer.addTask
    for循环中建立Runnable,调用scanPackageTracedLI搜索安装apk,dealer.addTask方法把该任务提交给线程池处理.
  2. dealer.waitAll()
    主线程等待方法,同步锁是mObjWaitAll.只有当mTaskCount>0,即当仍然存在任务的时候,主线程进入线程等待.
  3. afterExecute(Runnable r, Throwable t)
    afterExecute方法会在线程任务执行后发生,这里最后会调用mObjWaitAll.notify()方法,去唤醒处于等待的主线程,当然他的判断条件显示是mTaskCount<=0,即是任务全部执行完成后.
    简单总结
    addTask针对每一个apkfile的scanpackage任务提交到线程池处理,并且mTaskCount+=1做任务的计数.
    TaskCompleteNotify在每个任务执行后进行, mTaskCount-=1做任务的计数,并且判断是否需要唤醒等待的主线程.(通过mTaskCount判断任务是否全部完成 )
    waitAll,添加所有任务到线程池后,主线程做等待,等待任务全部完成后的唤醒,然后继续执行

6.6 调整开机动画调度,优化开机时间-------节省了 0.3 秒

frameworks/base/cmds/bootanimation/bootanim.rc
writepid /dev/cpuset/background/tasks /dev/stune/background/tasks

涉及到CGroup 中background system-background foreground top-app CPU调度

6.7 打开WITH_DEXPREOPT宏后首次开机仍慢

 说明开机之后又去提取预置apk的odex文件(原本应该是在预编译阶段就生成的); 主要原因是预置apk的Android.mk对32bit和64bit的配置不准确导致。

[SOLUTION] 搜索main log关键字:dex2oat : /system/bin/dex2oat
这条log打印出就代表这个apk有在做dex2oat且是32还是64的指令集

I dex2oat : /system/bin/dex2oat --zip-fd=11 --zip-location=/system/app/.apk --oat-fd=12 --oat-location=/data/dalvik-cache/arm or arm64/system@app@@*[email protected] --instruction-set=arm or arm64 --instruction-set-features=default --runtime-arg -Xms64m --runtime-arg -Xmx512m --swap-fd=13

oat-location表示odex文件存储位置

Instruction-set表示此apk的primaryCpuAbi对应的指令集(arm对应32bit / arm64对应64bit)

请严格遵守:

1、对于64bit的芯片,若apk只32bit的lib或者只能作为32bit运行,请在预置apk时在android.mk中添加下边的TAG标记此apk为32bit:LOCAL_MULTILIB :=32 (比如出现上述做dex2oat arm的log,则需这样设定)

2、而对于有源码无lib库的apk,请注释掉LOCAL_MULTILIB :=32 (比如出现上述做dex2oat arm64的log,则需这样注释掉)

3、开机之后既提取arm又提取arm64的apk,请设定LOCAL_MULTILIB :=both (比如出现上述做dex2oat arm以及arm64的log,则需这样设定)

总之,对32bit 和 64bit 的apk做不同处理

6.8 系统APP精简

开机各阶段的耗时情况 具体开机时间的优化需要根据开机流程来分析: 找出各个阶段的耗时情况

6.9 检查期间是否有selinux avc问题导致wait耗时

1.观察events.log 发现boot_progress_enable_screen到wm_boot_animation_done 存在avc error

07-20 05:12:34.423 1577 1577 I boot_progress_ams_ready: 15555
07-20 05:12:34.504 1577 1577 I thermal_changed: [CPU0,0,43.500004,0,-2147483648]
07-20 05:12:34.504 1577 1577 I thermal_changed: [CPU1,0,43.500004,0,-2147483648]
07-20 05:12:34.504 1577 1577 I thermal_changed: [CPU2,0,43.500004,0,-2147483648]
07-20 05:12:34.504 1577 1577 I thermal_changed: [CPU3,0,43.500004,0,-2147483648]
07-20 05:12:34.504 1577 1577 I thermal_changed: [CPU4,0,46.400002,0,-2147483648]
07-20 05:12:34.504 1577 1577 I thermal_changed: [CPU5,0,50.600002,0,-2147483648]
07-20 05:12:34.504 1577 1577 I thermal_changed: [CPU6,0,44.800003,0,-2147483648]
07-20 05:12:34.504 1577 1577 I thermal_changed: [CPU7,0,48.000004,0,-2147483648]
07-20 05:12:34.504 1577 1577 I thermal_changed: [GPU,1,40.900002,0,-2147483648]
07-20 05:12:34.504 1577 1577 I thermal_changed: [battery,2,31.900002,0,-2147483648]
07-20 05:12:34.504 1577 1577 I thermal_changed: [skin,3,35.260002,0,-2147483648]
07-20 05:12:34.505 1577 1577 I battery_status: [2,2,1,1,Li-ion]
07-20 05:12:34.505 1577 1577 I battery_level: [17,3815,319]
07-20 05:12:34.579 1577 1577 I am_uid_running: 10135
07-20 05:12:34.617 1577 1940 I commit_sys_config_file: [settings-0-0,7]
07-20 05:12:34.637 1577 1691 I am_proc_start: [0,2005,10135,com.android.systemui,service,{com.android.systemui/com.android.systemui.ImageWallpaper}]
07-20 05:12:34.639 1577 1620 I am_proc_bound: [0,2005,com.android.systemui]
07-20 05:12:34.644 1577 1620 I am_uid_active: 10135
07-20 05:12:34.648 1577 1944 I am_uid_running: 1037
07-20 05:12:34.672 1577 1954 I commit_sys_config_file: [net-policy,11]
07-20 05:12:34.713 1577 1691 I am_proc_start: [0,2039,1037,WebViewLoader-armeabi-v7a,NULL,]
07-20 05:12:34.753 1577 1577 I am_uid_running: 1073
07-20 05:12:34.754 1577 1691 I am_proc_start: [0,2053,1037,WebViewLoader-arm64-v8a,NULL,]
07-20 05:12:34.755 1577 2036 I am_proc_bound: [0,2039,WebViewLoader-armeabi-v7a]
07-20 05:12:34.756 1577 2036 I am_uid_active: 1037
07-20 05:12:34.778 1577 1691 I am_proc_start: [0,2086,1073,com.android.networkstack.process,service,{com.google.android.networkstack/com.android.server.NetworkStackService}]
07-20 05:12:34.785 1577 2036 I am_proc_bound: [0,2053,WebViewLoader-arm64-v8a]
07-20 05:12:34.804 1577 2036 I am_proc_bound: [0,2086,com.android.networkstack.process]
07-20 05:12:34.806 731 731 I auditd : type=1400 audit(0.0:169): avc: denied { read } for comm=“Loc_hal_worker” name=“u:object_r:vendor_pd_locater_dbg_prop:s0” dev=“tmpfs” ino=3384 scontext=u:r:hal_gnss_qti:s0 tcontext=u:object_r:vendor_pd_locater_dbg_prop:s0 tclass=file permissive=0
07-20 05:12:34.806 1577 2036 I am_uid_active: 1073
07-20 05:12:34.837 1577 1577 I am_wtf : [0,1577,system_server,-1,ActivityManager,Sending non-protected broadcast com.android.intent.START_SWITCH_USER from system 1577:system/1000 pkg android]
07-20 05:12:34.853 1577 1577 I am_uid_running: 1001
07-20 05:12:34.858 1577 1577 I am_uid_running: 10106
07-20 05:12:34.951 1577 1940 I commit_sys_config_file: [settings-0-0,10]
07-20 05:12:35.061 1577 1577 I wm_task_created: [1,0]
07-20 05:12:35.062 1577 1577 I wm_task_moved: [1,0,2147483647]
07-20 05:12:35.062 1577 1577 I am_create_task: [0,1]
07-20 05:12:35.062 1577 1577 I am_create_activity: [0,230018530,1,com.android.settings/.FallbackHome,android.intent.action.MAIN,NULL,NULL,276824320]
07-20 05:12:35.063 1577 1577 I wm_task_moved: [1,0,2147483647]
07-20 05:12:35.069 1577 1940 I commit_sys_config_file: [settings-2-0,57]
07-20 05:12:35.127 1577 1691 I am_proc_start: [0,2127,1001,.dataservices,added application,.dataservices]
07-20 05:12:35.131 1577 1577 I sysui_multi_action: [757,804,799,boot_system_server_ready,801,16263,802,1]
07-20 05:12:35.136 1577 2032 I am_proc_bound: [0,2127,.dataservices]
07-20 05:12:35.141 1577 2032 I am_uid_active: 1001
07-20 05:12:35.143 1577 2158 I am_proc_died: [0,2039,WebViewLoader-armeabi-v7a,-700,0]
07-20 05:12:35.145 1577 2158 I am_mem_factor: [3,0]
07-20 05:12:35.147 1577 2158 I am_low_memory: 9
07-20 05:12:35.163 1577 2157 I am_proc_died: [0,2053,WebViewLoader-arm64-v8a,-700,0]
07-20 05:12:35.163 1577 2157 I am_uid_stopped: 1037
07-20 05:12:35.164 1577 2157 I am_low_memory: 8
07-20 05:12:35.169 1577 1691 I am_proc_start: [0,2187,1001,.qtidataservices,added application,.qtidataservices]
07-20 05:12:35.176 1577 1577 I notification_cancel_all: [1000,1577,android,0,0,0,17,NULL]
07-20 05:12:35.209 1577 1691 I am_proc_start: [0,2204,1001,com.qualcomm.qti.telephonyservice,added application,com.qualcomm.qti.telephonyservice]
07-20 05:12:35.238 1577 1691 I am_proc_start: [0,2226,10106,com.qualcomm.qtil.aptxals,added application,com.qualcomm.qtil.aptxals]
07-20 05:12:35.247 1577 1620 I am_proc_bound: [0,2187,.qtidataservices]
07-20 05:12:35.261 1577 1620 I am_proc_bound: [0,2204,com.qualcomm.qti.telephonyservice]
07-20 05:12:35.271 1577 1691 I am_proc_start: [0,2249,1001,com.android.phone,added application,com.android.phone]
07-20 05:12:35.297 1577 2036 I am_proc_bound: [0,2226,com.qualcomm.qtil.aptxals]
07-20 05:12:35.301 1577 2036 I am_uid_active: 10106
07-20 05:12:35.307 1577 1691 I am_proc_start: [0,2274,1000,com.android.settings,activity,{com.android.settings/com.android.settings.FallbackHome}]
07-20 05:12:35.322 1577 2036 I am_proc_bound: [0,2249,com.android.phone]
07-20 05:12:35.354 1577 1663 I commit_sys_config_file: [notification-policy,15]
07-20 05:12:35.376 2274 2274 I service_manager_slow: [11,activity]
07-20 05:12:35.380 1577 2036 I am_proc_bound: [0,2274,com.android.settings]
07-20 05:12:35.390 1577 2036 I am_restart_activity: [0,230018530,1,com.android.settings/.FallbackHome]
07-20 05:12:35.391 1577 2036 I am_set_resumed_activity: [0,com.android.settings/.FallbackHome,minimalResumeActivityLocked]
07-20 05:12:35.478 1577 1940 I commit_sys_config_file: [settings-2-0,59]
07-20 05:12:35.512 1577 2036 I am_uid_running: 10120
07-20 05:12:35.546 1577 1691 I am_proc_start: [0,2373,10120,com.android.launcher3,service,{com.android.launcher3/com.android.quickstep.TouchInteractionService}]
07-20 05:12:35.606 1577 1577 I am_uid_running: 10061
07-20 05:12:35.641 1577 1621 I am_proc_bound: [0,2373,com.android.launcher3]
07-20 05:12:35.644 1577 1621 I am_uid_active: 10120
07-20 05:12:35.646 1577 1691 I am_proc_start: [0,2408,10061,com.google.android.ext.services,service,{com.google.android.ext.services/android.ext.services.watchdog.ExplicitHealthCheckServiceImpl}]
07-20 05:12:35.669 2274 2274 I am_on_create_called: [0,com.android.settings.FallbackHome,performCreate]
07-20 05:12:35.674 2274 2274 I am_on_start_called: [0,com.android.settings.FallbackHome,handleStartActivity]
07-20 05:12:35.675 2274 2274 I am_on_resume_called: [0,com.android.settings.FallbackHome,RESUME_ACTIVITY]
07-20 05:12:35.690 1577 2036 I am_proc_bound: [0,2408,com.google.android.ext.services]
07-20 05:12:35.696 2274 2274 I am_on_top_resumed_gained_called: [0,com.android.settings.FallbackHome,topStateChangedWhenResumed]
07-20 05:12:35.697 1577 2036 I am_uid_active: 10061
07-20 05:12:35.791 1577 2032 I am_uid_running: 10163
07-20 05:12:35.823 1577 1664 I boot_progress_enable_screen: 16955
07-20 05:12:35.824 1577 1664 I screen_toggled: 1
07-20 05:12:35.829 1577 1691 I am_proc_start: [0,2484,10163,com.google.android.inputmethod.latin,service,{com.google.android.inputmethod.latin/com.android.inputmethod.latin.LatinIME}]
07-20 05:12:35.864 1577 2157 I am_proc_bound: [0,2484,com.google.android.inputmethod.latin]
07-20 05:12:35.869 1577 2157 I am_uid_active: 10163
07-20 05:12:35.936 2249 2249 I auditd : type=1400 audit(0.0:170): avc: denied { read } for comm=“m.android.phone” name=“tp_info” dev=“proc” ino=4026532524 scontext=u:rs0 tcontext=u:object_r:proc_touchpad:s0 tclass=file permissive=0
07-20 05:12:36.017 1577 1691 I am_proc_start: [0,2587,1001,com.qualcomm.qcrilmsgtunnel,service,{com.qualcomm.qcrilmsgtunnel/com.qualcomm.qcrilmsgtunnel.QcrilMsgTunnelService}]
07-20 05:12:36.084 1577 2157 I am_proc_bound: [0,2587,com.qualcomm.qcrilmsgtunnel]
07-20 05:12:36.212 1577 1689 I am_wtf : [0,2249,com.android.phone,684211789,SystemConfig,SystemConfig is being accessed by a process other than system_server.]
07-20 05:12:36.286 1577 1577 I notification_cancel_all: [1000,1577,com.android.systemui,0,0,0,17,NULL]
07-20 05:12:36.289 1577 2158 I am_pause_activity: [0,230018530,com.android.settings/.FallbackHome,userLeaving=false]
07-20 05:12:36.292 1577 2158 I am_add_to_stopping: [0,230018530,com.android.settings/.FallbackHome,makeInvisible]
07-20 05:12:36.305 2274 2274 I am_on_top_resumed_lost_called: [0,com.android.settings.FallbackHome,topStateChangedWhenResumed]
07-20 05:12:36.306 2274 2274 I am_on_paused_called: [0,com.android.settings.FallbackHome,performPause]
07-20 05:12:36.309 1577 1664 I am_stop_activity: [0,230018530,com.android.settings/.FallbackHome]
07-20 05:12:36.310 1577 1664 I sysui_multi_action: [757,803,799,window_time_0,802,5]
07-20 05:12:36.311 2274 2274 I am_on_stop_called: [0,com.android.settings.FallbackHome,STOP_ACTIVITY_ITEM]
07-20 05:12:36.444 2249 2249 I service_manager_stats: [100,38,17576]
07-20 05:12:36.472 990 1143 I liblog : 61
07-20 05:12:36.522 1577 1621 I am_uid_running: 10119
07-20 05:12:36.528 1577 1691 I am_proc_start: [0,2746,1000,com.android.cellbroadcastreceiver,broadcast,{com.android.cellbroadcastreceiver/com.android.cellbroadcastreceiver.CellBroadcastReceiver}]
07-20 05:12:36.563 1577 1940 I commit_sys_config_file: [settings-0-0,51]
07-20 05:12:36.563 1577 1691 I am_proc_start: [0,2760,10119,com.google.android.ims,service,{com.google.android.ims/com.google.android.ims.services.CarrierServicesImsService}]
07-20 05:12:36.602 1577 2036 I am_proc_bound: [0,2746,com.android.cellbroadcastreceiver]
07-20 05:12:36.635 1577 1621 I am_proc_bound: [0,2760,com.google.android.ims]
07-20 05:12:36.638 1577 1621 I am_uid_active: 10119
07-20 05:12:36.649 1577 1686 I sysui_multi_action: [319,531,322,921,325,16,757,761,758,7,759,3,806,com.android.settings,871,com.android.settings.FallbackHome,905,0,945,518,1320,5,1321,1]
07-20 05:12:36.651 1577 1686 I am_activity_launch_time: [0,230018530,com.android.settings/.FallbackHome,921]
07-20 05:12:36.761 1577 2036 I am_uid_running: 10153
07-20 05:12:36.788 1577 1691 I am_proc_start: [0,2813,10153,com.qti.service.colorservice,service,{com.qti.service.colorservice/com.qti.service.colorservice.ColorServiceApp}]
07-20 05:12:36.828 2249 2249 I service_manager_slow: [11,telephony.registry]
07-20 05:12:36.858 1577 2158 I am_proc_bound: [0,2813,com.qti.service.colorservice]
07-20 05:12:36.863 1577 2158 I am_uid_active: 10153
07-20 05:12:37.618 2005 2005 I sysui_multi_action: [757,111,758,1]
07-20 05:12:37.619 2005 2005 I sysui_multi_action: [757,126,758,1,759,126,927,0,928,0,1593,0]
07-20 05:12:37.619 2005 2005 I sysui_multi_action: [757,113,758,1,759,113,927,1,928,0,1593,0]
07-20 05:12:37.620 2005 2005 I sysui_multi_action: [757,118,758,1,759,118,927,2,928,0,1593,0]
07-20 05:12:37.620 2005 2005 I sysui_multi_action: [757,119,758,1,759,119,927,3,928,0,1593,0]
07-20 05:12:37.620 2005 2005 I sysui_multi_action: [757,123,758,1,759,123,927,4,928,1,1593,0]
07-20 05:12:37.621 2005 2005 I sysui_multi_action: [757,261,758,1,759,261,927,5,928,0,1593,0]
07-20 05:12:37.625 1577 2036 I sysui_multi_action: [757,127,758,1]
07-20 05:12:37.625 1577 2036 I sysui_multi_action: [757,804,799,note_load,801,0,802,1]
07-20 05:12:37.625 1577 2036 I notification_panel_revealed: 0
07-20 05:12:37.674 2005 2005 I sysui_multi_action: [757,196,758,1,759,0]
07-20 05:12:37.675 2005 2005 I sysui_status_bar_state: [1,1,0,0,0,1]
07-20 05:12:37.702 1577 1940 I commit_sys_config_file: [settings-2-0,31]
07-20 05:12:37.706 1869 1869 I auditd : type=1400 audit(0.0:171): avc: denied { read write } for comm=“imsrcsd” name=“diag” dev=“tmpfs” ino=4750 scontext=u:r:hal_rcsservice:s0 tcontext=u:object_r:diag_device:s0 tclass=chr_file permissive=0
07-20 05:12:37.707 1577 1664 I user_activity_timeout_override: 10000
07-20 05:12:39.668 509 509 I auditd : avc: denied { find } for service=media.metrics pid=1279 uid=1013 scontext=u:r:bootanim:s0 tcontext=u:object_r:mediametrics_service:s0 tclass=service_manager permissive=0
07-20 05:12:39.713 1577 2038 I service_manager_stats: [188,84,5465]
07-20 05:12:39.768 509 509 I auditd : avc: denied { find } for service=media.metrics pid=1279 uid=1013 scontext=u:r:bootanim:s0 tcontext=u:object_r:mediametrics_service:s0 tclass=service_manager permissive=0
07-20 05:12:44.283 509 509 I chatty : uid=1000(system) servicemanager identical 45 lines
07-20 05:12:44.383 509 509 I auditd : avc: denied { find } for service=media.metrics pid=1279 uid=1013 scontext=u:r:bootanim:s0 tcontext=u:object_r:mediametrics_service:s0 tclass=service_manager permissive=0
07-20 05:12:44.471 1577 2033 I commit_sys_config_file: [appops,42]
07-20 05:12:44.484 509 509 I auditd : avc: denied { find } for service=media.metrics pid=1279 uid=1013 scontext=u:r:bootanim:s0 tcontext=u:object_r:mediametrics_service:s0 tclass=service_manager permissive=0
07-20 05:12:44.584 509 509 I chatty : uid=1000(system) servicemanager identical 1 line
07-20 05:12:44.684 509 509 I auditd : avc: denied { find } for service=media.metrics pid=1279 uid=1013 scontext=u:r:bootanim:s0 tcontext=u:object_r:mediametrics_service:s0 tclass=service_manager permissive=0
07-20 05:12:45.649 787 1738 I sf_stop_bootanim: 26781
07-20 05:12:45.651 1577 1664 I wm_boot_animation_done: 26782
2.同时间节点观察main.log 发现servermanager wait

07-20 05:12:39.668 1279 1344 I ServiceManager: Waiting for service ‘media.metrics’ on ‘/dev/binder’…
07-20 05:12:39.768 1279 1344 I ServiceManager: Waiting for service ‘media.metrics’ on ‘/dev/binder’…
07-20 05:12:39.869 1279 1344 I ServiceManager: Waiting for service ‘media.metrics’ on ‘/dev/binder’…
07-20 05:12:39.969 1279 1344 I ServiceManager: Waiting for service ‘media.metrics’ on ‘/dev/binder’…
07-20 05:12:40.069 1279 1344 I ServiceManager: Waiting for service ‘media.metrics’ on ‘/dev/binder’…
07-20 05:12:40.170 1279 1344 I ServiceManager: Waiting for service ‘media.metrics’ on ‘/dev/binder’…
07-20 05:12:40.270 1279 1344 I ServiceManager: Waiting for service ‘media.metrics’ on ‘/dev/binder’…
07-20 05:12:40.370 1279 1344 I ServiceManager: Waiting for service ‘media.metrics’ on ‘/dev/binder’…
07-20 05:12:40.471 1279 1344 I ServiceManager: Waiting for service ‘media.metrics’ on ‘/dev/binder’…
07-20 05:12:40.571 1279 1344 I ServiceManager: Waiting for service ‘media.metrics’ on ‘/dev/binder’…
07-20 05:12:40.671 1279 1344 I ServiceManager: Waiting for service ‘media.metrics’ on ‘/dev/binder’…
07-20 05:12:40.772 1279 1344 I ServiceManager: Waiting for service ‘media.metrics’ on ‘/dev/binder’…
07-20 05:12:40.872 1279 1344 I ServiceManager: Waiting for service ‘media.metrics’ on ‘/dev/binder’…
07-20 05:12:40.972 1279 1344 I ServiceManager: Waiting for service ‘media.metrics’ on ‘/dev/binder’…
07-20 05:12:41.073 1279 1344 I ServiceManager: Waiting for service ‘media.metrics’ on ‘/dev/binder’…
07-20 05:12:41.173 1279 1344 I ServiceManager: Waiting for service ‘media.metrics’ on ‘/dev/binder’…
07-20 05:12:41.273 1279 1344 I ServiceManager: Waiting for service ‘media.metrics’ on ‘/dev/binder’…
07-20 05:12:41.374 1279 1344 I ServiceManager: Waiting for service ‘media.metrics’ on ‘/dev/binder’…
07-20 05:12:41.474 1279 1344 I ServiceManager: Waiting for service ‘media.metrics’ on ‘/dev/binder’…
07-20 05:12:41.574 1279 1344 I ServiceManager: Waiting for service ‘media.metrics’ on ‘/dev/binder’…
07-20 05:12:41.675 1279 1344 I ServiceManager: Waiting for service ‘media.metrics’ on ‘/dev/binder’…
07-20 05:12:41.775 1279 1344 I ServiceManager: Waiting for service ‘media.metrics’ on ‘/dev/binder’…
07-20 05:12:41.876 1279 1344 I ServiceManager: Waiting for service ‘media.metrics’ on ‘/dev/binder’…
07-20 05:12:41.976 1279 1344 I ServiceManager: Waiting for service ‘media.metrics’ on ‘/dev/binder’…
07-20 05:12:42.076 1279 1344 I ServiceManager: Waiting for service ‘media.metrics’ on ‘/dev/binder’…
07-20 05:12:42.176 1279 1344 I ServiceManager: Waiting for service ‘media.metrics’ on ‘/dev/binder’…
07-20 05:12:42.277 1279 1344 I ServiceManager: Waiting for service ‘media.metrics’ on ‘/dev/binder’…
07-20 05:12:42.377 509 509 E SELinux : avc: denied { find } for service=media.metrics pid=1279 uid=1013 scontext=u:r:bootanim:s0 tcontext=u:object_r:mediametrics_service:s0 tclass=service_manager permissive=0
07-20 05:12:42.377 1279 1344 I ServiceManager: Waiting for service ‘media.metrics’ on ‘/dev/binder’…
07-20 05:12:42.477 509 509 E SELinux : avc: denied { find } for service=media.metrics pid=1279 uid=1013 scontext=u:r:bootanim:s0 tcontext=u:object_r:mediametrics_service:s0 tclass=service_manager permissive=0
07-20 05:12:42.477 1279 1344 I ServiceManager: Waiting for service ‘media.metrics’ on ‘/dev/binder’…
07-20 05:12:42.578 509 509 E SELinux : avc: denied { find } for service=media.metrics pid=1279 uid=1013 scontext=u:r:bootanim:s0 tcontext=u:object_r:mediametrics_service:s0 tclass=service_manager permissive=0
07-20 05:12:42.578 1279 1344 I ServiceManager: Waiting for service ‘media.metrics’ on ‘/dev/binder’…
07-20 05:12:42.678 509 509 E SELinux : avc: denied { find } for service=media.metrics pid=1279 uid=1013 scontext=u:r:bootanim:s0 tcontext=u:object_r:mediametrics_service:s0 tclass=service_manager permissive=0
07-20 05:12:42.678 1279 1344 I ServiceManager: Waiting for service ‘media.metrics’ on ‘/dev/binder’…
07-20 05:12:42.778 509 509 E SELinux : avc: denied { find } for service=media.metrics pid=1279 uid=1013 scontext=u:r:bootanim:s0 tcontext=u:object_r:mediametrics_service:s0 tclass=service_manager permissive=0
07-20 05:12:42.778 1279 1344 I ServiceManager: Waiting for service ‘media.metrics’ on ‘/dev/binder’…
07-20 05:12:42.879 509 509 E SELinux : avc: denied { find } for service=media.metrics pid=1279 uid=1013 scontext=u:r:bootanim:s0 tcontext=u:object_r:mediametrics_service:s0 tclass=service_manager permissive=0
07-20 05:12:42.879 1279 1344 I ServiceManager: Waiting for service ‘media.metrics’ on ‘/dev/binder’…
07-20 05:12:42.979 509 509 E SELinux : avc: denied { find } for service=media.metrics pid=1279 uid=1013 scontext=u:r:bootanim:s0 tcontext=u:object_r:mediametrics_service:s0 tclass=service_manager permissive=0
07-20 05:12:42.979 1279 1344 I ServiceManager: Waiting for service ‘media.metrics’ on ‘/dev/binder’…
07-20 05:12:43.079 509 509 E SELinux : avc: denied { find } for service=media.metrics pid=1279 uid=1013 scontext=u:r:bootanim:s0 tcontext=u:object_r:mediametrics_service:s0 tclass=service_manager permissive=0
07-20 05:12:43.079 1279 1344 I ServiceManager: Waiting for service ‘media.metrics’ on ‘/dev/binder’…
07-20 05:12:43.180 509 509 E SELinux : avc: denied { find } for service=media.metrics pid=1279 uid=1013 scontext=u:r:bootanim:s0 tcontext=u:object_r:mediametrics_service:s0 tclass=service_manager permissive=0
07-20 05:12:43.180 1279 1344 I ServiceManager: Waiting for service ‘media.metrics’ on ‘/dev/binder’…
07-20 05:12:43.280 509 509 E SELinux : avc: denied { find } for service=media.metrics pid=1279 uid=1013 scontext=u:r:bootanim:s0 tcontext=u:object_r:mediametrics_service:s0 tclass=service_manager permissive=0
07-20 05:12:43.280 1279 1344 I ServiceManager: Waiting for service ‘media.metrics’ on ‘/dev/binder’…
07-20 05:12:43.380 509 509 E SELinux : avc: denied { find } for service=media.metrics pid=1279 uid=1013 scontext=u:r:bootanim:s0 tcontext=u:object_r:mediametrics_service:s0 tclass=service_manager permissive=0
07-20 05:12:43.380 1279 1344 I ServiceManager: Waiting for service ‘media.metrics’ on ‘/dev/binder’…
07-20 05:12:43.481 509 509 E SELinux : avc: denied { find } for service=media.metrics pid=1279 uid=1013 scontext=u:r:bootanim:s0 tcontext=u:object_r:mediametrics_service:s0 tclass=service_manager permissive=0
07-20 05:12:43.481 1279 1344 I ServiceManager: Waiting for service ‘media.metrics’ on ‘/dev/binder’…
07-20 05:12:43.581 509 509 E SELinux : avc: denied { find } for service=media.metrics pid=1279 uid=1013 scontext=u:r:bootanim:s0 tcontext=u:object_r:mediametrics_service:s0 tclass=service_manager permissive=0
07-20 05:12:43.581 1279 1344 I ServiceManager: Waiting for service ‘media.metrics’ on ‘/dev/binder’…
07-20 05:12:43.681 509 509 E SELinux : avc: denied { find } for service=media.metrics pid=1279 uid=1013 scontext=u:r:bootanim:s0 tcontext=u:object_r:mediametrics_service:s0 tclass=service_manager permissive=0
07-20 05:12:43.681 1279 1344 I ServiceManager: Waiting for service ‘media.metrics’ on ‘/dev/binder’…
07-20 05:12:43.782 509 509 E SELinux : avc: denied { find } for service=media.metrics pid=1279 uid=1013 scontext=u:r:bootanim:s0 tcontext=u:object_r:mediametrics_service:s0 tclass=service_manager permissive=0
07-20 05:12:43.782 1279 1344 I ServiceManager: Waiting for service ‘media.metrics’ on ‘/dev/binder’…
07-20 05:12:43.882 509 509 E SELinux : avc: denied { find } for service=media.metrics pid=1279 uid=1013 scontext=u:r:bootanim:s0 tcontext=u:object_r:mediametrics_service:s0 tclass=service_manager permissive=0
07-20 05:12:43.882 1279 1344 I ServiceManager: Waiting for service ‘media.metrics’ on ‘/dev/binder’…
07-20 05:12:43.982 509 509 E SELinux : avc: denied { find } for service=media.metrics pid=1279 uid=1013 scontext=u:r:bootanim:s0 tcontext=u:object_r:mediametrics_service:s0 tclass=service_manager permissive=0
07-20 05:12:43.982 1279 1344 I ServiceManager: Waiting for service ‘media.metrics’ on ‘/dev/binder’…
07-20 05:12:44.083 509 509 E SELinux : avc: denied { find } for service=media.metrics pid=1279 uid=1013 scontext=u:r:bootanim:s0 tcontext=u:object_r:mediametrics_service:s0 tclass=service_manager permissive=0
07-20 05:12:44.083 1279 1344 I ServiceManager: Waiting for service ‘media.metrics’ on ‘/dev/binder’…
07-20 05:12:44.183 509 509 E SELinux : avc: denied { find } for service=media.metrics pid=1279 uid=1013 scontext=u:r:bootanim:s0 tcontext=u:object_r:mediametrics_service:s0 tclass=service_manager permissive=0
07-20 05:12:44.183 1279 1344 I ServiceManager: Waiting for service ‘media.metrics’ on ‘/dev/binder’…
07-20 05:12:44.283 509 509 E SELinux : avc: denied { find } for service=media.metrics pid=1279 uid=1013 scontext=u:r:bootanim:s0 tcontext=u:object_r:mediametrics_service:s0 tclass=service_manager permissive=0
07-20 05:12:44.283 1279 1344 I ServiceManager: Waiting for service ‘media.metrics’ on ‘/dev/binder’…
07-20 05:12:44.383 509 509 E SELinux : avc: denied { find } for service=media.metrics pid=1279 uid=1013 scontext=u:r:bootanim:s0 tcontext=u:object_r:mediametrics_service:s0 tclass=service_manager permissive=0
07-20 05:12:44.383 1279 1344 I ServiceManager: Waiting for service ‘media.metrics’ on ‘/dev/binder’…
07-20 05:12:44.484 509 509 E SELinux : avc: denied { find } for service=media.metrics pid=1279 uid=1013 scontext=u:r:bootanim:s0 tcontext=u:object_r:mediametrics_service:s0 tclass=service_manager permissive=0
07-20 05:12:44.484 1279 1344 I ServiceManager: Waiting for service ‘media.metrics’ on ‘/dev/binder’…
07-20 05:12:44.584 509 509 E SELinux : avc: denied { find } for service=media.metrics pid=1279 uid=1013 scontext=u:r:bootanim:s0 tcontext=u:object_r:mediametrics_service:s0 tclass=service_manager permissive=0
07-20 05:12:44.584 1279 1344 I ServiceManager: Waiting for service ‘media.metrics’ on ‘/dev/binder’…
07-20 05:12:44.684 509 509 E SELinux : avc: denied { find } for service=media.metrics pid=1279 uid=1013 scontext=u:r:bootanim:s0 tcontext=u:object_r:mediametrics_service:s0 tclass=service_manager permissive=0
07-20 05:12:44.684 1279 1344 W ServiceManager: Service media.metrics didn’t start. Returning NULL
修改如下,即可优化-----5s

prebuilts/api/29.0/public/bootanim.te
public/bootanim.te
+allow bootanim mediametrics_service:service_manager find;
+allow bootanim mediametrics:binder call;

七、总结:

7.1、zygote阶段

一般有两个耗时点:

a). 预加载class/resource的时间。需要确认是否有添加很多系统资源

b). 这期间是否有很多GC动作

7.2、SystemServer阶段:

Check各个service开机初始化过程的耗时情况

通常耗时点:

a). pms scan package阶段:

系统 App 裁剪 PackageManagerService

scanDirTracedLI

(1)减少预置APP的数量(对开机速度会有较为明显的提升);

(2)删除没有必要的apk包;

(3)单线程scan分区里面的apk并不一定能充分使用IO资源,尝试改为多线程异步scan;

(4)精简系统,把系统中用不到的apk包、有重复功能的apk移除,这样既可以使系统有更大的剩余存储空间又可以减少scan的时间,加快开机;

你可能感兴趣的:(android)