android多用户下应用安装详解二(开机读取流程)
2015-01-27 15:46
531 查看
ok,午休完了,继续未竟的调研。
这偏主要分析开机过程,系统是怎么读取相关配置文件来获取应用安装情况的。
1。PackageManagerService初始化
public PackageManagerService(Context context, Installer installer,
boolean factoryTest, boolean onlyCore) {
.......................................................................
mAppInstallDir = new File(dataDir, "app");
mRestoredSettings = mSettings.readLPw(this, sUserManager.getUsers(false),
mSdkVersion, mOnlyCore);
.......................................................................
mAppInstallObserver = new AppDirObserver(
mAppInstallDir.getPath(), OBSERVER_EVENTS, false, false);
mAppInstallObserver.startWatching();
scanDirLI(mAppInstallDir, 0, scanMode, 0);
.......................................................................
}
2. com.android.server.pm.Settings
boolean readLPw(PackageManagerService service, List<UserInfo> users, int sdkVersion,
boolean onlyCore) {
FileInputStream str = null;
。。。。。。。。。。。。。。。。。。。。。。。。
str = new FileInputStream(mSettingsFilename);
}
XmlPullParser parser = Xml.newPullParser();
parser.setInput(str, null);
............................................................
String tagName = parser.getName();
if (tagName.equals("package")) {
readPackageLPw(parser);
这里是关键,实际上就是解析/data/system/packages.xml文件,这个文件很庞大,记载了每个应用的详细情况,包括permission,shared-user,key等等,每一个应用都对应一个package节点,所以一开机,就可以把系统内安装的所有应用都读到Settings的mPackages对象中,它是一个map,维护了系统内所有应用的详情。当然这个文件里维护的是全系统的所有应用,不区分用户,接下来才是应用在每一个用户里的安装情况。
.................................................................................
if (users == null) {
readPackageRestrictionsLPr(0);
} else {
for (UserInfo user : users) {
readPackageRestrictionsLPr(user.id);
}
}
我们重点看一下readPackageRestrictionsLPr方法:
void readPackageRestrictionsLPr(int userId) {
FileInputStream str = null;
.........................................................
PackageSetting ps = null;
while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
&& (type != XmlPullParser.END_TAG
|| parser.getDepth() > outerDepth)) {
.........................................................
if (tagName.equals(TAG_PACKAGE)) {
final boolean installed = installedStr == null
? true : Boolean.parseBoolean(installedStr);
.........................................................
ps.setUserState(userId, enabled, installed, stopped, notLaunched, blocked,
enabledCaller, enabledComponents, disabledComponents);
这里实际上是读取/data/system/users/userId/package-restrictions.xml文件里面对于每个应用在每个用户下的安装信息,这个在上篇中已经说明过了。这里我们注意一下淡蓝色部分可以看到,对于该用户下是否安装该应用,采用的是默认安装的原则。就是如果文件中如果没有配置inst属性,那么认为是安装。
..........................................................................................
3. 第2部分分析的是开机过程读取配置文件的过程,我们注意到实际上接下来还会有一个扫描/data/app目录下所有apk资源的过程(部分1中红色部分),这块也会影响到应用安装数据的读取,我们也来分析一下。
i. private void scanDirLI(File dir, int flags, int scanMode, long currentTime) {
String[] files = dir.list();
..........................................................
for (i=0; i<files.length; i++) {
..........................................................
PackageParser.Package pkg = scanPackageLI(file,
flags|PackageParser.PARSE_MUST_BE_APK, scanMode, currentTime, null);
..........................................................
}
ii. private PackageParser.Package scanPackageLI(File scanFile,
int parseFlags, int scanMode, long currentTime, UserHandle user) {
..........................................................
PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanMode
| SCAN_UPDATE_SIGNATURE, currentTime, user);
..........................................................
}
iii. ....................................................................................
我们发现最终和上篇中5步骤之后的逻辑一致,实际上最终也是会走到com.android.server.pm.Settings的getPackageLPw方法中,殊途同归。但这里不同的是,这个扫描的过程实际上是一个查漏补确的过程,如果/data/app/下有一个apk资源在packages.xml中没有相关信息的话,开机的过程就可以走到新应用安装的流程,这种情况会出现在安装时手机死机重启的情况。所以这里我们可以知道/data/app/目录下所有应用都会被安装到系统中。
好了,我们来总体上总结一下开机过程中的应用状态读取流程:
一。读取/data/system/packages.xml文件,获取系统中安装的所有应用信息
二。读取/data/system/usres/userId/package-restrictions.xml文件(userId代表每个用户id),获取每个应用在相应用户下的安装情况。
三。扫描/data/app/xx.apk资源,确保所有apk已经安装。
至此,我们分析完了开机加载应用安装信息的流程,下篇我们会对于一个特殊需求来分析应该怎样打patch
这偏主要分析开机过程,系统是怎么读取相关配置文件来获取应用安装情况的。
1。PackageManagerService初始化
public PackageManagerService(Context context, Installer installer,
boolean factoryTest, boolean onlyCore) {
.......................................................................
mAppInstallDir = new File(dataDir, "app");
mRestoredSettings = mSettings.readLPw(this, sUserManager.getUsers(false),
mSdkVersion, mOnlyCore);
.......................................................................
mAppInstallObserver = new AppDirObserver(
mAppInstallDir.getPath(), OBSERVER_EVENTS, false, false);
mAppInstallObserver.startWatching();
scanDirLI(mAppInstallDir, 0, scanMode, 0);
.......................................................................
}
2. com.android.server.pm.Settings
boolean readLPw(PackageManagerService service, List<UserInfo> users, int sdkVersion,
boolean onlyCore) {
FileInputStream str = null;
。。。。。。。。。。。。。。。。。。。。。。。。
str = new FileInputStream(mSettingsFilename);
}
XmlPullParser parser = Xml.newPullParser();
parser.setInput(str, null);
............................................................
String tagName = parser.getName();
if (tagName.equals("package")) {
readPackageLPw(parser);
这里是关键,实际上就是解析/data/system/packages.xml文件,这个文件很庞大,记载了每个应用的详细情况,包括permission,shared-user,key等等,每一个应用都对应一个package节点,所以一开机,就可以把系统内安装的所有应用都读到Settings的mPackages对象中,它是一个map,维护了系统内所有应用的详情。当然这个文件里维护的是全系统的所有应用,不区分用户,接下来才是应用在每一个用户里的安装情况。
.................................................................................
if (users == null) {
readPackageRestrictionsLPr(0);
} else {
for (UserInfo user : users) {
readPackageRestrictionsLPr(user.id);
}
}
我们重点看一下readPackageRestrictionsLPr方法:
void readPackageRestrictionsLPr(int userId) {
FileInputStream str = null;
.........................................................
PackageSetting ps = null;
while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
&& (type != XmlPullParser.END_TAG
|| parser.getDepth() > outerDepth)) {
.........................................................
if (tagName.equals(TAG_PACKAGE)) {
final boolean installed = installedStr == null
? true : Boolean.parseBoolean(installedStr);
.........................................................
ps.setUserState(userId, enabled, installed, stopped, notLaunched, blocked,
enabledCaller, enabledComponents, disabledComponents);
这里实际上是读取/data/system/users/userId/package-restrictions.xml文件里面对于每个应用在每个用户下的安装信息,这个在上篇中已经说明过了。这里我们注意一下淡蓝色部分可以看到,对于该用户下是否安装该应用,采用的是默认安装的原则。就是如果文件中如果没有配置inst属性,那么认为是安装。
..........................................................................................
3. 第2部分分析的是开机过程读取配置文件的过程,我们注意到实际上接下来还会有一个扫描/data/app目录下所有apk资源的过程(部分1中红色部分),这块也会影响到应用安装数据的读取,我们也来分析一下。
i. private void scanDirLI(File dir, int flags, int scanMode, long currentTime) {
String[] files = dir.list();
..........................................................
for (i=0; i<files.length; i++) {
..........................................................
PackageParser.Package pkg = scanPackageLI(file,
flags|PackageParser.PARSE_MUST_BE_APK, scanMode, currentTime, null);
..........................................................
}
ii. private PackageParser.Package scanPackageLI(File scanFile,
int parseFlags, int scanMode, long currentTime, UserHandle user) {
..........................................................
PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanMode
| SCAN_UPDATE_SIGNATURE, currentTime, user);
..........................................................
}
iii. ....................................................................................
我们发现最终和上篇中5步骤之后的逻辑一致,实际上最终也是会走到com.android.server.pm.Settings的getPackageLPw方法中,殊途同归。但这里不同的是,这个扫描的过程实际上是一个查漏补确的过程,如果/data/app/下有一个apk资源在packages.xml中没有相关信息的话,开机的过程就可以走到新应用安装的流程,这种情况会出现在安装时手机死机重启的情况。所以这里我们可以知道/data/app/目录下所有应用都会被安装到系统中。
好了,我们来总体上总结一下开机过程中的应用状态读取流程:
一。读取/data/system/packages.xml文件,获取系统中安装的所有应用信息
二。读取/data/system/usres/userId/package-restrictions.xml文件(userId代表每个用户id),获取每个应用在相应用户下的安装情况。
三。扫描/data/app/xx.apk资源,确保所有apk已经安装。
至此,我们分析完了开机加载应用安装信息的流程,下篇我们会对于一个特殊需求来分析应该怎样打patch
相关文章推荐
- android多用户下应用安装详解三(特殊需求实现)
- android多用户下应用安装详解一(新应用安装情况)
- 【Android应用开发详解】第01期:第三方授权认证(一)实现第三方授权登录、分享以及获取用户资料
- android 如何在手机第一次开机的时候,把用户放在外置SD卡上的APK自动安装到手机的存储卡。
- Android实训案例(六)——四大组件之一BroadcastReceiver的基本使用,拨号,短信,SD卡,开机,应用安装卸载监听
- Android实训案例(六)——四大组件之一BroadcastReceiver的基本使用,拨号,短信,SD卡,开机,应用安装卸载监听
- Android系统启动流程分析之安装应用
- 【Android应用开发详解】第01期:第三方授权认证(一)实现第三方授权登录、分享以及获取用户资料
- android应用安装流程(备忘)
- Android系统启动流程分析之安装应用
- 【Android应用开发详解】第01期:第三方授权认证(一)实现第三方授权登录、分享以及获取用户资料
- Android读取桌面安装的应用
- android 用户应用使用系统权限如reboot的permission办法 包括顺利安装到手机上INSTALL_FAILED_INVALID_INSTALL_LOCATION
- 【Android应用开发详解】第01期:第三方授权认证(一)实现第三方授权登录、分享以及获取用户资料
- Android实训案例(六)——四大组件之一BroadcastReceiver的基本使用,拨号,短信,SD卡,开机,应用安装卸载监听
- 为什么Android手机应用安装数量比WP用户少?和Android恶意软件野蛮生长有很大关系!
- 【Android应用开发详解】第01期:第三方授权认证(一)实现第三方授权登录、分享以及获取用户资料
- 【Android应用开发详解】第01期:第三方授权认证(一)实现第三方授权登录、分享以及获取用户资料
- 【Android应用开发详解】实现第三方授权登录、分享以及获取用户资料
- Android 应用的安装过程详解