Android学习之PackageManagerService的启动。

内容完全来自,《深入理解Android 卷II》。作为学习笔记。

1.SystemServer.java

IPackageManager pm = null;

//PKMS的核心 main

pm = PackageManagerService.main(context, installer,factoryTest != SystemServer.FACTORY_TEST_OFF, onlyCore);

//后续操作

firstBoot = pm.isFirstBoot();

pm.performBootDexOpt();//dex优化

pm.systemReady();//通知系统

2.PackageManagerService.java

main(){
//两个操作

new PackageManagerService();

ServerManager.addService();

}

//构造函数

public PackageManagerService(Context context, Installer installer,

            boolean factoryTest, boolean onlyCore) {

mSettings = new Settings(context);

        mSettings.addSharedUserLPw(“android.uid.system”,

                Process.SYSTEM_UID, ApplicationInfo.FLAG_SYSTEM);

//最后调用Settings.java的addUserLPw,将Package的uid保存在mUserIds中,将系统Package的uid保存在mOtherUsersIds中
//……

WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
//  得到wm

Display d = wm.getDefaul;

d.getMetrics(mMetrics);
//当前显示屏

mHandlerThread.start();
//ThreadHandler对象,用于程序安装和卸载

readPermissions();
//—>readPermissionsFromXml();读取/system/etc/permissions/下的文件,将XML的标签转换成对应的数据结构(XML->java)

//解析package*.xml(5个文件),建立并更新对应的数据结构

mRestoredSettings = mSettings.readLPw(sUserManager.getUsers(false),mSdkVersion, mOnlyCore);

//以下对system/framework下的文件jar,apk进行dex优化

boolean didDexOpt = false;

//……

if (didDexOpt) {
//到此,为真则清空缓存(new File(mDalvikCacheDir, fn)).delete();

//以下三个*InstallerObserver,scanDirLI分别对三个文件夹进行监视并扫描apk:system/framework,system/app,vendor/app

//……

//scanDirLI比较关键,其中调用了scanPackageLI,把APK文件转换为java的数据结构Package。

//mOnlyCore用于控制是否扫描非系统Package

if(!mOnlyCore){

//扫描data/app ,data/app_private

}

//汇总并更新和Permisson相关信息

updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
                    | (regrantPermissions
                            ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL)
                            : 0));
 // 写到package*.xml

mSettings.writeLPr();

}

3.PackageManagerService.java

private PackageParser.Package scanPackageLI(File scanFile,

            int parseFlags, int scanMode, long currentTime, UserHandle user) {

//PackageParser.java,负责apk文件的解析,解析apk中的AndroidManifest.xml,

final PackageParser.Package pkg = pp.parsePackage(scanFile,

                scanPath, mMetrics, parseFlags);

//再次调用同名函数

PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanMode

                | SCAN_UPDATE_SIGNATURE, currentTime, user);

}

private PackageParser.Package scanPackageLI(PackageParser.Package pkg,

            int parseFlags, int scanMode, long currentTime, UserHandle user) {

//单独处理了”android”的Package,与之对应的apk为framework-res.apk

 if (pkg.packageName.equals(“android”)) {

//……ChooseActivity->ResolveActivity主要

}

 synchronized (mPackages) {

//uses-librarie in mShareLibraries ?

if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null)

//SharedUserSettings

if (pkg.mSharedUserId != null)

// Check if we are renaming from an original package name.

if (pkg.mOriginalPackages != null)

// Just create the setting

pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile,

                    destResourceFile, pkg.applicationInfo.nativeLibraryDir,

                    pkg.applicationInfo.flags, user, false);

//check the sigature

if (!verifySignaturesLP(pkgSetting, pkg))

// Verify that this new package doesn’t have any content providers that conflict with existing packages.

 if ((scanMode&SCAN_NEW_INSTALL) != 0)

//adopt ownership of permissions

 if (pkg.mAdoptPermissions != null)

//set pkg.applicationInfo.dataDir

 File dataPath;

 pkg.applicationInfo.dataDir = dataPath.getPath();

//处理native动态库,从apk中解压复制到对应目录

if (pkg.applicationInfo.nativeLibraryDir != null) 

//四大组件登记到PKMS内部的财产管理对象中

synchronized (mPackages) {

//……

}

 

    原文作者:_Linday
    原文地址: https://blog.csdn.net/u012227549/article/details/11968455
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞