Android系统-PMS scanPackageDirtyLI的LI是什么意思
如标题,这个问题是最近在面试的时候被问到的,当我听到这个问题的时候脑子里确实是一点概念都没有,平时看源码流程从一个方法跳到另一个方法,但是从来没有考虑过这个函数名称为什么是这个样子的,考虑的太少了。面试结束后回来就立马查一下这个问题,在这里也记录一下。
在PMS的源码中除了LI结尾的方法,还有其他例如LIF、LPw、LPr结尾的函数,下面列举了一部分。
后缀 | 方法名 |
---|---|
LI | collectCertificatesLI() installPackageLI() scanPackageLI() scanDirLI() |
LIF | deletePackageLIF() deleteSystemPackageLIF() clearApplicationUserDataLIF() clearAppDataLIF() |
LP | grantPermissionsLPw() updatePermissionsLPw() enableSystemPackageLPw() setInstallerPackageNameLPw() |
LPr | getRequiredInstallerLPr() verifyPackageUpdateLPr() normalizePackageNameLPr() needsNetworkVerificationLPr() |
首先看一下PMS源码中的注释
1 | /** |
从上面的注释中可以了解到PMS中有两个锁,mPackages和mInstallLock,这两个锁在PMS中非常重要。而LI、LIF、LPw、LPr这些方法,L指的是Lock,I和P就指的是mInstallLock和mPackages。最后面w表示writing,r表示reading,F表示Freeze。
在上面注释中也可以看到mInstallLock是单线程的,操作慢,所以在已经持有mPackages
同步锁的时候,千万不要再请求mInstallLock
同步锁。
错误方式
1 | synchronized (mPackages) { |
正确方式
1 | synchronized (mInstaller) { |
许多内部方法依赖于调用者来持有适当的锁,在调用函数时,要遵循以下规则
方法名 | 使用方式 |
---|---|
fooLI() | 调用fooLI(),必须先持有mInstallLock 锁。 |
fooLIF() | 调用fooLIF(),必须先持有mInstallLock 锁,并且正在被修改的包(package)必须被冻结(be frozen)。 |
fooLPr() | 调用fooLPr(),必须先持有mPackages 锁,并且只用于读操作。 |
fooLPw() | 调用fooLPw(),必须先持有mPackages 锁,并且只用于写操作。 |
例如要调用installPackageTracedLI
,必须先持有mInstallLock
锁,因此,调用为:
1 | synchronized (mInstallLock) { |
再例如verifyPackageUpdateLPr
1 | // writer |
最后还有一个注解@GuardedBy
用于标记哪些变量要用同步锁保护起来。
1 | "mPackages") ( |
这个注解表示在使用变量的地方,必须获取对应的锁,以防止并发错误
1 | synchronized (mPackages) { |
嗯,又学习到了一个知识点。