包管理服务( PackageManagerService)ANDROID的系统服务之一,主要功能实现应用包的解析、安装、更新、移动、卸载等服务。

系统类图如下:

PackageManagerService主要通过InstallerUserManagerAppDirObserverSettingsDefaultContainerServicePackageHelperNativeLibraryHelperPackageHandlerPackageParser等类实现相应的功能。

Installer类与本地服务installd建立LocalSocket连接,借助installd实现包的installremovedexopt等功能。

UserManager类实现与用户相关的用户数据和包的安装、创建和管理,包括用户及用户数据的创建、删除。

AppDirObserver实现对/system/framework,/system/app /vendor/app/data/app/data/app-private等目录的addremove事件的监听,实现包的动态安装和卸载。

Settings类实现data/system/目录下的包安装信息相关的文件的读取和管理(创建、更新等),解析和读取如下packages.xml"packages-backup.xml""packages.list""packages-stopped.xml""packages-stopped-backup.xml" XML文件。

packages.xm是在解析apk时由 writeLP()创建的,里面记录了系统的permissions以及每个apkname ,codePath, pkgFlags, timeStamp, versionCode,uesrid等信息,这些信息主要通过apk AndroidManifest.xml解析获取,解析完apk后将更新信息写入这个文件并保存到flash,下次开机直接从里面读取相关信息添加到内存相关列表中。当有apk升级,安装或删除时会更新这个文件。

packages.list记录了如下数据:pkgNameuserIddebugFlagdataPath(包的数据路径)。

packages-stopped.xml记录处于停止状态的包的信息,主要包括包名、notLaunched状态等信息。

DefaultContainerService是一个应用服务,具体负责实现APK等相关资源文件在内部或外部存储器上的存储工作。 DefaultContainerService服务中提供了一个IMediaContainerService.Stub桩对象。PackageManagerService包管理服务在PackageHandler对象接收到应用安装消息后首先与该服务建立连接(通过BINDSERVICE)。在服务建立连接后onServiceConnected回调被调用,在onServiceConnected回调函数中根据参数传进来的IMediaContainerService.Stub的对象引用创建一个远程代理对象。以后PackageManagerService服务通过该代理对象访问DefaultContainerService服务。

PackageHelper是提供包安装用到的 MountServiceAPI方法的帮助类。

NativeLibraryHelper是提供APK包含的库文件安装、删除、空间大小计算等方法的帮助类。

PackageHandler实现包处理相关的消息的处理,如apk安装请求消息,如adb install等。PackageHandler运行在独立的线程。

PackageHandler对象对应用包的处理请求使用了模板和命令模式,把要处理的请求作为对象通过消息传递给处理函数;包的安装、移动及获得包的大小消息请求分别打包为InstallParamsMoveParamsMeasureParams对象,三个类都继承自HandlerParams超类,HandlerParams超类中定义了一个模板函数startCopy,模板函数startCopy中使用的三个函数在超类中没有实现,是虚函数,具体实现的功能由具体类确定;如虚函数handleStartCopy对于InstallParams类实现的是包的安装工作,对于MoveParams类实现的是包的移动工作,而MeasureParams类中的handleStartCopy函数实现的是包的测量工作。

InstallParamsMoveParamsMeasureParams三个类中提供了对应的观察者接口IPackageInstallObserverIPackageMoveObserverIPackageStatsObserver,三个接口在PackageManagerService的客户端对象调用PackageManagerService服务的包的安装、移动及获得包的大小等相关API时作为参数传进来,并在InstallParamsMoveParamsMeasureParams三个对象实例化时赋值给对应的观察者接口。因此三个观察者接口指向的对象实际是客户端提供的观察者对象(桩对象)的远程代理对象,InstallParamsMoveParamsMeasureParams三个对象通过对应的观察者接口向远端客户端发送通知。采用的模式是代理模式和观察者模式的复合模式。

POST_INSTALL消息的处理也采用了命令设计模式,把请求的参数打包为PostInstallData对象,PostInstallData对象中包括InstallArgsPackageInstalledInfo对象,InstallArgs是一个虚类,提供copyApk等接口,接口的具体实现在其具体类FileInstallArgsSdInstallArgs中完成。

PackageParser实现应用包的解析功能,主要是解析每个apkAndroidManifest.xml文件,处理asset/res等资源文件,建立起每个apk的配置结构信息。PackageParser是其它类功能实现的基础,是包管理服务最重要的一个类。PackageParser类在实现应用包的解析时采用了解释器模式,对于应用包中的每种语法结构都创建了对应的类,来分别搜集应用包中的相应信息。类结构图如下:

图中除了ResourcesXmlPullParser两个类外其余的类都是PackageParser类的内部类,应用包的每个语法结构的对应类都派生自componet类或属于componet类的内部成员,Package类(一个包一个Package对象)是一个聚合类,把解析出来的一个应用包中的componet聚合到Package类中进行统一管理,PackageParser类将解析出的每个componet及其它信息添加到Package中。

ResourcesXmlPullParser两个类负责XML资源读取的工作。

整个解析流程:

1、PackageManagerService服务的构造函数中调用scanDirLI函数对如下FrameworkDir/system/framework)、SystemAppDir/system/app)、VendorAppDir/vendor/app)、AppInstallDir/data/app)、DrmAppPrivateInstallDir/data/app-private)五个目录下的APK文件进行扫描;

2、scanDirLI函数对扫描目录下的每个APK文件调用scanPackageLI(file, flags|PackageParser.PARSE_MUST_BE_APK, scanMode, currentTime)函数对每个APK文件进行解析,返回包含解析信息的PackageParser.Package对象。scanDirLI函数在解析失败后还删除解析的无效APK文件;

3、在函数scanPackageLI中首先实例化一个PackageParser对象,接着调用PackageParser对象的parsePackage(scanFile,scanPath, mMetrics, parseFlags)函数对待解析文件进行解析;

4、parsePackage函数中对文件进行一些判断后,先实例化一个AssetManager对象,并调用AssetManager对象的addAssetPath函数把被解析文件的路径添加到AssetManager对象,添加成功后实例化一个Resources对象,然后调用AssetManager对象的openXmlResourceParser(cookie, ANDROID_MANIFEST_FILENAME)函数打开一个解析AndroidManifest.xml文件的XML解析器,接着调用parsePackage(res, parser, flags, errorText)函数开始具体解析工作;

5、 parsePackage函数先调用parsePackageName函数解析出包名,接着根据包名实例化一个Package对象,接着从AndroidManifest.xml文件中解析出被解析包的VersionCodeVersionNameinstallLocation等全局属性信息;然后根据XML文件的标签循环解析XML文件包含的其它组成部分,对于tagName名称为application标签时调用parseApplication函数解析该application标签下包含的组件等信息(只能对一个application标签进行解析);对于tagName名称为"permission-group"时调用parsePermissionGroup函数进行解析;对于tagName名称为"permission"时调用parsePermission函数进行解析;对于tagName名称为"permission-tree"时调用parsePermissionTree函数进行解析;对于tagName名称为"permission-tree"时调用parsePermissionTree函数进行解析;对于tagName名称为"instrumentation"时调用parseInstrumentation函数进行解析;并解析或跳过其它标签,如"uses-feature""uses-configuration""uses-sdk""supports-screens"等标签,获得应用包的其它属性;

6、parseApplication函数中首先解析出应用标签下的包含的应用属性信息,然后根据XML文件的标签循环解析应用标签下包含的其它组件;对于"activity"标签调用parseActivity函数进行解析,并返回一个Activity对象,添加到Package对象的activities列表中;对于"receiver"标签也调用parseActivity函数进行解析,返回一个Activity对象,添加到Package对象的receivers列表中;对于"service"标签调用parseService函数进行解析,并返回一个Service对象,添加到Package对象的services列表中;对于"provider"标签调用parseProvider函数进行解析,并返回一个Provider对象,添加到Package对象的providers列表中;对于"activity-alias"标签调用parseActivityAlias函数进行解析,并返回一个Activity对象,添加到Package对象的activities列表中;对于"meta-data"标签调用parseMetaData函数进行解析,解析出应用的MetaData;解析或跳过其它标签,如"uses-library""uses-package"等标签;

7、parseActivity函数中先实例化一个ParseComponentArgs对象和ActivityInfo对象,再实例化Activity对象(实例化的ParseComponentArgs对象和ActivityInfo对象作为参数传给Activity对象的构造函数),然后解析"activity"标签包含的各种属性信息并赋值给Activity对象的内部ActivityInfo对象的相应属性;然后根据XML文件的标签循环解析"activity"标签下包含的其它部分,对于"intent-filter"标签先实例化一个ActivityIntentInfo对象,并调用parseIntent解析"intent-filter"部分,解析出的信息放在作为参数传给parseIntent函数的ActivityIntentInfo对象中,解析后把包含解析信息的ActivityIntentInfo对象添加到Activity对象的intents列表中;对于"meta-data"标签调用parseMetaData函数进行解析,解析出Activity对应的MetaData,并跳过其它标签;标签循环解析完成后返回已包含解析信息的Activity对象;

8、对于其它组件进行同样过程的解析过程。

componet类的每个派生类内部都有一个对应的info对象,具体指向每个componet包含的信息,具体类图如下:

每个componet的信息类都派生自PackageInfo类和PackageItemInfo的子类ComponentInfoPackageInfo类一个容器类,应用包中解析出的信息都被聚合到PackageInfo类中进行统一管理。

上一篇 版权所有,转载时请尊重原创显要处注明链接,谢谢!

下一篇

更多相关文章

  1. android 解析json数据格式
  2. Android(安卓)Bundle类
  3. Android—— 4.2 Vold挂载管理_CommandListener (二)
  4. Android中XML的三种解析方式
  5. android调节屏幕亮度
  6. listView显示对象以及access any RESTFull service that uses JS
  7. android时序图 以及UML中时序图、流程图、状态图、协作图之间的
  8. 箭头函数的基础使用
  9. 类和 Json对象

随机推荐

  1. 最新eclipse中android插件安装下载地址
  2. Android4.0 设置系统默认输入法
  3. android 透明对话框
  4. Android的第一个程序运行
  5. linux下android开发环境的配置
  6. android camera 布局分析
  7. Lottie-移动动画效果框架
  8. Android(安卓)源码编译make的错误处理
  9. android中webview开启了硬件加速后会出现
  10. android上传图片到服务器,求服务器那边和a