专栏名称: 鸿洋
你好,欢迎关注鸿洋的公众号,每天为您推送高质量文章,让你每天都能涨知识。点击历史消息,查看所有已推送的文章,喜欢可以置顶本公众号。此外,本公众号支持投稿,如果你有原创的文章,希望通过本公众号发布,欢迎投稿。
目录
相关文章推荐
郭霖  ·  Android Studio 中的 ... ·  昨天  
郭霖  ·  音视频基础能力之 Android ... ·  3 天前  
鸿洋  ·  掌握这17张图,掌握RecyclerView ... ·  3 天前  
51好读  ›  专栏  ›  鸿洋

AndroidManifest中配置的各种信息解读

鸿洋  · 公众号  · android  · 2024-12-13 08:35

正文

前言
阅读该篇之前,建议先阅读下面的系列文章:
Android深入理解包管理--PackageManagerService和它的“小伙伴”
Android深入理解包管理--记录存储模块
Android深入理解包管理--共享库模块

本文摘要

这是包管理系列的第四篇文章,apk信息指的是AndroidManifest.xml文件中配置的各种信息,通过本文您将了解到apk信息为啥如此重要,apk信息的解析,apk信息最终被存放在哪。(文中代码基于Android13)

本文大纲

1. apk信息如此重要
2. apk信息的解析
3. apk信息的一生

4. 总结

1
apk信息如此重要

首先apk信息指的是AndroidManifest.xml文件中配置的各种信息,比如apk版本信息、apk包名、声明了哪些四大组件、使用了哪些权限、声明了哪些权限、使用了哪些共享库等。
本篇内容为啥要介绍apk信息呢?
首要的原因是因为apk信息对于PackageManagerService服务来说非常的重要,PackageManagerService管理的对象是apk,而要想知道apk内包含了哪些内容是不是需要从AndroidManifest.xml文件中获取到apk信息,只有获取到apk信息才能对apk进行管理。
其次是PackageManagerService很多的模块都是为apk信息服务的,比如共享库模块是为apk声明共享库 (在AndroidManifest.xml文件中使用library标签)和使用共享库 (在AndroidManifest.xml文件中使用uses-library标签)信息服务的,权限管理模块是为apk声明权限 (在AndroidManifest.xml文件中使用permission标签)和使用权限 (在AndroidManifest.xml文件中使用uses-permission标签)信息服务的。

说了这么多apk信息的重要性,那我们来看下apk信息是如何解析的吧?

2
apk信息的解析

PackageManagerService要想知道apk信息,就得需要从apk的AndroidManifest.xml文件中把这些信息解析为对应的标签数据类,那就来介绍下这些数据类吧。介绍数据类时秉持从小到大的原则来介绍,啥叫从小到大呢,也就是先把AndroidManifest.xml文件中的常用小标签对应的数据类开始,逐步在来介绍更大一些的标签对应的数据类,那先从四大组件开始。

2.1 四大组件对应的标签数据类

大家都知道四大组件对应的标签是activity、receiver、service、provider,下图展示了它们的类图关系。

图解

ParsedComponent

很多的标签都存在一些共同的配置信息,如下代码activity和permission标签都存在android:iconandroid:banner配置信息,而ParsedComponent接口的作用就是把多个标签共有的配置信息收集起来,提供统一的方法
<activity  android:icon="" android:banner="">
<permission  android:icon=""  android:banner=""/>


ParsedComponentImpl

该类从名字上看就知道它是实现了ParsedComponent接口。

ParsedMainComponentImpl

上图没有体现出来,该类实现了ParsedMainComponent接口,而该接口的作用是把四大组件的标签共有的配置信息收集起来,提供统一的方法,如下代码展示了一些共有的配置信息。
<provider android:name="" android:process="" android:enabled="" android:exported=""/>
<service android:name="" android:process="" android:enabled="" android:exported=""/>
<receiver android:name="" android:process="" android:enabled="" android:exported=""/>
<activity android:name="" android:exported="" android:enabled=""  android:process="">


ParsedActivityImpl

activity、receiver这两个标签会被解析为ParsedActivityImpl类,标签中配置的数据自然而然的就存放在该类中,如android:launchMode配置的信息存放在该类的launchMode属性中。
下图是ParsedActivityImpl的继承关系。

ParsedActivity是一个接口,它定义了activity和receiver标签独有的接口,而ParsedActivityImpl类实现了ParsedActivity接口同时也继承了ParsedMainComponentImpl类。

ParsedServiceImpl

service标签会被解析为该类,而该类也继承了ParsedMainComponentImpl类,并且它也实现了自己的接口ParsedService。

ParsedProviderImpl

provider标签会被解析为该类,它同样也继承了ParsedMainComponentImpl类,并且它也实现了自己的接口ParsedProvider。

2.2 权限相关的标签数据类

安装在Android设备上的app基本都会使用到各式各样的权限,权限也属于常用到的标签,故介绍下它们。权限分为声明权限和使用权限。
声明权限也就是app可以在AndroidManifest.xml中通过permission标签来声明权限,如下代码:
"string resource"
            android:icon="drawable resource"
            android:label="string resource"
            android:name="string"
            android:permissionGroup="string"
            android:protectionLevel=["normal" | "dangerous" |
                                     "signature" | ...] />
而使用权限就是在AndroidManifest.xml中通过uses-permission标签来使用权限,如下代码:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>


下面是权限标签对应的类图。

图解

ParsedPermissionImpl
permission标签会被解析为该类,它实现了ParsedPermission接口。
ParsedUsesPermissionImpl
uses-permission标签会被解析为该类,它实现了ParsedUsesPermission接口。
因为AndroidManifest中的标签很多,只把常用的介绍完就够用了,如果大家想了解其他的标签可以遵循如下的原则:
  1. 标签数据类的命名格式是ParsedXXXXImpl (如ParsedActivityImpl)。
  2. 每个标签数据类都有自己对应的接口,接口命名格式为ParsedXXXX (如ParsedActivity),即使像ParsedUsesPermissionImpl这么简单的类它都有自己的接口ParsedUsesPermission
  3. ParsedComponentImpl类收集了大部分标签共用的信息,而它的接口是ParsedComponent。
  4. ParsedMainComponentImpl类收集了四大组件标签共用的信息,而它的接口是ParsedMainComponent。

2.3 AndroidManifest对应的数据类

AndroidManifest内有各种标签,基本每个标签都会有自己的标签数据类 (除了application、manifest标签),在AndroidManifest中每个标签都会被包含于某个大标签内 (如 application被包含于 manifest标签),同样也会有一个最终的标签数据类把所有的标签数据类都包含进来,这个类就是PackageImpl,如下是它的类图:

图解

PackageImpl
AndroidManifest中的信息会对应一个PackageImpl实例,它实现了ParsedPackage、AndroidPackage接口,并且它继承了ParsingPackageImpl类,大部分逻辑可都是集中在ParsingPackageImpl类中
ParsingPackageImpl
如上图,它的很多属性,如下:
  1. activities它包含了很多的ParsedActivity。
  2. receivers它包含了很多的ParsedActivity。
  3. services它包含了很多的ParsedService。
  4. attributions它包含了很多的ParsedAttribution。
  5. permissions它包含了很多的ParsedPermission。
ParsingPackageImpl类的属性包含的都是各标签数据类的接口,这就是所谓的面向接口编程,好处就是该类基本不需要改动,比如ParseActivity又增加了一个子类,那在往ParsingPackageImpl中添加该子类的时候就不需要改动ParsingPackageImpl里的代码了。
application和manifest标签并没有对应的标签数据类,它们配置的信息也是放在ParsingPackageImpl类中的,比如application标签中配置的android:name信息,它是存放在ParsingPackageImpl的类型为String的className属性中的。

2.4 小结

  1. 四大组件对应的数据类分别是ParsedActivityImpl、ParsedServiceImpl、ParsedProviderImpl
  2. 权限相关的标签permission、uses-permission对应的数据类是ParsedPermissionImpl、ParsedUsesPermissionImpl
  3. AndroidManifest会对应一个PackageImpl实例,而它的父类ParsingPackageImpl存放了所有的数据类。

标签数据类有一个规则:每个类的命名规则是ParsedXXXXImpl (XXXX 代表对应的标签),每个类都有对应的接口命名规则是ParsedXXXX 。

3
apk信息的一生

从apk信息的诞生、apk信息的归属地、apk信息的消亡来介绍apk信息在PackageManagerService服务中的一生。

3.1 apk信息的诞生

apk信息的诞生时机主要是在apk安装、apk升级、Android设备启动时扫描所有apk三种情况,不管哪种情况首要做的最重要的工作是从apk的AndroidManifest.xml文件中把配置信息解析出来,配置信息解析出来就代表apk信息诞生了。
无论是apk安装、apk升级、扫描所有apk或多或少都会使用apk信息来进行各种验证,比如apk完整性验证、apk版本验证 (如果存在老apk)、新老apk签名验证 (如果存在老apk),经过各种步骤后,apk顺利的安装完成了,而apk信息也需要找一个归属地来存储它们。

3.2 apk信息的归属地

apk信息的归属地代表需要在PackageManagerService中把apk信息保存起来,如下代码:
//PackageManagerService类

//mPackages存储了所有的apk信息,key值为包名,value为apk信息
final WatchedArrayMap<String, AndroidPackage> mPackages = new WatchedArrayMap<>();


而apk信息中的四大组件,则是存放在四大组件模块,如下代码:
//PackageManagerService类

//mComponentResolver存储了四大组件
final ComponentResolver mComponentResolver;


apk信息保存下来后就可以被使用了,比如启动该apk的某个Activity,ActivityTaskManagerService就需要从四大组件模块中查询到相应的Activity信息,进而才执行后面的启动操作。再比如某个App获取该apk的ApplicationInfo信息,则会从PackageManagerService的mPackages属性中根据包名找到对应的apk信息,进而返回。

3.3 apk信息的消亡

apk被卸载或者systemserver进程死掉的话,PackageManagerService和四大组件模块中保存的apk信息会被移除,代表apk信息消亡了。如果不存在上面的情况,则apk信息会随着PackageManagerService一直存活着。

4
总结


本文介绍了apk信息在PackageManagerService服务中的重要性,以及apk信息的解析和apk信息在PackageManagerService中的一生。



最后推荐一下我做的网站,玩Android: wanandroid.com ,包含详尽的知识体系、好用的工具,还有本公众号文章合集,欢迎体验和收藏!


扫一扫 关注我的公众号

如果你想要跟大家分享你的文章,欢迎投稿~


┏(^0^)┛明天见!