参考学习视频:framwork面试集合,大厂老司机带你扫清framework难点
目录
- 一、zygote相关知识点
- 二、PMS相关知识点
- 1.PMS服务是干什么?PMS跟咱们的安装速度和启动速度有关系吗?
- 2.为什么需要PMS
- 3.PMS被谁启动的,它是一个单独进程运行吗?如果不是,又是在哪个进程呢?
- 4.PMS扫描是为了什么,为什么PMS需要这样设计呢?
- 5. PackageManagerService类图关系?
- 6. android 安装APK的原理是?
- 7. Launcher3 应用是怎么展示的?
- 8. 安卓手机开机很慢,大概是什么原因?
- 9. PackageManagerService 是什么?
- 10. AActivity 调转到BActivity {LaunchMode},请问launchMode是什么时候解析的?
- 11. 手机开机后,为什么能够收到开机广播?
- 12. 权限申请源码流程总结:
- 三、AMS相关知识点
- 四、Binder相关知识点
- 五、WMS相关知识点
- 六、Activity与Window相关概念
一、zygote相关知识点
1. zygote是谁启动的?
答: init.rc
2.为什么需要zygote?
答:如果没有zygote,app要开启一个进程,会调用系统api帮我们来开启,app自己去fork开启,结果app开发者不遵循对应规范,假如一个app本身内存空间是50M,通过fork()函数开启系统的api,让内存可以达到500M,这样就会出问题。
zygote进程就是对开进程进行了一个管理,开进程是一个危险操作,开启一个进程需要耗费很大资源和cpu
3. 为什么需要socket方式而不是binder?
答:google工程师为了反防止app hook zygote对应开启进程的api,导致开启进程开不了。
1)安全方面(binder通讯是非常hook的)
2)站在设计角度(C/S模型)
本质原因是,在fork过程中如果采用binder,binder是并发的,binder并发过程中会有这个对象锁,那么对象锁正在锁的过程中如果fork的话,那这个对象锁是没有办法解锁的,在fork产生的新进程里面,这个进程就会出现对象处于一个锁的状态,而且没有人去给它解锁,所以这种情况下就会出现对象死锁状态
4.从launcher是如何通知zygote进程创建app的过程?
答:

启动流程:
① 点击桌面App图标,Launcher进程采用Binder IPC向system_server进程发起startActivity请求;
② system_server进程接收到请求后,向zygote进程发送创建进程的请求;
③ Zygote进程fork出新的子进程,即App进程;
④ App进程,通过Binder IPC向system_server进程发起attachApplication请求;
⑤ system_server进程在收到请求后,进行一系列准备工作后,再通过Binder IPC向App进程发送scheduleLauncherActivity请求;
⑥ App进程的binder线程(ApplicationThread)在收到请求后,通过handler向主线程发送LAUNCH_ACTIVITY消息;
⑦ 主线程在收到Message后,通过反射机制创建目标Activity,并回调Activity.onCreate等方法;
⑧ 到此,App便正式启动,开始进入Activity生命周期,执行完onCreate/onStart/onResume方法,UI渲染结束后便可以看到App的主界面。


二、PMS相关知识点
1.PMS服务是干什么?PMS跟咱们的安装速度和启动速度有关系吗?
PMS:PackageManagerService
安装apk、管理apk、提前加载Activity。
PMS跟咱们的安装速度和启动速度有关,PMS会遍历/data/app安装目录,app安装越多,执行的效率就越低,时间就耗的越长
2.为什么需要PMS
答:1)每次开启一个App,需要遍历/data/app目录,通过包名可以定位到跳转的app;
2)IO操作获取AndroidManifest.xml;
3) dom解析遍历AndroidManifest.xml,找到intent-filter里面的属性为" category android:name=“android.intent.category.LAUNCHER” " 入口Activity;
4)加载入口Activity。
3.PMS被谁启动的,它是一个单独进程运行吗?如果不是,又是在哪个进程呢?
答:是由system_server进程启动,它不是单独进程,是由SystemServer调用PMS的main()方法启动。
system_server的父进程是zygote,,PMS和AMS是运行在system_server进程中。
SystemServer.java
public static void main(String[] args) {
new SystemServer().run();
}
SystemServer.java
private void run() {
... ...
// Start services.
try {
traceBeginAndSlog("StartServices");
startBootstrapServices();
startCoreServices();
startOtherServices();
SystemServerInitThreadPool.shutdown();
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
} finally {
traceEnd();
}
... ...
}
SystemServer.java
/**
* Starts the small tangle of critical services that are needed to get the system off the
* ground. These services have complex mutual dependencies which is why we initialize them all
* in one place here. Unless your service is also entwined in these dependencies, it should be
* initialized in one of the other functions.
*/
private void startBootstrapServices() {
... ...
ActivityTaskManagerService atm = mSystemServiceManager.startService(
ActivityTaskManagerService.Lifecycle.class).getService();
mActivityManagerService = ActivityManagerService.Lifecycle.startService(
mSystemServiceManager, atm);
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);
... ...
try {
Watchdog.getInstance().pauseWatchingCurrentThread("packagemanagermain");
mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
} finally {
Watchdog.getInstance().resumeWatchingCurrentThread("packagemanagermain");
}
... ...
}
SystemServiceManager.java
/**
* Creates and starts a system service. The class must be a subclass of
* {@link com.android.server.SystemService}.
*
* @param serviceClass A Java class that implements the SystemService interface.
* @return The service instance, never null.
* @throws RuntimeException if the service fails to start.
*/
@SuppressWarnings("unchecked")
public <T extends SystemService> T startService(Class<T> serviceClass) {
try {
final String name = serviceClass.getName();
Slog.i(TAG, "Starting " + name);
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartService " + name);
// Create the service.
if (!SystemService.class.isAssignableFrom(serviceClass)) {
throw new RuntimeException("Failed to create " + name
+ ": service must extend " + SystemService.class.getName());
}
final T service;
try {
// 通过反射的方式去构建一个对象,并加这个对象返回,并startService
Constructor<T> constructor = serviceClass.getConstructor(Context.class);
service = constructor.newInstance(mContext);
} catch (InstantiationException ex) {
throw new RuntimeException("Failed to create service " + name
+ ": service could not be instantiated", ex);
} catch (IllegalAccessException ex) {
throw new RuntimeException("Failed to create service " + name
+ ": service must have a public constructor with a Context argument", ex);
} catch (NoSuchMethodException ex) {
throw new RuntimeException("Failed to create service " + name
+ ": service must have a public constructor with a Context argument", ex);
} catch (InvocationTargetException ex) {
throw new RuntimeException("Failed to create service " + name
+ ": service constructor threw an exception", ex);
}
startService(service);
return service;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
}
通过反射的方式去构建一个service对象,并将这个对象返回,并通过startService开启了这个service,因此说AMS与SystemServer在同一个进程中。
PackageManagerService.java
public static PackageManagerService main(Context context, Installer installer,
boolean factoryTest, boolean onlyCore) {
// Self-check for initial settings.
PackageManagerServiceCompilerMapping.checkProperties();
PackageManagerService m = new PackageManagerService(context, installer,
factoryTest, onlyCore);
m.enableSystemUserPackages();
ServiceManager.addService("package", m);
final PackageManagerNative pmn = m.new PackageManagerNative();
ServiceManager.addService("package_native", pmn);
return m;
}
只是调用了一个普通的main()方法。
4.PMS扫描是为了什么,为什么PMS需要这样设计呢?
答:PMS扫描只是将每个apk文件进行解析,解析里面的AndroidManifest文件,解析该文件会生成一个javabean。javabean中包含了AndroidManifest中所有的标签属性字段
PackageParser.java
@UnsupportedAppUsage
public final ArrayList<Permission> permissions = new ArrayList<Permission>(0);
@UnsupportedAppUsage
public final ArrayList<PermissionGroup> permissionGroups = new ArrayList<PermissionGroup>(0);
//其中这个Activity是指一个内部类,只是一个javabean。public final static class Activity extends Component<ActivityIntentInfo> implements Parcelable
@UnsupportedAppUsage
public final ArrayList<Activity> activities = new ArrayList<Activity>(0);
@UnsupportedAppUsage
public final ArrayList<Activity> receivers = new ArrayList<Activity>(0);
@UnsupportedAppUsage
public final ArrayList<Provider> providers = new ArrayList<Provider>(0);
@UnsupportedAppUsage
public final ArrayList<Service> services = new ArrayList<Service>(0);
@UnsupportedAppUsage
public final ArrayList<Instrumentation> instrumentation = new ArrayList<Instrumentation>(0);
@UnsupportedAppUsage
public final ArrayList<String> requestedPermissions = new ArrayList<String>();
5. PackageManagerService类图关系?


其中,PackageManagerService相当于binder机制的服务端,PackageManager是抽象类,具体实现类为ApplicationPackageManager,ApplicationPackageManager相当于binder机制的客户端;两者通过IPackageManager.Stub进行跨进程通信。
\frameworks\frameworks\base\core\java\android\content\pm\IPackageManager.aidl
6. android 安装APK的原理是?
答:第一步:Copy apk到指定目录, 第二步:扫描指定目录的apk
adb push ***.apk data/app/ --> 第一步:Copy apk 到指定目录
adb reboot 重启手机(重启会扫描所有的apk,包含系统应用和普通应用)--> 第二步:扫描指定目录的apk
7. Launcher3 应用是怎么展示的?
答:Launcher3应用是系统应用,在packages/apps/Launcher3目录下,向PKMS跨进程通信(因为应用级别进程必须跨到服务级别进程向pkms查询所所有的服务),访问读取 PKMS 查询而来
8. 安卓手机开机很慢,大概是什么原因?
答:七步曲:(startBootStrapServices 引导服务包含前四步,startOtherServices其他服务包含后面三步)
一步曲:启动Install服务
二步曲:获取设备是否加密
三步曲:调用PKMS.main 实例化PKMS构造
四步曲:设置加密的操作
五步曲:dex优化操作
六步曲:磁盘优化维护操作
七步曲:PKMS准备就绪
其中,第三步调用PKMS.main 实例化PKMS构造和第五步dex优化操作尤为耗时
PKMS构造函数包含五个阶段:
阶段一:开始阶段
阶段二:系统扫描阶段(扫描系统应用)
阶段三:Data扫描阶段(扫描普通应用)
阶段四:扫描结束阶段
阶段五:就绪阶段
PKMS Data扫描阶段流程:
1)PKMS.scanDirTracedLI
2)PKMS.scanDirLI
3)ParallelPackageParser.submit
4)PackageParser2.parsePackage
5)ParsingPackageUtils.parsePackage
6)parseClusterPackage(目录解析)
7)parseMonolithicPackage(APK文件解析)
8)parseBaseApk
9)parseBaseApkTags
10)parseBaseApplication
11)PKMS.addForInitLI
android 11.0版本 所有的清单文件、四大组件保存到ParsingPackage类中
Android 10.0版本 所有的清单文件、四大组件保存到Package类中
保存到ParsingPackage类的作用是每次跳转Activity,或者Launched3打开应用,直接向内存中的ParsingPackage类获取
9. PackageManagerService 是什么?
答:PKMS是安卓系统的核心服务之一,负责应用信息查询、安装、卸载等
10. AActivity 调转到BActivity {LaunchMode},请问launchMode是什么时候解析的?
答:手机开机的时候, PKMS 构造函数 第三阶段 就已经扫描给PKMS解析到内存中
11. 手机开机后,为什么能够收到开机广播?
答:因为手机开机时,PKMS构造函数 第三阶段(Data扫描阶段) 已经全部扫描了,所有APK清单文件,进行了静态广播注册了
12. 权限申请源码流程总结:
第一步:MainActivity调用requestPermissions进行动态权限申请;
第二步:requestPermissions函数通过隐式意图,激活PackageInstaller的GrantPermissionsActivity界面,让用户选择是否授权;
第三步:经过PKMS把相关信息传递给PermissionManagerService处理;
第四步:PermissionManagerService处理结束后回调给–>PKMS中的onPermissionGranted方法把处理结果返回;
第五步:PKMS通知过程中权限变化,并调用writeRuntimePermissionsForUserLPr函数让PackageManager的settings记录下相关授权信息。
应用申请的权限放到的目录文件:
data/system/users/0/runtime-permissions.xml
PermissionManagerService.java --> 负责权限管理
三、AMS相关知识点
1.AMS与PMS之间的关系是什么,他们在同一个进程吗?
答:PMS用于包的管理,AMS用于生命周期的管理;两者相辅相成,PMS在前,AMS在后,只有PMS进行先管理、缓存、扫描,之后才会进入AMS的生命周期管理。
AMS与PMS在同一个进程system_server中。
2.系统是如何存AMS服务对象的,以及应用层如何拿到AMS应用的?
答:ActivityThread类中有个mActivities变量用于缓存开启的activity。
ActivityThread.java
final ArrayMap<IBinder, ActivityClientRecord> mActivities = new ArrayMap<>();
SystemServiceManager.java
private final ArrayList<SystemService> mServices = new ArrayList<SystemService>();
应用层通过ServiceManager.getService(Context.ACTIVITY_SERVICE); 来获取AMS中相关服务
3.AMS与servicemanage进程是什么关系,app启动流程讲一讲
答:sevicemanage用来管理AMS,AMS是serviceManage进程所持有。但是AMS属于system_server进程的,systemSever只是用来开启服务。
SystemServiceManager:管理服务的生命周期
ServiceManager:管理binder服务的,handle = 0
SystemServer:是一个进程,包含90+多个服务,管理SystemService,SystemService代表是系统服务
4.AMS与ActivityThread之间是什么关系,它的交互机制详细说一下。
答:ActivityThread作为AMS的缓存对象,把曾经启动的activity缓存到ActivityThread类中的mActivities 集合中
四、Binder相关知识点
可参考:Binder相关面试题目
1.Android是基于Linux系统展开的,为什么Android不直接用Linux的进程通讯,而是要重复造轮子呢?
答:linux现有进程间通讯:管道、信号量(用的比较少)、socket、File(文件存储)、共享内存。
从性能角度来看:共享内存 > binder > 管道 > socket > File
整个android架构是基于C/S架构,zygote是C/S架构,socket也是C/S架构。binder是C/S架构
Binder与传统IPC对比
| Binder | 共享内存 | Socket | |
|---|---|---|---|
| 性能 | 需要拷贝一次 | 无需拷贝 | 需要拷贝两次 |
| 特点 | 基于C/S架构,易用性高 | 控制复杂,易用性差 | 基于C/S架构,作为一款通用接口,其传输效率低,开销大 |
| 安全性 | 为每个APP分配UID,同时支持实名和匿名 | 依赖上层协议,访问接入点是开放的,不安全 | 依赖上层协议,访问接入点是开放的,不安全 |
2.Intent传递参数最大是多少?在哪里限制了这个参数呢,异步呢?
限制大小: 1M - 8K
实际传递过程中比(1M - 8K)还要小些,数据还需要打包
就好像网络通信过程中数据会有包头、命令等
ProcessState.cpp
ProcessState.cpp

如果在异步情况下,限制大小: (1M - 8K)/ 2
binder.c
proc->free_async_space = proc->buffer_size / 2;
native层,什么类代表binder? --> BBinder、JavaBBinder
java层,什么类代表binder?–> Binder
什么数据结构代表binder? --> binder_node结构体
3.Binder一次拷贝原理是什么?
答:Linux通过将一个虚拟内存区域与一个磁盘上的对象关联起来,以初始化这个虚拟内存区域的内容,这个过程称为内存映射(memory mapping, mmap)。
通过mmap机制进行一次拷贝。
一次拷贝发生在客户端
建立映射发生在服务端与binder驱动所在内存之间,映射内存区域大小为1M - 8K
binder驱动主要功能就是维护一个进程信息的链表(双向)。
4.Binder通讯机制简单说一说?
由于发送方进程1和接收方进程2不能直接进行通信,由于内核空间是共享的,发送方通过copy_from_user()把数据直接拷贝到内核空间,因为内核空间与接收方的用户空间同时映射到一块物理内存中,所以说数据通过copy_from_user()拷贝到内核地址空间指定的虚拟内存后,相对于直接进入了接收方的用户空间,所以整个通信过程只进行了一次内存拷贝,这个映射就是通过mmap实现的。
五、WMS相关知识点
WMS的职责:
-
窗口管理
WMS 是窗口的管理者,它负责窗口的启动、添加和删除。另外窗口的大小和层级也是由 WMS 进行管理的。 -
窗口动画
窗口间进行切换时,使用动画可以显得更炫一些,窗口动画由 WMS 的动画子系统来负责,动画子系统的管理者为 WindowAnimator。 -
输入系统中转站
通过对窗口的触摸从而产生触摸事件,InputManagerService(IMS) 会对触摸事件进行处理,它会寻找一个最合适的窗口来处理触摸反馈信息,WMS 是窗口的管理者,它作为输入系统的中转站再合适不过了。 -
Surface 管理
窗口不具备绘制功能,因此每个窗口都需要有一块 Surface 来供自己绘制,为每个窗口分配 Surface 是由WMS 来完成的。
1. 什么是SurfaceView
答:SurfaceView是一个控件,它单独拥有一个画布surface
一个window(window包含多个view)拥有一个surface
应用的场景:图像、摄影、自拍、一些游戏中
SurfaceView是View的子类,它是一个专门用于做频繁绘制的View子类,它的绘制操作是在子线程中执行,所以频繁绘制不会阻塞线程,使用它去做一些需要频繁绘制和长时间绘制效果会高很多。
SurfaceView两个特性:
- 子线程绘制
- SurfaceView 是在一个新起的单独线程中可以重新绘制画面,而View必须在UI的主线程中更新画面。那么在UI的主线程中更新画面,可能会引发问题,比如你更新画面的时间过长,那么你的主UI线程会被你正在画的函数阻塞。
- 但这也带来了另外一个问题,就是事件同步。比如你触屏了一下,你需要surfaceView中thread 处理,一般就需要有一个event queue 的设计来保存touch event,这涉及到线程同步
- 双缓冲模式
- 通俗来讲就是两个缓冲区,一个后台缓冲区和一个前台缓冲区,每次后台缓冲区接受数据,当填充完整后交换给前台缓冲,这样就保证了前台缓冲里的数据都是完整的
- 在后台线程执行繁重的绘图任务,把所有绘制的东西缓存起来,绘制完毕后,再回到UI线程,一次性把所绘制的东西渲染到屏幕上(本质:就是后台线程绘制,UI主线程渲染)
2. View和SurfaceView的区别?
答:相同点:都是控件
不同点:
View放置到window中,没有单独的surface;多个view放到一个window下,一个window拥有一个surface。自定义view只能在主线程中更新UI;帧数是60Hz每秒
SurfaceView:
①单独有一个surface;
②可以在任何线程中更新UI,性能效率更高;
③帧数可以进行控制, 帧动画可以放到SurfaceView中执行;
④SurfaceView是放置在底层,可以在其上面放置一层,但是不能是透明的;
⑤SurfaceView定义和使用比View会复杂些,占用的资源也会多些,因为它单独控制着一个surface
3. App应用程序如何与SurfaceFling通信的,View的绘制是如何把数据传递给SurfaceFling的?
答:

App应用程序如何与SurfaceFling通信的?
surface会持有BufferQueueLayer中Producer客户端的引用,这样surface才能与BufferQueueLayer中的生产者进行通信。
如何把数据传递给SurfaceFling的?
先将数据给到BufferQueueLayer图层里面的Producer生产者,对数据进行一个queue入队操作,入队完了之后,消费者Consumer进行dequeue出队操作进行一个读取。
4. relayout是如何向SurfaceFlinger申请Surface

六、Activity与Window相关概念
- Activity只负责生命周期和事件处理
- Window只控制视图
- 一个Activity包含一个Window,如果Activity没有Window,那就相当于Service
- AMS统一调度所有应用程序的Activity
- WMS控制所有Window的显示与隐藏以及要显示的位置
1. Window
"Window"表面它是和窗口相关的,“窗口”是一个抽象的概念,从用户的角度来讲,它是一个“界面”;从SurfaceFlinger的角度来看,它是一个Layer,承载着和界面相关的数据和属性;从WMS角度来看,它是一个WindowState,用于管理和界面相关的状态。
- 表示一个窗口的概念,是所有View的直接管理者,任何视图都通过Window呈现(点击事件由Window -> DecorView -> View; Activity的setContentView底层通过Window完成)
- Window是一个抽象类,具体实现是PhoneWindow
- 创建Window需要通过WindowManager创建
- WindowManager是外界访问Window的入口
- Window具体实现位于WindowManagerService中
- WindowManager和WindowManagerService的交互是通过IPC完成
- 定义窗口样式和行为的抽象基类,用于作为顶层的View加到WindowManager中,其实现类是PhoneWindow
- 每个Window都需要指定一个Type(应用窗口、子窗口、系统窗口),Activity对应的窗口是应用窗口;PopupWindow,ContextMenu,OptionMenu是常用的子窗口;像Toast和系统警告提示框(如ANR)就是系统窗口,还有很多应用的悬浮框也属于系统窗口类型。
2. WindowManager
用来在应用与Window之间的管理接口,管理窗口顺序,消息等。
3. WindowManagerService
简称WMS,WindowManagerService管理窗口的创建、更新和删除,显示顺序等,是WindowManager这个管理接口的真正实现类。它运行在System_server进行,作为服务端,客户端(应用程序)通过IPC调用和它进行交互。
4. Token
指窗口令牌(Window Token),是一种特殊的Binder令牌,WMS用它唯一标识系统中的一个窗口。
5.Window的type
- 应用窗口:层级范围是1~99
- 子窗口:层级范围是1000~1999
- 系统窗口:层级范围是2000~2999
本文深入探讨了Android系统中的关键组件和服务,包括Zygote、PMS(PackageManagerService)、AMS(ActivityManagerService)以及Binder通信机制。Zygote作为Android系统的孵化器,负责初始化和创建应用进程。PMS管理应用的安装、卸载和元数据,启动时会扫描所有APK以解析AndroidManifest.xml。AMS则管理应用的生命周期,与PMS在同一进程中。Binder作为Android的进程间通信机制,确保高效的数据传输。此外,还介绍了SurfaceFlinger、WMS(WindowManagerService)以及Window和Activity的相关概念,涉及窗口管理、SurfaceView的工作原理以及与SurfaceFlinger的交互。
3936

被折叠的 条评论
为什么被折叠?



