I received from my phone carrier, Vodafone IT, the official OTA Google update to Android Ice Cream Sandwich 4.0.4 on my Nexus S. When automatically rebooting for the first time after the update, the system displayed a notice stating that it was optimizing the installed apps. What kind of optimization does Android 4.0+ do at the first reboot?
1 Answer
Digging into the PackageManagerService class on grepCode (warning: this class file is huge, your browser may chug a fair bit when rendering it), the optimizing message is displayed in the following context:
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);
}
}
}
}
}
Here the value of com.android.internal.R.string.android_upgrading_apk
is the string "Optimizing application". In layman's terms, it loops through each application on the device, updates the message on the screen by calling showBootMessage()
and then calls performDexOptLI()
on the application. So naturally, the next question is "What does performDexOptLI()
do?" Well here's what that looks like:
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;
}
So this invokes the dexopt
utility on all of the applications that need it. It's difficult to find any simple documentation regarding dexopt
, but there's a high-level overview here. Suffice it to say, it's being used by the Just In Time (JIT) compiler to create optimized .dex files that help improve the performance of the apps on your device and it outputs them into the VM cache. The reason it stores the .dex files in the cache is because otherwise it would have to re-extract them any time you want to run the app (the .apk is just an archive, it is not an executable file!). Thus, it makes sense to just keep them in the /data/dalvik-cache
directory to reuse them, and dexopt
performs some optimizations during the initial extraction while it's at it.
TL;DR (or non-programmer summary, I guess): It's rebuilding the Dalvik cache.
-
That's indeed the message I saw when the system went through all installed apps. Thanks for the great answer. Commented Apr 10, 2012 at 17:58