鏇存柊鏂囨。
This commit is contained in:
2
.obsidian/workspace.json
vendored
2
.obsidian/workspace.json
vendored
@@ -200,6 +200,7 @@
|
|||||||
},
|
},
|
||||||
"active": "25c9f7051aac05b3",
|
"active": "25c9f7051aac05b3",
|
||||||
"lastOpenFiles": [
|
"lastOpenFiles": [
|
||||||
|
"docs/android面试/系统原理/PMS常见面试题.md",
|
||||||
"docs/android面试/系统原理/DPMS常见面试题.md",
|
"docs/android面试/系统原理/DPMS常见面试题.md",
|
||||||
"docs/android面试/系统原理/DPMS常见面试题",
|
"docs/android面试/系统原理/DPMS常见面试题",
|
||||||
"docs/DPMS常见面试题",
|
"docs/DPMS常见面试题",
|
||||||
@@ -229,7 +230,6 @@
|
|||||||
"docs/Google开发文档体系/核心主题/后台任务.md",
|
"docs/Google开发文档体系/核心主题/后台任务.md",
|
||||||
"docs/Google开发文档体系/核心主题/Material_Design.md",
|
"docs/Google开发文档体系/核心主题/Material_Design.md",
|
||||||
"docs/Google开发文档体系/核心主题/Jetpack组件.md",
|
"docs/Google开发文档体系/核心主题/Jetpack组件.md",
|
||||||
"docs/Google开发文档体系/示例代码/架构示例.md",
|
|
||||||
"docs/Google开发文档体系/视频和教程",
|
"docs/Google开发文档体系/视频和教程",
|
||||||
"docs/Google开发文档体系/核心主题",
|
"docs/Google开发文档体系/核心主题",
|
||||||
"docs/Google开发文档体系/示例代码",
|
"docs/Google开发文档体系/示例代码",
|
||||||
|
|||||||
710
docs/android面试/系统原理/PMS常见面试题.md
Normal file
710
docs/android面试/系统原理/PMS常见面试题.md
Normal file
@@ -0,0 +1,710 @@
|
|||||||
|
# PMS常见面试题
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 一、PMS基础概念
|
||||||
|
|
||||||
|
### Q1: 什么是PMS?它的作用是什么?
|
||||||
|
|
||||||
|
**A:** PMS(PackageManagerService)是Android系统的核心服务之一,运行在system_server进程中。
|
||||||
|
|
||||||
|
**主要作用:**
|
||||||
|
|
||||||
|
1. **应用安装管理**:管理应用的安装、卸载、更新
|
||||||
|
2. **权限管理**:管理应用权限的授予、撤销和检查
|
||||||
|
3. **组件管理**:管理Activity、Service、BroadcastReceiver、ContentProvider等组件信息
|
||||||
|
4. **包扫描**:扫描系统和应用目录中的APK文件
|
||||||
|
5. **签名验证**:验证APK的签名信息,确保应用安全性
|
||||||
|
6. **多用户管理**:支持多用户环境下的应用隔离和管理
|
||||||
|
|
||||||
|
### Q2: PMS在系统启动流程中的位置?
|
||||||
|
|
||||||
|
**A:** PMS在系统启动流程中的位置:
|
||||||
|
|
||||||
|
1. **Bootloader阶段**:加载Linux内核
|
||||||
|
2. **Kernel启动**:初始化硬件,启动init进程
|
||||||
|
3. **Init进程**:解析init.rc,启动Zygote和ServiceManager
|
||||||
|
4. **Zygote进程**:预加载类和资源,fork出SystemServer进程
|
||||||
|
5. **SystemServer进程**:启动各类系统服务
|
||||||
|
- 启动PMS(PackageManagerService)
|
||||||
|
- 启动AMS(ActivityManagerService)
|
||||||
|
- 启动WMS(WindowManagerService)
|
||||||
|
- 启动其他系统服务
|
||||||
|
6. **PMS扫描应用**:系统启动时,PMS扫描系统目录和应用目录中的APK文件
|
||||||
|
|
||||||
|
### Q3: PMS与其他系统服务的关系?
|
||||||
|
|
||||||
|
**A:** PMS与其他系统服务的关系:
|
||||||
|
|
||||||
|
1. **PMS与AMS**:AMS需要PMS提供包信息来启动Activity
|
||||||
|
2. **PMS与Installer**:PMS通过Installer执行实际的APK安装操作
|
||||||
|
3. **PMS与UserManagerService**:PMS需要UserManagerService管理多用户
|
||||||
|
4. **PMS与StorageManagerService**:PMS需要StorageManagerService管理存储空间
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 二、应用安装流程
|
||||||
|
|
||||||
|
### Q4: 请详细描述应用的安装流程?
|
||||||
|
|
||||||
|
**A:** 应用安装流程:
|
||||||
|
|
||||||
|
**客户端进程:**
|
||||||
|
1. `PackageInstaller.install()`:用户点击安装或调用安装API
|
||||||
|
2. `PackageInstaller.Session.commit()`:提交安装会话
|
||||||
|
3. `PackageInstaller.Session.commit()`:通过Binder调用PMS
|
||||||
|
|
||||||
|
**服务端进程(system_server):**
|
||||||
|
4. `PackageManagerService.installPackageAsUser()`:PMS接收安装请求
|
||||||
|
5. `PackageManagerService.createInstallSession()`:创建安装会话
|
||||||
|
6. `PackageManagerService.writeApkToSession()`:写入APK文件到临时目录
|
||||||
|
7. `PackageManagerService.commitSession()`:提交安装会话
|
||||||
|
8. `PackageManagerService.installPackageTracedLI()`:执行安装
|
||||||
|
9. `PackageParser.parsePackage()`:解析APK文件
|
||||||
|
- 解析AndroidManifest.xml
|
||||||
|
- 提取四大组件信息
|
||||||
|
- 提取权限信息
|
||||||
|
- 验证签名
|
||||||
|
10. `PackageManagerService.scanPackageTracedLI()`:扫描包信息
|
||||||
|
11. `PackageManagerService.updateSettingsLI()`:更新包设置
|
||||||
|
12. `PackageManagerService.sendPackageBroadcast()`:发送安装完成广播
|
||||||
|
|
||||||
|
**关键步骤:**
|
||||||
|
- 权限检查:检查安装权限
|
||||||
|
- APK解析:解析APK的AndroidManifest.xml
|
||||||
|
- 签名验证:验证APK签名
|
||||||
|
- 冲突检查:检查包名冲突、版本冲突
|
||||||
|
- 存储检查:检查存储空间是否足够
|
||||||
|
- 安装执行:复制APK文件、创建数据目录
|
||||||
|
- 组件注册:注册Activity、Service等组件
|
||||||
|
- 权限授予:授予声明的权限
|
||||||
|
|
||||||
|
### Q5: APK解析过程是怎样的?
|
||||||
|
|
||||||
|
**A:** APK解析过程:
|
||||||
|
|
||||||
|
1. **创建PackageParser**
|
||||||
|
```java
|
||||||
|
PackageParser parser = new PackageParser();
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **解析APK文件**
|
||||||
|
```java
|
||||||
|
PackageParser.Package pkg = parser.parsePackage(apkFile, flags);
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **解析AndroidManifest.xml**
|
||||||
|
- 解析包名、版本号等基本信息
|
||||||
|
- 解析四大组件(Activity、Service、BroadcastReceiver、ContentProvider)
|
||||||
|
- 解析权限声明
|
||||||
|
- 解析Intent Filter
|
||||||
|
- 解析资源信息
|
||||||
|
|
||||||
|
4. **收集证书信息**
|
||||||
|
```java
|
||||||
|
collectCertificates(pkg);
|
||||||
|
collectManifestDigest(pkg);
|
||||||
|
```
|
||||||
|
|
||||||
|
5. **提取组件信息**
|
||||||
|
```java
|
||||||
|
extractActivities(pkg);
|
||||||
|
extractServices(pkg);
|
||||||
|
extractReceivers(pkg);
|
||||||
|
extractProviders(pkg);
|
||||||
|
extractPermissions(pkg);
|
||||||
|
```
|
||||||
|
|
||||||
|
6. **验证签名**
|
||||||
|
- 验证APK签名是否有效
|
||||||
|
- 检查签名是否匹配
|
||||||
|
- 验证签名证书链
|
||||||
|
|
||||||
|
### Q6: 签名验证是如何进行的?
|
||||||
|
|
||||||
|
**A:** 签名验证过程:
|
||||||
|
|
||||||
|
1. **提取签名信息**
|
||||||
|
```java
|
||||||
|
// 从APK中提取签名
|
||||||
|
Signature[] signatures = packageInfo.signatures;
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **验证签名格式**
|
||||||
|
- 检查签名文件是否存在(META-INF/)
|
||||||
|
- 验证签名文件格式是否正确
|
||||||
|
|
||||||
|
3. **验证签名证书**
|
||||||
|
- 验证证书是否有效
|
||||||
|
- 验证证书是否过期
|
||||||
|
- 验证证书链是否完整
|
||||||
|
|
||||||
|
4. **验证签名匹配**
|
||||||
|
- 如果是更新安装,验证新签名是否与旧签名匹配
|
||||||
|
- 如果是共享UID应用,验证签名是否一致
|
||||||
|
|
||||||
|
5. **关键代码位置**
|
||||||
|
- `PackageManagerService.verifySignatures()`
|
||||||
|
- `PackageParser.collectCertificates()`
|
||||||
|
- `PackageManagerService.checkUpgradeKeySetLocked()`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 三、应用卸载流程
|
||||||
|
|
||||||
|
### Q7: 应用卸载流程是怎样的?
|
||||||
|
|
||||||
|
**A:** 应用卸载流程:
|
||||||
|
|
||||||
|
1. **卸载请求**
|
||||||
|
```java
|
||||||
|
packageManager.deletePackage(packageName, observer, flags);
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **PMS处理卸载**
|
||||||
|
```java
|
||||||
|
PackageManagerService.deletePackageAsUser(packageName, userId, flags);
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **检查卸载条件**
|
||||||
|
- 检查应用是否正在运行
|
||||||
|
- 检查是否有其他应用依赖
|
||||||
|
- 检查卸载权限
|
||||||
|
|
||||||
|
4. **停止应用**
|
||||||
|
- 停止应用的所有Activity
|
||||||
|
- 停止应用的所有Service
|
||||||
|
- 取消注册BroadcastReceiver
|
||||||
|
|
||||||
|
5. **删除文件**
|
||||||
|
- 删除APK文件
|
||||||
|
- 删除应用数据目录
|
||||||
|
- 删除应用缓存
|
||||||
|
|
||||||
|
6. **更新包信息**
|
||||||
|
- 从包列表中移除
|
||||||
|
- 清理组件注册信息
|
||||||
|
- 清理权限信息
|
||||||
|
|
||||||
|
7. **发送卸载广播**
|
||||||
|
```java
|
||||||
|
sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, packageName);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Q8: 卸载时如何清理应用数据?
|
||||||
|
|
||||||
|
**A:** 卸载时清理应用数据:
|
||||||
|
|
||||||
|
1. **删除应用目录**
|
||||||
|
```java
|
||||||
|
// 删除应用数据目录
|
||||||
|
/data/data/<package_name>/
|
||||||
|
/data/user/<user_id>/<package_name>/
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **删除APK文件**
|
||||||
|
```java
|
||||||
|
// 删除APK文件
|
||||||
|
/data/app/<package_name>-<random>/
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **删除外部存储数据**
|
||||||
|
```java
|
||||||
|
// 删除外部存储中的应用数据
|
||||||
|
/sdcard/Android/data/<package_name>/
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **清理数据库**
|
||||||
|
- 清理包信息数据库
|
||||||
|
- 清理权限数据库
|
||||||
|
- 清理组件注册信息
|
||||||
|
|
||||||
|
5. **清理缓存**
|
||||||
|
- 清理系统缓存中的应用信息
|
||||||
|
- 清理其他服务中的应用引用
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 四、权限管理
|
||||||
|
|
||||||
|
### Q9: PMS如何管理应用权限?
|
||||||
|
|
||||||
|
**A:** PMS权限管理机制:
|
||||||
|
|
||||||
|
1. **权限声明**
|
||||||
|
- 应用在AndroidManifest.xml中声明权限
|
||||||
|
- PMS解析时提取权限信息
|
||||||
|
|
||||||
|
2. **权限授予**
|
||||||
|
```java
|
||||||
|
// 授予权限
|
||||||
|
packageManager.grantRuntimePermission(packageName, permission, userHandle);
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **权限检查**
|
||||||
|
```java
|
||||||
|
// 检查权限
|
||||||
|
int result = packageManager.checkPermission(permission, packageName);
|
||||||
|
if (result == PackageManager.PERMISSION_GRANTED) {
|
||||||
|
// 权限已授予
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **权限撤销**
|
||||||
|
```java
|
||||||
|
// 撤销权限
|
||||||
|
packageManager.revokeRuntimePermission(packageName, permission, userHandle);
|
||||||
|
```
|
||||||
|
|
||||||
|
5. **权限存储**
|
||||||
|
- 权限授予状态存储在`/data/system/users/<user_id>/runtime-permissions.xml`
|
||||||
|
- 系统启动时加载权限状态
|
||||||
|
|
||||||
|
### Q10: 运行时权限和安装时权限的区别?
|
||||||
|
|
||||||
|
**A:** 运行时权限和安装时权限的区别:
|
||||||
|
|
||||||
|
**安装时权限(Normal Permissions):**
|
||||||
|
- 在应用安装时自动授予
|
||||||
|
- 不需要用户确认
|
||||||
|
- 通常是低风险权限
|
||||||
|
- 例如:网络访问、振动等
|
||||||
|
|
||||||
|
**运行时权限(Dangerous Permissions):**
|
||||||
|
- 需要运行时动态申请
|
||||||
|
- 需要用户确认
|
||||||
|
- 通常是高风险权限
|
||||||
|
- 例如:相机、位置、存储等
|
||||||
|
|
||||||
|
**权限分类:**
|
||||||
|
```java
|
||||||
|
// 权限保护级别
|
||||||
|
PROTECTION_NORMAL // 普通权限,安装时授予
|
||||||
|
PROTECTION_DANGEROUS // 危险权限,运行时申请
|
||||||
|
PROTECTION_SIGNATURE // 签名权限,同签名应用自动授予
|
||||||
|
PROTECTION_SIGNATURE_OR_SYSTEM // 签名或系统权限
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 五、包扫描机制
|
||||||
|
|
||||||
|
### Q11: PMS如何扫描应用?
|
||||||
|
|
||||||
|
**A:** PMS包扫描机制:
|
||||||
|
|
||||||
|
1. **系统目录扫描**
|
||||||
|
- `/system/app/`:系统应用目录
|
||||||
|
- `/system/priv-app/`:系统特权应用目录
|
||||||
|
- `/vendor/app/`:厂商应用目录
|
||||||
|
- `/oem/app/`:OEM应用目录
|
||||||
|
|
||||||
|
2. **用户目录扫描**
|
||||||
|
- `/data/app/`:用户安装的应用目录
|
||||||
|
- `/data/app-private/`:私有应用目录
|
||||||
|
|
||||||
|
3. **扫描流程**
|
||||||
|
```java
|
||||||
|
// PMS扫描流程
|
||||||
|
void scanDirTracedLI(File scanDir, int parseFlags, int scanFlags) {
|
||||||
|
// 1. 遍历目录中的APK文件
|
||||||
|
File[] files = scanDir.listFiles();
|
||||||
|
|
||||||
|
// 2. 解析每个APK
|
||||||
|
for (File file : files) {
|
||||||
|
PackageParser.Package pkg = parsePackage(file, parseFlags);
|
||||||
|
|
||||||
|
// 3. 扫描包信息
|
||||||
|
scanPackageTracedLI(pkg, parseFlags, scanFlags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **增量扫描**
|
||||||
|
- 只扫描新增或修改的APK
|
||||||
|
- 使用文件时间戳判断是否需要重新扫描
|
||||||
|
- 优化启动速度
|
||||||
|
|
||||||
|
### Q12: 系统启动时PMS如何扫描应用?
|
||||||
|
|
||||||
|
**A:** 系统启动时PMS扫描流程:
|
||||||
|
|
||||||
|
1. **扫描系统应用**
|
||||||
|
```java
|
||||||
|
// 扫描系统目录
|
||||||
|
scanDirTracedLI(new File("/system/app"), ...);
|
||||||
|
scanDirTracedLI(new File("/system/priv-app"), ...);
|
||||||
|
scanDirTracedLI(new File("/vendor/app"), ...);
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **扫描用户应用**
|
||||||
|
```java
|
||||||
|
// 扫描用户安装目录
|
||||||
|
scanDirTracedLI(new File("/data/app"), ...);
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **并行扫描优化**
|
||||||
|
- 使用多线程并行扫描不同目录
|
||||||
|
- 提高扫描速度
|
||||||
|
|
||||||
|
4. **延迟扫描**
|
||||||
|
- 非关键目录延迟扫描
|
||||||
|
- 优先扫描系统应用
|
||||||
|
- 用户应用可以延迟扫描
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 六、多用户管理
|
||||||
|
|
||||||
|
### Q13: PMS如何支持多用户?
|
||||||
|
|
||||||
|
**A:** PMS多用户支持:
|
||||||
|
|
||||||
|
1. **用户包状态管理**
|
||||||
|
```java
|
||||||
|
// 每个用户有独立的包状态
|
||||||
|
final SparseArray<PackageSetting> mSettingsByUser = new SparseArray<>();
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **用户数据目录**
|
||||||
|
- 主用户:`/data/data/<package_name>/`
|
||||||
|
- 其他用户:`/data/user/<user_id>/<package_name>/`
|
||||||
|
|
||||||
|
3. **用户包安装**
|
||||||
|
```java
|
||||||
|
// 为用户安装包
|
||||||
|
installPackageAsUser(packageName, userId);
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **用户包卸载**
|
||||||
|
```java
|
||||||
|
// 删除用户包
|
||||||
|
removePackageAsUser(packageName, userId);
|
||||||
|
```
|
||||||
|
|
||||||
|
5. **用户权限管理**
|
||||||
|
- 每个用户有独立的权限授予状态
|
||||||
|
- 权限存储在`/data/system/users/<user_id>/runtime-permissions.xml`
|
||||||
|
|
||||||
|
### Q14: 多用户下应用数据如何隔离?
|
||||||
|
|
||||||
|
**A:** 多用户数据隔离机制:
|
||||||
|
|
||||||
|
1. **数据目录隔离**
|
||||||
|
```java
|
||||||
|
// 主用户(user_id = 0)
|
||||||
|
/data/data/<package_name>/
|
||||||
|
|
||||||
|
// 其他用户
|
||||||
|
/data/user/<user_id>/<package_name>/
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **包状态隔离**
|
||||||
|
- 每个用户有独立的PackageSetting
|
||||||
|
- 包启用/禁用状态独立管理
|
||||||
|
|
||||||
|
3. **权限隔离**
|
||||||
|
- 每个用户有独立的权限授予状态
|
||||||
|
- 权限授予不影响其他用户
|
||||||
|
|
||||||
|
4. **组件隔离**
|
||||||
|
- Activity、Service等组件按用户隔离
|
||||||
|
- 不同用户看到不同的应用列表
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 七、组件管理
|
||||||
|
|
||||||
|
### Q15: PMS如何管理Activity组件?
|
||||||
|
|
||||||
|
**A:** PMS管理Activity组件:
|
||||||
|
|
||||||
|
1. **组件注册**
|
||||||
|
```java
|
||||||
|
// 解析AndroidManifest.xml时注册Activity
|
||||||
|
extractActivities(package);
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **组件查询**
|
||||||
|
```java
|
||||||
|
// 查询Activity
|
||||||
|
ResolveInfo resolveInfo = packageManager.resolveActivity(intent, flags);
|
||||||
|
List<ResolveInfo> activities = packageManager.queryIntentActivities(intent, flags);
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **组件信息存储**
|
||||||
|
- Activity信息存储在PackageParser.Package中
|
||||||
|
- Intent Filter信息用于匹配Activity
|
||||||
|
|
||||||
|
4. **组件启用/禁用**
|
||||||
|
```java
|
||||||
|
// 启用/禁用组件
|
||||||
|
packageManager.setComponentEnabledSetting(componentName,
|
||||||
|
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
|
||||||
|
PackageManager.DONT_KILL_APP);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Q16: Intent匹配是如何工作的?
|
||||||
|
|
||||||
|
**A:** Intent匹配机制:
|
||||||
|
|
||||||
|
1. **Intent Filter解析**
|
||||||
|
- PMS解析AndroidManifest.xml中的Intent Filter
|
||||||
|
- 提取action、category、data等信息
|
||||||
|
|
||||||
|
2. **Intent匹配**
|
||||||
|
```java
|
||||||
|
// Intent匹配
|
||||||
|
List<ResolveInfo> resolveInfos = packageManager.queryIntentActivities(intent, flags);
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **匹配规则**
|
||||||
|
- Action匹配:Intent的action必须在Intent Filter中声明
|
||||||
|
- Category匹配:Intent的所有category都必须在Intent Filter中
|
||||||
|
- Data匹配:Intent的data必须匹配Intent Filter的data规则
|
||||||
|
|
||||||
|
4. **匹配优先级**
|
||||||
|
- 精确匹配优先
|
||||||
|
- 系统应用优先
|
||||||
|
- 按优先级排序
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 八、PMS源码分析
|
||||||
|
|
||||||
|
### Q17: PMS的关键类有哪些?
|
||||||
|
|
||||||
|
**A:** PMS的关键类:
|
||||||
|
|
||||||
|
1. **PackageManagerService**
|
||||||
|
- PMS的主类,系统服务的实现
|
||||||
|
- 管理所有包的安装、卸载、更新
|
||||||
|
|
||||||
|
2. **PackageParser**
|
||||||
|
- 解析APK文件
|
||||||
|
- 提取包信息和组件信息
|
||||||
|
|
||||||
|
3. **PackageSettings**
|
||||||
|
- 存储包的安装信息和设置
|
||||||
|
- 管理包的启用/禁用状态
|
||||||
|
|
||||||
|
4. **Installer**
|
||||||
|
- 执行实际的APK安装操作
|
||||||
|
- 管理APK文件的复制和删除
|
||||||
|
|
||||||
|
5. **PackageInstaller**
|
||||||
|
- 应用层使用的安装接口
|
||||||
|
- 管理安装会话
|
||||||
|
|
||||||
|
### Q18: PMS的关键方法有哪些?
|
||||||
|
|
||||||
|
**A:** PMS的关键方法:
|
||||||
|
|
||||||
|
**安装相关:**
|
||||||
|
- `installPackageAsUser()`:安装应用
|
||||||
|
- `installPackageTracedLI()`:执行安装
|
||||||
|
- `scanPackageTracedLI()`:扫描包信息
|
||||||
|
|
||||||
|
**卸载相关:**
|
||||||
|
- `deletePackageAsUser()`:卸载应用
|
||||||
|
- `removePackage()`:移除包
|
||||||
|
|
||||||
|
**权限相关:**
|
||||||
|
- `grantRuntimePermission()`:授予权限
|
||||||
|
- `revokeRuntimePermission()`:撤销权限
|
||||||
|
- `checkPermission()`:检查权限
|
||||||
|
|
||||||
|
**查询相关:**
|
||||||
|
- `getPackageInfo()`:获取包信息
|
||||||
|
- `getApplicationInfo()`:获取应用信息
|
||||||
|
- `queryIntentActivities()`:查询Activity
|
||||||
|
- `resolveActivity()`:解析Activity
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 九、性能优化
|
||||||
|
|
||||||
|
### Q19: 如何优化PMS的启动速度?
|
||||||
|
|
||||||
|
**A:** PMS启动速度优化:
|
||||||
|
|
||||||
|
1. **延迟扫描**
|
||||||
|
- 非关键目录延迟扫描
|
||||||
|
- 优先扫描系统应用
|
||||||
|
- 用户应用可以延迟扫描
|
||||||
|
|
||||||
|
2. **并行扫描**
|
||||||
|
- 使用多线程并行扫描不同目录
|
||||||
|
- 提高扫描速度
|
||||||
|
|
||||||
|
3. **增量扫描**
|
||||||
|
- 只扫描新增或修改的APK
|
||||||
|
- 使用文件时间戳判断
|
||||||
|
|
||||||
|
4. **缓存机制**
|
||||||
|
- 缓存已解析的包信息
|
||||||
|
- 减少重复解析
|
||||||
|
|
||||||
|
5. **优化解析**
|
||||||
|
- 优化PackageParser解析速度
|
||||||
|
- 减少不必要的解析操作
|
||||||
|
|
||||||
|
### Q20: 如何优化应用安装速度?
|
||||||
|
|
||||||
|
**A:** 应用安装速度优化:
|
||||||
|
|
||||||
|
1. **优化APK解析**
|
||||||
|
- 只解析必要的信息
|
||||||
|
- 延迟解析非关键信息
|
||||||
|
|
||||||
|
2. **优化文件操作**
|
||||||
|
- 使用异步IO
|
||||||
|
- 批量操作减少IO次数
|
||||||
|
|
||||||
|
3. **优化签名验证**
|
||||||
|
- 缓存签名信息
|
||||||
|
- 优化签名验证算法
|
||||||
|
|
||||||
|
4. **优化数据库操作**
|
||||||
|
- 批量更新数据库
|
||||||
|
- 使用事务减少数据库操作
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 十、问题排查
|
||||||
|
|
||||||
|
### Q21: 如何排查应用安装失败的问题?
|
||||||
|
|
||||||
|
**A:** 应用安装失败排查:
|
||||||
|
|
||||||
|
1. **查看日志**
|
||||||
|
```bash
|
||||||
|
adb logcat | grep -i "package"
|
||||||
|
adb logcat | grep -i "install"
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **检查包信息**
|
||||||
|
```bash
|
||||||
|
adb shell dumpsys package <package_name>
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **检查安装会话**
|
||||||
|
```bash
|
||||||
|
adb shell dumpsys package sessions
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **常见原因**
|
||||||
|
- 签名验证失败
|
||||||
|
- 存储空间不足
|
||||||
|
- 包名冲突
|
||||||
|
- 版本冲突
|
||||||
|
- 权限不足
|
||||||
|
|
||||||
|
### Q22: 如何排查权限问题?
|
||||||
|
|
||||||
|
**A:** 权限问题排查:
|
||||||
|
|
||||||
|
1. **查看权限状态**
|
||||||
|
```bash
|
||||||
|
adb shell dumpsys package permissions
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **查看应用权限**
|
||||||
|
```bash
|
||||||
|
adb shell dumpsys package <package_name> | grep -i permission
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **检查权限授予状态**
|
||||||
|
```java
|
||||||
|
int result = packageManager.checkPermission(permission, packageName);
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **常见问题**
|
||||||
|
- 权限未声明
|
||||||
|
- 权限未授予
|
||||||
|
- 权限被撤销
|
||||||
|
- 权限保护级别不匹配
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 十一、高级问题
|
||||||
|
|
||||||
|
### Q23: 静默安装是如何实现的?
|
||||||
|
|
||||||
|
**A:** 静默安装实现:
|
||||||
|
|
||||||
|
1. **系统权限要求**
|
||||||
|
- 需要系统签名
|
||||||
|
- 需要INSTALL_PACKAGES权限
|
||||||
|
|
||||||
|
2. **使用PackageInstaller**
|
||||||
|
```java
|
||||||
|
PackageInstaller.Session session = packageInstaller.openSession(sessionId);
|
||||||
|
session.write("app.apk", 0, -1, inputStream);
|
||||||
|
session.commit(createIntentSender());
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **直接调用PMS**
|
||||||
|
```java
|
||||||
|
// 需要系统权限
|
||||||
|
IPackageManager pm = ActivityManager.getService().getPackageManager();
|
||||||
|
pm.installPackageAsUser(packageUri, observer, flags, installerPackageName, userId);
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **注意事项**
|
||||||
|
- 静默安装需要系统权限
|
||||||
|
- 普通应用无法实现静默安装
|
||||||
|
- 需要用户授权或系统签名
|
||||||
|
|
||||||
|
### Q24: 应用更新安装的流程?
|
||||||
|
|
||||||
|
**A:** 应用更新安装流程:
|
||||||
|
|
||||||
|
1. **版本检查**
|
||||||
|
- 检查新版本号是否大于旧版本
|
||||||
|
- 检查签名是否匹配
|
||||||
|
|
||||||
|
2. **停止旧应用**
|
||||||
|
- 停止所有Activity
|
||||||
|
- 停止所有Service
|
||||||
|
- 取消注册BroadcastReceiver
|
||||||
|
|
||||||
|
3. **备份数据**
|
||||||
|
- 备份应用数据
|
||||||
|
- 备份SharedPreferences
|
||||||
|
|
||||||
|
4. **安装新版本**
|
||||||
|
- 安装新APK
|
||||||
|
- 保留应用数据
|
||||||
|
|
||||||
|
5. **恢复数据**
|
||||||
|
- 恢复应用数据
|
||||||
|
- 恢复SharedPreferences
|
||||||
|
|
||||||
|
6. **启动新版本**
|
||||||
|
- 注册新组件
|
||||||
|
- 发送更新广播
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 总结
|
||||||
|
|
||||||
|
PMS是Android系统的核心服务,负责管理应用的安装、卸载、权限管理等。
|
||||||
|
|
||||||
|
**关键知识点:**
|
||||||
|
1. PMS的职责和架构
|
||||||
|
2. 应用安装流程(APK解析、签名验证、安装执行)
|
||||||
|
3. 应用卸载流程(停止应用、删除文件、清理数据)
|
||||||
|
4. 权限管理机制(权限声明、授予、检查、撤销)
|
||||||
|
5. 包扫描机制(系统目录扫描、用户目录扫描)
|
||||||
|
6. 多用户支持(数据隔离、权限隔离)
|
||||||
|
7. 组件管理(Activity、Service等组件注册和查询)
|
||||||
|
8. PMS源码关键类和方法
|
||||||
|
9. 性能优化和问题排查
|
||||||
|
|
||||||
|
**面试重点:**
|
||||||
|
- 深入理解应用安装流程
|
||||||
|
- 掌握APK解析和签名验证机制
|
||||||
|
- 了解权限管理原理
|
||||||
|
- 能够分析安装失败问题
|
||||||
|
- 了解多用户支持机制
|
||||||
@@ -211,6 +211,7 @@ nav:
|
|||||||
- android面试/技术面试问题回答.md
|
- android面试/技术面试问题回答.md
|
||||||
- android面试/系统原理/AMS面试.md
|
- android面试/系统原理/AMS面试.md
|
||||||
- android面试/系统原理/WMS面试.md
|
- android面试/系统原理/WMS面试.md
|
||||||
|
- android面试/系统原理/DPMS常见面试题.md
|
||||||
- android面试/README.md
|
- android面试/README.md
|
||||||
- android面试/基础知识/Android基础.md
|
- android面试/基础知识/Android基础.md
|
||||||
- android面试/基础知识/Android版本特性.md
|
- android面试/基础知识/Android版本特性.md
|
||||||
@@ -290,7 +291,7 @@ nav:
|
|||||||
- android面试/项目经验/技术选型.md
|
- android面试/项目经验/技术选型.md
|
||||||
- android面试/项目经验/问题排查经验.md
|
- android面试/项目经验/问题排查经验.md
|
||||||
- android面试/项目经验/项目架构设计.md
|
- android面试/项目经验/项目架构设计.md
|
||||||
- android面试/系统原理/DPMS常见面试题.md
|
- android面试/系统原理/PMS常见面试题.md
|
||||||
- Google开发文档体系:
|
- Google开发文档体系:
|
||||||
- Google开发文档体系/API参考/Android_API概览.md
|
- Google开发文档体系/API参考/Android_API概览.md
|
||||||
- Google开发文档体系/API参考/Jetpack_API.md
|
- Google开发文档体系/API参考/Jetpack_API.md
|
||||||
|
|||||||
Reference in New Issue
Block a user