您的位置:首页 > 其它

PackageManagerService学习笔记二-构造方法

2014-02-05 16:41 549 查看
PKMS构造方法部分源码:

/*
Android 4.2.2源码
*/
public PackageManagerService(Context context, Installer installer, boolean factoryTest, boolean onlyCore)
{
/*---省略部分代码---*/
if(mSdkVersion <= 0)
{
Slog.w(TAG, "**** ro.build.version.sdk not set!");
}

mContext = context;
mFactoryTest = factoryTest;
mOnlyCore = onlyCore;
/*
如果是eng版,扫描Package后,不对Package做dex优化
dex:是android针对java字节码的一种优化技术,课提高运行效率
*/
mNoDexOpt = "eng".equals(SystemProperties.get("ro.build.type"));
mMetrics = new DisplayMetrics();
/*
Settings: 该类用于存储系统运行过程中的一些配置
*/
mSettings = new Settings(context);
mSettings.addSharedUserLPw("android.uid.system",
Process.SYSTEM_UID, ApplicationInfo.FLAG_SYSTEM);
mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID, ApplicationInfo.FLAG_SYSTEM);
mSettings.addSharedUserLPw("android.uid.log", LOG_UID, ApplicationInfo.FLAG_SYSTEM);
mSettings.addSharedUserLPw("com.tmobile.thememanager", THEME_MAMANER_GUID, ApplicationInfo.FLAG_SYSTEM);
mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID, ApplicationInfo.FLAG_SYSTEM);
mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID, ApplicationInfo.FLAG_SYSTEM);
/*---省略部分代码---*/
}


Settings

/*-------------Settings中相关-------------*/
class GrantedPermissions
{
int pkgFlags;
HashSet<String> grantedpermissions = new HashSet<>(String);
int[] grds;

GrantedPermissions(int pkgFlags)
{
setFlags(pkgFlags);
}

@SuppressWarnings("unchecked")
GrantedPermissions(GrantedPermissions base) {
pkgFlags = base.pkgFlags;
grantedPermissions = (HashSet<String>) base.grantedPermissions.clone();

if (base.gids != null) {
gids = base.gids.clone();
}
}

void setFlags(int pkgFlags) {
this.pkgFlags = pkgFlags
& (ApplicationInfo.FLAG_SYSTEM
| ApplicationInfo.FLAG_FORWARD_LOCK
| ApplicationInfo.FLAG_EXTERNAL_STORAGE);
}
}

/*
Settings data for a particular package we know about.
*/
final class PackageSetting extends PackageSettingBase {
int appId;
PackageParser.Package pkg;
SharedUserSetting sharedUser;

PackageSetting(String name, String realName, File codePath, File resourcePath,
String nativeLibraryPathString, int pVersionCode, int pkgFlags) {
super(name, realName, codePath, resourcePath, nativeLibraryPathString, pVersionCode,
pkgFlags);
}

/*
New instance of PackageSetting replicating the original settings.
Note that it keeps the same PackageParser.Package instance.
*/
PackageSetting(PackageSetting orig) {
super(orig);

appId = orig.appId;
pkg = orig.pkg;
sharedUser = orig.sharedUser;
}

@Override
public String toString() {
return "PackageSetting{"
+ Integer.toHexString(System.identityHashCode(this))
+ " " + name + "/" + appId + "}";
}
}

final class SharedUserSetting extends GrantedPermissions
{
final String name;
int userId;

/*
*/
final HashSet<PackageSetting> packages = new HashSet<PackageSetting>();
/*
包签名信息
*/
final PackageSignatures signatures = new PackageSignatures();

SharedUserSetting(String _name, int _pkgFlags)
{
super(_pkgFlags);
name = _name;
}

@Override
public String toString() {
return "SharedUserSetting{" + Integer.toHexString(System.identityHashCode(this)) + " "
+ name + "/" + userId + "}";
}
}

/*
Settings.java
--Settings中的成员变量
----mSharedUsers: HashMap<String, SharedUserSetting> 存储的是字符串与SharedUserSetting的键值对
*/
SharedUserSetting addSharedUserLPw(String name, int uid, int pkgFlags) {
SharedUserSetting s = mSharedUsers.get(name);
if (s != null) {
if (s.userId == uid) {
return s;
}
PackageManagerService.reportSettingsProblem(Log.ERROR,
"Adding duplicate shared user, keeping first: " + name);
return null;
}
s = new SharedUserSetting(name, pkgFlags);
s.userId = uid;
if (addUserIdLPw(uid, s, name)) {
mSharedUsers.put(name, s);
return s;
}
return null;
}

/*
Settings.java
--mUserIds: ArrayList<Object> 以UID为List索引,存放对应的ShardUserSetting对象
--mOtherUserIds: SparseArray<Object> 以UID为List索引,存放对应的ShardUserSetting对象
问题:
--Settings中已经有一个mSharedUsers成员,该成员中存放着name与ShardUserSetting对象的对应关系,为什么还要定义这个变量呢?
原因:
--通过id获取数组中的元素要比,通过key从HashMap中获取元素要快。(index = uid-Process.FIRST_APPLICATION_UID)
*/
private boolean addUserIdLPw(int uid, Object obj, Object name) {
/*
uid不能超出限制。
*/
if (uid > Process.LAST_APPLICATION_UID) {
return false;
}
/*
Process.FIRST_APPLICATION_UID : 10000
应用APK的uid所在进程uid从10000开始
*/
if (uid >= Process.FIRST_APPLICATION_UID) {
int N = mUserIds.size();
/*
通过uid计算索引
*/
final int index = uid - Process.FIRST_APPLICATION_UID;
while (index >= N) {
mUserIds.add(null);
N++;
}
if (mUserIds.get(index) != null) {
PackageManagerService.reportSettingsProblem(Log.ERROR,
"Adding duplicate user id: " + uid
+ " name=" + name);
return false;
}
mUserIds.set(index, obj);
} else {
if (mOtherUserIds.get(uid) != null) {
PackageManagerService.reportSettingsProblem(Log.ERROR,
"Adding duplicate shared id: " + uid
+ " name=" + name);
return false;
}
mOtherUserIds.put(uid, obj);
}
return true;
}

Settings中相关类的层次关系



总结:

1. PKMS中的mSettings成员变量中记录着用户进程中的信息

2. Settings中的成员变量

mSharedUsers中记录着string和SharedUserSettings对象的键值对;( “android.uid.system” --------> uid )

/*为了提高运行效率,以空间换时间*/

mSharedUserIds中存储着SharedUserSettings对象;(索引index = uid - PackageManagerService.FIRST_APPLICATION_UID)

mOtherUserIds: 非应用APKSharedUserSettings对象;  

<----------未完待续----------->
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: