安卓系统Framework面经(5/20)PMS深入浅出
牛客高级系列专栏:
安卓(安卓系统开发也要掌握)
- 想通关安卓面试,请看:《150道安卓高频面试题目录及答案链接》
- 想通关安卓系统面试,请看:《140道安卓系统Framework面试题目录及答案链接》
- 想进阶安卓开发,请看:《Android进阶知识体系解析_15大安卓进阶必备知识点》
- 想了解安卓APP完整开发流程,请看:《安卓APP完整开发流程》
- 想掌握安卓App性能优化,请看:《安卓性能优化讲解和实战专栏》
- 想掌握Gradle语法,制作Gradle插件,请看:《安卓Gradle语法解析和实践大全》
嵌入式
- 想通关嵌入式面试,请看: 《111道嵌入式面试题目录及答案链接》
- 想多掌握几个嵌入式项目,请看:《6个嵌入式项目交流分享(附源码)》
- 本人是2020年毕业于广东工业大学研究生:许乔丹,有国内大厂CVTE和世界500强企业安卓开发经验,该专栏整理本人从嵌入式Linux转Android系统开发过程中对常见安卓系统开发面试题的理解;
- 1份外卖价格助您提高安卓面试准备效率,为您面试保驾护航!!
正文开始⬇
面试题预览
1.简述PMS是什么?有什么作用?⭐⭐⭐⭐⭐
2.分别就应用接口层、Framework层、HAL层、内核层介绍下Android电源管理系统?⭐⭐⭐
3.PMS的作用是什么?PMS跟咱们的安装速度和启动速度有关系吗?⭐⭐⭐⭐
4.PMS被谁启动的,它是一个单独进程运行吗?如果不是,又是在哪个进程呢?⭐⭐⭐
5.PMS的启动过程是怎么样的?⭐⭐⭐
6.应用要怎么样才能调用PowerManager进行系统休眠或者唤醒呢?⭐⭐⭐⭐⭐
1 PMS简介
作为Android开发者,或多或少的都接触过Android的framework层架构,这也是开发者从使用Android到了解安卓的过程,framework层的核心功能有AMS、PMS、WMS等,这三个也是系统中最基础的使用,在Android程序启动完成后回启动一系列的核心服务,AMS、PMS、WMS就是在此过程中启动的。
2 PMS主要功能
1)管理设备上安装的所有应用程序,并在系统启动时加载应用程序;
2)根据请求的Intent匹配到对应的Activity、Provider、Service,提供包含包名和Component的信息对象;
3)调用需要权限的系统函数时,检查程序是否具备相应权限从而保证系统安全;
4)提供应用程序的安装、卸载的接口;
PMS跟咱们的安装速度和启动速度有关,PMS会遍历/data/app安装目录,app安装越多,执行的效率就越低,时间就耗的越长
3 PMS包管理
1)应用程序层:使用getPackageManager()获取包的管理对象PackageManager,PMS使用的也是Binder通信,PackageManager是从ServiceManager中获取注册的Binder对象,具体的实现为PackageManagerService,PMS实现对所有程序的安装和加载
2)PMS服务层:PMS运行在SystemServer进程中,主要使用/system/etc/permissions.xml和/data/system/packages.xml管理包信息;
3)数据文件管理:PMS负责对系统的配置文件、apk安装文件、apk的数据文件执行管理、读写、创建和删除等功能;
a.程序文件:所有系统程序的文件处于/system/app/目录下,第三方程序文件处于 /data/app/目录下,在程序安装过程中PMS会将要安装的apk文件复制到/data/app/目录下,以包名命名apk文件并添加“-x”后缀,在文件更新时会修改后缀编号
b./data/dalvik-cache/ 目录保存了程序中的执行代码,在应用程序运行前PMS会从apk中提取dex文件并保存在该目录下,以便之后能快速运行;
c.对framework库文件,PMS会将其中所有的apk、jar文件中提取dex文件,将dex文件保存在/data/dalvik-cache/目录下;
d.应用程序所使用的数据文件:数据以键值对保存、数据库保存、File保存所产生的文件都保存带/data/data/xxx/目录下,PMS在程序卸载会删除相应文件;
●/data/system/packages.xml :系统的配置文件,记录所有的应用程序的包管理信息,PMS根据此文件管理所有程序
- last-platform-version:记录系统最后一次修改的版本信息;
- permissions:保存系统中所有的权限信息列表,系统权限以androd开头、自定义权限以包名开头;
- sigs:签名标签,一个程序只能有一个签名但可以有多个证书,包含count属性表示证书数量;
- cert:表示签名证书,包含index、key属性,index表示证书的下标;
- perms:表示一个程序中声明使用的权限列表,存在package标签之下;
- package:包含一个应用程序的对应关系:
(1)name:应用程序的包名
(2)codePath:程序apk文件所在的路径
(3)nativeLibraryPath:程序中使用的native文件路径,一般指程序包下的lib文件中导入的依赖
(4)flags:表示应用程序的类型
(5)it、ut:分别表示程序首次安装的install time、更新时间update time
(6)userId:表示应用程序在Linux下的用户id
(7)shareId:表示应用程序所共享的Linux用户Id,与userId互斥
(8)installer:安装器的名称,在调用PackageManager.installPackage()方法时设置的名称
4 PMS的启动过程
在Android系统启动过程中,程序会执行到SystemServer中,然后调用startBootstrapServices()方法启动核心服务。在startBootstrapServices()方法中完成PMS的启动:
4.1 startBootstrapServices
private void startBootstrapServices() {
mPackageManagerService = PackageManagerService.main(mSystemContext,
installer,mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore); // 1、调用
main()创建PMS对象,注册Binder
mPackageManager = mSystemContext.getPackageManager(); //2、初始化PackageManager对象
}
}
- 调用PackageManagerService.main()方法,在main()方法中创建PMS的对象,并向ServiceManager注册Binder:
public static PackageManagerService main(Context context, Installer installer,
boolean factoryTest, boolean onlyCore) {
// 1、创建PMS对象
PackageManagerService m = new PackageManagerService(context,
installer,factoryTest, onlyCore);
m.enableSystemUserPackages();
ServiceManager.addService("package", m); // 2、注册PMS对象到ServiceManager中
final PackageManagerNative pmn = m.new PackageManagerNative(); // 3、 创建
PMN对象
ServiceManager.addService("package_native", pmn); // 4、注册PMN对象
return m;
}
调用ContextImpl.getPackageManager()获取PackageManager对象,getPackageManager()中使用ActivityThread.getPackageManager()获取前面创建并注册的 Binder对象,然后创建ApplicationPackageManager实例:
@Override
public PackageManager getPackageManager() {
IPackageManager pm = ActivityThread.getPackageManager(); // 3、初始化
PackageManagerService的代理Binder对象
if (pm != null) {
return (mPackageManager = new ApplicationPackageManager(this, pm)); //创建
Packagemanager的实例
}
return null;
}
程序在获取PMS对象时会调用ActivityThread.getPackageManager(),从ServiceManager中获取Binder,并获取BInder代理对象PMS实例
public static IPackageManager getPackageManager() {
if (sPackageManager != null) {
return sPackageManager;
} I
Binder b = ServiceManager.getService("package”); // 获取注册Binder
sPackageManager = IPackageManager.Stub.asInterface(b); // 获取IPackageManager代
理对象,即PMS
return sPackageManager;
}
从上面的3个过程可以得出以下结论:
- PMS使用Binder通信机制,最终IPackageManager接口的实现类为PackageManagerService类;
- 系统中获取的PackageManager对象具体实现的子类是ApplicationPackageManager对象;
4.2 系统准备工作
在PowerManagerService创建之后会调用systemReady做一些初始化相关的操作,获取与PowerManager相关的本地服务:
public void systemReady(IAppOpsService appOps) {
synchronized (mLock) {
//第一步:初始化相关的变量
mSystemReady = true;
mAppOps = appOps;
mDreamManager = getLocalService(DreamManagerInternal.class);
//初始化互动屏保管理
mDisplayManagerInternal = getLocalService(DisplayManagerInternal.class);
//初始化屏幕显示管理服务
mPolicy = getLocalService(WindowManagerPolicy.class);
mBatteryManagerInternal = getLocalService(BatteryManagerInternal.class);
//初始化电池管理服务
PowerManager pm = (PowerManager)
mContext.getSystemService(Context.POWER_SERVICE);
mScreenBrightnessSettingMinimum = pm.getMinimumScreenBrightnessSetting();
mScreenBrightnessSettingMaximum = pm.getMaximumScreenBrightnessSetting();
mScreenBrightnessSettingDefault = pm.getDefaultScreenBrightnessSetting();
//获取屏幕的亮度值,最大亮度,最小亮度,默认亮度
SensorManager sensorManager = new SystemSensorManager
(mContext, mHandler.getLooper());
//获取传感器管理服务
mBatteryStats = BatteryStatsService.getService();
//初始化电量统计服务
mNotifier = new Notifier(
Looper.getMainLooper(),
mBatteryStats,mAppOps,
createSuspendBlockerLocked("PowerManagerService.Broadcasts"),
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
2020年研究生毕业后,工作重心由嵌入式Linux转为安卓系统,Android发展已经很多年,网上面向中初级Android系统开发的面经还比较少,也不够集中,因此梳理出本专栏,本专栏收集了本人工作中持续积累的众多安卓系统知识,持续更新中。