8.2.9 调用scanDirLI方法扫描并安装APK包
调用scanDirLI方法扫描并安装system/framework/、system/app/、vendor/app/目录中的APK包;如果mOnlyCore为false,继续扫描并安装data/app、data/app-private目录中的APK包。这五个目录下的APK文件可以分为三类:
系统级安装包,即system/framework/、system/app/、vendor/app/这三个目录中的APK安装包。如果传给scanDirLI方法的flags参数中含有PackageParser.PARSE_IS_SYSTEM或者PackageParser.PARSE_IS_SYSTEM_DIR这两个标记,即为系统级安装包。
FORWARD_LOCK安装包,即data/app-private目录中的APK安装包。如果传给scanDirLI的flags参数中含有PackageParser.PARSE_FORWARD_LOCK这个标记,即为FORWARD_LOCK安装包。这种安装包需要做DRM保护处理。
一般安装包,即data/app目录中的APK安装包。不需要给scanDirLI传递特殊flags参数。
与一般安装包的区别是,FORWARD_LOCK安装包的APK文件会存于/data/app-private目录下,该目录受系统保护,而一般安装包的APK文件存于/data/app目录下。FORWARD_LOCK类型的APK在安装后会在data/app/目录下生成一个与其原始文件名相同、但扩展名为zip的包。例如,对于/data/app-private/allongtest.apk文件,安装后会生成data/app/allongtest.zip文件。
ZIP文件与原始APK文件的区别是:ZIP文件中,只保留APK中的res目录、AndroidManifest.xml和resources.arsc文件。其他如assets目录、lib目录、META-INF目录、classes.dex目录等则不会出现在ZIP文件中,这样可以起到保护APK中重要资源的目的。
注意 elly Bean中增加了/data/app-asec目录,提供了更严格的权限限制。
以system/app目录为例,其扫描安装的调用代码如下:
scanDirLI(mSystemAppDir, PackageParser.PARSE_IS_SYSTEM
|PackageParser.PARSE_IS_SYSTEM_DIR, scanMode,0);
其中mSystemAppDir表示system/app目录;PackageParser.PARSE_IS_SYSTEM|PackageParser.PARSE_IS_SYSTEM_DIR表示传给scanDirLI的flags标记,表示该目录下的APK为系统级APK;scanMode表示扫描策略。如果mNoDexOpt变量赋值为true,会在scanMode中增加一个SCAN_NO_DEX标记,该标记决定后续步骤中是否对扫描的APK进行dexopt优化。mNoDexOpt的赋值过程在8.2.2节中已经分析过。
scanDirLI的流程非常复杂,为了不打断对于PackageManagerService启动过程的分析,将在第9章中详细分析该流程。
扫描安装操作完成后,需要清理一些缓存文件,并将安装失败的APK的相关信息删除。最后还需要更新权限信息。这个过程比较简单,主要是更新mSettings、mUserManager以及mPackage中的记录。