定义

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

PackageManagerService系统类图如下:


PackageManagerService类图剖析:

PackageManagerService主要通过Installer、UserManager、AppDirObserver、Settings、DefaultContainerService、PackageHelper、NativeLibraryHelper、PackageHandler、PackageParser等类实现相应的功能。

各个类的功能解析:

Installer:与本地服务installd建立LocalSocket连接,借助installd实现包的install、remove、dexopt等功能。


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


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


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


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


packages.list:记录了如下数据:pkgName,userId,debugFlag,dataPath(包的数据路径)。


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


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

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


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


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


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


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


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


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

类结构图如下:

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


android包整个解析流程:

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文件中解析出被解析包的VersionCode、VersionName、installLocation等全局属性信息;然后根据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、在parseApplication函数中会调用parseActivity()来进行解析,在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的信息类都派生自PackageItemInfo类和PackageItemInfo的子类ComponentInfo,而PackageInfo类一个容器类,应用包中解析出的信息都被聚合到PackageInfo类中进行统一管理。

原文转自:http://blog.csdn.net/goohong/article/details/7881509

更多相关文章

  1. 安全新手入坑——HTML标签
  2. android:json解析库的选择
  3. Android(安卓)4.2 JellyBean Graphic Component -- SurfaceFling
  4. android servicemanager与binder源码分析三------如何进入内核通
  5. Android之WebView总结
  6. 内存管理 Memory Management for Android(安卓)Apps
  7. Android(安卓)c和c++函数调用堆栈分析
  8. Android(安卓)Camera HAL设计初步
  9. 推出Android原生开发工具包r16

随机推荐

  1. android中四大引用的区别,强引用、软引用
  2. 直播软件开发关于Android、iOS中的视频采
  3. 初学android-调用百度api显示地图(出现显
  4. Android透明度数值记录
  5. Android(安卓)盒子开发,TV开发,经验总结NO.
  6. 百度Android语音合成(TTS)SDK使用方法
  7. Android(安卓)ListView页眉页脚效果
  8. 制作一款简单的网络图片查看器
  9. 三星Tizen手机官网现身 上市或面临风险
  10. 几行代码,让你的app动感起来--Android(安