多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
PackageManagerService是本书分析的第一个核心服务,也是Android系统中最常用的服务之一。它负责系统中Package的管理,应用程序的安装、卸载、信息查询等。图4-1展示了PackageManagerService及客户端的类家族。 :-: ![](http://img.blog.csdn.net/20150803110319692?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center) 图4-1 PackageManagerService及客户端类家族 由图4-1可知: - IPackageManager接口类中定义了服务端和客户端通信的业务函数,还定义了内部类Stub,该类从Binder派生并实现了IPackageManager接口。 - PackageManagerService继承自IPackageManager.Stub类,由于Stub类从Binder派生,因此PackageManagerService将作为服务端参与Binder通信。 - Stub类中定义了一个内部类Proxy,该类有一个IBinder类型(实际类型为BinderProxy)的成员变量mRemote,根据第2章介绍的Binder系统的知识,mRemote用于和服务端PackageManagerService通信。 - IPackageManager接口类中定义了许多业务函数,但是出于安全等方面的考虑,Android对外(即SDK)提供的只是一个子集,该子集被封装在抽象类PackageManager中。客户端一般通过Context的getPackageManager函数返回一个类型为PackageManager的对象,该对象的实际类型是PackageManager的子类ApplicationPackageManager。这种基于接口编程的方式,虽然极大降低了模块之间的耦合性,却给代码分析带来了不小的麻烦。 - ApplicationPackageManager类继承自PackageManager类。它并没有直接参与Binder通信,而是通过mPM成员变量指向一个IPackageManager.Stub.Proxy类型的对象。 * * * * * **提示**:读者在源码中可能找不到IPackageManager.java文件。该文件在编译过程中是经aidl工具处理IPackageManager.aidl后得到,最终的文件位置在Android源码/out/target /common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/content/pm/目录中。如果读者没有整体编译过源码,也可使用aidl工具单独处理IPackageManager.aidl。 * * * * * aidl工具生成的结果文件有着相似的代码结构。读者不妨看看下面这个笔者通过编译生成的IPackageManager.java文件。注意,aidl工具生成的结果文件没有格式缩进,所以看起来惨不忍睹,读者可用Eclipse中的源文件格式化命令处理它。 **IPackageManager.java** ~~~ public interface IPackageManager extendsandroid.os.IInterface { //定义内部类Stub,派生自Binder,实现IPackageManager接口 publicstatic abstract class Stub extends android.os.Binder implements android.content.pm.IPackageManager { privatestatic final java.lang.String DESCRIPTOR = "android.content.pm.IPackageManager"; publicStub() { this.attachInterface(this,DESCRIPTOR); } ...... //定义Stub的内部类Proxy,实现IPackageManager接口 privatestatic class Proxy implements android.content.pm.IPackageManager{ //通过mRemote变量和服务端交互 private android.os.IBinder mRemote; Proxy(android.os.IBinderremote) { mRemote = remote; } ...... } ...... } ~~~ 接下来分析PackageManagerService,为书写方便起见,以后将其简称为PKMS。