PackageManagerService流程

PMS安裝應(yīng)用程序流程

一、啟動(dòng)時(shí)安裝

1、查看PMS的功能與啟動(dòng)過(guò)程,首先PMS是在systemserver中啟動(dòng)的。之后分為兩大部分啟動(dòng)

  • 1)恢復(fù)之前的引用安裝信息:在main中new,開(kāi)始調(diào)用readLP()恢復(fù)上一次引用程序安裝信息(讀取/data/system/packages.xml文件)----> ScanDirLP()掃描指定目錄---->readPackageLP()、addPackageLP()來(lái)讀取解析xml文件中的信息。。。。。
  • 2)應(yīng)用程序安裝過(guò)程:調(diào)用scanDirLI掃描指定目錄下(system/framework、system/app等)的文件時(shí)候有.apk的應(yīng)用,----->scanPackageLI()解析.apk---> PackageParser.parsePackage()實(shí)現(xiàn)真正的解析工作(讀取AndroidManfest.xml文件等)----->解析正確---->調(diào)用另一個(gè)重載的scanPackageLI()來(lái)安裝應(yīng)用。
  • 3)安裝好應(yīng)用之后,updatePermissionsLPw()-----> grantPermissionsLPw()-------->requestedPermissions,分配LINUX的用戶組ID,即資源訪問(wèn)權(quán)限,最后writeLP()將應(yīng)用信息寫入到本地---->writePackage()將應(yīng)用安裝信息寫到/data/system/packages.xml中,這正好一第一步中的readLP()與readPackageLP()形成閉環(huán)。

注意:

  • (a) 重載的scanPackageLI()來(lái)安裝應(yīng)用后,已經(jīng)安裝的應(yīng)用的四大組件都會(huì)記錄在PackageManagerService類的成員變量mActivitys,mReceivers,mServices,mProvidersByComponent中。應(yīng)用使用Packages對(duì)象保存在mPackages所屬的HashMap中
  • (b) AMS是負(fù)責(zé)管理應(yīng)用程序進(jìn)程的,在ActivityManagerService.java中會(huì)通過(guò) startProcessLocked()函數(shù)中的 pm.getPackageGids(app.info.packageName)獲取需要?jiǎng)?chuàng)建應(yīng)用程序的LINUX用戶ID和LInux用戶組ID,此LINUX用戶ID和LInux用戶組ID正是PMS安裝應(yīng)用程序時(shí)創(chuàng)建的。

二、用戶安裝

adb install xxx.apk

PM : pm.java---->run()---->runInstall()
                |
            .....binder.....
                |
PMS :      installPackageAsUser()
                |
                  消息機(jī)制
                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()流程
            然后再發(fā)送一個(gè)消息到 MCS_BOUND
                |
            case  MCS_BOUND
                |
            params.startCopy()
                |
            handleReturnCode()
                |
            processPendingInstall(mArgs, mRet)
                |
            installPackageLI(args, res)
                |
            pkg = pp.parsePackage(tmpPackageFile, parseFlags) //用parsePackage解析APK
                |
            installNewPackageLI()
                |
            scanPackageLI() //重載
                |
            接下你就和啟動(dòng)時(shí)安裝應(yīng)用流程一樣
                  .....

MCS_BOUND 消息發(fā)送流程
connectToService()的最后會(huì)在AMS中的publishServiceLocked()函數(shù)中通過(guò)ContextImpl傳過(guò)去的connection的IBinder接口,調(diào)用connected()函數(shù)

注意:

重載的scanPackageLI()函數(shù)

  • 1、private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags, ...
  • 2、private PackageParser.Package scanPackageLI(PackageParser.Package pkg, int parseFlags, ...
    和啟動(dòng)是被調(diào)用的scanPackageLI()不一樣,啟動(dòng)是安裝要調(diào)用兩次scanPackageLI()重載函數(shù),而用戶安裝值調(diào)用2

發(fā)現(xiàn)問(wèn)題:

Message消息循環(huán)
問(wèn)題:sendMessage與handleMessage是怎么實(shí)現(xiàn)的???
Android應(yīng)用程序在每一個(gè)線程啟動(dòng)的時(shí),都會(huì)在內(nèi)部創(chuàng)建一個(gè)消息隊(duì)列,然后進(jìn)入到無(wú)限循環(huán)中,不斷檢查消息隊(duì)列是否有新消息需要處理。如果有則會(huì)從消息隊(duì)列中取出來(lái),處理。否則線程就會(huì)進(jìn)入睡眠狀態(tài)

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()
    |
啟動(dòng)com.android.defcontainer/.DefaultContainerService   比較核心的拷貝/重命名/刪除都會(huì)在這個(gè)service中進(jìn)行
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,680評(píng)論 19 139
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,300評(píng)論 25 708
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類相關(guān)的語(yǔ)法,內(nèi)部類的語(yǔ)法,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法,線程的語(yǔ)...
    子非魚_t_閱讀 34,819評(píng)論 18 399
  • 仿佛眨眼間,已經(jīng)到了年尾,今天想寫一寫坐火車的記憶,這里面的感情太復(fù)雜,有鄉(xiāng)愁,也有理想。 我并不?;乩霞遥浀玫?..
    島嶼書閱讀 529評(píng)論 6 7

友情鏈接更多精彩內(nèi)容