设备安装150个应用后,开机耗时增加7s,主要是PMS扫描/data/app
,耗时6.5s。
分析发现,主要耗时在
scanPackageNewLI 解析apk文件commitReconciledScanResultLocked 将解析到的组件添加到PMS
backtrace如下:
frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.javascanDirTracedLI|--> scanDirLIfor ()|--> addForInitLI|--> scanPackageNewLI|--> commitReconciledScanResultLocked
scanPackageNewLI
主要是读取解析apk文件,优化空间不大。进一步分析commitReconciledScanResultLocked
commitReconciledScanResultLocked|--> commitPackageSettings|--> ComponentResolver.addAllComponents|--> addActivitiesLocked|--> ActivityIntentResolver.addActivity|--> mActivities.put(a.getComponentName(), a)
mActivities是ArrayMap,安装140个应用后超过40000个元素,开机过程put总耗时2500ms。
ArrayMap是用Array实现的map,比HashMap节省内存,但是牺牲了性能,主要原因是每次插入、删除元素时都会对整个数组使用二分查找。
如果是保存几百个元素时,性能差距不超过50%。
新机开机后,mActivities元素也有5000个,所以不适合用ArrayMap。
将mActivities类型改为HashMap后,安装150个应用后put总耗时126ms,开机耗时减少2500ms。