PackageManagerService流程

PMS安装应用程序流程

一、启动时安装

1、查看PMS的功能与启动过程,首先PMS是在systemserver中启动的。之后分为两大部分启动

  • 1)恢复之前的引用安装信息:在main中new,开始调用readLP()恢复上一次引用程序安装信息(读取/data/system/packages.xml文件)—-> ScanDirLP()扫描指定目录—->readPackageLP()、addPackageLP()来读取解析xml文件中的信息。。。。。
  • 2)应用程序安装过程:调用scanDirLI扫描指定目录下(system/framework、system/app等)的文件时候有.apk的应用,—–>scanPackageLI()解析.apk—> PackageParser.parsePackage()实现真正的解析工作(读取AndroidManfest.xml文件等)—–>解析正确—->调用另一个重载的scanPackageLI()来安装应用。
  • 3)安装好应用之后,updatePermissionsLPw()—–> grantPermissionsLPw()——–>requestedPermissions,分配LINUX的用户组ID,即资源访问权限,最后writeLP()将应用信息写入到本地—->writePackage()将应用安装信息写到/data/system/packages.xml中,这正好一第一步中的readLP()与readPackageLP()形成闭环。

注意:

  • (a) 重载的scanPackageLI()来安装应用后,已经安装的应用的四大组件都会记录在PackageManagerService类的成员变量mActivitys,mReceivers,mServices,mProvidersByComponent中。应用使用Packages对象保存在mPackages所属的HashMap中
  • (b) AMS是负责管理应用程序进程的,在ActivityManagerService.java中会通过 startProcessLocked()函数中的 pm.getPackageGids(app.info.packageName)获取需要创建应用程序的LINUX用户ID和LInux用户组ID,此LINUX用户ID和LInux用户组ID正是PMS安装应用程序时创建的。

二、用户安装

adb install xxx.apk

PM : pm.java---->run()---->runInstall()
                |
            .....binder.....
                |
PMS :      installPackageAsUser()
                |
                  消息机制
                final Message msg = mHandler.obtainMessage(INIT_COPY);
                msg.obj = new InstallParams(origin, observer, installFlags,
                    installerPackageName, verificationParams, user, packageAbiOverride);
                mHandler.sendMessage(msg)
                |
            doHandleMessage(Message msg) 
                |
            case INIT_COPY
                |
            connectToService()流程
            然后再发送一个消息到 MCS_BOUND
                |
            case  MCS_BOUND
                |
            params.startCopy()
                |
            handleReturnCode()
                |
            processPendingInstall(mArgs, mRet)
                |
            installPackageLI(args, res)
                |
            pkg = pp.parsePackage(tmpPackageFile, parseFlags) //用parsePackage解析APK
                |
            installNewPackageLI()
                |
            scanPackageLI() //重载
                |
            接下你就和启动时安装应用流程一样
                  .....

MCS_BOUND 消息发送流程
connectToService()的最后会在AMS中的publishServiceLocked()函数中通过ContextImpl传过去的connection的IBinder接口,调用connected()函数

注意:

重载的scanPackageLI()函数
– 1、private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags, …
– 2、private PackageParser.Package scanPackageLI(PackageParser.Package pkg, int parseFlags, …
和启动是被调用的scanPackageLI()不一样,启动是安装要调用两次scanPackageLI()重载函数,而用户安装值调用2

发现问题:

Message消息循环
问题:sendMessage与handleMessage是怎么实现的???
Android应用程序在每一个线程启动的时,都会在内部创建一个消息队列,然后进入到无限循环中,不断检查消息队列是否有新消息需要处理。如果有则会从消息队列中取出来,处理。否则线程就会进入睡眠状态

connectToService()流程

doHandleMessage             ----PMS
    | 
connectToService()      
    |
mContext.bindServiceAsUser()        ----ContextImpl.java
    |
ActivityManagerNative.getDefault().bindService()    ----ContextImpl.java
    |
{Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>()
IBinder b = ServiceManager.getService("activity")
IActivityManager am = asInterface(b)}
    |
IActivityManager.bindService()      ----ActivityManagerNative
    |
   ...binder...
    |
ActivityManagerService.bindService()    ----AMS
    |
mServices.bindServiceLocked()       ----ActiveServices.java
    |
retrieveServiceLocked()
bringUpServiceLocked()
    |
startProcessLocked()
    |
启动com.android.defcontainer/.DefaultContainerService   比较核心的拷贝/重命名/删除都会在这个service中进行
    原文作者:夏菠
    原文地址: https://blog.csdn.net/xiabodan/article/details/80258718
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞