这里先初步看一下做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开关控制)

更多相关文章

  1. Android中getView与inflate方法的详解
  2. (20120731)android面试总结(003)
  3. Android(安卓)- View的绘制流程二(layout)
  4. Android(安卓)ISurface PostBuffer 处理流程
  5. Android下在onCreate方法中获取TextView的高度
  6. 新版Cordova(>4.0)编译Android(安卓)APK打上签名方法
  7. Volley二次封装,实现网络请求缓存
  8. Android(安卓)ListView/ListActivity点击长按事件
  9. Windows下,Ant自动化编译Android项目具体步骤和方法

随机推荐

  1. Android(安卓)onTouchEvent, onClick及on
  2. Failed to resolve: com.android.support
  3. 关于 android 远程控制(pc 控制手机)
  4. Intent学习
  5. 浅谈Android的BaseAdapter适配器模式
  6. Android开发环境配置之ADT怪异问题
  7. Graphical layout无法正确显示的解决方法
  8. Android(安卓)中监听WIFI连接状态变化
  9. 【Android】10.1 扩展组件库和其他视图--
  10. Android(安卓)Camera 高级特性——闪光灯