Android 8.0 PKMS新变化之提取ABI
2018-01-09 21:53
239 查看
关于ABI的知识可以网上搜一下
在8.0之前,因为每次开机都要扫描APK,所以每次都要判断并设置ABI,这个过程比较花费时间,如果手机安装大量APK,势必会造成开机时间过慢
所以之前项目会对这一块做优化,将ABI信息写入一个xml文件中,首次开机或者安装删除APK就会更新这个文件,非首次开机就会直接读取里面的值
这次Android 8.0内部优化这一过程,而且比之前的方案更简单,下面来看看是怎么实现的:
之前在分析PKMS开机初始化的时候,知道最终会进入scanPackageDirtyLI方法内:
可以看到,这部分逻辑是,如果不是第一次开机或者升级,就从mSettings中读取PackageSetting类型的值,再将其中存储的关于ABI的值保存到临时变量中
再往下看
这里会再次判断是否第一次开机或者升级
如果是的话,调用
pkg.applicationInfo.primaryCpuAbi
pkg.applicationInfo.secondaryCpuAbi
如果不是,将上面第一次判断得到的临时变量的值复制到pkg中
获取到ABI后肯定要保存起来:
在commitPackageSettings方法中会调用:
之前分析PKMS的构造函数时候说到,在构造函数最后会执行
writeLPr函数会把mPackages相关信息写入到package.xml等文件中
而在package.xml中就记录了ABI的信息:
第一次判断的时候如果不是首次开机或者升级就从mSettings的mPackages中读取PackageSetting类型的值
下面看看packages.xml中的值是怎么读取到mPackages中的
在PKMS构造函数的开始,会调用
readLPw的逻辑就是删除packages.xml,从packages-backup.xml中读取值
再按照不同的节点来来调用不同的方法解析,这里主要看readPackageLPw方法
这样就加入到mPackages中了
在8.0之前,因为每次开机都要扫描APK,所以每次都要判断并设置ABI,这个过程比较花费时间,如果手机安装大量APK,势必会造成开机时间过慢
所以之前项目会对这一块做优化,将ABI信息写入一个xml文件中,首次开机或者安装删除APK就会更新这个文件,非首次开机就会直接读取里面的值
这次Android 8.0内部优化这一过程,而且比之前的方案更简单,下面来看看是怎么实现的:
之前在分析PKMS开机初始化的时候,知道最终会进入scanPackageDirtyLI方法内:
if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) == 0) { PackageSetting foundPs = mSettings.getPackageLPr(pkg.packageName); if (foundPs != null) { primaryCpuAbiFromSettings = foundPs.primaryCpuAbiString; secondaryCpuAbiFromSettings = foundPs.secondaryCpuAbiString; } }
可以看到,这部分逻辑是,如果不是第一次开机或者升级,就从mSettings中读取PackageSetting类型的值,再将其中存储的关于ABI的值保存到临时变量中
再往下看
if ((scanFlags & SCAN_NEW_INSTALL) == 0) { if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0) { Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi"); final boolean extractNativeLibs = !pkg.isLibrary(); derivePackageAbi(pkg, scanFile, cpuAbiOverride, extractNativeLibs, mAppLib32InstallDir); Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); // Some system apps still use directory structure for native libraries // in which case we might end up not detecting abi solely based on apk // structure. Try to detect abi based on directory structure. if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() && pkg.applicationInfo.primaryCpuAbi == null) { setBundledAppAbisAndRoots(pkg, pkgSetting); setNativeLibraryPaths(pkg, mAppLib32InstallDir); } } else { // This is not a first boot or an upgrade, don't bother deriving the // ABI during the scan. Instead, trust the value that was stored in the // package setting. pkg.applicationInfo.primaryCpuAbi = primaryCpuAbiFromSettings; pkg.applicationInfo.secondaryCpuAbi = secondaryCpuAbiFromSettings; setNativeLibraryPaths(pkg, mAppLib32InstallDir); if (DEBUG_ABI_SELECTION) { Slog.i(TAG, "Using ABIS and native lib paths from settings : " + pkg.packageName + " " + pkg.applicationInfo.primaryCpuAbi + ", " + pkg.applicationInfo.secondaryCpuAbi); } } }
这里会再次判断是否第一次开机或者升级
如果是的话,调用
derivePackageAbi方法解析abi路径等相关信息存到pkg中
pkg.applicationInfo.primaryCpuAbi
pkg.applicationInfo.secondaryCpuAbi
如果不是,将上面第一次判断得到的临时变量的值复制到pkg中
获取到ABI后肯定要保存起来:
在commitPackageSettings方法中会调用:
mSettings.insertPackageSettingLPw(pkgSetting, pkg)
[Settings.java] void insertPackageSettingLPw(PackageSetting p, PackageParser.Package pkg) { addPackageSettingLPw(p, p.sharedUser); } private void addPackageSettingLPw(PackageSetting p, SharedUserSetting sharedUser) { //这里会加入到mPackages中 mPackages.put(p.name, p); }
之前分析PKMS的构造函数时候说到,在构造函数最后会执行
mSettings.writeLPr()
writeLPr函数会把mPackages相关信息写入到package.xml等文件中
而在package.xml中就记录了ABI的信息:
<package name="com.google.andro 9d44 id.youtube" codePath="/system/app/YouTube" nativeLibraryPath="/system/app/YouTube/lib" primaryCpuAbi="arm64-v8a" ......> <package name="com.android.chrome" codePath="/system/app/Chrome" nativeLibraryPath="/system/app/Chrome/lib" primaryCpuAbi="armeabi-v7a" secondaryCpuAbi="arm64-v8a" .......>
第一次判断的时候如果不是首次开机或者升级就从mSettings的mPackages中读取PackageSetting类型的值
下面看看packages.xml中的值是怎么读取到mPackages中的
在PKMS构造函数的开始,会调用
mSettings.readLPw
[Settings.java] boolean readLPw(@NonNull List<UserInfo> users) { //mBackupSettingsFilename = new File(mSystemDir, "packages-backup.xml"); str = new FileInputStream(mBackupSettingsFilename); XmlPullParser parser = Xml.newPullParser(); parser.setInput(str, StandardCharsets.UTF_8.name()); if (tagName.equals("package")) { readPackageLPw(parser); } }
readLPw的逻辑就是删除packages.xml,从packages-backup.xml中读取值
再按照不同的节点来来调用不同的方法解析,这里主要看readPackageLPw方法
primaryCpuAbiString = parser.getAttributeValue(null, "primaryCpuAbi"); secondaryCpuAbiString = parser.getAttributeValue(null, "secondaryCpuAbi"); //读取一些值后调用addPackageLPw方法 packageSetting = addPackageLPw(......, primaryCpuAbiString,secondaryCpuAbiString,......); PackageSettinga ddPackageLPw(......) { p = new PackageSetting(......, primaryCpuAbiString, secondaryCpuAbiString,......); mPackages.put(name, p); }
这样就加入到mPackages中了
相关文章推荐
- Android 8.0 PKMS新变化之提取ABI
- Android 8.0 PKMS新变化之提取ABI
- Android 8.0 PKMS新变化之提取ABI
- Android 8.0 PKMS新变化之提取ABI
- Android 8.0 PKMS新变化之提取ABI
- Android 8.0 PKMS新变化之多线程扫描APK
- Android 8.0 PKMS新变化之多线程扫描APK
- Android 8.0 PKMS新变化之多线程扫描APK
- Android 8.0 PKMS新变化之多线程扫描APK
- Android 8.0 PKMS新变化之多线程扫描APK
- Android 8.0 PKMS新变化之多线程扫描APK
- Android 7.0以上(包含8.0), popupWindow弹窗位置异常, 解决方案
- android monitor tool (8.0 监控文件系统 添加哪个进程修改文件功能)
- Google pixel Android 8.0 模拟器
- 安卓Android ROM定制、移植,安卓软件反编译、汉化实战教程第五篇:HTC官方ROM提取(制作前篇)
- 关于android art模式提取的OAT转dex
- Android系统截屏功能提取
- Android 8.0系统上使用WindowManager添加view的一个问题
- Android 8.0 推出了Project Treble,最大的变化之一是 HAL binderized
- Android 8.0 RIL源码分析(一)