Я получил от своего оператора мобильной связи, Vodafone IT, официальное OTA-обновление Google для Android Ice Cream Sandwich 4.0.4 на своем Nexus S. При автоматической перезагрузке в первый раз после обновления система отображала уведомление о том, что она оптимизирует установленные приложения. Какую оптимизацию делает Android 4.0+ при первой перезагрузке?
Копаясь в классе PackageManagerService в grepCode (предупреждение: этот файл класса огромен, ваш браузер может немного зависнуть при его отображении), сообщение об оптимизации отображается в следующем контексте:
public void performBootDexOpt() {
ArrayList<PackageParser.Package> pkgs = null;
synchronized (mPackages) {
if (mDeferredDexOpt.size() > 0) {
pkgs = new ArrayList<PackageParser.Package>(mDeferredDexOpt);
mDeferredDexOpt.clear();
}
}
if (pkgs != null) {
for (int i=0; i<pkgs.size(); i++) {
if (!isFirstBoot()) {
try {
ActivityManagerNative.getDefault().showBootMessage(
mContext.getResources().getString(
com.android.internal.R.string.android_upgrading_apk,
i+1, pkgs.size()), true);
} catch (RemoteException e) {
}
}
PackageParser.Package p = pkgs.get(i);
synchronized (mInstallLock) {
if (!p.mDidDexOpt) {
performDexOptLI(p, false, false);
}
}
}
}
}
Здесь значением com.android.internal.R.string.android_upgrading_apk
является строка «Оптимизация приложения». С точки зрения непрофессионала, он просматривает каждое приложение на устройстве, обновляет сообщение на экране, вызывая вызов, showBootMessage()
а затем вызывает performDexOptLI()
приложение. Поэтому, естественно, следующий вопрос: «Что делает performDexOptLI()
?» Вот как это выглядит:
private int performDexOptLI(PackageParser.Package pkg, boolean forceDex, boolean defer) {
boolean performed = false;
if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0) {
String path = pkg.mScanPath;
int ret = 0;
try {
if (forceDex || dalvik.system.DexFile.isDexOptNeeded(path)) {
if (!forceDex && defer) {
mDeferredDexOpt.add(pkg);
return DEX_OPT_DEFERRED;
} else {
Log.i(TAG, "Running dexopt on: " + pkg.applicationInfo.packageName);
ret = mInstaller.dexopt(path, pkg.applicationInfo.uid,
!isForwardLocked(pkg));
pkg.mDidDexOpt = true;
performed = true;
}
}
} catch (...) {
//I've trimmed out a bunch of exception handling here, it basically just writes to
//the log and sets the return value
}
}
return performed ? DEX_OPT_PERFORMED : DEX_OPT_SKIPPED;
}
Так что это вызывает dexopt
утилиту для всех приложений, которые в ней нуждаются. Трудно найти какую-либо простую документацию по dexopt
, но здесь есть общий обзор . Достаточно сказать, что он используется компилятором Just In Time (JIT) для создания оптимизированных файлов .dex, которые помогают повысить производительность приложений на вашем устройстве, и выводит их в кеш виртуальной машины. Причина, по которой он хранит файлы .dex в кеше, заключается в том, что в противном случае ему пришлось бы повторно извлекать их каждый раз, когда вы хотите запустить приложение (.apk — это просто архив, а не исполняемый файл!). Таким образом, имеет смысл просто хранить их в /data/dalvik-cache
каталоге для повторного использования и dexopt
выполнять некоторые оптимизации во время первоначального извлечения, пока оно выполняется.
TL;DR (или краткое изложение для непрограммистов, я думаю): это восстановление кеша Dalvik.
Паоло Аморозо