PackageManagerService对象构造过程
来源:互联网 发布:.手机域名在哪里注册 编辑:程序博客网 时间:2024/05/29 18:00
PackageMangerService的构造方法是个比较复杂的过程:(具体构造方法的代码见源码,由于太多了,代码中加了注释,是Android4.0的)。流程见手稿。
先从构造方法一步一步,遇到关键的类,关键的点在说明。
public PackageManagerService(Context context, boolean factoryTest,boolean onlyCore) {
// PackageManagerService启动开始
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
SystemClock.uptimeMillis());
// SDK版本检查,final int mSdkVersion = Build.VERSION.SDK_INT
if (mSdkVersion <= 0) {
Slog.w(TAG, "**** ro.build.version.sdk not set!");
}
// ###//从SystemServer中获取的三个值,从main方法中获取,
mContext = context;
mFactoryTest = factoryTest;// 开机模式
mOnlyCore = onlyCore;
// 如果编译版本为eng,则不需要dex优化
mNoDexOpt = "eng".equals(SystemProperties.get("ro.build.type"));
// 获取手机分辨率,加载资源需要
mMetrics = new DisplayMetrics();
//###111===========创建Settings对象=====================@@@
// 存储系统运行过程中的设置信息
// 创建Settings,有关动态设置的信息持有,Settings构造方法在目录/data/system/下创建package.xml、package.list、package_backup.xml
mSettings = new Settings();
/*
* 创建SharedUserSetting对象并添加到Settings的成员变量mSharedUsers中,在Android系统中,
* 多个package通过设置sharedUserId属性可以运行在同一个进程,共享同一个UID
*/
// 添加四个lib
mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
ApplicationInfo.FLAG_SYSTEM);
mSettings.addSharedUserLPw("android.uid.phone",
MULTIPLE_APPLICATION_UIDS ? RADIO_UID : FIRST_APPLICATION_UID,
ApplicationInfo.FLAG_SYSTEM);
mSettings.addSharedUserLPw("android.uid.log",
MULTIPLE_APPLICATION_UIDS ? LOG_UID : FIRST_APPLICATION_UID,
ApplicationInfo.FLAG_SYSTEM);
mSettings.addSharedUserLPw("android.uid.nfc",
MULTIPLE_APPLICATION_UIDS ? NFC_UID : FIRST_APPLICATION_UID,
ApplicationInfo.FLAG_SYSTEM);
//================================@@@
函数首先创建一个Settings对象,用来保存一些设置信息,然后调用addSharedUserLPw向Settings类的成员变量mSharedUsers中添加SharedUserSetting对象,在Android系统中,通过设置android:sharedUserId="android.uid.system"属性可以为应用程序指定UID,SharedUserSetting对象保存同一共享进程UID的所有包信息,Settings对象用于管理Android系统运行过程中的一些设置信息,Settings的成员变量mSharedUsers以键值对的方式保存UID对应的SharedUserSetting对象。在Android系统中,可以通过在AndroidManifest.xml文件中设置sharedUserId属性来设置多个APK运行在同一个进程中。
在Settings的构造方法中,
Settings对象的构造过程很简单,就是创建一些目录和文件。首先创建/data/system/目录,然后分别创建以下五个文件:
/data/system/packages.xml
/data/system/packages-backup.xml
/data/system/packages.list
/data/system/packages-stopped.xml
/data/system/packages-stopped-backup.xml
Settings通过addSharedUserLPw函数添加向mSharedUsers预先添加SharedUserSetting对象
通过Settings对象调用addSharedUserLPw方法:
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;
}
private boolean addUserIdLPw(int uid, Object obj, Object name) {
// 如果uid大于或者等于系统最大的uid,那么返回false(10000+1000=11000)
if (uid >= PackageManagerService.FIRST_APPLICATION_UID
+ PackageManagerService.MAX_APPLICATION_UIDS) {
return false;
}
// uid>=1000
if (uid >= PackageManagerService.FIRST_APPLICATION_UID) {
int N = mUserIds.size();
final int index = uid - PackageManagerService.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;
}
而mSharedUsers的类型如:
final HashMap<String, SharedUserSetting> mSharedUsers = new HashMap<String, SharedUserSetting>();
上面的过程主要是:创建Settings对象;将四个默认的共享用户ID添加到HashMap<String, SharedUserSetting> mSharedUsers,还有:private final ArrayList<Object> mUserIds = new ArrayList<Object>()。
===========================================================================================
//222================================@@@
String separateProcesses = SystemProperties
.get("debug.separate_processes");
if (separateProcesses != null && separateProcesses.length() > 0) {
if ("*".equals(separateProcesses)) {
mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
mSeparateProcesses = null;
Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
} else {
mDefParseFlags = 0;
mSeparateProcesses = separateProcesses.split(",");
Slog.w(TAG, "Running with debug.separate_processes: "
+ separateProcesses);
}
} else {
mDefParseFlags = 0;
mSeparateProcesses = null;
}
//================================@@@
//333================================@@@
// 创建Installer,通过Installer与底层进行通信,进行安装,卸载等操作
mInstaller = new Installer();
// 获取屏幕尺寸大小
WindowManager wm = (WindowManager) context
.getSystemService(Context.WINDOW_SERVICE);
Display d = wm.getDefaultDisplay();
d.getMetrics(mMetrics);
上面主要是,获取系统的配置信息,获取手机分辨率,便于加载资源文件,还有就是创建一个Installer对象,创建Installer对象,用于访问installd服务进程,完成一些apk安装,卸载,优化工作,对于Installer中的方法,都很容易理解,通过,方法:
private boolean connect() {
if (mSocket != null) {
return true;
}
Slog.i(TAG, "connecting...");
try {
mSocket = new LocalSocket();
LocalSocketAddress address = new LocalSocketAddress("installd",
LocalSocketAddress.Namespace.RESERVED);
mSocket.connect(address);
mIn = mSocket.getInputStream();
mOut = mSocket.getOutputStream();
} catch (IOException ex) {
disconnect();
return false;
}
return true;
}
来联接底层的操作,没有探讨。。。。。。。
- PackageManagerService对象构造过程
- Android PackageManagerService启动过程
- PackageManagerService启动过程
- PackageManagerService启动过程
- java对象构造过程
- java对象构造过程
- pms包管理服务分析-PackageManagerService构造函数和包扫描过程
- PackageManagerService的启动过程分析
- PackageManagerService的启动过程分析
- PackageManagerService的启动过程分析
- PackageManagerService的启动过程分析
- PackageManagerService的启动过程分析
- 浅谈Scala对象构造过程
- Java之对象构造过程
- PackageManagerService.java 构造函数的 分析
- PackageManagerService学习笔记二-构造方法
- PackageManagerService学习笔记三-构造方法
- PackageManagerService学习笔记五-构造方法
- alsa编程
- linux进程间通信概述
- C#总结1
- WebKit加载网页的流程
- 有一个分数数列2/1,3/2,5/3,8/5,。。。。。求出这个数列的前20项之和
- PackageManagerService对象构造过程
- alsa声音编程介绍
- 一个网站从诞生到发展的全过程
- Android 自定义属性详解
- Linux 查看系统 32位还是64位
- 关于USB-AUDIO使用ALSA编程的一点问题
- Eclipse去除JavaScript验证错误
- 怎样建本身的网站?如何建立一个网站?
- IOS7状态栏标准适配