From 4b60d29375d3422e4d08382c44b0faa5343f6eda Mon Sep 17 00:00:00 2001 From: Yurii Zubrytskyi Date: Thu, 1 Dec 2022 00:34:09 -0800 Subject: [PATCH] Move IO from under the ResourcesManager lock ApkAssets.isUpToDate() performs IO for many types of assets, and doing it under a highly contended lock may cause visible jank. Given that we don't have to remove the key right at the time of the lookup, it's fine to move the up-to-date check out of the lock - if it's not, the function would replace the outdated asset anyway Bug: 259941466 Test: build + boot Change-Id: I8828deadc82180e93bbd9fc34f80a7bd9411d4ad --- core/java/android/app/ResourcesManager.java | 26 +++++++++++---------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java index d275c8336251d..322176100e926 100644 --- a/core/java/android/app/ResourcesManager.java +++ b/core/java/android/app/ResourcesManager.java @@ -305,9 +305,13 @@ public class ResourcesManager { for (int i = mCachedApkAssets.size() - 1; i >= 0; i--) { final ApkKey key = mCachedApkAssets.keyAt(i); if (key.path.equals(path)) { - WeakReference apkAssetsRef = mCachedApkAssets.removeAt(i); - if (apkAssetsRef != null && apkAssetsRef.get() != null) { - apkAssetsRef.get().close(); + final WeakReference apkAssetsRef = mCachedApkAssets.removeAt(i); + if (apkAssetsRef == null) { + continue; + } + final ApkAssets apkAssets = apkAssetsRef.get(); + if (apkAssets != null) { + apkAssets.close(); } } } @@ -446,16 +450,14 @@ public class ResourcesManager { ApkAssets apkAssets; // Optimistically check if this ApkAssets exists somewhere else. + final WeakReference apkAssetsRef; synchronized (mLock) { - final WeakReference apkAssetsRef = mCachedApkAssets.get(key); - if (apkAssetsRef != null) { - apkAssets = apkAssetsRef.get(); - if (apkAssets != null && apkAssets.isUpToDate()) { - return apkAssets; - } else { - // Clean up the reference. - mCachedApkAssets.remove(key); - } + apkAssetsRef = mCachedApkAssets.get(key); + } + if (apkAssetsRef != null) { + apkAssets = apkAssetsRef.get(); + if (apkAssets != null && apkAssets.isUpToDate()) { + return apkAssets; } }