Android 8.0 dexoptレコード
ここではまずodexの最適化を行ういくつかの場所を初歩的に見て、後で詳細な過程を補充します.
一、installdの変化
まず7.0でinstalldがどのように起動したかを思い出します:installd.rc:
ここでinstalldを起動すると同時にsocketも起動し、installd.cppにこのsocketを取得した場所が
もう時代遅れなので、他のことは言わないで、8.0でどのように起動したかを見てみましょう.installd.rc:
installdを起動するだけで、installdに入って見てみましょう
これを見てください.hでは以下のように定義する.
これを見てよく知っている感じがしますか?以前Native Serviceを実装したとき、私たちが定義したTestPlayServiceはこのように定義されていました.
これはinstalldとクライアントがbinderを介して通信していることを示している.
では、このサービスをサービスマネージャに追加する場所があり、start()を見続ける方法があるに違いありません.
明らかに、publish()という方法によって、その定義を見ることができます.
では、このInstalldNativeServiceは私たちが見つけなければならないinstalldではないでしょうか.servicemanagerに追加された名前を見てみましょう.
installdだ!
二、odex最適化の場所
1.初回起動またはアップグレード
SystemServerでJAvaにはmPackageManagerServicesがあります.updatePackagesIfNeeded()ここではまず流れを列挙し、具体的な手順は空いてからupdatePackagesIfNeed->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には
moveAbArtifacts関数の論理:1.アップグレードするかどうかを判断する.スキャンしたパッケージにコードがあるかどうかを判断し、ない場合はスキップする.packageのcodeパスが空かどうかを判断し、空であればスキップ4.パッケージのコードがsystemまたはvendorディレクトリの下にある場合は、5をスキップします.上記条件を満たす、Installerを呼び出す.JAvaのmoveAbメソッドは最終的にdexoptを呼び出す.cppのmove_abメソッド
OtaDexoptServiceはshellコマンドにもいくつかのメソッドを呼び出します
6.システムが空いている場合:
BackgroundDexOptServiceによって実現され、BackgroundDexOptServiceはJobServiceを継承するここで2つのタスク1を開始した.起動時にodex最適化JOB_を実行POST_BOOT_UPDATE実行条件:起動1分以内2.システム休止時に最適化JOB_を実行IDLE_OPTIMIZE実行条件:設備が空き、充電器を挿入し、1分または1日おきに検査する(debugスイッチ制御による)
一、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;
}
これを見てください.hでは以下のように定義する.
class InstalldNativeService : public BinderService<InstalldNativeService>, public os::BnInstalld
これを見てよく知っている感じがしますか?以前Native Serviceを実装したとき、私たちが定義したTestPlayServiceはこのように定義されていました.
class TestPlayService : public BinderService<TestPlayService>, public BnTestPlayService
これはinstalldとクライアントがbinderを介して通信していることを示している.
では、このサービスをサービスマネージャに追加する場所があり、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にはmPackageManagerServicesがあります.updatePackagesIfNeeded()ここではまず流れを列挙し、具体的な手順は空いてからupdatePackagesIfNeed->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.アップグレードするかどうかを判断する.スキャンしたパッケージにコードがあるかどうかを判断し、ない場合はスキップする.packageのcodeパスが空かどうかを判断し、空であればスキップ4.パッケージのコードがsystemまたはvendorディレクトリの下にある場合は、5をスキップします.上記条件を満たす、Installerを呼び出す.JAvaのmoveAbメソッドは最終的にdexoptを呼び出す.cppのmove_abメソッド
OtaDexoptServiceはshellコマンドにもいくつかのメソッドを呼び出します
6.システムが空いている場合:
BackgroundDexOptServiceによって実現され、BackgroundDexOptServiceはJobServiceを継承するここで2つのタスク1を開始した.起動時にodex最適化JOB_を実行POST_BOOT_UPDATE実行条件:起動1分以内2.システム休止時に最適化JOB_を実行IDLE_OPTIMIZE実行条件:設備が空き、充電器を挿入し、1分または1日おきに検査する(debugスイッチ制御による)