Android(安卓)8.0 dexopt记录
这里先初步看一下做odex优化的几个地方,以后再补充详细过程
一、installd的变化
首先回忆一下在7.0中installd是如何启动的:
在installd.rc中:
service installd /system/bin/installd class main socket installd stream 600 system system
这里启动installd的同时还启动了一个socket,在installd.cpp中有获取这个socket的地方android_get_control_socket
由于已经过时,其它的不再说了,下面看看8.0中是如何启动的:
在installd.rc中:
service installd /system/bin/installd class main
只是启动installd,进入installd看一下
[installd.cpp]int main(const int argc, char *argv[]) { return android::installd::installd_main(argc, argv);}static int installd_main(const int argc ATTRIBUTE_UNUSED, char *argv[]) { …… if ((ret = InstalldNativeService::start()) != android::OK) { SLOGE("Unable to start InstalldNativeService: %d", ret); exit(1); } IPCThreadState::self()->joinThreadPool(); LOG(INFO) << "installd shutting down"; return 0;}
看看这个InstalldNativeService是什么,InstalldNativeService .h中定义如下:
class InstalldNativeService : public BinderService<InstalldNativeService>, public os::BnInstalld
看到这是否有熟悉的感觉?之前在实现Native Service的时候,我们自己定义的TestPlayService就是这样定义的:
class TestPlayService : public BinderService<TestPlayService>, public BnTestPlayService
这说明installd和客户端是通过binder来通信的
那么肯定就有把这个service加入到servicemanager中的地方,继续看start()方法:
[InstalldNativeService.cpp]status_t InstalldNativeService::start() { IPCThreadState::self()->disableBackgroundScheduling(true); status_t ret = BinderService<InstalldNativeService>::publish(); if (ret != android::OK) { return ret; } sp<ProcessState> ps(ProcessState::self()); ps->startThreadPool(); ps->giveThreadPoolName(); return android::OK;}
明显,就是通过publish()这个方法的,可以看下它的定义
[BinderService.h]static status_t publish(bool allowIsolated = false) { sp sm(defaultServiceManager()); return sm->addService( String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated);}
那这个InstalldNativeService是不是我们要找到的installd呢,看一下它加入到servicemanager中的名字,
static char const* getServiceName() { return "installd"; }
就是installd !
二、odex优化的地方
1.首次开机或者升级
在SystemServer.java 中有mPackageManagerService.updatePackagesIfNeeded()
这里先列举流程,具体步骤有空再贴上
updatePackagesIfNeeded->performDexOptUpgrade->performDexOptTraced->performDexOptInternal->performDexOptInternalWithDependenciesLI->PackageDexOptimizer.performDexOpt->performDexOptLI->dexOptPath->Installer.dexopt->InstalldNativeService.dexopt->dexopt.dexopt
2.安装应用:
在PKMS.installPackageLI函数中有:
mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles,
null /* instructionSets /, false / checkProfiles */,
getCompilerFilterForReason(REASON_INSTALL),
getOrCreateCompilerPackageStats(pkg),
mDexManager.isUsedByOtherApps(pkg.packageName));
3.IPackageManager.aidl提供了performDexOpt方法
在PKMS中有实现的地方,但是没找到调用的地方
4.IPackageManager.aidl提供了performDexOptMode方法
在PKMS中有实现的地方,在PackageManagerShellCommand中会被调用,应该是提供给shell命令调用
5.OTA升级后:
在SystemServer.java 中有OtaDexoptService.main(mSystemContext, mPackageManagerService);
public static OtaDexoptService main(Context context, PackageManagerService packageManagerService) { OtaDexoptService ota = new OtaDexoptService(context, packageManagerService); ServiceManager.addService("otadexopt", ota); // Now it's time to check whether we need to move any A/B artifacts. ota.moveAbArtifacts(packageManagerService.mInstaller); return ota;}
private void moveAbArtifacts(Installer installer) { if (mDexoptCommands != null) { throw new IllegalStateException("Should not be ota-dexopting when trying to move."); } //如果不是升级上来的,就return掉 if (!mPackageManagerService.isUpgrade()) { Slog.d(TAG, "No upgrade, skipping A/B artifacts check."); return; } installer.moveAb(path, dexCodeInstructionSet, oatDir);}
moveAbArtifacts函数的逻辑:
1.判断是否升级
2.判断扫描过的package是否有code,没有则跳过
3.判断package的code路径是否为空,为空则跳过
4.如果package的code在system或者vendor目录下,跳过
5.满足上述条件,调用Installer.java中的moveAb方法
最终是调用dexopt.cpp的move_ab方法
OtaDexoptService也提供给shell命令一些方法来调用
6.在系统空闲的时候:
是通过BackgroundDexOptService来实现的,BackgroundDexOptService继承了JobService
这里启动了两个任务
1.开机的时候执行odex优化 JOB_POST_BOOT_UPDATE
执行条件:开机一分钟内
2.在系统休眠的时候执行优化 JOB_IDLE_OPTIMIZE
执行条件:设备处于空闲,插入充电器,且每隔一分钟或者一天就检查一次(根据debug开关控制)
更多相关文章
- Android中getView与inflate方法的详解
- (20120731)android面试总结(003)
- Android(安卓)- View的绘制流程二(layout)
- Android(安卓)ISurface PostBuffer 处理流程
- Android下在onCreate方法中获取TextView的高度
- 新版Cordova(>4.0)编译Android(安卓)APK打上签名方法
- Volley二次封装,实现网络请求缓存
- Android(安卓)ListView/ListActivity点击长按事件
- Windows下,Ant自动化编译Android项目具体步骤和方法