(一)Intent查找与匹配
Android使用Intent进行组件,进程之间的通信和跳转。Intent具有隐式Intent和显式Intent两种,Android系统通过PackageManagerService来进行系统组件的维护。
系统启动之后会注册各种系统服务,其中就包括PackageManagerService。在启动之后,PMS会扫描已安装的apk目录,解析apk包下的AndroidManifest.xml文件得到App的相关信息,而每个AndroidManifest.xml又包含了Activity,Service等组件的注册信息,当PMS扫描并且解析完信息后,就清晰地描绘出了整棵apk的信息树。
PackageManagerService的构造函数大概有700多行,它加载了系统已安装的各类apk,并加载了Framework资源和核心库。加载了资源和核心库之后才开始对扫描的指定目录下的apk文件进行解析。实现这一操作的代码是scanDirLi函数。
private void scanDirLI(File dir, final int parseFlags, int scanFlags, long currentTime) {
final File[] files = dir.listFiles();
if (ArrayUtils.isEmpty(files)) {
Log.d(TAG, "No files in app dir " + dir);
return;
}
if (DEBUG_PACKAGE_SCANNING) {
Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags
+ " flags=0x" + Integer.toHexString(parseFlags));
}
for (File file : files) {
final boolean isPackage = (isApkFile(file) || file.isDirectory())
&& !PackageInstallerService.isStageName(file.getName());
if (!isPackage) {
// Ignore entries which are not packages
continue;
}
try {
scanPackageTracedLI(file, parseFlags | PackageParser.PARSE_MUST_BE_APK,
scanFlags, currentTime, null);
} catch (PackageManagerException e) {
Slog.w(TAG, "Failed to parse " + file + ": " + e.getMessage());
// Delete invalid userdata apps
if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
e.error == PackageManager.INSTALL_FAILED_INVALID_APK) {
logCriticalInfo(Log.WARN, "Deleting invalid package at " + file);
removeCodePa