1.背景

在系统优化后期,需要针对百毫秒级别的服务进行优化,今天优化的对象是PKMS,可以从log中看到PKMS创建消耗1861ms,其中扫描系统apk消耗1107ms, 一共扫描200个包,平均5ms扫描一个包。

1
9285 1970/01/01 08:00:16.398706 16.0397 114 ECU1 Syst LOGD 356 log debug verbose 1 D/SystemServerTiming( 805): StartPackageManagerService took to complete: 1861ms
1
5543 1970/01/01 08:00:15.973980 15.0962 212 ECU1 Pack LOGD 356 log info verbose 1 I/PackageManager( 805): Finished scanning system apps. Time: 1107 ms, packageCount: 200 , timePerPackage: 5 , cached: 0

2.分析PKMS扫描过程

PKMS详细的分析见《重温PackageManagerService-源码分析 | Learn OS concepts by coding them! (jackou.top)

简单来讲,PKMS扫描APK是在构造方法中采用单线程的方式对系统中指定目录下的所有APK进行扫描,其中扫描到apk中的Manifest.xml文件之后之后,最终会保存在PackageParser.Package对象的形式保存在mPackages对象中。提前剧透一下,mPackages对象是被加锁的!!!

1
2
@GuardedBy("mPackages")
final ArrayMap<String, PackageParser.Package> mPackages = new ArrayMap<String, PackageParser.Package>();

因此我们第一想到的是能否用并发扫描apk的方式来加快apk的扫描。

有了此思路,那我们就开始实践。

此前看并发编程的时候发现一个工具类叫CountDownLatch,专门用于做多线程并发初始化任务的。原理很简单,初始化一个等待值,当等待值减为0之后,开始继续执行await()后面的代码。CountDownLatch的原理可以百度一下,一大堆。下面我基于此思路,先写一个demo, pkms代码太多,直接上验证周期太长了。demo如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
private static Object mInstallLock = new Object();
private static Object mPackages = new Object();
public static void main(String[] args) {

final CountDownLatch latch = new CountDownLatch(3); //经过分析,准备开3个线程来扫包。后面有分析原因。
synchronized (mInstallLock) {
synchronized (mPackages) {
ExecutorService es1 = Executors.newSingleThreadExecutor();
es1.execute(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000); //模拟耗时扫包
synchronized (mPackages) {
System.out.println(123); // 保存扫描结果(PackageParser.Package)到mPackages中
}
System.out.println("子线程:"+Thread.currentThread().getName()+"执行" + Thread.currentThread());
} catch (InterruptedException e) {
e.printStackTrace();
}
latch.countDown();
}
});
es1.shutdown();

//第二个子线程执行
ExecutorService es2 = Executors.newSingleThreadExecutor();
es2.execute(new Runnable() {
@Override
public void run() {
synchronized (mPackages) { //此处没有睡眠,模拟任务比较少的场景
System.out.println(456); // 保存扫描结果(PackageParser.Package)到mPackages中
}
System.out.println("子线程:"+Thread.currentThread().getName()+"执行" + Thread.currentThread());
latch.countDown();
}
});
es2.shutdown();

ExecutorService es3 = Executors.newSingleThreadExecutor();
es3.execute(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
synchronized (mPackages) {
System.out.println(789);
}
System.out.println("子线程:"+Thread.currentThread().getName()+"执行" + Thread.currentThread());
} catch (InterruptedException e) {
e.printStackTrace();
}
latch.countDown();
}
});
es3.shutdown();
} // mPackages
} // mInstallLock
// 此处一定要释放以上两把锁!否则会在子线程访问mPackages的时候造成死锁,血的教训,一定在此处释放

System.out.println("等待三个线程执行完毕…… ……" + Thread.currentThread());
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("三个子线程都执行完毕,继续执行主线程");

synchronized (mInstallLock) {
synchronized (mPackages) {
// pmks剩余的代码
}
}
}
1
2
3
4
5
6
7
8
456
等待三个线程执行完毕…… ……Thread[main,5,main]
子线程:pool-2-thread-1执行Thread[pool-2-thread-1,5,main]
789
子线程:pool-3-thread-1执行Thread[pool-3-thread-1,5,main]
123
子线程:pool-1-thread-1执行Thread[pool-1-thread-1,5,main]
三个子线程都执行完毕,继续执行主线程

有了上面的demo,那我们来分析如何做扫包均衡

3.扫包均衡

使用如下指令分析当前系统apk所在目录。

1
pm list package -f 

3.1 system app

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
Line 3: package:/system/app/AccountCenter/AccountCenter.apk=com.iflytek.autofly.accountcenter
Line 4: package:/system/app/XSystemServer/XSystemServer.apk=com.iflytek.autofly.systemserver
Line 7: package:/system/app/CarMultiInstanceService/CarMultiInstanceService.apk=com.gxatek.multiinstanceservice
Line 13: package:/system/app/NaviSelect/NaviSelect.apk=com.iflytek.autofly.naviselect
Line 14: package:/system/app/CarDiagHMI/CarDiagHMI.apk=com.gxatek.cockpit.diagnostic
Line 18: package:/system/app/DMSApp/DMSApp.apk=com.iflytek.autofly.vision.dms
Line 24: package:/system/app/CarTimeSync/CarTimeSync.apk=com.gxa.car.timesync
Line 25: package:/system/app/Protips/Protips.apk=com.android.protips
Line 26: package:/system/app/AtmospherelampService/AtmospherelampService.apk=com.gxatek.cockpit.atmospherelampservice
Line 27: package:/system/app/CarIqiyi/CarIqiyi.apk=com.qiyi.video.pad
Line 30: package:/system/app/uimremoteclient/uimremoteclient.apk=com.qualcomm.uimremoteclient
Line 31: package:/system/app/HTMLViewer/HTMLViewer.apk=com.android.htmlviewer
Line 33: package:/system/app/CompanionDeviceManager/CompanionDeviceManager.apk=com.android.companiondevicemanager
Line 34: package:/system/app/QuickSearchBox/QuickSearchBox.apk=com.android.quicksearchbox
Line 36: package:/system/app/CarExternalKeyService/CarExternalKeyService.apk=com.gxa.car.externalkey
Line 37: package:/system/app/GacAccountService/GacAccountService.apk=com.gxa.service.account
Line 40: package:/system/app/GxaViceLauncher/GxaViceLauncher.apk=com.gxatek.cockpit.vicelauncher
Line 42: package:/system/app/QnxMessageService/QnxMessageService.apk=com.gxa.car.qnxapp
Line 43: package:/system/app/CarGalleryHMI/CarGalleryHMI.apk=com.gxatek.cockpit.gallery
Line 44: package:/system/app/SoundRecorder/SoundRecorder.apk=com.android.soundrecorder
Line 46: package:/system/app/CarUsbUpdate/CarUsbUpdate.apk=com.gxa.service.carusbupdate
Line 47: package:/system/app/uimremoteserver/uimremoteserver.apk=com.qualcomm.uimremoteserver
Line 49: package:/system/app/ConfURIDialer/ConfURIDialer.apk=com.qti.confuridialer
Line 51: package:/system/app/CarMapsPlaceholder/CarMapsPlaceholder.apk=com.android.car.mapsplaceholder
Line 53: package:/system/app/PacProcessor/PacProcessor.apk=com.android.pacprocessor
Line 54: package:/system/app/SimAppDialog/SimAppDialog.apk=com.android.simappdialog
Line 55: package:/system/app/GxaViceHvacControl/GxaViceHvacControl.apk=com.gxatek.cockpit.copilot.hvacservice
Line 57: package:/system/app/CertInstaller/CertInstaller.apk=com.android.certinstaller
Line 61: package:/system/app/Camera2/Camera2.apk=com.android.camera2
Line 63: package:/system/app/GxatekSchedule/GxatekSchedule.apk=com.gxatek.cockpit.schedule
Line 64: package:/system/app/SystemUpdater/SystemUpdater.apk=com.android.car.systemupdater
Line 65: package:/system/app/EngineeringModeService/EngineeringModeService.apk=com.gxa.car.engineMode
Line 66: package:/system/app/CarMessageCenterServiceHmi/CarMessageCenterServiceHmi.apk=com.gxatek.cockpit.msgcenter
Line 68: package:/system/app/EasterEgg/EasterEgg.apk=com.android.egg
Line 70: package:/system/app/NfcNci/NfcNci.apk=com.android.nfc
Line 71: package:/system/app/Stk/Stk.apk=com.android.stk
Line 74: package:/system/app/CPDeviceManager/CPDeviceManager.apk=com.gxa.service.devicemanager
Line 78: package:/system/app/Calendar/Calendar.apk=com.android.calendar
Line 84: package:/system/app/Operatormall/Operatormall.apk=com.iflytek.auto.mall.hmi
Line 86: package:/system/app/DynamicDDSService/DynamicDDSService.apk=com.qualcomm.qti.dynamicddsservice
Line 92: package:/system/app/CarSettingsHMI/CarSettingsHMI.apk=com.gxatek.cockpit.carsettings
Line 93: package:/system/app/PrintSpooler/PrintSpooler.apk=com.android.printspooler
Line 95: package:/system/app/BasicDreams/BasicDreams.apk=com.android.dreams.basic
Line 96: package:/system/app/GosApplet/GosApplet.apk=com.gxatek.cockpit.applet
Line 97: package:/system/app/webview/webview.apk=com.android.webview
Line 99: package:/system/app/SecureElement/SecureElement.apk=com.android.se
Line 101: package:/system/app/CarLensPickerApp/CarLensPickerApp.apk=com.android.support.car.lenspicker
Line 102: package:/system/app/BuiltInPrintService/BuiltInPrintService.apk=com.android.bips
Line 105: package:/system/app/GxatekAppList/GxatekAppList.apk=com.iflytek.autofly.applist
Line 108: package:/system/app/GxatekScenesEngine/GxatekScenesEngine.apk=com.gxatek.cockpit.scenesengine
Line 109: package:/system/app/CarExtConnectivityService/CarExtConnectivityService.apk=com.gxa.car.ncm
Line 111: package:/system/app/ExtShared/ExtShared.apk=android.ext.shared
Line 114: package:/system/app/GxaViceCarControl/GxaViceCarControl.apk=com.gxatek.cockpit.carcontrol
Line 115: package:/system/app/KeyChain/KeyChain.apk=com.android.keychain
Line 117: package:/system/app/CarWeatherHMI/CarWeatherHMI.apk=com.gxatek.cockpit.weather
Line 118: package:/system/app/CarMessageCenterService/CarMessageCenterService.apk=com.gxa.service.messagecenter
Line 119: package:/system/app/PrintRecommendationService/PrintRecommendationService.apk=com.android.printservice.recommendation
Line 120: package:/system/app/Gallery2/Gallery2.apk=com.android.gallery3d
Line 125: package:/system/app/CarrierDefaultApp/CarrierDefaultApp.apk=com.android.carrierdefaultapp
Line 126: package:/system/app/GacCloudService/GacCloudService.apk=com.gac.cloud.app
Line 129: package:/system/app/CarProcManagementService/CarProcManagementService.apk=com.gxa.car.procmanagement
Line 130: package:/system/app/CarAdapterService/CarAdapterService.apk=com.gxa.appservice.caradapter
Line 131: package:/system/app/Browser2/Browser2.apk=org.chromium.webview_shell
Line 136: package:/system/app/PhotoTable/PhotoTable.apk=com.android.dreams.phototable
Line 137: package:/system/app/HvacService/HvacService.apk=com.gxa.cockpit.hvac
Line 138: package:/system/app/GacStore/GacStore.apk=cn.gaei.appstore
Line 140: package:/system/app/GxaFirewallApp/GxaFirewallApp.apk=com.gxa.firewall
Line 141: package:/system/app/CarVoiceCtrl/CarVoiceCtrl.apk=com.gxatek.cockpit.voicecarctrl
Line 142: package:/system/app/IVISafety/IVISafety.apk=com.gaci.ivi.ids
Line 143: package:/system/app/WAPPushManager/WAPPushManager.apk=com.android.smspush
Line 144: package:/system/app/LiveWallpapersPicker/LiveWallpapersPicker.apk=com.android.wallpaper.livepicker
Line 145: package:/system/app/CarWeatherService/CarWeatherService.apk=com.gxa.service.weather
Line 148: package:/system/app/CarAdapterMainService/CarAdapterMainService.apk=com.gxa.appservice.platformadapter.adaptermainservice
Line 151: package:/system/app/BookmarkProvider/BookmarkProvider.apk=com.android.bookmarkprovider
Line 152: package:/system/app/GxatekMiniProgramApp/GxatekMiniProgramApp.apk=com.gxatek.cockpit.miniprogram
Line 154: package:/system/app/SnapdragonSVA/SnapdragonSVA.apk=com.qualcomm.qti.sva
Line 155: package:/system/app/GosCarService/GosCarService.apk=com.gxatek.cockpit.carservice
Line 156: package:/system/app/CarAvdcHMI/CarAvdcHMI.apk=com.gxatek.cockpit.avdc
Line 157: package:/system/app/ExactCalculator/ExactCalculator.apk=com.android.calculator2
Line 160: package:/system/app/CarSettingHMI/CarSettingHMI.apk=com.gxatek.cockpit.settings
Line 161: package:/system/app/CtsShimPrebuilt/CtsShimPrebuilt.apk=com.android.cts.ctsshim
Line 162: package:/system/app/CarAudioService/CarAudioService.apk=com.gxa.car.audio
Line 163: package:/system/app/CarPower/CarPower.apk=com.gxa.car.power
Line 164: package:/system/app/SceneManagerService/SceneManagerService.apk=com.gxa.car.scene
Line 165: package:/system/app/IflytekIME/IflytekIME.apk=com.iflytek.inputmethod
Line 166: package:/system/app/QTIDiagServices/QTIDiagServices.apk=com.qti.diagservices
Line 167: package:/system/app/DMSService/DMSService.apk=com.iflytek.autofly.dms
Line 170: package:/system/app/Email/Email.apk=com.android.email
Line 171: package:/system/app/Music/Music.apk=com.android.music
Line 174: package:/system/app/WallpaperBackup/WallpaperBackup.apk=com.android.wallpaperbackup
Line 178: package:/system/app/CarWifiService/CarWifiService.apk=com.gxa.car.wifi.service
Line 180: package:/system/app/DeskClock/DeskClock.apk=com.android.deskclock
Line 182: package:/system/app/CarPki/CarPki.apk=com.gxa.pki
Line 183: package:/system/app/BluetoothMidiService/BluetoothMidiService.apk=com.android.bluetoothmidiservice
Line 185: package:/system/app/VPAMultiMode/VPAMultiMode.apk=com.gxatek.cockpit.vpamultimode
Line 186: package:/system/app/CarPermission/CarPermission.apk=com.gxa.permission
Line 187: package:/system/app/CarHardKeyService/CarHardKeyService.apk=com.gxa.car.hardkey
Line 188: package:/system/app/Traceur/Traceur.apk=com.android.traceur
Line 189: package:/system/app/ScreenSaverService/ScreenSaverService.apk=com.gxatek.cockpit.screensaver
Line 192: package:/system/app/Bluetooth/Bluetooth.apk=com.android.bluetooth
Line 196: package:/system/app/CaptivePortalLogin/CaptivePortalLogin.apk=com.android.captiveportallogin
Line 198: package:/system/app/GlobalSearch/GlobalSearch.apk=com.gxatek.cockpit.globalsearch

从上面可以看出在system/app目录下有102个apk

3.2 priv-app

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package:/system/priv-app/CtsShimPrivPrebuilt/CtsShimPrivPrebuilt.apk=com.android.cts.priv.ctsshim
Line 5: package:/system/priv-app/CarMessengerApp/CarMessengerApp.apk=com.android.car.messenger
Line 10: package:/system/priv-app/TelephonyProvider/TelephonyProvider.apk=com.android.providers.telephony
Line 11: package:/system/priv-app/GxaSystemAPPService/GxaSystemAPPService.apk=com.gxatek.cockpit.gxasystemappservice
Line 12: package:/system/priv-app/CalendarProvider/CalendarProvider.apk=com.android.providers.calendar
Line 15: package:/system/priv-app/CarMediaProvider/CarMediaProvider.apk=com.android.providers.media
Line 17: package:/system/priv-app/WallpaperCropper/WallpaperCropper.apk=com.android.wallpapercropper
Line 19: package:/system/priv-app/CarMediaApp/CarMediaApp.apk=com.android.car.media
Line 20: package:/system/priv-app/CNEService/CNEService.apk=com.quicinc.cne.CNEService
Line 21: package:/system/priv-app/CarRadioApp/CarRadioApp.apk=com.android.car.radio
Line 22: package:/system/priv-app/CarTrustAgentService/CarTrustAgentService.apk=com.android.car.trust
Line 28: package:/system/priv-app/DocumentsUI/DocumentsUI.apk=com.android.documentsui
Line 29: package:/system/priv-app/ExternalStorageProvider/ExternalStorageProvider.apk=com.android.externalstorage
Line 32: package:/system/priv-app/XOSLauncher/XOSLauncher.apk=com.gxatek.cockpit.launcher
Line 35: package:/system/priv-app/MmsService/MmsService.apk=com.android.mms.service
Line 39: package:/system/priv-app/DownloadProvider/DownloadProvider.apk=com.android.providers.downloads
Line 45: package:/system/priv-app/android.car.cluster.loggingrenderer/android.car.cluster.loggingrenderer.apk=android.car.cluster.loggingrenderer
Line 48: package:/system/priv-app/DefaultContainerService/DefaultContainerService.apk=com.android.defcontainer
Line 52: package:/system/priv-app/DownloadProviderUi/DownloadProviderUi.apk=com.android.providers.downloads.ui
Line 58: package:/system/priv-app/CarrierConfig/CarrierConfig.apk=com.android.carrierconfig
Line 60: package:/system/priv-app/Contacts/Contacts.apk=com.android.contacts
Line 62: package:/system/priv-app/WfdService/WfdService.apk=com.qualcomm.wfd.service
Line 67: package:/system/priv-app/CarService/CarService.apk=com.android.car
Line 69: package:/system/priv-app/MtpDocumentsProvider/MtpDocumentsProvider.apk=com.android.mtp
Line 72: package:/system/priv-app/BackupRestoreConfirmation/BackupRestoreConfirmation.apk=com.android.backupconfirm
Line 73: package:/system/priv-app/ClusterService/ClusterService.apk=com.gxatek.appservice.cluster
Line 75: package:/system/priv-app/Provision/Provision.apk=com.android.provision
Line 76: package:/system/priv-app/StatementService/StatementService.apk=com.android.statementservice
Line 77: package:/system/priv-app/SettingsIntelligence/SettingsIntelligence.apk=com.android.settings.intelligence
Line 80: package:/system/priv-app/CarLife/CarLife.apk=com.gxatek.cockpit.carlife
Line 81: package:/system/priv-app/CarPlay/CarPlay.apk=com.gxatek.cockpit.carplay
Line 82: package:/system/priv-app/IflytekAvatar/IflytekAvatar.apk=com.iflytek.autofly.avatar
Line 85: package:/system/priv-app/CarSettings/CarSettings.apk=com.android.car.settings
Line 87: package:/system/priv-app/GxaAIAngela/GxaAIAngela.apk=com.iflytek.autofly.aiangela
Line 88: package:/system/priv-app/CarHvacApp/CarHvacApp.apk=com.android.car.hvac
Line 89: package:/system/priv-app/qcrilmsgtunnel/qcrilmsgtunnel.apk=com.qualcomm.qcrilmsgtunnel
Line 90: package:/system/priv-app/SettingsProvider/SettingsProvider.apk=com.android.providers.settings
Line 91: package:/system/priv-app/SharedStorageBackup/SharedStorageBackup.apk=com.android.sharedstoragebackup
Line 98: package:/system/priv-app/BtCallApp/BtCallApp.apk=com.gxatek.cockpit.btcall
Line 100: package:/system/priv-app/InputDevices/InputDevices.apk=com.android.inputdevices
Line 104: package:/system/priv-app/dpmserviceapp/dpmserviceapp.apk=com.qti.dpmserviceapp
Line 106: package:/system/priv-app/DefaultStorageMonitoringCompanionApp/DefaultStorageMonitoringCompanionApp.apk=com.google.android.car.defaultstoragemonitoringcompanionapp
Line 107: package:/system/priv-app/MusicFX/MusicFX.apk=com.android.musicfx
Line 110: package:/system/priv-app/CellBroadcastReceiver/CellBroadcastReceiver.apk=com.android.cellbroadcastreceiver
Line 112: package:/system/priv-app/OneTimeInitializer/OneTimeInitializer.apk=com.android.onetimeinitializer
Line 113: package:/system/priv-app/Telecom/Telecom.apk=com.android.server.telecom
Line 121: package:/system/priv-app/ExtServices/ExtServices.apk=android.ext.services
Line 123: package:/system/priv-app/CallLogBackup/CallLogBackup.apk=com.android.calllogbackup
Line 124: package:/system/priv-app/CarPackageInstaller/CarPackageInstaller.apk=com.android.packageinstaller
Line 127: package:/system/priv-app/LocalMediaPlayer/LocalMediaPlayer.apk=com.android.car.media.localmediaplayer
Line 128: package:/system/priv-app/ProxyHandler/ProxyHandler.apk=com.android.proxyhandler
Line 132: package:/system/priv-app/CarUsbHandler/CarUsbHandler.apk=android.car.usb.handler
Line 133: package:/system/priv-app/CarSettingsService/CarSettingsService.apk=com.gxa.service.settings
Line 134: package:/system/priv-app/ManagedProvisioning/ManagedProvisioning.apk=com.android.managedprovisioning
Line 135: package:/system/priv-app/MediaCenterService/MediaCenterService.apk=com.gxa.service.mediacenterservice
Line 146: package:/system/priv-app/VmsSubscriberClientSample/VmsSubscriberClientSample.apk=com.google.android.car.vms.subscriber
Line 149: package:/system/priv-app/CarSystemUI/CarSystemUI.apk=com.gxa.service.systemui
Line 150: package:/system/priv-app/StorageManager/StorageManager.apk=com.android.storagemanager
Line 153: package:/system/priv-app/Settings/Settings.apk=com.android.settings
Line 159: package:/system/priv-app/BtCallService/BtCallService.apk=com.gxa.service.bluetooth
Line 168: package:/system/priv-app/VpnDialogs/VpnDialogs.apk=com.android.vpndialogs
Line 169: package:/system/priv-app/IflytekPlatformService/IflytekPlatformService.apk=com.iflytek.autofly.platformservice
Line 172: package:/system/priv-app/TeleService/TeleService.apk=com.android.phone
Line 173: package:/system/priv-app/Shell/Shell.apk=com.android.shell
Line 175: package:/system/priv-app/BlockedNumberProvider/BlockedNumberProvider.apk=com.android.providers.blockednumber
Line 176: package:/system/priv-app/UserDictionaryProvider/UserDictionaryProvider.apk=com.android.providers.userdictionary
Line 177: package:/system/priv-app/EmergencyInfo/EmergencyInfo.apk=com.android.emergency
Line 179: package:/system/priv-app/FusedLocation/FusedLocation.apk=com.android.location.fused
Line 181: package:/system/priv-app/SystemUI/SystemUI.apk=com.android.systemui
Line 194: package:/system/priv-app/ContactsProvider/ContactsProvider.apk=com.android.providers.contacts
Line 195: package:/system/priv-app/DVR/DVR.apk=com.gxatek.cockpit.dvr
Line 197: package:/system/priv-app/VmsPublisherClientSample/VmsPublisherClientSample.apk=com.google.android.car.vms.publisher
Line 199: package:/system/priv-app/NrNetworkSettingApp/NrNetworkSettingApp.apk=org.codeaurora.qti.nrNetworkSettingApp
Line 200: package:/system/priv-app/GacAccountHmi/GacAccountHmi.apk=com.gxatek.cockpit.account

从上面可以看出在system/priv-app目录下有74个apk。

3.3 其他

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Line 2: package:/vendor/app/SSGTelemetryService/SSGTelemetryService.apk=com.qualcomm.qti.qms.service.telemetry
Line 8: package:/vendor/app/com.qualcomm.qti.improvetouch.service/com.qualcomm.qti.improvetouch.service.apk=com.qualcomm.qti.improvetouch.service
Line 23: package:/vendor/app/CoreSystemServer/CoreSystemServer.apk=com.core.system.service
Line 38: package:/vendor/app/ConnectionSecurityService/ConnectionSecurityService.apk=com.qualcomm.qti.qms.service.connectionsecurity
Line 94: package:/vendor/app/improveTouchStudio/improveTouchStudio.apk=com.qualcomm.qti.improvetouch
Line 184: package:/vendor/app/PowerOffAlarm/PowerOffAlarm.apk=com.qualcomm.qti.poweroffalarm
Line 190: package:/vendor/app/TrustZoneAccessService/TrustZoneAccessService.apk=com.qualcomm.qti.qms.service.trustzoneaccess
Line 193: package:/vendor/app/TimeService/TimeService.apk=com.qualcomm.timeservice
Line 6: package:/vendor/overlay/DisplayCutoutEmulationCorner/DisplayCutoutEmulationCornerOverlay.apk=com.android.internal.display.cutout.emulation.corner
Line 9: package:/vendor/overlay/DisplayCutoutEmulationDouble/DisplayCutoutEmulationDoubleOverlay.apk=com.android.internal.display.cutout.emulation.double
Line 56: package:/vendor/overlay/DisplayCutoutEmulationTall/DisplayCutoutEmulationTallOverlay.apk=com.android.internal.display.cutout.emulation.tall
Line 79: package:/vendor/overlay/SysuiDarkTheme/SysuiDarkThemeOverlay.apk=com.android.systemui.theme.dark
Line 83: package:/vendor/overlay/ExtConnectivityServiceOverlay.apk=com.gxa.car.ncm.overlay
system/framework/frameworks-res.apk

从上面可以看出在其他目录下有14个apk。

因为PKMS扫描apk是基于目录的,所以我们可以将所有apk分为以上三类。

分好类之后,开始执行优化,此处由于代码敏感,只列一个目录的代码,其他目录原理是一模一样的。大家在执行过程中,一定要注意demo代码中两个锁的释放,血的教训告诉大家子线程开始扫描不释放锁,一定会死锁卡死。验证一次起码半天时间!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
ExecutorService es1 = Executors.newSingleThreadExecutor();
es1.execute(new Runnable() {

public void run() {
try {
// Collect privileged system packages.
Slog.i(TAG, "========start to scan packages concurrently..." + Thread.currentThread());
scanDirTracedLI(privilegedAppDir,
mDefParseFlags
| PackageParser.PARSE_IS_SYSTEM_DIR,
concurrentScanSystemPrivilegedFlags,
0);
Slog.i(TAG, "1.scan system privileged packages finish...");
} catch (Exception e) {
e.printStackTrace();
} finally {
scanLatch.countDown();
}
}
});
es1.shutdown();

4.验收效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
I/PackageManager( 754): ========start to scan packages concurrently...Thread[main,5,main]
I/PackageManager( 754): wait to finish scan package..
I/PackageManager( 754): ========start to scan packages concurrently...Thread[pool-3-thread-1,5,main]
I/PackageManager( 754): ========start to scan packages concurrently...Thread[pool-2-thread-1,5,main]
I/PackageManager( 754): ========start to scan packages concurrently...Thread[pool-1-thread-1,5,main]
I/PackageManager( 754): 3.scan vendor & product packages finish...
I/PackageManager( 754): 4.scan framework-res.apk packages finish...
I/PackageManager( 754): 5.scan vendor app packages finish...
I/PackageManager( 754): 6.scan odm & oem packages finish...
W/PackageManager( 754): Failed to scan /system/priv-app/CarSettingsService: Application package com.gxa.service.settings already installed. Skipping duplicate.
I/PackageManager( 754): 1.scan system privileged packages finish...
I/PackageManager( 754): 2.scan system app packages finish...
I/PackageManager( 754): finish scan package!
I/PackageManager( 754): Finished scanning system apps. Time: 809 ms, packageCount: 200 , timePerPackage: 4 , cached: 0

我们可以看到启动三个线程对所有apk包进行扫描。扫描200个apk总共消耗809ms, 平均优化了298ms!