From be78258e5530613a56bb9d7c3b4a31a5d248ba85 Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Mon, 15 Feb 2016 18:35:57 -0700 Subject: [PATCH] Add path cache to avoid SharedPreferences jank. The old getSharedPreferences() API had a side-effect behavior that subsequent calls wouldn't touch disk if there was a cache hit. Now that we're using File as the cache key, we were generating the path every time, which resulted in touching disk. To bring back the old behavior, let's add yet another cache! Bug: 26979210 Change-Id: Ib8346c6f69ae25f8f164e3b7e05bc6358de38906 --- core/java/android/app/ContextImpl.java | 29 ++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index 282707152e6ac..377758ee575ac 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -134,7 +134,14 @@ class ContextImpl extends Context { /** * Map from package name, to preference name, to cached preferences. */ - private static ArrayMap> sSharedPrefs; + @GuardedBy("ContextImpl.class") + private static ArrayMap> sSharedPrefsCache; + + /** + * Map from preference name to generated path. + */ + @GuardedBy("ContextImpl.class") + private ArrayMap mSharedPrefsPaths; final ActivityThread mMainThread; final LoadedApk mPackageInfo; @@ -335,7 +342,17 @@ class ContextImpl extends Context { } } - final File file = getSharedPreferencesPath(name); + File file; + synchronized (ContextImpl.class) { + if (mSharedPrefsPaths == null) { + mSharedPrefsPaths = new ArrayMap<>(); + } + file = mSharedPrefsPaths.get(name); + if (file == null) { + file = getSharedPreferencesPath(name); + mSharedPrefsPaths.put(name, file); + } + } return getSharedPreferences(file, mode); } @@ -363,15 +380,15 @@ class ContextImpl extends Context { } private ArrayMap getSharedPreferencesCacheLocked() { - if (sSharedPrefs == null) { - sSharedPrefs = new ArrayMap<>(); + if (sSharedPrefsCache == null) { + sSharedPrefsCache = new ArrayMap<>(); } final String packageName = getPackageName(); - ArrayMap packagePrefs = sSharedPrefs.get(packageName); + ArrayMap packagePrefs = sSharedPrefsCache.get(packageName); if (packagePrefs == null) { packagePrefs = new ArrayMap<>(); - sSharedPrefs.put(packageName, packagePrefs); + sSharedPrefsCache.put(packageName, packagePrefs); } return packagePrefs;