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) {
//......

}
 





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值