生活随笔
收集整理的這篇文章主要介紹了
Android系统启动流程分析之安装应用
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
2016六月 21
原 Android系統(tǒng)啟動(dòng)流程分析之安裝應(yīng)用
分類:Android系統(tǒng)源碼研究
?(295)??(0)??舉報(bào)??收藏
跟隨上一篇博客Android系統(tǒng)的啟動(dòng)流程簡要分析繼續(xù)分析android系統(tǒng)的啟動(dòng).上一篇文章里講了,SystemServer在main方法里創(chuàng)建了一個(gè)線程ServerThread,并調(diào)用 initAndLoop方法. [java]?view plain?copy ServerThread?thr?=?new?ServerThread();?? thr.initAndLoop();?? 在initAndLoop方法里加載各種服務(wù),比如WindowManagerService(Wms)、ActivityManagerService(Ams)、PackageManagerService(Pms)等. 看下啟動(dòng)PackageManagerServer的代碼 [java]?view plain?copy pm?=?PackageManagerService.main(context,?installer,?factoryTest?!=?SystemServer.FACTORY_TEST_OFF,?onlyCore);?? 這個(gè)pm是IPackageManager的實(shí)例,IPackageManager是由IPackageManager.aidl文件編譯生成的. PackageManagerService繼承自IPackageManager.Stub [java]?view plain?copy public?class?PackageManagerService?extends?IPackageManager.Stub?{?? PackageManagerService調(diào)用main方法,傳入四個(gè)參數(shù) context 上下文 installer 安裝器 factoryTest != SystemServer.FACTORY_TEST_OFF 是否為正常的工廠模式 onlyCore 為true表示在加密的設(shè)備只啟動(dòng)核心的程序
那么查看PackageManagerService的main方法.
PackageManagerService定義在frameworks/base/services/java/com/android/server/PackageManagerService.java文件中.
main方法是這樣的
[java]?view plain?copy public?static?final?IPackageManager?main(Context?context,?Installer?installer,?boolean?factoryTest,?boolean?onlyCore)?{?? ????????PackageManagerService?m?=?new?PackageManagerService(context,?installer,?factoryTest,?onlyCore);?? ????????ServiceManager.addService("package",?m);?? ????????return?m;?? ????}??
根據(jù)傳入的四個(gè)參數(shù)創(chuàng)建PackageManagerService的實(shí)例,
然后通過ServiceManager添加這個(gè)PackageManagerService實(shí)例. 既然創(chuàng)建了這個(gè)實(shí)例,那么就調(diào)用了它的有參構(gòu)造函數(shù) 1.在構(gòu)造函數(shù)里會(huì)掃描制定目錄的apk文件 [java]?view plain?copy ?? ????????????????mFrameworkInstallObserver?=?new?AppDirObserver(frameworkDir.getPath(),?OBSERVER_EVENTS,?true,?false,?false);?? ????????????????mFrameworkInstallObserver.startWatching();?? ????????????????scanDirLI(frameworkDir,?PackageParser.PARSE_IS_SYSTEM?|?PackageParser.PARSE_IS_SYSTEM_DIR?|?PackageParser.PARSE_IS_PRIVILEGED,?scanMode?|?SCAN_NO_DEX,?0);?? ?????????????????? ?????????????????? ????????????????File?privilegedAppDir?=?new?File(Environment.getRootDirectory(),?"priv-app");?? ????????????????mPrivilegedInstallObserver?=?new?AppDirObserver(privilegedAppDir.getPath(),?OBSERVER_EVENTS,?true,?true,?false);?? ????????????????mPrivilegedInstallObserver.startWatching();?? ????????????????scanDirLI(privilegedAppDir,?PackageParser.PARSE_IS_SYSTEM?|?PackageParser.PARSE_IS_SYSTEM_DIR?|?PackageParser.PARSE_IS_PRIVILEGED,?scanMode,?0);?? ?? ?????????????????? ????????????????File?systemAppDir?=?new?File(Environment.getRootDirectory(),?"app");?? ????????????????mSystemInstallObserver?=?new?AppDirObserver(systemAppDir.getPath(),?OBSERVER_EVENTS,?true,?false,?false);?? ????????????????mSystemInstallObserver.startWatching();?? ????????????????scanDirLI(systemAppDir,?PackageParser.PARSE_IS_SYSTEM?|?PackageParser.PARSE_IS_SYSTEM_DIR,?scanMode,?0);?? ?? ?????????????????? ????????????????File?vendorAppDir?=?new?File("/vendor/app");?? ????????????????mVendorInstallObserver?=?new?AppDirObserver(vendorAppDir.getPath(),?OBSERVER_EVENTS,?true,?false,?false);?? ????????????????mVendorInstallObserver.startWatching();?? ????????????????scanDirLI(vendorAppDir,?PackageParser.PARSE_IS_SYSTEM?|?PackageParser.PARSE_IS_SYSTEM_DIR,?scanMode,?0);?? 掃描調(diào)用的方法是scanDirLI,傳入四個(gè)參數(shù),context(上下文),flag(標(biāo)志),scanMode(掃描模式),currentTime(當(dāng)前時(shí)間). 2.在scanDirLI方法內(nèi)部會(huì)調(diào)用 [java]?view plain?copy PackageParser.Package?pkg?=?scanPackageLI(file,?flags?|?PackageParser.PARSE_MUST_BE_APK,?scanMode,?currentTime,?null);?? 3.scanPackageLI通過解析安裝包parsePackage獲取到安裝包的信息結(jié)構(gòu) [java]?view plain?copy PackageParser?pp?=?new?PackageParser(scanPath)?? ????????pp.setSeparateProcesses(mSeparateProcesses);?? ????????pp.setOnlyCoreApps(mOnlyCore);?? ????????final?PackageParser.Package?pkg?=?pp.parsePackage(scanFile,?scanPath,?mMetrics,?parseFlags);?? 4.之后調(diào)用parsePackage的重載方法解析,將應(yīng)用信息保存在PackageManagerService,比如VersionCode、VersionName等 [java]?view plain?copy try?{?? ????????????? ???????????pkg?=?parsePackage(res,?parser,?flags,?errorText);?? ???????}?catch?(Exception?e)?{?? ???????????errorException?=?e;?? ???????????mParseError?=?PackageManager.INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION;?? ???????}?? 5.回到第3步,調(diào)用scanPackageLI的重載方法 [java]?view plain?copy PackageParser.Package?scannedPkg?=?scanPackageLI(pkg,?parseFlags,?scanMode?|?SCAN_UPDATE_SIGNATURE,?currentTime,?user);6.?? 6.然后調(diào)用createDataDirsLI方法 [java]?view plain?copy ?? ret?=?createDataDirsLI(pkgName,?pkg.applicationInfo.uid,?pkg.applicationInfo.seinfo);?? 7.在createDataDirsLI方法里調(diào)用mInstaller的install方法進(jìn)行安裝. [java]?view plain?copy int?res?=?mInstaller.install(packageName,?uid,?uid,?seinfo);??
版權(quán)聲明:本文為博主原創(chuàng)文章,轉(zhuǎn)載請注明出處:鄧志勇博客 http://blog.csdn.net/qq_31530015/
總結(jié)
以上是生活随笔為你收集整理的Android系统启动流程分析之安装应用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。