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中进行
网友评论