有关FrameWork相关面试题

本文深入探讨了Android系统中的关键组件和服务,包括Zygote、PMS(PackageManagerService)、AMS(ActivityManagerService)以及Binder通信机制。Zygote作为Android系统的孵化器,负责初始化和创建应用进程。PMS管理应用的安装、卸载和元数据,启动时会扫描所有APK以解析AndroidManifest.xml。AMS则管理应用的生命周期,与PMS在同一进程中。Binder作为Android的进程间通信机制,确保高效的数据传输。此外,还介绍了SurfaceFlinger、WMS(WindowManagerService)以及Window和Activity的相关概念,涉及窗口管理、SurfaceView的工作原理以及与SurfaceFlinger的交互。
摘要由CSDN通过智能技术生成

参考学习视频:framwork面试集合,大厂老司机带你扫清framework难点

目录

一、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两个特性:

  1. 子线程绘制
    • SurfaceView 是在一个新起的单独线程中可以重新绘制画面,而View必须在UI的主线程中更新画面。那么在UI的主线程中更新画面,可能会引发问题,比如你更新画面的时间过长,那么你的主UI线程会被你正在画的函数阻塞。
    • 但这也带来了另外一个问题,就是事件同步。比如你触屏了一下,你需要surfaceView中thread 处理,一般就需要有一个event queue 的设计来保存touch event,这涉及到线程同步
  2. 双缓冲模式
    • 通俗来讲就是两个缓冲区,一个后台缓冲区和一个前台缓冲区,每次后台缓冲区接受数据,当填充完整后交换给前台缓冲,这样就保证了前台缓冲里的数据都是完整的
    • 在后台线程执行繁重的绘图任务,把所有绘制的东西缓存起来,绘制完毕后,再回到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
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值