Android系统在启动过程中,会扫描系统中的特定目录,以便可以对保存在里面的应用程序进行安装。这是通过Package管理服务PackageManagerService来实现的。PMS在安装一个应用程序的过程中,主要是完成两件事情。第一件事是解析这个应用程序的程序配置文件AndroidManifest.xml,以便可以获得它的安装信息;第二件事是为了这个应用程序分配Linux用户ID和用户组ID,以便它可以在系统中获得合适的运行权限。
1. 应用程序的安装过程
一个应用程序可以配置的安装信息很多,其中,最重要的就是它的组件信息。一个应用程序组件只有在配置文件中被正确地配置之后,才可以被ActivityManagerService正常地启动起来。
Android系统中的每一个应用程序都有一个Linux用户ID。这些Linux用户ID就是由PMS来负责分配的。PMS在安装一个应用程序时,如果发现它没有与其他应用程序共享同一个Linux用户ID,那么就会为它分配一个唯一的Linux用户ID,以便它可以在系统中获得合适的运行权限。
一个应用程序除了拥有一个Linux用户ID之外,还可以拥有若干个Linux用户组ID,以便可以可以在系统中获得更多的资源访问权限,例如,读取联系人信息、使用摄像头、发送短信,以及拨打电话等权限。这些用户组ID也是由PMS来负责分配的。PMS在安装一个应用程序时,如果发现它申请了一个特定的资源访问权限,那么就会为它分配一个相应的Linux用户组ID。
PackageManagerService类有一个类型为Settings的成员变量mSettings,它是用来管理应用程序的安装信息的。例如,用来管理PMS为应用程序分配的Linux用户ID和Linux用户组ID。
由于Android系统每次启动时,都会重新安装一遍系统中的应用程序,但有些应用程序信息每次安装都是需要保持一致的。因此,PMS每次在安装完成应用程序之后,都需要将他们的信息保存下来,以便下次安装时可以恢复回来。
恢复上一次的应用程序安装信息是通过调用PMS类的成员变量mSettings的成员函数readLP来实现的。
成员函数updatePermissionsLP来为申请了特定的资源访问权限的应用程序分配相应的Linux用户组ID。
成员函数writeLP将前面所获得的应用程序安装信息保存在本地的一个配置文件中,以便下一次再安装这些应用程序时,可以将需要保持一致的应用程序信息恢复回来。
在应用程序配置文件AndroidManifest.xml中,分别使用activity、receiver、service和provider标签来描述一个应用程序的Activity、broadcast receiver、Service和Content provider组件的配置信息,它们均是application标签里面的一个子标签。
系统中所有已经安装了的应用程序都是使用一个Package对象来描述的。这些Package对象保存在PackageManagerService类的成员变量mPackages所描述的一个HashMap中,key为包名。
系统中每一个已经安装了的应用程序都包含了一系列的Activity、Broadcast Receive、Service和Content Provider组件,这些组件的配置信息分别保存在PMS类的成员变量mActivity、mReceives、mServices和mProviderByComponent中。
系统中的所有应用程序的安装信息都使用一个PackageSetting对象来描述,并且保存在Settings类的成员变量mPackages所描述的一个HashMap中。这些安装信息有可能是来自于全新安装的应用程序的,还有可能是来自于上一次安装的应用程序的。
属性userId和shareUserId是互斥的,即它们之间只有一个人会存在于一个package标签中,因为一个应用程序要么单独使用一个Linux用户ID,要么与其他应用程序共享同一个Linux用户ID。
PMS将每一个应用程序所使用的Linux用户ID保存起来了,这样以后无论如何重新安装一个应用程序,PMS都可以保证这个应用程序所使用的Linux用户ID是不变的。
当我们从网络上下载一个应用程序到设备上安装时,系统会调用PackageManager类的成员函数installPackage来启动这个应用程序的安装过程,而installPackage最终是通过PMS类的成员函数scanPackageLI来完成这个应用程序的安装过程的。
2. 应用程序的显示过程
Android系统提供了一个默认的Home应用程序——Laucher,用来显示系统中已经安装了的安装应用程序,它是由systrm进程负责启动的,同时它也是系统中第一个启动的应用程序。