鏇存柊鏂囨。
This commit is contained in:
2
.obsidian/workspace.json
vendored
2
.obsidian/workspace.json
vendored
@@ -200,6 +200,7 @@
|
||||
},
|
||||
"active": "25c9f7051aac05b3",
|
||||
"lastOpenFiles": [
|
||||
"docs/android面试/系统原理/PMS常见面试题.md",
|
||||
"docs/android面试/系统原理/DPMS常见面试题.md",
|
||||
"docs/android面试/系统原理/DPMS常见面试题",
|
||||
"docs/DPMS常见面试题",
|
||||
@@ -229,7 +230,6 @@
|
||||
"docs/Google开发文档体系/核心主题/后台任务.md",
|
||||
"docs/Google开发文档体系/核心主题/Material_Design.md",
|
||||
"docs/Google开发文档体系/核心主题/Jetpack组件.md",
|
||||
"docs/Google开发文档体系/示例代码/架构示例.md",
|
||||
"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面试/系统原理/AMS面试.md
|
||||
- android面试/系统原理/WMS面试.md
|
||||
- android面试/系统原理/DPMS常见面试题.md
|
||||
- android面试/README.md
|
||||
- android面试/基础知识/Android基础.md
|
||||
- android面试/基础知识/Android版本特性.md
|
||||
@@ -290,7 +291,7 @@ nav:
|
||||
- android面试/项目经验/技术选型.md
|
||||
- android面试/项目经验/问题排查经验.md
|
||||
- android面试/项目经验/项目架构设计.md
|
||||
- android面试/系统原理/DPMS常见面试题.md
|
||||
- android面试/系统原理/PMS常见面试题.md
|
||||
- Google开发文档体系:
|
||||
- Google开发文档体系/API参考/Android_API概览.md
|
||||
- Google开发文档体系/API参考/Jetpack_API.md
|
||||
|
||||
Reference in New Issue
Block a user