在Android服务之PackageManagerService启动源码分析中介绍了PackageManagerService服务的整个启动过程,启动过程相对来说较为简单,就是构造一个PackageManagerService对象,然后注册到ServiceManager进程中,只是PackageManagerService对象的构造过程比较复杂,任务比较繁重,在前面介绍PackageManagerService构造过程中,介绍到PackageManagerService会扫描系统指定目录下的Apk文件,本文就结合源代码详细介绍PackageManagerService对Apk的整个扫描过程。
- private void scanDirLI(File dir, int flags, int scanMode, long currentTime) {
- String[] files = dir.list();
- if (files == null) {
- Log.d(TAG, "No files in app dir " + dir);
- return;
- }
- int i;
- for (i=0; i<files.length; i++) {
- File file = new File(dir, files[i]);
- //如果不是apk文件,则跳过继续扫描
- if (!isPackageFilename(files[i])) {
- continue;
- }
- //解析扫描到的apk文件
- PackageParser.Package pkg = scanPackageLI(file,
- flags|PackageParser.PARSE_MUST_BE_APK, scanMode, currentTime);
- //如果是系统分区内的无效安装包,则删除该apk文件
- if (pkg == null && (flags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
- mLastScanError == PackageManager.INSTALL_FAILED_INVALID_APK) {
- Slog.w(TAG, "Cleaning up failed install of " + file);
- file.delete();
- }
- }
- }
private void scanDirLI(File dir, int flags, int scanMode, long currentTime) {
String[] files = dir.list();
if (files == null) {
Log.d(TAG, "No files in app dir " + dir);
return;
}
int i;
for (i=0; i<files.length; i++) {
File file = new File(dir, files[i]);
//如果不是apk文件,则跳过继续扫描
if (!isPackageFilename(files[i])) {
continue;
}
//解析扫描到的apk文件
PackageParser.Package pkg = scanPackageLI(file,
flags|PackageParser.PARSE_MUST_BE_APK, scanMode, currentTime);
//如果是系统分区内的无效安装包,则删除该apk文件
if (pkg == null && (flags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
mLastScanError == PackageManager.INSTALL_FAILED_INVALID_APK) {
Slog.w(TAG, "Cleaning up failed install of " + file);
file.delete();
}
}
}
该函数用于扫描指定目录下的Apk文件,函数实现比较简单,就是遍历目录下的以.apk为后缀的安装包文件,然后调用另一个scanDirLI函数来对每一个Apk文件进行解析。扫描每个Apk包括两个步骤:
首先是解析Apk中的AndroidManifest.xml文件,然后是更新每一个安装包在PackageManagerService中的设置信息。
- private PackageParser.Package scanPackageLI(File scanFile,
- int parseFlags, int scanMode, long currentTime) {
- mLastScanError = PackageManager.INSTALL_SUCCEEDED;
- String scanPath = scanFile.getPath();
- parseFlags |= mDefParseFlags;
- //使用PackageParser对象来解析apk安装包
- PackageParser pp = new PackageParser(scanPath);
- pp.setSeparateProcesses(mSeparateProcesses);
- pp.setOnlyCoreApps(mOnlyCore);
- //解析当前扫描的apk文件,得到描述apk信息的PackageParser.Package对象
- final PackageParser.Package pkg = pp.parsePackage(scanFile,
- scanPath, mMetrics, parseFlags);
- if (pkg == null) {
- mLastScanError = pp.getParseError();
- return null;
- }
- // /data/app/.delrecord文件用于记录删除的安装包
- File delRecord = new File("/data/app/.delrecord");
- //如果当前apk文件位于"/system/preloadapp"目录下,并且安装包删除记录文件存在
- if(isPreloadApp(scanFile.getParent()) && delRecord.exists()){
- //如果当前apk安装包曾经安装过,但已经被删除,则直接返回该apk的描述对象
- if(isDeleteApp(pkg.packageName))return pkg;
- }
private PackageParser.Package scanPackageLI(File scanFile,
int parseFlags, int scanMode, long currentTime) {
mLastScanError = PackageManager.INSTALL_SUCCEEDED;
String scanPath = scanFile.getPath();
parseFlags |= mDefParseFlags;
//使用PackageParser对象来解析apk安装包
PackageParser pp = new PackageParser(scanPath);
pp.setSeparateProcesses(mSeparateProcesses);
pp.setOnlyCoreApps(mOnlyCore);
//解析当前扫描的apk文件,得到描述apk信息的PackageParser.Package对象
final PackageParser.Package pkg = pp.parsePackage(scanFile,
scanPath, mMetrics, parseFlags);
if (pkg == null) {
mLastScanError = pp.getParseError();
return null;
}
// /data/app/.delrecord文件用于记录删除的安装包
File delRecord = new File("/data/app/.delrecord");
//如果当前apk文件位于"/system/preloadapp"目录下,并且安装包删除记录文件存在
if(isPreloadApp(scanFile.getParent()) && delRecord.exists()){
//如果当前apk安装包曾经安装过,但已经被删除,则直接返回该apk的描述对象
if(isDeleteApp(pkg.packageName))return pkg;
}
这部分内容就是对每一个Apk文件的扫描过程,使用PackageParser对象来解析每一个Apk拥有的AndroidManifest.xml文件。
- //更新系统中的安装包信息
- PackageSetting ps = null;
- PackageSetting updatedPkg;
- synchronized (mPackages) {
- //mSettings.mRenamedPackages中保存了所有安装包的名字变更,以键值对的形式保存安装包新的包名和原始包名: newName-oldName
- String oldName = mSettings.mRenamedPackages.get(pkg.packageName);
- if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
- //mSettings.mPackages中保存了所有安装包的设置信息,以键值对的形式保存每个apk包的包名和设置:name-PackageSetting,这里通过旧包名从mSettings.mPackages中取出该apk原始的PackageSetting对象
- ps = mSettings.peekPackageLPr(oldName);
- }
- //如果没有原始包设置PackageSetting,则使用apk的当前包名来获取其对应的PackageSetting
- if (ps == null) {
- ps = mSettings.peekPackageLPr(pkg.packageName);
- } //mSettings.mDisabledSysPackages中保存了所有已替换的安装包的设置信息,以键值对的形式保存每个apk包的包名和设置:name-PackageSetting,使用包名从mSettings.mDisabledSysPackages中取得对应的PackageSetting对象
- updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
- }
- //如果是系统安装包
- if (updatedPkg != null && (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
- //如果apk的路径已经更改
- if (ps != null && !ps.codePath.equals(scanFile)) {
- //判断当前apk版本号是否小于原始版本
- if (pkg.mVersionCode < ps.versionCode) {
- // 系统包已经是最新版本,且安装路径不匹配,忽略
- mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
- return null;
- } else {
- //更新安装包到系统分区中
- synchronized (mPackages) {
- // 从PackageManagerService的安装包列表中删除该包
- mPackages.remove(ps.name);
- }
- //创建安装参数InstallArgs
- InstallArgs args = createInstallArgs(packageFlagsToInstallFlags(ps),
- ps.codePathString, ps.resourcePathString, ps.nativeLibraryPathString);
- synchronized (mInstaller) {
- //清空dex文件及安装包的挂载点
- args.cleanUpResourcesLI();
- }
- synchronized (mPackages) {
- mSettings.enableSystemPackageLPw(ps.name);
- }
- }
- }
- }
- if (updatedPkg != null) {
- parseFlags |= PackageParser.PARSE_IS_SYSTEM;
- }
- //安装包校验
- if (!collectCertificatesLI(pp, ps, pkg, scanFile, parseFlags)) {
- Slog.w(TAG, "Failed verifying certificates for package:" + pkg.packageName);
- return null;
- }
- //先前安装过相同包名的apk,但现在作为系统apk来安装
- boolean shouldHideSystemApp = false;
- if (updatedPkg == null && ps != null
- && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
- //apk签名匹配,如果失败,清空apk文件及其数据
- if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
- != PackageManager.SIGNATURE_MATCH) {
- deletePackageLI(pkg.packageName, true, 0, null, false);
- ps = null;
- } else {//签名匹配成功
- //如果新增的系统apk版本低于先前安装的apk版本
- if (pkg.mVersionCode < ps.versionCode) {
- shouldHideSystemApp = true;
- } else {
- //更新系统apk程序,但保持应用数据不变
- InstallArgs args = createInstallArgs(packageFlagsToInstallFlags(ps),
- ps.codePathString, ps.resourcePathString, ps.nativeLibraryPathString);
- synchronized (mInstaller) {
- args.cleanUpResourcesLI();
- }
- }
- }
- }
- if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
- parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
- }
- String codePath = null;
- String resPath = null;
- if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0) {
- if (ps != null && ps.resourcePathString != null) {
- resPath = ps.resourcePathString;
- } else {
- // Should not happen at all. Just log an error.
- Slog.e(TAG, "Resource path not set for pkg : " + pkg.packageName);
- }
- } else {
- resPath = pkg.mScanPath;
- }
- codePath = pkg.mScanPath;
- // Set application objects path explicitly.
- setApplicationInfoPaths(pkg, codePath, resPath);
- //调用另一个scanPackageLI函数
- PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanMode
- | SCAN_UPDATE_SIGNATURE, currentTime);
- if (shouldHideSystemApp) {
- synchronized (mPackages) {
- grantPermissionsLPw(pkg, true);
- mSettings.disableSystemPackageLPw(pkg.packageName);
- }
- }
- return scannedPkg;
//更新系统中的安装包信息
PackageSetting ps = null;
PackageSetting updatedPkg;
synchronized (mPackages) {
//mSettings.mRenamedPackages中保存了所有安装包的名字变更,以键值对的形式保存安装包新的包名和原始包名: newName-oldName
String oldName = mSettings.mRenamedPackages.get(pkg.packageName);
if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
//mSettings.mPackages中保存了所有安装包的设置信息,以键值对的形式保存每个apk包的包名和设置:name-PackageSetting,这里通过旧包名从mSettings.mPackages中取出该apk原始的PackageSetting对象
ps = mSettings.peekPackageLPr(oldName);
}
//如果没有原始包设置PackageSetting,则使用apk的当前包名来获取其对应的PackageSetting
if (ps == null) {
ps = mSettings.peekPackageLPr(pkg.packageName);
} //mSettings.mDisabledSysPackages中保存了所有已替换的安装包的设置信息,以键值对的形式保存每个apk包的包名和设置:name-PackageSetting,使用包名从mSettings.mDisabledSysPackages中取得对应的PackageSetting对象
updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
}
//如果是系统安装包
if (updatedPkg != null && (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
//如果apk的路径已经更改
if (ps != null && !ps.codePath.equals(scanFile)) {
//判断当前apk版本号是否小于原始版本
if (pkg.mVersionCode < ps.versionCode) {
// 系统包已经是最新版本,且安装路径不匹配,忽略
mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
return null;
} else {
//更新安装包到系统分区中
synchronized (mPackages) {
// 从PackageManagerService的安装包列表中删除该包
mPackages.remove(ps.name);
}
//创建安装参数InstallArgs
InstallArgs args = createInstallArgs(packageFlagsToInstallFlags(ps),
ps.codePathString, ps.resourcePathString, ps.nativeLibraryPathString);
synchronized (mInstaller) {
//清空dex文件及安装包的挂载点
args.cleanUpResourcesLI();
}
synchronized (mPackages) {
mSettings.enableSystemPackageLPw(ps.name);
}
}
}
}
if (updatedPkg != null) {
parseFlags |= PackageParser.PARSE_IS_SYSTEM;
}
//安装包校验
if (!collectCertificatesLI(pp, ps, pkg, scanFile, parseFlags)) {
Slog.w(TAG, "Failed verifying certificates for package:" + pkg.packageName);
return null;
}
//先前安装过相同包名的apk,但现在作为系统apk来安装
boolean shouldHideSystemApp = false;
if (updatedPkg == null && ps != null
&& (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
//apk签名匹配,如果失败,清空apk文件及其数据
if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
!= PackageManager.SIGNATURE_MATCH) {
deletePackageLI(pkg.packageName, true, 0, null, false);
ps = null;
} else {//签名匹配成功
//如果新增的系统apk版本低于先前安装的apk版本
if (pkg.mVersionCode < ps.versionCode) {
shouldHideSystemApp = true;
} else {
//更新系统apk程序,但保持应用数据不变
InstallArgs args = createInstallArgs(packageFlagsToInstallFlags(ps),
ps.codePathString, ps.resourcePathString, ps.nativeLibraryPathString);
synchronized (mInstaller) {
args.cleanUpResourcesLI();
}
}
}
}
if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
}
String codePath = null;
String resPath = null;
if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0) {
if (ps != null && ps.resourcePathString != null) {
resPath = ps.resourcePathString;
} else {
// Should not happen at all. Just log an error.
Slog.e(TAG, "Resource path not set for pkg : " + pkg.packageName);
}
} else {
resPath = pkg.mScanPath;
}
codePath = pkg.mScanPath;
// Set application objects path explicitly.
setApplicationInfoPaths(pkg, codePath, resPath);
//调用另一个scanPackageLI函数
PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanMode
| SCAN_UPDATE_SIGNATURE, currentTime);
if (shouldHideSystemApp) {
synchronized (mPackages) {
grantPermissionsLPw(pkg, true);
mSettings.disableSystemPackageLPw(pkg.packageName);
}
}
return scannedPkg;
}
这部分是Apk安装信息的更新过程。Apk文件的扫描过程就是对Apk包中的AndroidManifest文件的解析过程
- public Package parsePackage(File sourceFile, String destCodePath,
- DisplayMetrics metrics, int flags) {
- mParseError = PackageManager.INSTALL_SUCCEEDED;
- mArchiveSourcePath = sourceFile.getPath();
- if (!sourceFile.isFile()) {
- Slog.w(TAG, "Skipping dir: " + mArchiveSourcePath);
- mParseError = PackageManager.INSTALL_PARSE_FAILED_NOT_APK;
- return null;
- }
- if (!isPackageFilename(sourceFile.getName())
- && (flags&PARSE_MUST_BE_APK) != 0) {
- if ((flags&PARSE_IS_SYSTEM) == 0) {
- Slog.w(TAG, "Skipping non-package file: " + mArchiveSourcePath);
- }
- mParseError = PackageManager.INSTALL_PARSE_FAILED_NOT_APK;
- return null;
- }
- XmlResourceParser parser = null;
- AssetManager assmgr = null;
- Resources res = null;
- boolean assetError = true;
- try {
- //创建一个资源管理器对象
- assmgr = new AssetManager();
- int cookie = assmgr.addAssetPath(mArchiveSourcePath);
- if (cookie != 0) {
- res = new Resources(assmgr, metrics, null);
- assmgr.setConfiguration(0, 0, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- Build.VERSION.RESOURCES_SDK_INT);
- //使用XML解析器打开AndroidManifest.xml文件
- parser = assmgr.openXmlResourceParser(cookie, ANDROID_MANIFEST_FILENAME);
- assetError = false;
- } else {
- Slog.w(TAG, "Failed adding asset path:"+mArchiveSourcePath);
- }
- } catch (Exception e) {
- Slog.w(TAG, "Unable to read AndroidManifest.xml of "
- + mArchiveSourcePath, e);
- }
- if (assetError) {
- if (assmgr != null) assmgr.close();
- mParseError = PackageManager.INSTALL_PARSE_FAILED_BAD_MANIFEST;
- return null;
- }
- String[] errorText = new String[1];
- Package pkg = null;
- Exception errorException = null;
- try {
- //解析AndroidManifest.xml文件,得到Package对象
- pkg = parsePackage(res, parser, flags, errorText);
- } catch (Exception e) {
- errorException = e;
- mParseError = PackageManager.INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION;
- }
- if (pkg == null) {
- if (!mOnlyCoreApps || mParseError != PackageManager.INSTALL_SUCCEEDED) {
- if (errorException != null) {
- Slog.w(TAG, mArchiveSourcePath, errorException);
- } else {
- Slog.w(TAG, mArchiveSourcePath + " (at "
- + parser.getPositionDescription()
- + "): " + errorText[0]);
- }
- if (mParseError == PackageManager.INSTALL_SUCCEEDED) {
- mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
- }
- }
- parser.close();
- assmgr.close();
- return null;
- }
- parser.close();
- assmgr.close();
- pkg.mPath = destCodePath;
- pkg.mScanPath = mArchiveSourcePath;
- pkg.mSignatures = null;
- return pkg;
- }
public Package parsePackage(File sourceFile, String destCodePath,
DisplayMetrics metrics, int flags) {
mParseError = PackageManager.INSTALL_SUCCEEDED;
mArchiveSourcePath = sourceFile.getPath();
if (!sourceFile.isFile()) {
Slog.w(TAG, "Skipping dir: " + mArchiveSourcePath);
mParseError = PackageManager.INSTALL_PARSE_FAILED_NOT_APK;
return null;
}
if (!isPackageFilename(sourceFile.getName())
&& (flags&PARSE_MUST_BE_APK) != 0) {
if ((flags&PARSE_IS_SYSTEM) == 0) {
Slog.w(TAG, "Skipping non-package file: " + mArchiveSourcePath);
}
mParseError = PackageManager.INSTALL_PARSE_FAILED_NOT_APK;
return null;
}
XmlResourceParser parser = null;
AssetManager assmgr = null;
Resources res = null;
boolean assetError = true;
try {
//创建一个资源管理器对象
assmgr = new AssetManager();
int cookie = assmgr.addAssetPath(mArchiveSourcePath);
if (cookie != 0) {
res = new Resources(assmgr, metrics, null);
assmgr.setConfiguration(0, 0, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
Build.VERSION.RESOURCES_SDK_INT);
//使用XML解析器打开AndroidManifest.xml文件
parser = assmgr.openXmlResourceParser(cookie, ANDROID_MANIFEST_FILENAME);
assetError = false;
} else {
Slog.w(TAG, "Failed adding asset path:"+mArchiveSourcePath);
}
} catch (Exception e) {
Slog.w(TAG, "Unable to read AndroidManifest.xml of "
+ mArchiveSourcePath, e);
}
if (assetError) {
if (assmgr != null) assmgr.close();
mParseError = PackageManager.INSTALL_PARSE_FAILED_BAD_MANIFEST;
return null;
}
String[] errorText = new String[1];
Package pkg = null;
Exception errorException = null;
try {
//解析AndroidManifest.xml文件,得到Package对象
pkg = parsePackage(res, parser, flags, errorText);
} catch (Exception e) {
errorException = e;
mParseError = PackageManager.INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION;
}
if (pkg == null) {
if (!mOnlyCoreApps || mParseError != PackageManager.INSTALL_SUCCEEDED) {
if (errorException != null) {
Slog.w(TAG, mArchiveSourcePath, errorException);
} else {
Slog.w(TAG, mArchiveSourcePath + " (at "
+ parser.getPositionDescription()
+ "): " + errorText[0]);
}
if (mParseError == PackageManager.INSTALL_SUCCEEDED) {
mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
}
}
parser.close();
assmgr.close();
return null;
}
parser.close();
assmgr.close();
pkg.mPath = destCodePath;
pkg.mScanPath = mArchiveSourcePath;
pkg.mSignatures = null;
return pkg;
}
该函数根据Apk包路径创建一个对应的资源管理器对象AssetManager,通过该对象来访问Apk包中的资源信息,包括AndroidManifest.xml文件。
- parser = assmgr.openXmlResourceParser(cookie, ANDROID_MANIFEST_FILENAME);
parser = assmgr.openXmlResourceParser(cookie, ANDROID_MANIFEST_FILENAME);
通过资源管理器对象打开AndroidManifest.xml文件并且得到XML解析器。接着调用parsePackage函数开始解析AndroidManifest文件。在了解整个解析过程前,先认识一下Android定义的一些用于管理Apk信息的数据结构。
Package用于描述一个Apk的信息,一个Apk应用程序可能包括一系列的Activity,Service,Provider等组件,在Package中同样定义了对应的数据结构来保存这些组件信息。
这里不在沾上整个解析过程的源代码,只介绍解析过程使用的方法及数据结构。在
frameworks/base/core/res/res/values/attrs_manifest.xml文件中定义了AndroidManifest文件中的各个标签或属性
通过遍历AndroidManifest文件,并匹配对应的标签来读取指定标签的属性值,各个标签属性读取方式如下:
- TypedArray sa = res.obtainAttributes(attrs,com.android.internal.R.styleable.AndroidManifest);
- pkg.mVersionCode = sa.getInteger(com.android.internal.R.styleable.AndroidManifest_versionCode, 0);
- pkg.mVersionName = sa.getNonConfigurationString(com.android.internal.R.styleable.AndroidManifest_versionName, 0);
TypedArray sa = res.obtainAttributes(attrs,com.android.internal.R.styleable.AndroidManifest);
pkg.mVersionCode = sa.getInteger(com.android.internal.R.styleable.AndroidManifest_versionCode, 0);
pkg.mVersionName = sa.getNonConfigurationString(com.android.internal.R.styleable.AndroidManifest_versionName, 0);
res是Resources对象,通过Resources对象的obtainAttributes方法来读取指定标签的属性内容,比如这里读取AndroidManifest标签的属性
最后根据属性名称从TypedArray中读取对应属性值,各个标签下的属性名称在frameworks/base/core/res/res/values/attrs_manifest.xml文件已经定义。下表为各个标签对应的解析函数:
application | parseApplication()
| ||||||||||||||||||||
permission-group | parsePermissionGroup() | ||||||||||||||||||||
permission | parsePermission() | ||||||||||||||||||||
permission-tree | parsePermissionTree() | ||||||||||||||||||||
uses-permission | parsePackage() | ||||||||||||||||||||
uses-configuration | parsePackage() | ||||||||||||||||||||
uses-feature | parsePackage() | ||||||||||||||||||||
uses-sdk | parsePackage() | ||||||||||||||||||||
supports-screens | parsePackage() | ||||||||||||||||||||
protected-broadcast | parsePackage() | ||||||||||||||||||||
instrumentation | parseInstrumentation() | ||||||||||||||||||||
original-package | parsePackage() | ||||||||||||||||||||
adopt-permissions | parsePackage() | ||||||||||||||||||||
uses-gl-texture | parsePackage() | ||||||||||||||||||||
compatible-screens | parsePackage() | ||||||||||||||||||||
eat-comment | parsePackage() |
在Package类中为每个标签定义了对应的数据结构来保存数据信息,解析XML的目的就是读取AndroidManifest文件中的内容到Package对象中。
Package成员 | 定义的属性 | XML中的标签 | |||||
mVersionCode | AndroidManifest
|
manifest | |||||
mVersionName | |||||||
mSharedUserId | |||||||
mSharedUserLabel | |||||||
installLocation | |||||||
applicationInfo | AndroidManifestApplication | application | |||||
创建PermissionGroup对象并将信息保存该对象的成员Info中,同时将创建的PermissionGroup对象添加到permissionGroups中 | AndroidManifestPermissionGroup
| permission-group | |||||
创建Permission对象并将信息保存该对象的成员Info中,同时将创建的Permission对象添加到permissions中 | AndroidManifestPermission | permission | |||||
创建Permission对象并将信息保存该对象的成员Info中,同时将创建的Permission对象添加到permissions中 | AndroidManifestPermissionTree
| permission-tree | |||||
requestedPermissions 保存权限名称 | AndroidManifestUsesPermission
| uses-permission | |||||
requestedPermissionsRequired | |||||||
创建ConfigurationInfo对象,并将信息保存到该对象中,同时将该对象添加到configPreferences中 | AndroidManifestUsesConfiguration | uses-configuration | |||||
创建FeatureInfo对象,并将信息保存到该对象中,同时将该对象添加到reqFeatures中 | AndroidManifestUsesFeature | uses-feature | |||||
applicationInfo.targetSdkVersion | AndroidManifestUsesSdk | uses-sdk | |||||
applicationInfo | AndroidManifestSupportsScreens | supports-screens | |||||
protectedBroadcasts | AndroidManifestProtectedBroadcast | protected-broadcast | |||||
instrumentation | AndroidManifestInstrumentation | instrumentation | |||||
mOriginalPackages | AndroidManifestOriginalPackage | original-package | |||||
mAdoptPermissions | AndroidManifestOriginalPackage | adopt-permissions | |||||
mAppMetaData | AndroidManifestMetaData | meta-data | |||||
usesLibraries usesOptionalLibraries | AndroidManifestUsesLibrary | uses-library | |||||
activities | AndroidManifestActivityAlias | activity-alias | |||||
AndroidManifestActivity | activity | ||||||
receivers | AndroidManifestActivity | receiver | |||||
services | AndroidManifestService | service | |||||
providers |
| provider |